From: balakrishnan <balakrishnan@e-consystems.com>
To: openembedded-devel@lists.openembedded.org
Subject: [PATCH] Add pxa270 based Regulus Board
Date: Wed, 17 Mar 2010 19:44:40 +0530 [thread overview]
Message-ID: <1268835281.28188.19.camel@balakrishnan-desktop> (raw)
In-Reply-To: <mailman.5.1268823603.27114.openembedded-devel@lists.openembedded.org>
[-- Attachment #1: Type: text/plain, Size: 774 bytes --]
Hi,
Please neglect my previous patches(16-03-2010), B'coz some swpfiles
are presents in my previous patches.
Latest patches are attached with this mail.
With Regards
J.Balakrishnan
>On Wed, 2010-03-17 at 12:00 +0100,
>openembedded-devel-request@lists.openembedded.org wrote:
> Hello balakrishnan,
>
> On Tue 16 Mar 2010 05:42 PM, balakrishnan wrote:
> > Regulus is pxa270 based machine, attached patches need to be
> reviewed and
> > added to oe tree. This patches are used to create u-boot, kernel and
> > demo-image for regulus machine.
> You've included vim swapfiles in the patch, please remove these and
> re-submit. I'm not a Openembedded developer, so there may be other
> comments
> as well.
>
> --
> With regards,
> Ruud Althuizen
[-- Attachment #2: 0001-regulus-pxa270-based-machine.patch --]
[-- Type: text/x-patch, Size: 2127 bytes --]
From 2e38f3419c8dcabe283770cf165b667403956172 Mon Sep 17 00:00:00 2001
From: balakrishnan <balakrishnan@e-consystems.com>
Date: Wed, 17 Mar 2010 19:12:36 +0530
Subject: [PATCH] regulus: pxa270 based machine
* Regulus is a pxa270 based reference kit
* It is a product of e-con Systems India Pvt Ltd
Signed-off-by: balakrishnan <balakrishnan@e-consystems.com>
---
conf/machine/regulus.conf | 53 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
create mode 100644 conf/machine/regulus.conf
diff --git a/conf/machine/regulus.conf b/conf/machine/regulus.conf
new file mode 100644
index 0000000..d409832
--- /dev/null
+++ b/conf/machine/regulus.conf
@@ -0,0 +1,53 @@
+#@TYPE: Machine
+#@NAME: Regulus machine
+#@DESCRIPTION: Machine configuration for the http://www.e-consystems.com board
+TARGET_ARCH = "arm"
+
+PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
+XSERVER = "xserver-xorg \
+ xf86-input-evdev \
+ xf86-input-mouse \
+ xf86-video-fbdev \
+ xf86-input-keyboard \
+ xf86-input-tslib "
+
+# PREFERRED_PROVIDER_virtual/xserver = "xserver-kdrive"
+# XSERVER = "xserver-kdrive-fbdev"
+
+
+# Only has VGA adaptor for external screen
+GUI_MACHINE_CLASS = "bigscreen"
+
+PREFERRED_PROVIDER_virtual/kernel = "linux"
+PREFERRED_VERSION_linux = "2.6.25"
+
+ARM_INSTRUCTION_SET = "arm"
+THUMB_INTERWORK = "no"
+
+require conf/machine/include/tune-xscale.inc
+
+# Increase this everytime you change something in the kernel
+MACHINE_KERNEL_PR = "r1"
+
+KERNEL_IMAGETYPE = "uImage"
+
+UBOOT_ENTRYPOINT = "0xA0008000"
+UBOOT_LOADADDRESS = "0xA0008000"
+
+# Build u-boot
+EXTRA_IMAGEDEPENDS += "u-boot"
+
+IMAGE_FSTYPES += "tar.bz2 "
+
+# Guesswork
+SERIAL_CONSOLE = "115200 ttyS2"
+
+# To Select regulus machine
+UBOOT_MACHINE = "regulus_config"
+
+# U-Boot version
+PREFERRED_VERSION_u-boot = "2008.10"
+
+# MACHINE_FEATURES = "kernel26 usbgadget usbhost vfat alsa screen"
+MACHINE_FEATURES = "kernel26 usbgadget usbhost vfat alsa touchscreen"
+
--
1.6.0.4
[-- Attachment #3: 0002-linux_2.6.25-Regulus-support-added.patch --]
[-- Type: text/x-patch, Size: 2052705 bytes --]
From f710a2b5bb437142c6f6c6d08759724838c22a33 Mon Sep 17 00:00:00 2001
From: balakrishnan <balakrishnan@e-consystems.com>
Date: Wed, 17 Mar 2010 19:14:20 +0530
Subject: [PATCH] linux_2.6.25: Regulus support added
* Regulus patch & configuration will be applied to the linux-2.6.25 kernel
Signed-off-by: balakrishnan <balakrishnan@e-consystems.com>
---
recipes/linux/linux-2.6.25/regulus/defconfig | 1629 +
.../regulus/regulus_linux-2.6.25.patch |66865 ++++++++++++++++++++
recipes/linux/linux_2.6.25.bb | 5 +
3 files changed, 68499 insertions(+), 0 deletions(-)
create mode 100644 recipes/linux/linux-2.6.25/regulus/defconfig
create mode 100644 recipes/linux/linux-2.6.25/regulus/regulus_linux-2.6.25.patch
diff --git a/recipes/linux/linux-2.6.25/regulus/defconfig b/recipes/linux/linux-2.6.25/regulus/defconfig
new file mode 100644
index 0000000..cb5e955
--- /dev/null
+++ b/recipes/linux/linux-2.6.25/regulus/defconfig
@@ -0,0 +1,1629 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25
+# Mon Jan 4 14:41:18 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_KGDB_PXA_SERIAL=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+CONFIG_BLK_DEV_BSG=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+CONFIG_MACH_REGULUS=y
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_PCM027 is not set
+CONFIG_PXA27x=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+# CONFIG_BT_BNEP is not set
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=y
+# CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
+# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
+
+#
+# Selecting 'y' for an algorithm will
+#
+
+#
+# build the algorithm into mac80211.
+#
+CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_SIMPLE is not set
+# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
+# CONFIG_MAC80211_DEBUG is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x2000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PXA2XX is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_REGULUS=y
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=m
+CONFIG_IDE_MAX_HWIFS=4
+# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID10 is not set
+CONFIG_MD_RAID456=y
+CONFIG_MD_RAID5_RESHAPE=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+CONFIG_DM_MULTIPATH_RDAC=m
+CONFIG_DM_MULTIPATH_HP=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_REGULUS_AX88796B=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_E1000E_ENABLED is not set
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+CONFIG_ZD1211RW=m
+CONFIG_ZD1211RW_DEBUG=y
+# CONFIG_RT2X00 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_PXA27x is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_UCB1400=y
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_E_CON_QUAD_UART_TI16C174B=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=y
+CONFIG_I2C_ALGOPCA=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+# CONFIG_DEBUG_GPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+CONFIG_SSB=y
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_VIVI=y
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_VMALLOC=y
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_PARAMETERS=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=y
+CONFIG_SND_PXA2XX_AC97=y
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_SSB is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_DEBUG=y
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SA1100 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_DEBUG=y
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# 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_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# 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_9 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_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
+# CONFIG_KGDB is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SALSA20=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CAMELLIA=y
+# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/recipes/linux/linux-2.6.25/regulus/regulus_linux-2.6.25.patch b/recipes/linux/linux-2.6.25/regulus/regulus_linux-2.6.25.patch
new file mode 100644
index 0000000..dc58d0e
--- /dev/null
+++ b/recipes/linux/linux-2.6.25/regulus/regulus_linux-2.6.25.patch
@@ -0,0 +1,66865 @@
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_crt_640_480_defconfig linux-2.6.25/arch/arm/configs/regulus_crt_640_480_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_crt_640_480_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_crt_640_480_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1454 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Thu Apr 9 19:19:12 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=m
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_H1900 is not set
++CONFIG_MTD_NAND_REGULUS=m
++CONFIG_MTD_NAND_IDS=m
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_SHARPSL is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++CONFIG_PPP_DEFLATE=y
++CONFIG_PPP_BSDCOMP=y
++# CONFIG_PPP_MPPE is not set
++# CONFIG_PPPOE is not set
++# CONFIG_PPPOL2TP is not set
++# CONFIG_SLIP is not set
++CONFIG_SLHC=y
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=y
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++CONFIG_I2C_PXA_SLAVE=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_LCD_DISPLAY_3P5_INCH_320_240 is not set
++# CONFIG_LCD_DISPLAY_5P7_INCH_640_480 is not set
++# CONFIG_LCD_DISPLAY_6P5_INCH_640_480 is not set
++CONFIG_CRT_DISPLAY_640_480=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_dallas1338_rtc_defconfig linux-2.6.25/arch/arm/configs/regulus_dallas1338_rtc_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_dallas1338_rtc_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_dallas1338_rtc_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1447 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Wed Jan 21 18:09:10 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_IDE_MAX_HWIFS=4
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++CONFIG_USB_ZD1201=y
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_HOSTAP=y
++# CONFIG_HOSTAP_FIRMWARE is not set
++CONFIG_B43=y
++# CONFIG_B43_DEBUG is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=y
++CONFIG_ZD1211RW_DEBUG=y
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=m
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++CONFIG_I2C_PXA_SLAVE=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++CONFIG_I2C_DEBUG_CORE=y
++CONFIG_I2C_DEBUG_ALGO=y
++CONFIG_I2C_DEBUG_BUS=y
++CONFIG_I2C_DEBUG_CHIP=y
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_WRITEBUFFER is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_defconfig linux-2.6.25/arch/arm/configs/regulus_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_defconfig 2009-08-13 12:30:07.000000000 +0530
+@@ -0,0 +1,1504 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Thu Aug 13 12:27:04 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++CONFIG_KGDB_PXA_SERIAL=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++CONFIG_NL80211=y
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_H1900 is not set
++CONFIG_MTD_NAND_REGULUS=y
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_SHARPSL is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++CONFIG_LIBERTAS=m
++# CONFIG_LIBERTAS_USB is not set
++CONFIG_LIBERTAS_SDIO=m
++# CONFIG_LIBERTAS_DEBUG is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_B43 is not set
++# CONFIG_B43LEGACY is not set
++# CONFIG_ZD1211RW is not set
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++CONFIG_PPP_DEFLATE=y
++CONFIG_PPP_BSDCOMP=y
++# CONFIG_PPP_MPPE is not set
++# CONFIG_PPPOE is not set
++# CONFIG_PPPOL2TP is not set
++# CONFIG_SLIP is not set
++CONFIG_SLHC=y
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=y
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++# CONFIG_I2C_PXA_SLAVE is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++# CONFIG_NFS_V4 is not set
++CONFIG_NFS_DIRECTIO=y
++CONFIG_NFSD=y
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++# CONFIG_ROOT_NFS is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=y
++CONFIG_NFS_ACL_SUPPORT=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_BIND34 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_WANT_EXTRA_DEBUG_INFORMATION is not set
++# CONFIG_KGDB is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_ethernet_quaduart_pxauarts_defconfig linux-2.6.25/arch/arm/configs/regulus_ethernet_quaduart_pxauarts_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_ethernet_quaduart_pxauarts_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_ethernet_quaduart_pxauarts_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1323 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Tue Jan 13 14:55:37 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_IDE_MAX_HWIFS=4
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++CONFIG_USB_ZD1201=y
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_HOSTAP=y
++# CONFIG_HOSTAP_FIRMWARE is not set
++CONFIG_B43=y
++# CONFIG_B43_DEBUG is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=y
++CONFIG_ZD1211RW_DEBUG=y
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=m
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_ethernet_rtc_quaduart_defconfig linux-2.6.25/arch/arm/configs/regulus_ethernet_rtc_quaduart_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_ethernet_rtc_quaduart_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_ethernet_rtc_quaduart_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1446 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Sat Jan 24 17:18:43 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_IDE_MAX_HWIFS=4
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++CONFIG_USB_ZD1201=y
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_HOSTAP=y
++# CONFIG_HOSTAP_FIRMWARE is not set
++CONFIG_B43=y
++# CONFIG_B43_DEBUG is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=y
++CONFIG_ZD1211RW_DEBUG=y
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++CONFIG_I2C_PXA_SLAVE=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++CONFIG_I2C_DEBUG_CORE=y
++CONFIG_I2C_DEBUG_ALGO=y
++CONFIG_I2C_DEBUG_BUS=y
++CONFIG_I2C_DEBUG_CHIP=y
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++# CONFIG_JFFS2_FS_WRITEBUFFER is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_ethernet_rtc_quaduart_nand_defconfig linux-2.6.25/arch/arm/configs/regulus_ethernet_rtc_quaduart_nand_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_ethernet_rtc_quaduart_nand_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_ethernet_rtc_quaduart_nand_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1459 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Wed Feb 4 16:48:23 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=m
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_H1900 is not set
++CONFIG_MTD_NAND_REGULUS=m
++CONFIG_MTD_NAND_IDS=m
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_SHARPSL is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_IDE_MAX_HWIFS=4
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++CONFIG_USB_ZD1201=y
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_HOSTAP=y
++CONFIG_HOSTAP_FIRMWARE=y
++CONFIG_HOSTAP_FIRMWARE_NVRAM=y
++CONFIG_B43=y
++# CONFIG_B43_DEBUG is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=y
++CONFIG_ZD1211RW_DEBUG=y
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=y
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++CONFIG_I2C_PXA_SLAVE=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++CONFIG_I2C_DEBUG_CORE=y
++CONFIG_I2C_DEBUG_ALGO=y
++CONFIG_I2C_DEBUG_BUS=y
++CONFIG_I2C_DEBUG_CHIP=y
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_lcd_3p5_inch_240_320_defconfig linux-2.6.25/arch/arm/configs/regulus_lcd_3p5_inch_240_320_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_lcd_3p5_inch_240_320_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_lcd_3p5_inch_240_320_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1454 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Thu Apr 23 17:23:29 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=m
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_H1900 is not set
++CONFIG_MTD_NAND_REGULUS=m
++CONFIG_MTD_NAND_IDS=m
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_SHARPSL is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++CONFIG_PPP_DEFLATE=y
++CONFIG_PPP_BSDCOMP=y
++# CONFIG_PPP_MPPE is not set
++# CONFIG_PPPOE is not set
++# CONFIG_PPPOL2TP is not set
++# CONFIG_SLIP is not set
++CONFIG_SLHC=y
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=y
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++# CONFIG_I2C_PXA_SLAVE is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++CONFIG_LCD_DISPLAY_3P5_INCH_320_240=y
++# CONFIG_LCD_DISPLAY_5P7_INCH_640_480 is not set
++# CONFIG_LCD_DISPLAY_6P5_INCH_640_480 is not set
++# CONFIG_CRT_DISPLAY_640_480 is not set
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_lcd_6p5_inch_640_480_defconfig linux-2.6.25/arch/arm/configs/regulus_lcd_6p5_inch_640_480_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_lcd_6p5_inch_640_480_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_lcd_6p5_inch_640_480_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1454 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Thu Apr 9 18:40:26 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++# CONFIG_IKCONFIG_PROC is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_STANDALONE is not set
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=m
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++# CONFIG_MTD_NAND_H1900 is not set
++CONFIG_MTD_NAND_REGULUS=m
++CONFIG_MTD_NAND_IDS=m
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_SHARPSL is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_REGULUS_AX88796B=y
++# CONFIG_AX88796 is not set
++# CONFIG_SMC91X is not set
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++CONFIG_PPP_DEFLATE=y
++CONFIG_PPP_BSDCOMP=y
++# CONFIG_PPP_MPPE is not set
++# CONFIG_PPPOE is not set
++# CONFIG_PPPOL2TP is not set
++# CONFIG_SLIP is not set
++CONFIG_SLHC=y
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=y
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_E_CON_QUAD_UART_TI16C174B=y
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++CONFIG_I2C_ALGOPCF=y
++CONFIG_I2C_ALGOPCA=y
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_GPIO is not set
++CONFIG_I2C_PXA=y
++CONFIG_I2C_PXA_SLAVE=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7418 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_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 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_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 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_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_LCD_DISPLAY_3P5_INCH_320_240 is not set
++# CONFIG_LCD_DISPLAY_5P7_INCH_640_480 is not set
++CONFIG_LCD_DISPLAY_6P5_INCH_640_480=y
++# CONFIG_CRT_DISPLAY_640_480 is not set
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++CONFIG_DISPLAY_SUPPORT=y
++
++#
++# Display hardware drivers
++#
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++CONFIG_RTC_DEBUG=y
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++CONFIG_RTC_DRV_DS1307=y
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_SA1100 is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++CONFIG_JFFS2_SUMMARY=y
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_minimal_defconfig linux-2.6.25/arch/arm/configs/regulus_minimal_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_minimal_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_minimal_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,963 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Mon Jan 5 13:29:58 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_VFAT_FS is not set
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++# CONFIG_CRYPTO_SEQIV is not set
++# CONFIG_CRYPTO_MANAGER is not set
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_touch_defconfig linux-2.6.25/arch/arm/configs/regulus_touch_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_touch_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_touch_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1022 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Tue Jan 6 11:02:40 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++# CONFIG_WIRELESS_EXT is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++# CONFIG_SCSI_DMA is not set
++# CONFIG_SCSI_NETLINK is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_VFAT_FS is not set
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++# CONFIG_CRYPTO_SEQIV is not set
++# CONFIG_CRYPTO_MANAGER is not set
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_usbclient_lcd_defconfig linux-2.6.25/arch/arm/configs/regulus_usbclient_lcd_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_usbclient_lcd_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_usbclient_lcd_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1266 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Wed Jan 7 18:42:08 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_USB_ZD1211B_WLAN=y
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_VFAT_FS is not set
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_usbclient_lcd_usbwifi_defconfig linux-2.6.25/arch/arm/configs/regulus_usbclient_lcd_usbwifi_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_usbclient_lcd_usbwifi_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_usbclient_lcd_usbwifi_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1321 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Thu Jan 8 18:39:51 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_WLAN_80211=y
++# CONFIG_LIBERTAS is not set
++CONFIG_USB_ZD1201=y
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_RTL8187 is not set
++# CONFIG_P54_COMMON is not set
++CONFIG_HOSTAP=y
++# CONFIG_HOSTAP_FIRMWARE is not set
++CONFIG_B43=y
++# CONFIG_B43_DEBUG is not set
++# CONFIG_B43LEGACY is not set
++CONFIG_ZD1211RW=y
++CONFIG_ZD1211RW_DEBUG=y
++# CONFIG_RT2X00 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++CONFIG_INPUT_MISC=y
++# CONFIG_INPUT_ATI_REMOTE is not set
++# CONFIG_INPUT_ATI_REMOTE2 is not set
++# CONFIG_INPUT_KEYSPAN_REMOTE is not set
++# CONFIG_INPUT_POWERMATE is not set
++# CONFIG_INPUT_YEALINK is not set
++# CONFIG_INPUT_UINPUT is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++CONFIG_SSB=y
++# CONFIG_SSB_DEBUG is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_SYS_FOPS is not set
++CONFIG_FB_DEFERRED_IO=y
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_PXA=y
++CONFIG_FB_PXA_PARAMETERS=y
++# CONFIG_FB_MBX is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DEBUG=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_PXA2XX is not set
++CONFIG_USB_GADGET_PXA27X=y
++CONFIG_USB_PXA27X=y
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++# CONFIG_USB_GADGET_DUALSPEED is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=m
++# CONFIG_USB_ETH_RNDIS is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_DEBUG=y
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++CONFIG_JFFS2_FS_WBUF_VERIFY=y
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/configs/regulus_usbhost_sdcard_defconfig linux-2.6.25/arch/arm/configs/regulus_usbhost_sdcard_defconfig
+--- linux-2.6.25_original/arch/arm/configs/regulus_usbhost_sdcard_defconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/configs/regulus_usbhost_sdcard_defconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1203 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.25
++# Tue Jan 6 19:33:29 2009
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ARCH_SUPPORTS_AOUT=y
++CONFIG_ZONE_DMA=y
++CONFIG_ARCH_MTD_XIP=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_GROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_RT_GROUP_SCHED is not set
++CONFIG_USER_SCHED=y
++# CONFIG_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_BLK_DEV_INITRD is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_COMPAT_BRK=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION is not set
++# CONFIG_ARCH_PNX4008 is not set
++CONFIG_ARCH_PXA=y
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM7X00A is not set
++
++#
++# Intel PXA2xx/PXA3xx Implementations
++#
++# CONFIG_ARCH_LUBBOCK is not set
++# CONFIG_MACH_LOGICPD_PXA270 is not set
++# CONFIG_MACH_MAINSTONE is not set
++CONFIG_MACH_REGULUS=y
++# CONFIG_ARCH_PXA_IDP is not set
++# CONFIG_PXA_SHARPSL is not set
++# CONFIG_ARCH_PXA_ESERIES is not set
++# CONFIG_MACH_TRIZEPS4 is not set
++# CONFIG_MACH_EM_X270 is not set
++# CONFIG_MACH_COLIBRI is not set
++# CONFIG_MACH_ZYLONITE is not set
++# CONFIG_MACH_LITTLETON is not set
++# CONFIG_MACH_ARMCORE is not set
++# CONFIG_MACH_MAGICIAN is not set
++# CONFIG_MACH_PCM027 is not set
++CONFIG_PXA27x=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_XSCALE=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5T=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_THUMB is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_OUTER_CACHE is not set
++CONFIG_IWMMXT=y
++CONFIG_XSCALE_PMU=y
++
++#
++# Bus support
++#
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++# CONFIG_NO_HZ is not set
++# CONFIG_HIGH_RES_TIMERS is not set
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=ttyS2,115200,n81 mem=128M rootfstype=jffs2 root=/dev/mtdblock4 rw"
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++# CONFIG_FPE_NWFPE_XP is not set
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_PACKET is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++# CONFIG_IP_PNP_DHCP is not set
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_SCH_FIFO=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++CONFIG_CFG80211=y
++# CONFIG_NL80211 is not set
++CONFIG_WIRELESS_EXT=y
++CONFIG_MAC80211=y
++
++#
++# Rate control algorithm selection
++#
++CONFIG_MAC80211_RC_DEFAULT_PID=y
++# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
++# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
++
++#
++# Selecting 'y' for an algorithm will
++#
++
++#
++# build the algorithm into mac80211.
++#
++CONFIG_MAC80211_RC_DEFAULT="pid"
++CONFIG_MAC80211_RC_PID=y
++# CONFIG_MAC80211_RC_SIMPLE is not set
++# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
++# CONFIG_MAC80211_DEBUG is not set
++CONFIG_IEEE80211=y
++# CONFIG_IEEE80211_DEBUG is not set
++CONFIG_IEEE80211_CRYPT_WEP=y
++# CONFIG_IEEE80211_CRYPT_CCMP is not set
++# CONFIG_IEEE80211_CRYPT_TKIP is not set
++# CONFIG_IEEE80211_SOFTMAC is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++# CONFIG_MTD_CONCAT is not set
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++CONFIG_MTD_CFI=y
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_GEN_PROBE=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_CFI_NOSWAP=y
++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
++CONFIG_MTD_CFI_GEOMETRY=y
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++# CONFIG_MTD_CFI_I2 is not set
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_OTP is not set
++CONFIG_MTD_CFI_INTELEXT=y
++# CONFIG_MTD_CFI_AMDSTD is not set
++# CONFIG_MTD_CFI_STAA is not set
++CONFIG_MTD_CFI_UTIL=y
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++# CONFIG_MTD_XIP is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x00000000
++CONFIG_MTD_PHYSMAP_LEN=0x2000000
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PXA2XX is not set
++# CONFIG_MTD_ARM_INTEGRATOR is not set
++# CONFIG_MTD_SHARP_SL is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_UB is not set
++# CONFIG_BLK_DEV_RAM is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++CONFIG_HAVE_IDE=y
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++# CONFIG_BLK_DEV_IDECD is not set
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++# CONFIG_IDE_TASK_IOCTL is not set
++CONFIG_IDE_PROC_FS=y
++
++#
++# IDE chipset support/bugfixes
++#
++# CONFIG_IDE_GENERIC is not set
++# CONFIG_BLK_DEV_PLATFORM is not set
++# CONFIG_BLK_DEV_IDEDMA is not set
++CONFIG_IDE_ARCH_OBSOLETE_INIT=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++CONFIG_SCSI_LOGGING=y
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_PHYLIB is not set
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_AX88796 is not set
++CONFIG_SMC91X=y
++# CONFIG_DM9000 is not set
++# CONFIG_SMC911X is not set
++# CONFIG_IBM_NEW_EMAC_ZMII is not set
++# CONFIG_IBM_NEW_EMAC_RGMII is not set
++# CONFIG_IBM_NEW_EMAC_TAH is not set
++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
++# CONFIG_B44 is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_E1000E_ENABLED is not set
++CONFIG_NETDEV_10000=y
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++CONFIG_USB_ZD1211B_WLAN=y
++# CONFIG_WLAN_80211 is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_PXA27x is not set
++# CONFIG_KEYBOARD_GPIO is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++CONFIG_TOUCHSCREEN_UCB1400=m
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++# CONFIG_SERIO_SERPORT is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++CONFIG_SERIAL_PXA=y
++CONFIG_SERIAL_PXA_CONSOLE=y
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++CONFIG_HAVE_GPIO_LIB=y
++
++#
++# GPIO Support
++#
++# CONFIG_DEBUG_GPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++
++#
++# Advanced Linux Sound Architecture
++#
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++# CONFIG_SND_SEQUENCER is not set
++# CONFIG_SND_MIXER_OSS is not set
++# CONFIG_SND_PCM_OSS is not set
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++# CONFIG_SND_DEBUG is not set
++
++#
++# Generic devices
++#
++CONFIG_SND_AC97_CODEC=y
++# CONFIG_SND_DUMMY is not set
++# CONFIG_SND_MTPAV is not set
++# CONFIG_SND_SERIAL_U16550 is not set
++# CONFIG_SND_MPU401 is not set
++
++#
++# ALSA ARM devices
++#
++CONFIG_SND_PXA2XX_PCM=y
++CONFIG_SND_PXA2XX_AC97=y
++
++#
++# USB devices
++#
++# CONFIG_SND_USB_AUDIO is not set
++# CONFIG_SND_USB_CAIAQ is not set
++
++#
++# System on Chip audio support
++#
++# CONFIG_SND_SOC is not set
++
++#
++# SoC Audio support for SuperH
++#
++
++#
++# ALSA SoC audio for Freescale SOCs
++#
++
++#
++# Open Sound System
++#
++# CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=y
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_USB_HIDINPUT_POWERBOOK is not set
++# CONFIG_HID_FF is not set
++# CONFIG_USB_HIDDEV is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB_ARCH_HAS_EHCI is not set
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_ISP116X_HCD is not set
++CONFIG_USB_OHCI_HCD=y
++# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
++# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
++CONFIG_USB_OHCI_LITTLE_ENDIAN=y
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++CONFIG_USB_MON=y
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_AUERSWALD is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++
++#
++# MMC/SD Host Controller Drivers
++#
++CONFIG_MMC_PXA=y
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4DEV_FS is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++# CONFIG_VFAT_FS is not set
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_SYSFS=y
++# CONFIG_TMPFS is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_NETWORK_FILESYSTEMS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# 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_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# 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_9 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_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++CONFIG_DETECT_SOFTLOCKUP=y
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_DEBUG_SG is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_SAMPLES is not set
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_ERRORS=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_ICEDCC is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++# CONFIG_CRYPTO_SEQIV is not set
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=y
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_LZO is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Naur linux-2.6.25_original/arch/arm/Kconfig linux-2.6.25/arch/arm/Kconfig
+--- linux-2.6.25_original/arch/arm/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -45,6 +45,10 @@
+ bool
+ default y
+
++config KGDB_PXA_SERIAL
++ bool
++ default y
++
+ config NO_IOPORT
+ bool
+ default n
+diff -Naur linux-2.6.25_original/arch/arm/kernel/entry-armv.S linux-2.6.25/arch/arm/kernel/entry-armv.S
+--- linux-2.6.25_original/arch/arm/kernel/entry-armv.S 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/entry-armv.S 2009-05-16 18:43:58.000000000 +0530
+@@ -15,6 +15,7 @@
+ * that causes it to save wrong values... Be aware!
+ */
+
++#include <asm/kgdb.h>
+ #include <asm/memory.h>
+ #include <asm/glue.h>
+ #include <asm/vfpmacros.h>
+@@ -245,6 +246,7 @@
+ beq preempt_return @ go again
+ b 1b
+ #endif
++ CFI_END_FRAME(__irq_svc)
+
+ .align 5
+ __und_svc:
+diff -Naur linux-2.6.25_original/arch/arm/kernel/kgdb.c linux-2.6.25/arch/arm/kernel/kgdb.c
+--- linux-2.6.25_original/arch/arm/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/kgdb.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,208 @@
++/*
++ * arch/arm/kernel/kgdb.c
++ *
++ * ARM KGDB support
++ *
++ * Copyright (c) 2002-2004 MontaVista Software, Inc
++ *
++ * Authors: George Davis <davis_g@mvista.com>
++ * Deepak Saxena <dsaxena@plexity.net>
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/spinlock.h>
++#include <linux/personality.h>
++#include <linux/ptrace.h>
++#include <linux/elf.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/kgdb.h>
++
++#include <asm/atomic.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/ptrace.h>
++#include <asm/traps.h>
++
++/* Make a local copy of the registers passed into the handler (bletch) */
++void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
++{
++ int regno;
++
++ /* Initialize all to zero (??) */
++ for (regno = 0; regno < GDB_MAX_REGS; regno++)
++ gdb_regs[regno] = 0;
++
++ gdb_regs[_R0] = kernel_regs->ARM_r0;
++ gdb_regs[_R1] = kernel_regs->ARM_r1;
++ gdb_regs[_R2] = kernel_regs->ARM_r2;
++ gdb_regs[_R3] = kernel_regs->ARM_r3;
++ gdb_regs[_R4] = kernel_regs->ARM_r4;
++ gdb_regs[_R5] = kernel_regs->ARM_r5;
++ gdb_regs[_R6] = kernel_regs->ARM_r6;
++ gdb_regs[_R7] = kernel_regs->ARM_r7;
++ gdb_regs[_R8] = kernel_regs->ARM_r8;
++ gdb_regs[_R9] = kernel_regs->ARM_r9;
++ gdb_regs[_R10] = kernel_regs->ARM_r10;
++ gdb_regs[_FP] = kernel_regs->ARM_fp;
++ gdb_regs[_IP] = kernel_regs->ARM_ip;
++ gdb_regs[_SP] = kernel_regs->ARM_sp;
++ gdb_regs[_LR] = kernel_regs->ARM_lr;
++ gdb_regs[_PC] = kernel_regs->ARM_pc;
++ gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
++}
++
++/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
++void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
++{
++ kernel_regs->ARM_r0 = gdb_regs[_R0];
++ kernel_regs->ARM_r1 = gdb_regs[_R1];
++ kernel_regs->ARM_r2 = gdb_regs[_R2];
++ kernel_regs->ARM_r3 = gdb_regs[_R3];
++ kernel_regs->ARM_r4 = gdb_regs[_R4];
++ kernel_regs->ARM_r5 = gdb_regs[_R5];
++ kernel_regs->ARM_r6 = gdb_regs[_R6];
++ kernel_regs->ARM_r7 = gdb_regs[_R7];
++ kernel_regs->ARM_r8 = gdb_regs[_R8];
++ kernel_regs->ARM_r9 = gdb_regs[_R9];
++ kernel_regs->ARM_r10 = gdb_regs[_R10];
++ kernel_regs->ARM_fp = gdb_regs[_FP];
++ kernel_regs->ARM_ip = gdb_regs[_IP];
++ kernel_regs->ARM_sp = gdb_regs[_SP];
++ kernel_regs->ARM_lr = gdb_regs[_LR];
++ kernel_regs->ARM_pc = gdb_regs[_PC];
++ kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS - 1];
++}
++
++static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
++{
++ return (struct pt_regs *)
++ ((unsigned long)task->thread_info + THREAD_SIZE -
++ 8 - sizeof(struct pt_regs));
++}
++
++void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
++ struct task_struct *task)
++{
++ int regno;
++ struct pt_regs *thread_regs;
++
++ /* Just making sure... */
++ if (task == NULL)
++ return;
++
++ /* Initialize to zero */
++ for (regno = 0; regno < GDB_MAX_REGS; regno++)
++ gdb_regs[regno] = 0;
++
++ /* Otherwise, we have only some registers from switch_to() */
++ thread_regs = kgdb_get_user_regs(task);
++ gdb_regs[_R0] = thread_regs->ARM_r0; /* Not really valid? */
++ gdb_regs[_R1] = thread_regs->ARM_r1; /* " " */
++ gdb_regs[_R2] = thread_regs->ARM_r2; /* " " */
++ gdb_regs[_R3] = thread_regs->ARM_r3; /* " " */
++ gdb_regs[_R4] = thread_regs->ARM_r4;
++ gdb_regs[_R5] = thread_regs->ARM_r5;
++ gdb_regs[_R6] = thread_regs->ARM_r6;
++ gdb_regs[_R7] = thread_regs->ARM_r7;
++ gdb_regs[_R8] = thread_regs->ARM_r8;
++ gdb_regs[_R9] = thread_regs->ARM_r9;
++ gdb_regs[_R10] = thread_regs->ARM_r10;
++ gdb_regs[_FP] = thread_regs->ARM_fp;
++ gdb_regs[_IP] = thread_regs->ARM_ip;
++ gdb_regs[_SP] = thread_regs->ARM_sp;
++ gdb_regs[_LR] = thread_regs->ARM_lr;
++ gdb_regs[_PC] = thread_regs->ARM_pc;
++ gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
++}
++
++static int compiled_break;
++
++int kgdb_arch_handle_exception(int exception_vector, int signo,
++ int err_code, char *remcom_in_buffer,
++ char *remcom_out_buffer,
++ struct pt_regs *linux_regs)
++{
++ long addr;
++ char *ptr;
++
++ switch (remcom_in_buffer[0]) {
++ case 'c':
++ kgdb_contthread = NULL;
++
++ /*
++ * Try to read optional parameter, pc unchanged if no parm.
++ * If this was a compiled breakpoint, we need to move
++ * to the next instruction or we will just breakpoint
++ * over and over again.
++ */
++ ptr = &remcom_in_buffer[1];
++ if (kgdb_hex2long(&ptr, &addr)) {
++ linux_regs->ARM_pc = addr;
++ } else if (compiled_break == 1) {
++ linux_regs->ARM_pc += 4;
++ }
++
++ compiled_break = 0;
++
++ return 0;
++ }
++
++ return -1;
++}
++
++static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
++{
++ kgdb_handle_exception(1, SIGTRAP, 0, regs);
++
++ return 0;
++}
++
++static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
++{
++ compiled_break = 1;
++ kgdb_handle_exception(1, SIGTRAP, 0, regs);
++
++ return 0;
++}
++
++static struct undef_hook kgdb_brkpt_hook = {
++ .instr_mask = 0xffffffff,
++ .instr_val = KGDB_BREAKINST,
++ .fn = kgdb_brk_fn
++};
++
++static struct undef_hook kgdb_compiled_brkpt_hook = {
++ .instr_mask = 0xffffffff,
++ .instr_val = KGDB_COMPILED_BREAK,
++ .fn = kgdb_compiled_brk_fn
++};
++
++/*
++ * Register our undef instruction hooks with ARM undef core.
++ * We regsiter a hook specifically looking for the KGB break inst
++ * and we handle the normal undef case within the do_undefinstr
++ * handler.
++ */
++int kgdb_arch_init(void)
++{
++ register_undef_hook(&kgdb_brkpt_hook);
++ register_undef_hook(&kgdb_compiled_brkpt_hook);
++
++ return 0;
++}
++
++struct kgdb_arch arch_kgdb_ops = {
++#ifndef __ARMEB__
++ .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
++#else
++ .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
++#endif
++};
+diff -Naur linux-2.6.25_original/arch/arm/kernel/kgdb-jmp.S linux-2.6.25/arch/arm/kernel/kgdb-jmp.S
+--- linux-2.6.25_original/arch/arm/kernel/kgdb-jmp.S 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/kgdb-jmp.S 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,31 @@
++/*
++ * arch/arm/kernel/kgdb-jmp.S
++ *
++ * Trivial setjmp and longjmp procedures to support bus error recovery
++ * which may occur during kgdb memory read/write operations.
++ *
++ * Author: MontaVista Software, Inc. <source@mvista.com>
++ * source@mvista.com
++ *
++ * 2002-2005 (c) MontaVista Software, Inc. This file is licensed under the
++ * terms of the GNU General Public License version 2. This program as licensed
++ * "as is" without any warranty of any kind, whether express or implied.
++ */
++#include <linux/linkage.h>
++
++ENTRY (kgdb_fault_setjmp)
++ /* Save registers */
++ stmia r0, {r0-r14}
++ str lr,[r0, #60]
++ mrs r1,cpsr
++ str r1,[r0,#64]
++ ldr r1,[r0,#4]
++ mov r0, #0
++ mov pc,lr
++
++ENTRY (kgdb_fault_longjmp)
++ /* Restore registers */
++ mov r1,#1
++ str r1,[r0]
++ ldmia r0,{r0-pc}^
++
+diff -Naur linux-2.6.25_original/arch/arm/kernel/Makefile linux-2.6.25/arch/arm/kernel/Makefile
+--- linux-2.6.25_original/arch/arm/kernel/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -18,6 +18,8 @@
+ obj-$(CONFIG_ISA_DMA) += dma-isa.o
+ obj-$(CONFIG_PCI) += bios32.o isa.o
+ obj-$(CONFIG_SMP) += smp.o
++obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o
++
+ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+ obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
+ obj-$(CONFIG_ATAGS_PROC) += atags.o
+diff -Naur linux-2.6.25_original/arch/arm/kernel/setup.c linux-2.6.25/arch/arm/kernel/setup.c
+--- linux-2.6.25_original/arch/arm/kernel/setup.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/setup.c 2009-05-16 18:43:58.000000000 +0530
+@@ -853,6 +853,11 @@
+ conswitchp = &dummy_con;
+ #endif
+ #endif
++
++#if defined(CONFIG_KGDB)
++ extern void __init early_trap_init(void);
++ early_trap_init();
++#endif
+ }
+
+
+diff -Naur linux-2.6.25_original/arch/arm/kernel/traps.c linux-2.6.25/arch/arm/kernel/traps.c
+--- linux-2.6.25_original/arch/arm/kernel/traps.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/kernel/traps.c 2009-05-16 18:43:58.000000000 +0530
+@@ -294,6 +294,7 @@
+ unsigned int instr;
+ struct undef_hook *hook;
+ siginfo_t info;
++ mm_segment_t fs;
+ void __user *pc;
+ unsigned long flags;
+
+@@ -304,6 +305,8 @@
+ */
+ regs->ARM_pc -= correction;
+
++ fs = get_fs();
++ set_fs(KERNEL_DS);
+ pc = (void __user *)instruction_pointer(regs);
+
+ if (processor_mode(regs) == SVC_MODE) {
+@@ -313,6 +316,7 @@
+ } else {
+ get_user(instr, (u32 __user *)pc);
+ }
++ set_fs(fs);
+
+ #ifdef CONFIG_KPROBES
+ /*
+@@ -708,6 +712,14 @@
+
+ void __init trap_init(void)
+ {
++#if defined(CONFIG_KGDB)
++ return;
++}
++
++void __init early_trap_init(void)
++{
++#endif
++
+ unsigned long vectors = CONFIG_VECTORS_BASE;
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
+diff -Naur linux-2.6.25_original/arch/arm/mach-pxa/generic.c linux-2.6.25/arch/arm/mach-pxa/generic.c
+--- linux-2.6.25_original/arch/arm/mach-pxa/generic.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/mach-pxa/generic.c 2009-05-16 18:43:58.000000000 +0530
+@@ -116,6 +116,11 @@
+ .pfn = __phys_to_pfn(0x50000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
++ }, { /* Quad Uart */
++ .virtual = 0xfd000000,
++ .pfn = __phys_to_pfn(0x14000000),
++ .length = 0x01000000,
++ .type = MT_DEVICE
+ }, { /* IMem ctl */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0x58000000),
+diff -Naur linux-2.6.25_original/arch/arm/mach-pxa/Kconfig linux-2.6.25/arch/arm/mach-pxa/Kconfig
+--- linux-2.6.25_original/arch/arm/mach-pxa/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/mach-pxa/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -36,6 +36,10 @@
+ bool "Intel HCDDBBVA0 Development Platform"
+ select PXA27x
+
++config MACH_REGULUS
++ bool "e-con Systems's esom270 based Reference Platform"
++ select PXA27x
++
+ config ARCH_PXA_IDP
+ bool "Accelent Xscale IDP"
+ select PXA25x
+diff -Naur linux-2.6.25_original/arch/arm/mach-pxa/kgdb-serial.c linux-2.6.25/arch/arm/mach-pxa/kgdb-serial.c
+--- linux-2.6.25_original/arch/arm/mach-pxa/kgdb-serial.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/mach-pxa/kgdb-serial.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,117 @@
++/*
++ * linux/arch/arm/mach-pxa/kgdb-serial.c
++ *
++ * Provides low level kgdb serial support hooks for PXA2xx boards
++ *
++ * Author: Nicolas Pitre
++ * Copyright: (C) 2002-2005 MontaVista Software Inc.
++ *
++ * 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/config.h>
++#include <linux/serial_reg.h>
++#include <linux/kgdb.h>
++#include <asm/processor.h>
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++#define CONFIG_KGDB_PXA_STUART 1
++//#define CONFIG_KGDB_PXA_FFUART 1
++
++#if defined(CONFIG_KGDB_PXA_FFUART)
++
++#define UART FFUART
++//#define CKEN_UART CKEN6_FFUART
++#define CKEN_UART CKEN_FFUART
++//#define GPIO_RX_MD GPIO34_FFRXD_MD
++//#define GPIO_TX_MD GPIO39_FFTXD_MD
++
++#define GPIO_TX_MD (99 | GPIO_ALT_FN_3_OUT)
++#define GPIO_RX_MD (102 | GPIO_ALT_FN_3_IN)
++
++#elif defined(CONFIG_KGDB_PXA_BTUART)
++
++#define UART BTUART
++//#define CKEN_UART CKEN7_BTUART
++#define CKEN_UART CKEN_BTUART
++#define GPIO_RX_MD GPIO42_BTRXD_MD
++#define GPIO_TX_MD GPIO43_BTTXD_MD
++
++#elif defined(CONFIG_KGDB_PXA_STUART)
++
++#define UART STUART
++//#define CKEN_UART CKEN5_STUART
++#define CKEN_UART CKEN_STUART
++#define GPIO_RX_MD GPIO46_STRXD_MD
++#define GPIO_TX_MD GPIO47_STTXD_MD
++
++#endif
++
++#define UART_BAUDRATE (CONFIG_KGDB_BAUDRATE)
++
++static volatile unsigned long *port = (unsigned long *)&UART;
++
++static int kgdb_serial_init(void)
++{
++ pxa_set_cken(CKEN_UART, 1);
++ pxa_gpio_mode(GPIO_RX_MD);
++ pxa_gpio_mode(GPIO_TX_MD);
++
++ port[UART_IER] = 0;
++ port[UART_LCR] = LCR_DLAB;
++ port[UART_DLL] = ((921600 / UART_BAUDRATE) & 0xff);
++ port[UART_DLM] = ((921600 / UART_BAUDRATE) >> 8);
++ port[UART_LCR] = LCR_WLS1 | LCR_WLS0;
++ port[UART_MCR] = 0;
++ port[UART_IER] = IER_UUE;
++ port[UART_FCR] = FCR_ITL_16;
++
++// printk("************/////////kgdb-serial.c: serial port initialised////////************\n");
++
++ return 0;
++}
++
++static void kgdb_serial_putchar(int c)
++{
++
++ if (!(CKEN & CKEN_UART) || port[UART_IER] != IER_UUE)
++ {
++// printk("kgdb-serial: function:%s line:%d char is: %c\n ",__FUNCTION__,__LINE__,c);
++ kgdb_serial_init(); }
++ while (!(port[UART_LSR] & LSR_TDRQ))
++ {// printk("kgdb-serial: function:%s line:%d char is: %c\n ",__FUNCTION__,__LINE__,c);
++ cpu_relax();}
++ port[UART_TX] = c;
++// printk("kgdb-serial: function:%s line:%d\n ",__FUNCTION__,__LINE__);
++}
++
++static void kgdb_serial_flush(void)
++{
++ if ((CKEN & CKEN_UART) && (port[UART_IER] & IER_UUE))
++ while (!(port[UART_LSR] & LSR_TEMT))
++ cpu_relax();
++}
++
++static int kgdb_serial_getchar(void)
++{
++ unsigned char c;
++
++ if (!(CKEN & CKEN_UART) || port[UART_IER] != IER_UUE)
++ {
++// printk("kgdb-serial: function:%s line:%d\n ",__FUNCTION__,__LINE__);
++ kgdb_serial_init();}
++ while (!(port[UART_LSR] & UART_LSR_DR))
++ cpu_relax();
++ c = port[UART_RX];
++ return c;
++}
++struct kgdb_io kgdb_io_ops = {
++ .init = kgdb_serial_init,
++ .write_char = kgdb_serial_putchar,
++ .flush = kgdb_serial_flush,
++ .read_char = kgdb_serial_getchar,
++};
++
+diff -Naur linux-2.6.25_original/arch/arm/mach-pxa/Makefile linux-2.6.25/arch/arm/mach-pxa/Makefile
+--- linux-2.6.25_original/arch/arm/mach-pxa/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/mach-pxa/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -15,6 +15,7 @@
+ obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+ obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
+ obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
++obj-$(CONFIG_MACH_REGULUS) += regulus.o
+ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
+ obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
+ obj-$(CONFIG_MACH_COLIBRI) += colibri.o
+@@ -51,7 +52,9 @@
+ obj-$(CONFIG_PM) += pm.o sleep.o standby.o
+ obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
+ obj-$(CONFIG_PXA_SSP) += ssp.o
+-
++ifeq ($(CONFIG_KGDB),y)
++obj-$(CONFIG_KGDB_PXA_SERIAL) += kgdb-serial.o
++endif
+ ifeq ($(CONFIG_PCI),y)
+ obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
+ endif
+diff -Naur linux-2.6.25_original/arch/arm/mach-pxa/regulus.c linux-2.6.25/arch/arm/mach-pxa/regulus.c
+--- linux-2.6.25_original/arch/arm/mach-pxa/regulus.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/arch/arm/mach-pxa/regulus.c 2009-08-13 12:30:07.000000000 +0530
+@@ -0,0 +1,716 @@
++/*
++ * linux/arch/arm/mach-pxa/regulus.c
++ *
++ * Support for the Intel HCDDBBVA0 Development Platform.
++ * (go figure how they came up with such name...)
++ *
++ * Author: Nicolas Pitre
++ * Created: Nov 05, 2002
++ * Copyright: MontaVista Software Inc.
++ *
++ * 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/init.h>
++#include <linux/platform_device.h>
++#include <linux/sysdev.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/bitops.h>
++#include <linux/fb.h>
++#include <linux/ioport.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/types.h>
++#include <asm/setup.h>
++#include <asm/memory.h>
++#include <asm/mach-types.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/sizes.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/flash.h>
++
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/regulus.h>
++#include <asm/arch/audio.h>
++#include <asm/arch/pxafb.h>
++#include <asm/arch/mmc.h>
++#include <asm/arch/irda.h>
++#include <asm/arch/ohci.h>
++#include <linux/i2c.h>
++#include <linux/serial.h>
++#include "generic.h"
++
++#ifdef CONFIG_PXA27x
++#include <asm/arch/pxa2xx-regs.h>
++#endif
++
++#define GPIO99_MMC_SD_WP_MD (99 | GPIO_IN)
++#define GPIO100_MMC_SD_CD_MD (100 | GPIO_IN)
++
++#define USBCLIENT_ENABLE_GPIO 107
++#define USBCLIENT_ENABLE_GPIO_MD (USBCLIENT_ENABLE_GPIO | GPIO_OUT)
++
++#define PXA270M_LCD_ENABLE_GPIO 20
++#define PXA270M_LCD_ENABLE_GPIO_MD (PXA270M_LCD_ENABLE_GPIO | GPIO_OUT)
++
++#define GPIO50_LCD_BACKLIGHT_MD (50 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define GPIO53_PSAVE_MD (53 | GPIO_OUT | GPIO_DFLT_HIGH)
++
++
++#define GPIO_FOR_ASIX_IRQ 37
++#define IRQ_EINT11 IRQ_GPIO(GPIO_FOR_ASIX_IRQ)
++#define GPIO_FOX_ASIX_IRQ_MD ( GPIO_FOR_ASIX_IRQ | GPIO_IN)
++#define GPIO80_GPIO_OUT (80 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define IMCR_GPIO_x (1<<10)
++#define ICLR_GPIO_x (1<<10)
++#define IRQ_FALLING_EDGE 1
++
++
++// Macros for USB OHCI Driver for USB Host Port 2
++#define GPIO21_FOR_USBHPEN2 21
++#define GPIO16_FOR_USBHPWR2 16
++#define GPIO119_FOR_USBHPWR2 119
++#define GPIO120_FOR_USBHPEN2 120
++#define GPIO35_USB_P2_1 (35 | GPIO_ALT_FN_2_IN)
++#define GPIO34_USB_P2_2 (34 | GPIO_ALT_FN_1_OUT)
++#define GPIO38_USB_P2_3 (38 | GPIO_ALT_FN_3_IN)
++#define GPIO36_USB_P2_4 (36 | GPIO_ALT_FN_1_OUT)
++#define GPIO40_USB_P2_5 (40 | GPIO_ALT_FN_3_IN)
++#define GPIO39_USB_P2_6 (39 | GPIO_ALT_FN_1_OUT)
++#define GPIO41_USB_P2_7 (41 | GPIO_ALT_FN_2_IN)
++#define GPIO21_USBHPEN2_MD (21 | GPIO_OUT)
++#define GPIO16_USBHPWR2_MD (16 | GPIO_IN)
++#define GPIO55_USB_PORT2_SUSPEND_MD (55 | GPIO_OUT | GPIO_DFLT_LOW)
++#define GPIO119_USBHPWR2_MD ( GPIO119_FOR_USBHPWR2 | GPIO_ALT_FN_1_IN )
++#define GPIO120_USBHPEN2_MD ( GPIO120_FOR_USBHPEN2 | GPIO_ALT_FN_2_OUT )
++
++#define UP2OCR_ADDR 0xf2600020
++#define UP2OCR_VALUE 0x03020300 //Differential port- OFF Single-Ended port2-Externel Non-OTG Tran Host
++
++#define GPSR3_ADDR 0xf2e00118
++#define GPSR3_VALUE ~(0x00040000)
++
++#define GPCR3_ADDR 0xf2e00124
++#define GPCR3_VALUE (0x01 << 18)
++
++
++
++#define GPCR1_ADDR 0xf2e00028
++#define GPCR1_VALUE (0x01 << 5)
++
++
++
++#define GFER3_ADDR 0xf2e0013c
++#define GFER3_VALUE (0x00040000)
++
++
++#define GFER2_ADDR 0xf2e00044
++#define GFER2_VALUE (0x01 << 26)
++
++
++#define UHCRHPS1_ADDR 0xf8000054
++#define UHCRHPS2_ADDR 0xf8000058
++#define UHCRHPS3_ADDR 0xf800005c
++
++
++
++#define UHCHIT_ADDR 0xf800006c // Software interrupt enable register.
++#define UHCHIT_VALUE (0x01 << 9)
++
++
++#define UHCINTE_ADDR 0xf8000010 //OHCI interrupt enable register
++#define UHCINTE_VALUE 0x80000040
++
++
++
++#ifdef CONFIG_MACH_SIRIUS
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x15000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00400000
++#define QUAD_UART_C_OFFSET_ADDR 0x00800000
++#define QUAD_UART_D_OFFSET_ADDR 0x00C00000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 19
++#define GPIO_FOR_QUAD_UART_B_IRQ 11
++#define GPIO_FOR_QUAD_UART_C_IRQ 13
++#define GPIO_FOR_QUAD_UART_D_IRQ 14
++#elif defined(CONFIG_MACH_REGULUS)
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x14000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00200000
++#define QUAD_UART_C_OFFSET_ADDR 0x00400000
++#define QUAD_UART_D_OFFSET_ADDR 0x00600000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 29
++#define GPIO_FOR_QUAD_UART_B_IRQ 115
++#define GPIO_FOR_QUAD_UART_C_IRQ 14
++#define GPIO_FOR_QUAD_UART_D_IRQ 114
++#endif
++#define GPIO_FOR_QUAD_UART_A_IRQ_MD (GPIO_FOR_QUAD_UART_A_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_B_IRQ_MD (GPIO_FOR_QUAD_UART_B_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_C_IRQ_MD (GPIO_FOR_QUAD_UART_C_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_D_IRQ_MD (GPIO_FOR_QUAD_UART_D_IRQ | GPIO_IN)
++#define QUAD_UART_A_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_A_IRQ)
++#define QUAD_UART_B_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_B_IRQ)
++#define QUAD_UART_C_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_C_IRQ)
++#define QUAD_UART_D_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_D_IRQ)
++
++
++#define GPIO033_CHIP_SELECT_QUAD (33 | GPIO_DFLT_HIGH|GPIO_ALT_FN_2_OUT)
++
++#define GPIO022_EXTERNAL_BUS_INTERFACE 22
++#define EXTERNAL_BUS_INTERFACE_GPIO22_OUT (GPIO22_EXTERNAL_BUS_INTERFACE | GPIO_OUT|GPIO_DFLT_LOW)
++
++
++
++
++#define ECON_DEBUG 0
++#if ECON_DEBUG
++#define econ_print(msg,args...) \
++ printk("ECON USB: " msg "\n", ## args)
++#define USB_TRACE(msg,args...) \
++ printk("ECON USB: " msg "\n", ## args)
++#else
++#define econ_print(msg,args...)
++#define USB_TRACE(msg,args...)
++#endif
++
++#define GPIO99_FFTXD 99
++#define GPIO99_FFTXD_MD (99 | GPIO_ALT_FN_3_OUT)
++#define GPIO102_FFRXD 102
++#define GPIO102_FFRXD_MD (102 | GPIO_ALT_FN_3_IN)
++
++
++
++
++static void __init regulus_init_irq(void)
++{
++ pxa27x_init_irq();
++}
++
++static int regulus_audio_startup(struct snd_pcm_substream *substream, void *priv)
++{
++ return 0;
++}
++
++static void regulus_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
++{
++}
++
++
++static void regulus_audio_suspend(void *priv)
++{
++}
++
++static void regulus_audio_resume(void *priv)
++{
++}
++
++static pxa2xx_audio_ops_t regulus_audio_ops = {
++ .startup = regulus_audio_startup,
++ .shutdown = regulus_audio_shutdown,
++ .suspend = regulus_audio_suspend,
++ .resume = regulus_audio_resume,
++};
++
++static struct platform_device regulus_audio_device = {
++ .name = "pxa2xx-ac97",
++ .id = -1,
++ .dev = { .platform_data = ®ulus_audio_ops },
++};
++
++static struct i2c_board_info regulus_rtc_info[] __initdata = {
++ {
++ .driver_name = "rtc-ds1307",
++ .addr = 0x68,
++ .type = "ds1338",
++ },
++};
++
++
++static void regulus_backlight_power(int on)
++{
++}
++
++
++static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
++ .pixclock = 110000,
++ .xres = 240,
++ .yres = 320,
++ .bpp = 16,
++ .hsync_len = 4,
++ .left_margin = 8,
++ .right_margin = 20,
++ .vsync_len = 3,
++ .upper_margin = 1,
++ .lower_margin = 10,
++ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
++};
++
++static struct pxafb_mach_info regulus_pxafb_info = {
++ .num_modes = 1,
++ .lccr0 = LCCR0_Act,
++ .lccr3 = LCCR3_PCP,
++ .pxafb_backlight_power = regulus_backlight_power,
++};
++
++
++static int i2c_regulus(void)
++{
++ pxa_gpio_mode(GPIO117_I2CSCL_MD);
++ pxa_gpio_mode(GPIO118_I2CSDA_MD);
++ pxa_set_cken(CKEN_I2C, 1);
++ return 0;
++}
++static int ffuart_regulus(void)
++{
++ pxa_gpio_mode(GPIO99_FFTXD_MD);
++ pxa_gpio_mode(GPIO102_FFRXD_MD);
++ FFLCR=0x83;
++ FFDLL=0x08;
++ FFDLH=0x00;
++ FFLCR=0x05;
++ FFIER=0x40;
++ pxa_set_cken(CKEN_FFUART, 1);
++ return 0;
++
++}
++static int btuart_regulus(void)
++{
++ pxa_gpio_mode(GPIO44_BTCTS_MD);
++ pxa_gpio_mode(GPIO43_BTTXD_MD);
++ pxa_gpio_mode(GPIO45_BTRTS_MD);
++ pxa_gpio_mode(GPIO42_BTRXD_MD);
++ BTLCR=0x83;
++ BTDLL=0x08;
++ BTDLH=0x00;
++ BTLCR=0x05;
++ BTIER=0x40;
++ pxa_set_cken(CKEN_BTUART, 1);
++ return 0;
++
++}
++
++static int lcd_config_regulus(void)
++{
++
++#define PWM_CTRL3 __REG(0x40C00010) /* PWM 3Control Register */
++#define PWM_PWDUTY3 __REG(0x40C00014) /* PWM 3 Duty Cycle Register */
++#define PWM_PERVAL3 __REG(0x40C00018) /* PWM 3 Period Control Register */
++#define PWM_CONTROL3_VALUE (0x00000013)
++#define PWMDCR3_VALUE (0x00000006)
++#define PWMPCR3_VALUE (0x0000001F)
++#define GPIO12_PWM3 (12 | GPIO_ALT_FN_2_OUT)
++#define LCCR5 __REG(0x44000014) /* LCD Controller Control Register 5 */
++
++
++ pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
++ pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD);
++ pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
++ pxa_gpio_mode(GPIO73_LDD_15_MD);
++ pxa_gpio_mode(GPIO72_LDD_14_MD);
++ pxa_gpio_mode(GPIO70_LDD_12_MD);
++ pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
++ pxa_gpio_mode(GPIO69_LDD_11_MD);
++ pxa_gpio_mode(GPIO64_LDD_6_MD);
++ pxa_gpio_mode(GPIO62_LDD_4_MD);
++ pxa_gpio_mode(GPIO61_LDD_3_MD);
++ pxa_gpio_mode(GPIO68_LDD_10_MD);
++ pxa_gpio_mode(GPIO60_LDD_2_MD);
++ pxa_gpio_mode(GPIO58_LDD_0_MD);
++ pxa_gpio_mode(GPIO59_LDD_1_MD);
++ pxa_gpio_mode(GPIO63_LDD_5_MD);
++ pxa_gpio_mode(GPIO66_LDD_8_MD);
++ pxa_gpio_mode(GPIO65_LDD_7_MD);
++ pxa_gpio_mode(GPIO67_LDD_9_MD);
++ pxa_gpio_mode(GPIO71_LDD_13_MD);
++ pxa_gpio_mode(GPIO50_LCD_BACKLIGHT_MD);
++ pxa_gpio_mode(GPIO53_PSAVE_MD);
++ pxa_set_cken(CKEN_LCD, 1);
++
++ pxa_gpio_mode(PXA270M_LCD_ENABLE_GPIO_MD);
++ // Set the PXA270M_LCD_ENABLE GPIO for Avoiding the blanking in the Bottom of the LCD display 3.5inch
++ GPSR(PXA270M_LCD_ENABLE_GPIO) = GPIO_bit(PXA270M_LCD_ENABLE_GPIO);
++
++ //To enabling overlay2 for camera
++ LCCR5 = 0x3f3f3f3f;
++
++ // Configure PWM Registers for Supporting 5.7 inch and 6.5 inch LCD displays in REGULUS Board
++ pxa_gpio_mode(GPIO12_PWM3);
++ PWM_CTRL3 = PWM_CONTROL3_VALUE;
++ PWM_PWDUTY3 = PWMDCR3_VALUE;
++ PWM_PERVAL3 = PWMPCR3_VALUE;
++ pxa_set_cken(CKEN_PWM0, 1);
++ pxa_set_cken(CKEN_PWM1, 1);
++
++ return 0;
++}
++
++static int regulus_mci_init(struct device *dev, irq_handler_t regulus_detect_int, void *data)
++{
++ int retval = 0;
++
++
++
++
++#define GPIO98_MMC_SD_WP 98
++#define GPIO101_MMC_SD_CD 101
++#define GPIO98_MMC_SD_WP_MD (98 | GPIO_IN)
++#define GPIO101_MMC_SD_CD_MD (101 | GPIO_IN)
++
++#define GPIO32_GPIO_OUT (32 | GPIO_OUT)
++#define GPIO112_GPIO_OUT (112 | GPIO_OUT)
++ GPSR(32)=GPIO_bit(32);
++ GPSR(112)=GPIO_bit(112);
++
++ pxa_gpio_mode(GPIO32_MMCCLK_MD);
++ pxa_gpio_mode(GPIO92_MMCDAT0_MD);
++ pxa_gpio_mode(GPIO109_MMCDAT1_MD);
++ pxa_gpio_mode(GPIO110_MMCDAT2_MD);
++ pxa_gpio_mode(GPIO111_MMCDAT3_MD);
++ pxa_gpio_mode(GPIO112_MMCCMD_MD);
++ pxa_gpio_mode(GPIO98_MMC_SD_WP_MD);
++ pxa_gpio_mode(GPIO101_MMC_SD_CD_MD);
++ pxa_set_cken(CKEN_MMC, 1);
++
++ /* Request card detect interrupt */
++ retval = request_irq(IRQ_GPIO(GPIO101_MMC_SD_CD), regulus_detect_int,IRQF_DISABLED, "MMC card detect", data);
++
++ if (retval)
++ {
++
++ printk(KERN_ERR "MMC/SD: can't request MMC card detect IRQ\n");
++ return -1;
++ }
++ set_irq_type(IRQ_GPIO(GPIO101_MMC_SD_CD), IRQT_BOTHEDGE);
++
++ return 0;
++}
++
++static void regulus_mci_setpower(struct device *dev, unsigned int vdd)
++{
++ struct pxamci_platform_data* p_d = dev->platform_data;
++
++ if (( 1 << vdd) & p_d->ocr_mask) {
++ printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
++ } else {
++ printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
++ }
++}
++
++static void regulus_mci_exit(struct device *dev, void *data)
++{
++ free_irq(IRQ_GPIO(GPIO101_MMC_SD_CD),data);
++
++}
++
++static struct pxamci_platform_data regulus_mci_platform_data = {
++ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
++ .init = regulus_mci_init,
++ .setpower = regulus_mci_setpower,
++ .exit = regulus_mci_exit,
++};
++
++static struct platform_device *platform_devices[] __initdata = {
++ ®ulus_audio_device,
++};
++
++
++static void usb_port2_conf(void);
++void gpio_settings_status(void)
++{
++
++#if ECON_DEBUG
++ unsigned int value=0;
++
++ value = GPDR0;
++ printk("\n Reg: GPDR0 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPDR1;
++ printk("Reg: GPDR1 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPDR2;
++ printk("Reg: GPDR2 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPDR3;
++ printk("Reg: GPDR3 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPLR0;
++ printk("Reg: GPLR0 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPLR1;
++ printk("Reg: GPLR1 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPLR2;
++ printk("Reg: GPLR2 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GPLR3;
++ printk("Reg: GPLR3 Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR0_L;
++ printk("Reg: GAFR0_L Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR0_U;
++ printk("Reg: GAFR0_U Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR1_L;
++ printk("Reg: GAFR1_L Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR1_U;
++ printk("Reg: GAFR1_U Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR2_L;
++ printk("Reg: GAFR2_L Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR2_U;
++ printk("Reg: GAFR2_U Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR3_L;
++ printk("Reg: GAFR3_L Value = 0x%x \n",value);
++ value = 0;
++
++ value = GAFR3_U;
++ printk("Reg: GAFR3_U Value = 0x%x \n",value);
++ value = 0;
++#endif
++
++}
++/*-------------------------------------------------------------------------*/
++
++
++static void usb_port2_conf(void)
++{
++ volatile unsigned int *addr;
++
++
++ pxa_gpio_mode(GPIO35_USB_P2_1);
++ pxa_gpio_mode(GPIO34_USB_P2_2);
++ pxa_gpio_mode(GPIO38_USB_P2_3);
++ pxa_gpio_mode(GPIO36_USB_P2_4);
++ pxa_gpio_mode(GPIO40_USB_P2_5);
++ pxa_gpio_mode(GPIO39_USB_P2_6);
++ pxa_gpio_mode(GPIO41_USB_P2_7);
++
++#if 1
++ // Reconfigure the USB_P2_7 GPIO as General GPIO, Direction Output, Default Drive value as High
++ pxa_gpio_mode(41 | GPIO_OUT | GPIO_DFLT_HIGH);
++ // Configure the GPIO55 as General GPIO, Direction Output, Default Drive value as High
++ pxa_gpio_mode(GPIO55_USB_PORT2_SUSPEND_MD);
++#endif
++
++
++ /* setup Port2 GPIO pin. */
++ pxa_gpio_mode(GPIO119_USBHPWR2_MD) ; /* USBHPWR2 */
++ pxa_gpio_mode(GPIO120_USBHPEN2_MD); /* USBHPEN2 */
++ pxa_gpio_mode(GPIO16_USBHPWR2_MD) ; /* USBHPWR2 */
++ pxa_gpio_mode(GPIO21_USBHPEN2_MD); /* USBHPEN2 */
++ GPCR(GPIO21_FOR_USBHPEN2) = GPIO_bit(GPIO21_FOR_USBHPEN2);
++
++ addr=(volatile unsigned int *)UP2OCR_ADDR;
++ *addr=UP2OCR_VALUE;
++
++ /* enable the ohci interrupt in UHCINTE Reg */
++ addr=(volatile unsigned int *)UHCINTE_ADDR;
++ *addr=*(addr)| UHCINTE_VALUE;
++
++}
++
++static int regulus_ohci_init(struct device *dev)
++{
++ USB_TRACE("UP2OCR=0x%x",*((volatile unsigned int *)UP2OCR_ADDR));
++
++ USB_TRACE("UHCRHPS1=0x%x",*((volatile unsigned int *)UHCRHPS1_ADDR));
++
++ USB_TRACE("UHCRHPS2=0x%x",*((volatile unsigned int *)UHCRHPS2_ADDR));
++
++ USB_TRACE("UHCRHPS3=0x%x",*((volatile unsigned int *)UHCRHPS3_ADDR));
++
++ econ_print("\n gpio settings status Before calling usb_port2_conf \n");
++ gpio_settings_status();
++
++ /* setup Port1 GPIO pin. */
++ pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
++ pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
++
++ /* setup Port2 GPIO pins */
++ usb_port2_conf();
++
++ /* Set the Power Control Polarity Low and Power Sense
++ Polarity Low to active low. */
++ UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
++ ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
++
++ econ_print("\n gpio settings status After calling econ_usb_port2_conf \n");
++ gpio_settings_status();
++
++ return 0;
++}
++
++static int ac97_regulus_init(void)
++{
++
++#define GPIO0_AC97_TOUCH_IRQ_MD (0 | GPIO_IN)
++#define GPIO116_AC97_SDATA_IN_MD (116 | GPIO_ALT_FN_2_IN)
++ // GPIO Configuration for AC97 Interface
++ pxa_gpio_mode(GPIO113_AC97_RESET_N_MD);
++ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
++ pxa_gpio_mode(GPIO0_AC97_TOUCH_IRQ_MD);
++ pxa_gpio_mode(GPIO116_AC97_SDATA_IN_MD);
++ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
++ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
++ // Enabling Clk for AC97 Unit
++ pxa_set_cken(CKEN_AC97, 1);
++
++ return 0;
++}
++
++
++
++
++
++static void asix_regulus_init(void)
++{
++
++ volatile unsigned int msc2_data=0;
++ //volatile unsigned int ncs4_config_data = 0x7FF9; // Slower Device, Maximum ROM/SRAM Recovery Time, Maximum ROM Delay Next Access, Maximum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++#define CS4_RBUFF(x) ((x) <<15)
++#define CS4_RRR(x) ((x) <<12)
++#define CS4_RDN(x) ((x) <<8)
++#define CS4_RDF(x) ((x) <<4)
++#define CS4_RBW(x) ((x) <<3)
++#define CS4_RT(x) ((x) <<0)
++
++ volatile unsigned int ncs4_config_data = (CS4_RBUFF(0) | CS4_RRR(0) |CS4_RDN(3) | CS4_RDF(5) | CS4_RBW(1) |CS4_RT(1)); // Slower Device, Minimum ROM/SRAM Recovery Time, Minimum ROM Delay Next Access, Minimum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++
++ //printk("FUNC %s() : LINE %d : Driver for AX88796B Non-PCI Fast Ethernet Chip \n",__FUNCTION__,__LINE__);
++
++ //printk("Configuring GPIO80 as GPIO and Drive Logic 1 on GPIO80 \n");
++ pxa_gpio_mode(GPIO80_GPIO_OUT);
++
++ //printk("Configuring GPIO80 as nCS4 \n");
++ pxa_gpio_mode(GPIO80_nCS_4_MD );
++
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Configuring the Memory Controller Register for nCS4 \n");
++ msc2_data = MSC2;
++ MSC2 = (ncs4_config_data & 0x0000FFFF) | (msc2_data & 0xFFFF0000);
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Physical address of nCS4 is 0x%08X \n",PXA_CS4_PHYS);
++
++ pxa_gpio_mode(GPIO_FOX_ASIX_IRQ_MD);
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ GFER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ GRER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#endif
++ ICMR |= IMCR_GPIO_x;
++ ICLR &= ~(ICLR_GPIO_x);
++
++}
++
++
++static struct pxaohci_platform_data regulus_ohci_platform_data = {
++ .port_mode = PMM_PERPORT_MODE,
++ .init = regulus_ohci_init,
++};
++
++
++extern struct platform_device pxa_device_i2c;
++
++static void __init regulus_init(void)
++{
++ pxa_gpio_mode(USBCLIENT_ENABLE_GPIO_MD);
++ // Set the USBCLIENT_ENABLE GPIO for Enabling the USBCLIENT
++ GPSR(USBCLIENT_ENABLE_GPIO) = GPIO_bit(USBCLIENT_ENABLE_GPIO);
++ asix_regulus_init();
++ ffuart_regulus();
++ btuart_regulus();
++ ac97_regulus_init();
++ lcd_config_regulus();
++ i2c_regulus();
++ i2c_register_board_info(0, regulus_rtc_info, ARRAY_SIZE(regulus_rtc_info));
++ platform_device_register(&pxa_device_i2c);
++ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
++ regulus_pxafb_info.modes = &toshiba_ltm035a776c_mode;
++ set_pxa_fb_info(®ulus_pxafb_info);
++ pxa_set_mci_info(®ulus_mci_platform_data);
++ pxa_set_ohci_info(®ulus_ohci_platform_data);
++
++}
++
++
++
++static void __init regulus_map_io(void)
++{
++ pxa_map_io();
++
++ /* initialize sleep mode regs (wake-up sources, etc) */
++ PGSR0 = 0x00008800;
++ PGSR1 = 0x00000002;
++ PGSR2 = 0x0001FC00;
++ PGSR3 = 0x00001F81;
++ PWER = 0xC0000002;
++ PRER = 0x00000002;
++ PFER = 0x00000002;
++ /* for use I SRAM as framebuffer. */
++ PSLR |= 0xF04;
++ PCFR = 0x66;
++ /* For Keypad wakeup. */
++ KPC &=~KPC_ASACT;
++ KPC |=KPC_AS;
++ PKWR = 0x000FD000;
++ /* Need read PKWR back after set it. */
++ PKWR;
++}
++
++MACHINE_START(REGULUS, "Regulus Reference Platform Kit ")
++ .phys_io = 0x40000000,
++ .boot_params = 0xa0000100, /* BLOB boot parameter setting */
++ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
++ .map_io = regulus_map_io,
++ .init_irq = regulus_init_irq,
++ .timer = &pxa_timer,
++ .init_machine = regulus_init,
++MACHINE_END
+diff -Naur linux-2.6.25_original/arch/arm/mm/extable.c linux-2.6.25/arch/arm/mm/extable.c
+--- linux-2.6.25_original/arch/arm/mm/extable.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/mm/extable.c 2009-05-16 18:43:58.000000000 +0530
+@@ -2,6 +2,7 @@
+ * linux/arch/arm/mm/extable.c
+ */
+ #include <linux/module.h>
++#include <linux/kgdb.h>
+ #include <asm/uaccess.h>
+
+ int fixup_exception(struct pt_regs *regs)
+@@ -11,6 +12,12 @@
+ fixup = search_exception_tables(instruction_pointer(regs));
+ if (fixup)
+ regs->ARM_pc = fixup->fixup;
++#ifdef CONFIG_KGDB
++ if (atomic_read(&debugger_active) && kgdb_may_fault)
++ /* Restore our previous state. */
++ kgdb_fault_longjmp(kgdb_fault_jmp_regs);
++ /* Not reached. */
++#endif
+
+ return fixup != NULL;
+ }
+diff -Naur linux-2.6.25_original/arch/arm/tools/mach-types linux-2.6.25/arch/arm/tools/mach-types
+--- linux-2.6.25_original/arch/arm/tools/mach-types 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/arch/arm/tools/mach-types 2009-05-16 18:43:58.000000000 +0530
+@@ -1611,3 +1611,4 @@
+ mt7108 MACH_MT7108 MT7108 1613
+ smtr2440 MACH_SMTR2440 SMTR2440 1614
+ manao MACH_MANAO MANAO 1615
++regulus MACH_REGULUS REGULUS 900
+diff -Naur linux-2.6.25_original/Documentation/DocBook/kgdb.tmpl linux-2.6.25/Documentation/DocBook/kgdb.tmpl
+--- linux-2.6.25_original/Documentation/DocBook/kgdb.tmpl 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/Documentation/DocBook/kgdb.tmpl 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,235 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
++ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
++
++<book id="kgdbInternals">
++ <bookinfo>
++ <title>KGDB Internals</title>
++
++ <authorgroup>
++ <author>
++ <firstname>Tom</firstname>
++ <surname>Rini</surname>
++ <affiliation>
++ <address>
++ <email>trini@kernel.crashing.org</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
++
++ <authorgroup>
++ <author>
++ <firstname>Amit S.</firstname>
++ <surname>Kale</surname>
++ <affiliation>
++ <address>
++ <email>amitkale@linsyssoft.com</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
++
++ <copyright>
++ <year>2004-2005</year>
++ <holder>MontaVista Software, Inc.</holder>
++ </copyright>
++ <copyright>
++ <year>2004</year>
++ <holder>Amit S. Kale</holder>
++ </copyright>
++
++ <legalnotice>
++ <para>
++ This file is licensed under the terms of the GNU General Public License
++ version 2. This program is licensed "as is" without any warranty of any
++ kind, whether express or implied.
++ </para>
++
++ </legalnotice>
++ </bookinfo>
++
++<toc></toc>
++ <chapter id="Introduction">
++ <title>Introduction</title>
++ <para>
++ kgdb is a source level debugger for linux kernel. It is used along
++ with gdb to debug a linux kernel. Kernel developers can debug a kernel
++ similar to application programs with the use of kgdb. It makes it
++ possible to place breakpoints in kernel code, step through the code
++ and observe variables.
++ </para>
++ <para>
++ Two machines are required for using kgdb. One of these machines is a
++ development machine and the other is a test machine. The machines are
++ typically connected through a serial line, a null-modem cable which
++ connects their serial ports. It is also possible however, to use an
++ ethernet connection between the machines. The kernel to be debugged
++ runs on the test machine. gdb runs on the development machine. The
++ serial line or ethernet connection is used by gdb to communicate to
++ the kernel being debugged.
++ </para>
++ </chapter>
++ <chapter id="CompilingAKernel">
++ <title>Compiling a kernel</title>
++ <para>
++ To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
++ and then select "KGDB: kernel debugging with remote gdb".
++ </para>
++ <para>
++ The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>.
++ This means that you will only be able to use KGDB after loading a
++ kernel module that defines how you want to be able to talk with
++ KGDB. There are two other choices (more on some architectures) that
++ can be enabled as modules later, if not picked here.
++ </para>
++ <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>.
++ This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol>
++ which toggles choosing the serial port by ttyS number or by specifying
++ a port and IRQ number.
++ </para>
++ <para>
++ The second of these choices on most systems for I/O is
++ <symbol>CONFIG_KGDBOE</symbol>. This requires that the machine to be
++ debugged has an ethernet card which supports the netpoll API, such as
++ the cards supported by <symbol>CONFIG_E100</symbol>. There are no
++ sub-options for this, but a kernel command line option is required.
++ </para>
++ </chapter>
++ <chapter id="BootingTheKernel">
++ <title>Booting the kernel</title>
++ <para>
++ The Kernel command line option <constant>kgdbwait</constant> makes kgdb
++ wait for gdb connection during booting of a kernel. If the
++ <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable,
++ another serial driver) this breakpoint will happen very early on, before
++ console output. If you wish to change serial port information and you
++ have enabled both <symbol>CONFIG_KGDB_8250</symbol> and
++ <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option
++ <constant>kgdb8250=<io or mmio>,<address>,<baud
++ rate>,<irq></constant> before <constant>kgdbwait</constant>.
++ The values <constant>io</constant> or <constant>mmio</constant> refer to
++ if the address being passed next needs to be memory mapped
++ (<constant>mmio</constant>) or not. The <constant>address</constant> must
++ be passed in hex and is the hardware address and will be remapped if
++ passed as <constant>mmio</constant>. The value
++ <constant>baud rate</constant> and <constant>irq</constant> are base-10.
++ The supported values for <constant>baud rate</constant> are
++ <constant>9600</constant>, <constant>19200</constant>,
++ <constant>38400</constant>, <constant>57600</constant>, and
++ <constant>115200</constant>.
++ </para>
++ <para>
++ To have KGDB stop the kernel and wait, with the compiled values for the
++ serial driver, pass in: <constant>kgdbwait</constant>.
++ </para>
++ <para>
++ To specify the values of the serial port at boot:
++ <constant>kgdb8250=io,3f8,115200,3</constant>.
++ On IA64 this could also be:
++ <constant>kgdb8250=mmio,0xff5e0000,115200,74</constant>
++ And to have KGDB also stop the kernel and wait for GDB to connect, pass in
++ <constant>kgdbwait</constant> after this arguement.
++ </para>
++ <para>
++ To configure the <symbol>CONFIG_KGDBOE</symbol> driver, pass in
++ <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant>
++ where:
++ <itemizedlist>
++ <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem>
++ <listitem><para>src-ip: source IP to use (interface address)</para></listitem>
++ <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem>
++ <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem>
++ <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem>
++ <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem>
++ </itemizedlist>
++ </para>
++ <para>
++ The <symbol>CONFIG_KGDBOE</symbol> driver can be reconfigured at run
++ time, if <symbol>CONFIG_SYSFS</symbol> and
++ <symbol>CONFIG_MODULES</symbol> by echo'ing a new config string to
++ <constant>/sys/module/kgdboe/parameter/kgdboe</constant>. The
++ driver can be unconfigured with the special string
++ <constant>not_configured</constant>.
++ </para>
++ </chapter>
++ <chapter id="ConnectingGDB">
++ <title>Connecting gdb</title>
++ <para>
++ If you have used any of the methods to have KGDB stop and create
++ an initial breakpoint described in the previous chapter, kgdb prints
++ the message "Waiting for connection from remote gdb..." on the console
++ and waits for connection from gdb. At this point you connect gdb to kgdb.
++ </para>
++ <para>
++ Example (serial):
++ </para>
++ <programlisting>
++ % gdb ./vmlinux
++ (gdb) set remotebaud 115200
++ (gdb) target remote /dev/ttyS0
++ </programlisting>
++ <para>
++ Example (ethernet):
++ </para>
++ <programlisting>
++ % gdb ./vmlinux
++ (gdb) target remote udp:192.168.2.2:6443
++ </programlisting>
++ <para>
++ Once connected, you can debug a kernel the way you would debug an
++ application program.
++ </para>
++ </chapter>
++ <chapter id="CommonBackEndReq">
++ <title>The common backend (required)</title>
++ <para>
++ There are a few flags which must be set on every architecture in
++ their <asm/kgdb.h> file. These are:
++ <itemizedlist>
++ <listitem>
++ <para>
++ NUMREGBYTES: The size in bytes of all of the registers, so
++ that we can ensure they will all fit into a packet.
++ </para>
++ <para>
++ BUFMAX: The size in bytes of the buffer GDB will read into.
++ This must be larger than NUMREGBYTES.
++ </para>
++ <para>
++ CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call
++ flush_cache_range or flush_icache_range. On some architectures,
++ these functions may not be safe to call on SMP since we keep other
++ CPUs in a holding pattern.
++ </para>
++ </listitem>
++ </itemizedlist>
++ </para>
++ <para>
++ There are also the following functions for the common backend,
++ found in kernel/kgdb.c that must be supplied by the
++ architecture-specific backend. No weak version of these is provided.
++ </para>
++!Iinclude/linux/kgdb.h
++ </chapter>
++ <chapter id="CommonBackEndOpt">
++ <title>The common backend (optional)</title>
++ <para>
++ These functions are part of the common backend, found in kernel/kgdb.c
++ and are optionally implemented. Some functions (with _hw_ in the name)
++ end up being required on arches which use hardware breakpoints.
++ </para>
++!Ikernel/kgdb.c
++ </chapter>
++ <chapter id="DriverSpecificFunctions">
++ <title>Driver-Specific Functions</title>
++ <para>
++ Some of the I/O drivers have additional functions that can be
++ called, that are specific to the driver. Calls from other places
++ to these functions must be wrapped in #ifdefs for the driver in
++ question.
++ </para>
++!Idrivers/serial/8250_kgdb.c
++ </chapter>
++</book>
++
+diff -Naur linux-2.6.25_original/Documentation/DocBook/Makefile linux-2.6.25/Documentation/DocBook/Makefile
+--- linux-2.6.25_original/Documentation/DocBook/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/Documentation/DocBook/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -11,7 +11,8 @@
+ procfs-guide.xml writing_usb_driver.xml networking.xml \
+ kernel-api.xml filesystems.xml lsm.xml usb.xml \
+ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
+- genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml
++ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
++ kgdb.xml
+
+ ###
+ # The build process is as follows (targets):
+diff -Naur linux-2.6.25_original/drivers/base/driver.c linux-2.6.25/drivers/base/driver.c
+--- linux-2.6.25_original/drivers/base/driver.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/base/driver.c 2009-05-16 18:43:58.000000000 +0530
+@@ -221,8 +221,12 @@
+ if ((drv->bus->probe && drv->probe) ||
+ (drv->bus->remove && drv->remove) ||
+ (drv->bus->shutdown && drv->shutdown))
++ {
++#if !CONFIG_MACH_REGULUS
+ printk(KERN_WARNING "Driver '%s' needs updating - please use "
+ "bus_type methods\n", drv->name);
++#endif
++ }
+ ret = bus_add_driver(drv);
+ if (ret)
+ return ret;
+diff -Naur linux-2.6.25_original/drivers/char/keyboard.c linux-2.6.25/drivers/char/keyboard.c
+--- linux-2.6.25_original/drivers/char/keyboard.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/char/keyboard.c 2009-05-16 18:43:58.000000000 +0530
+@@ -1190,6 +1190,7 @@
+ sysrq_down = 0;
+ if (sysrq_down && down && !rep) {
+ handle_sysrq(kbd_sysrq_xlate[keycode], tty);
++ sysrq_down = 0; /* In case we miss the 'up' event. */
+ return;
+ }
+ #endif
+diff -Naur linux-2.6.25_original/drivers/char/tty_io.c linux-2.6.25/drivers/char/tty_io.c
+--- linux-2.6.25_original/drivers/char/tty_io.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/char/tty_io.c 2009-05-16 18:43:58.000000000 +0530
+@@ -1976,6 +1976,7 @@
+ static void tty_line_name(struct tty_driver *driver, int index, char *p)
+ {
+ sprintf(p, "%s%d", driver->name, index + driver->name_base);
++
+ }
+
+ /**
+diff -Naur linux-2.6.25_original/drivers/input/touchscreen/ucb1400_ts.c linux-2.6.25/drivers/input/touchscreen/ucb1400_ts.c
+--- linux-2.6.25_original/drivers/input/touchscreen/ucb1400_ts.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/input/touchscreen/ucb1400_ts.c 2009-05-16 18:43:58.000000000 +0530
+@@ -28,8 +28,11 @@
+
+ #include <sound/core.h>
+ #include <sound/ac97_codec.h>
++#include <linux/irq.h>
++#include <asm/irq.h>
+
+-
++#define GPIO_FOR_AC97_TOUCHSCREEN_IRQ 0
++#define IRQ_FOR_AC97_TOUCHSCREEN IRQ_GPIO(GPIO_FOR_AC97_TOUCHSCREEN_IRQ)
+ /*
+ * Interesting UCB1400 AC-link registers
+ */
+@@ -275,7 +278,9 @@
+ if (isr & UCB_IE_TSPX)
+ ucb1400_ts_irq_disable(ucb);
+ else
+- printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
++ {
++ //printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
++ }
+
+ enable_irq(ucb->irq);
+ }
+@@ -302,9 +307,26 @@
+ }
+
+ ucb1400_adc_enable(ucb);
+- x = ucb1400_ts_read_xpos(ucb);
+- y = ucb1400_ts_read_ypos(ucb);
+- p = ucb1400_ts_read_pressure(ucb);
++ x = ucb1400_ts_read_xpos(ucb); // first dummy read x
++ x = ucb1400_ts_read_xpos(ucb); // second dummy read x
++ x = ucb1400_ts_read_xpos(ucb); // third dummy read x
++ x = ucb1400_ts_read_xpos(ucb); // fourth dummy read x
++ x = ucb1400_ts_read_xpos(ucb); // fifth dummy read x
++ x = ucb1400_ts_read_xpos(ucb); // actual read x
++
++ y = ucb1400_ts_read_ypos(ucb); // first dumy read y
++ y = ucb1400_ts_read_ypos(ucb); // second dummy read y
++ y = ucb1400_ts_read_ypos(ucb); // third dummy read y
++ y = ucb1400_ts_read_ypos(ucb); // fourth dummy read y
++ y = ucb1400_ts_read_ypos(ucb); // fifth dummy read y
++ y = ucb1400_ts_read_ypos(ucb); // actual read y
++
++ p = ucb1400_ts_read_pressure(ucb); // first dummy read p
++ p = ucb1400_ts_read_pressure(ucb); // second dummy read p
++ p = ucb1400_ts_read_pressure(ucb); // third dummy read p
++ p = ucb1400_ts_read_pressure(ucb); // fourth dummy read p
++ p = ucb1400_ts_read_pressure(ucb); // fifth dummy read p
++ p = ucb1400_ts_read_pressure(ucb); // actual read y
+ ucb1400_adc_disable(ucb);
+
+ /* Switch back to interrupt mode. */
+@@ -495,7 +517,8 @@
+ error = ucb1400_detect_irq(ucb);
+ if (error) {
+ printk(KERN_ERR "UCB1400: IRQ probe failed\n");
+- goto err_free_devs;
++ //goto err_free_devs;
++ ucb->irq=IRQ_FOR_AC97_TOUCHSCREEN;
+ }
+
+ error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
+@@ -505,6 +528,8 @@
+ ucb->irq, error);
+ goto err_free_devs;
+ }
++ set_irq_type(ucb->irq,IRQT_RISING);
++
+ printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);
+
+ input_set_drvdata(idev, ucb);
+diff -Naur linux-2.6.25_original/drivers/mmc/host/pxamci.c linux-2.6.25/drivers/mmc/host/pxamci.c
+--- linux-2.6.25_original/drivers/mmc/host/pxamci.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mmc/host/pxamci.c 2009-05-16 18:43:58.000000000 +0530
+@@ -461,7 +461,33 @@
+ static irqreturn_t pxamci_detect_irq(int irq, void *devid)
+ {
+ struct pxamci_host *host = mmc_priv(devid);
++ int sd_write_protect_status=0;
+
++#define GPIO101_MMC_SD_CD 101
++#define GPIO98_MMC_SD_WP 98
++#define GPIO98_MMC_SD_WP_MD (98 | GPIO_IN)
++
++ if((GPLR(GPIO101_MMC_SD_CD)&GPIO_bit(GPIO101_MMC_SD_CD)) != GPIO_bit(GPIO101_MMC_SD_CD))
++ {
++ printk("SD - card is present in SD/MMC slot\n");
++
++ mdelay(100);
++ pxa_gpio_mode(GPIO98_MMC_SD_WP_MD);
++
++ if((GPLR(GPIO98_MMC_SD_WP)&GPIO_bit(GPIO98_MMC_SD_WP)) == GPIO_bit(GPIO98_MMC_SD_WP))
++ {
++ sd_write_protect_status=1;
++ }
++ else
++ {
++ sd_write_protect_status=0;
++ }
++ printk("SD Card Write Protect is %s\n",(sd_write_protect_status==1)?"ON":"OFF");
++ }
++ else
++ {
++ printk("SD - card is removed from the SD/MMC slot\n");
++ }
+ mmc_detect_change(devid, host->pdata->detect_delay);
+ return IRQ_HANDLED;
+ }
+diff -Naur linux-2.6.25_original/drivers/mtd/chips/cfi_util.c linux-2.6.25/drivers/mtd/chips/cfi_util.c
+--- linux-2.6.25_original/drivers/mtd/chips/cfi_util.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/chips/cfi_util.c 2009-05-16 18:43:58.000000000 +0530
+@@ -35,8 +35,9 @@
+ int ofs_factor = cfi->interleave * cfi->device_type;
+ int i;
+ struct cfi_extquery *extp = NULL;
+-
++#if 0
+ printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
++#endif
+ if (!adr)
+ goto out;
+
+diff -Naur linux-2.6.25_original/drivers/mtd/maps/physmap.c linux-2.6.25/drivers/mtd/maps/physmap.c
+--- linux-2.6.25_original/drivers/mtd/maps/physmap.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/maps/physmap.c 2009-08-12 13:07:12.000000000 +0530
+@@ -90,6 +90,60 @@
+ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
+ #endif
+
++
++
++#ifdef CONFIG_MACH_REGULUS
++static struct mtd_partition pxa27x_partitions[] = {
++ {
++ .name = "BASIC BOOT",
++ .size = 0x00020000,
++ .offset = 0x00000000,
++ },
++ {
++ .name = "UBOOT ",
++ .size = 0x00080000,
++ .offset = 0x00020000,
++ },
++ {
++ .name = "UBOOT PARAMS ",
++ .size = 0x00020000,
++ .offset = 0x000A0000,
++ },
++ {
++ .name = "KERNEL",
++ .size = 0x00400000,
++ .offset = 0x000C0000,
++ },
++#if (CONFIG_MTD_PHYSMAP_LEN>=0x2000000)
++#warning "CONFIG_MTD_PHYSMAP_LEN is >= 0x2000000"
++ {
++ .name = "JFFS2 ROOT FILE SYSTEM",
++ .size = 0x01340000,
++ .offset = 0x004C0000
++ },
++ {
++ .name = "JFFS2 FLASH2 ",
++ .size = 0x00800000,
++ .offset = 0x01800000
++ }
++#else
++#warning "CONFIG_MTD_PHYSMAP_LEN is < 0x2000000"
++ {
++ .name = "JFFS2 ROOT FILE SYSTEM",
++ .size = 0x00B40000,
++ .offset = 0x004C0000
++ }
++
++#endif
++
++};
++
++#endif
++
++
++
++
++
+ static int physmap_flash_probe(struct platform_device *dev)
+ {
+ struct physmap_flash_data *physmap_data;
+@@ -173,6 +227,9 @@
+ goto err_out;
+
+ #ifdef CONFIG_MTD_PARTITIONS
++#ifdef CONFIG_MACH_REGULUS
++ add_mtd_partitions(info->cmtd, pxa27x_partitions, ARRAY_SIZE(pxa27x_partitions)); //changed by econ
++#else
+ err = parse_mtd_partitions(info->cmtd, part_probe_types, &info->parts, 0);
+ if (err > 0) {
+ add_mtd_partitions(info->cmtd, info->parts, err);
+@@ -186,7 +243,7 @@
+ return 0;
+ }
+ #endif
+-
++#endif
+ add_mtd_device(info->cmtd);
+ return 0;
+
+diff -Naur linux-2.6.25_original/drivers/mtd/nand/Kconfig linux-2.6.25/drivers/mtd/nand/Kconfig
+--- linux-2.6.25_original/drivers/mtd/nand/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/nand/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -57,6 +57,12 @@
+ help
+ This enables the driver for the iPAQ h1900 flash.
+
++config MTD_NAND_REGULUS
++ tristate "Micron Nand Flash on esom270 based boards"
++ depends on MACH_REGULUS
++ help
++ This enables the driver for the Micron Nand flash in PCMCIA Interface on esom270 based boards.
++
+ config MTD_NAND_SPIA
+ tristate "NAND Flash device on SPIA board"
+ depends on ARCH_P720T
+diff -Naur linux-2.6.25_original/drivers/mtd/nand/Makefile linux-2.6.25/drivers/mtd/nand/Makefile
+--- linux-2.6.25_original/drivers/mtd/nand/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/nand/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -18,6 +18,7 @@
+ obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
+ obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
+ obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
++obj-$(CONFIG_MTD_NAND_REGULUS) += regulus_nand.o
+ obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
+ obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
+ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o
+diff -Naur linux-2.6.25_original/drivers/mtd/nand/nand_base.c linux-2.6.25/drivers/mtd/nand/nand_base.c
+--- linux-2.6.25_original/drivers/mtd/nand/nand_base.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/nand/nand_base.c 2009-05-16 18:43:58.000000000 +0530
+@@ -52,6 +52,16 @@
+ #include <linux/mtd/partitions.h>
+ #endif
+
++
++#include <linux/proc_fs.h>
++#include <asm/uaccess.h>
++#include <linux/seq_file.h>
++
++extern int bad_blocks_count;
++extern int good_blocks_count;
++
++
++
+ /* Define default oob placement schemes for large and small page devices */
+ static struct nand_ecclayout nand_oob_8 = {
+ .eccbytes = 3,
+@@ -2633,6 +2643,10 @@
+ BUG();
+ }
+
++ //Reset the values for the good block and bad block counts
++ good_blocks_count=0;
++ bad_blocks_count=0;
++
+ ret = nand_scan_ident(mtd, maxchips);
+ if (!ret)
+ ret = nand_scan_tail(mtd);
+@@ -2665,15 +2679,81 @@
+ EXPORT_SYMBOL_GPL(nand_scan_tail);
+ EXPORT_SYMBOL_GPL(nand_release);
+
++
++
++
++
++
++#define PROCFS_MAX_SIZE 1024
++#define PROCFS_NAME "nandflash"
++
++static struct proc_dir_entry *Our_Proc_File; //this structure holds information about /proc file
++
++static char procfs_buffer[PROCFS_MAX_SIZE]; //buffer used to store character for this module
++
++static unsigned long procfs_buffer_size = 0; //buffer size
++
++/**
++ * This function is called then the /proc/nandflash file is read
++ */
++
++int
++nandflash_read(char *buffer,
++ char **buffer_location,
++ off_t offset, int buffer_length, int *eof, void *data)
++{
++
++ int ret;
++ int total_blocks=0;
++
++ printk(KERN_INFO "Number of badblocks is %d\n",bad_blocks_count);
++ printk(KERN_INFO "Number of goodblocks is %d\n",good_blocks_count);
++
++ if (offset > 0) {
++ ret = 0;
++ } else {
++ memcpy(buffer, procfs_buffer, procfs_buffer_size);
++ ret = procfs_buffer_size;
++
++
++ total_blocks = bad_blocks_count + good_blocks_count;
++ }
++
++ return ret;
++}
++
++
+ static int __init nand_base_init(void)
+ {
+ led_trigger_register_simple("nand-disk", &nand_led_trigger);
++ Our_Proc_File = create_proc_entry(PROCFS_NAME, 0644, NULL);
++
++
++ if (Our_Proc_File == NULL) {
++ remove_proc_entry(PROCFS_NAME, &proc_root);
++ printk(KERN_INFO "Error in initializing /proc/%s\n",
++ PROCFS_NAME);
++ return -ENOMEM;
++ }
++
++ Our_Proc_File->read_proc = nandflash_read;
++ Our_Proc_File->owner = THIS_MODULE;
++ Our_Proc_File->mode = S_IFREG | S_IRUGO;
++ Our_Proc_File->uid = 0;
++ Our_Proc_File->gid = 0;
++ Our_Proc_File->size = 37;
++
++
+ return 0;
+ }
+
+ static void __exit nand_base_exit(void)
+ {
+ led_trigger_unregister_simple(nand_led_trigger);
++ printk(KERN_INFO "the proc entry is removed \n ");
++ remove_proc_entry(PROCFS_NAME, &proc_root);
++ return;
++
+ }
+
+ module_init(nand_base_init);
+diff -Naur linux-2.6.25_original/drivers/mtd/nand/nand_bbt.c linux-2.6.25/drivers/mtd/nand/nand_bbt.c
+--- linux-2.6.25_original/drivers/mtd/nand/nand_bbt.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/mtd/nand/nand_bbt.c 2009-08-13 12:30:07.000000000 +0530
+@@ -61,7 +61,13 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ #include <linux/vmalloc.h>
++#include <linux/autoconf.h>
++#include <linux/proc_fs.h>
++#include <asm/uaccess.h>
++#include <linux/seq_file.h>
+
++int bad_blocks_count=0;
++int good_blocks_count=0;
+ /**
+ * check_pattern - [GENERIC] check if a pattern is in the buffer
+ * @buf: the buffer to search
+@@ -124,7 +130,9 @@
+ /* Compare the pattern */
+ for (i = 0; i < td->len; i++) {
+ if (p[td->offs + i] != td->pattern[i])
++ {
+ return -1;
++ }
+ }
+ return 0;
+ }
+@@ -145,6 +153,7 @@
+ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+ int bits, int offs, int reserved_block_code)
+ {
++
+ int res, i, j, act = 0;
+ struct nand_chip *this = mtd->priv;
+ size_t retlen, len, totlen;
+@@ -210,6 +219,7 @@
+ */
+ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int res = 0, i;
+ int bits;
+@@ -238,6 +248,7 @@
+ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+ size_t len)
+ {
++
+ struct mtd_oob_ops ops;
+
+ ops.mode = MTD_OOB_RAW;
+@@ -256,6 +267,7 @@
+ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
+ uint8_t *buf, uint8_t *oob)
+ {
++
+ struct mtd_oob_ops ops;
+
+ ops.mode = MTD_OOB_PLACE;
+@@ -282,6 +294,7 @@
+ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+ struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+ {
++
+ struct nand_chip *this = mtd->priv;
+
+ /* Read the primary version, if available */
+@@ -333,25 +346,30 @@
+ struct mtd_oob_ops ops;
+ int j, ret;
+
++
+ ops.ooblen = mtd->oobsize;
+ ops.oobbuf = buf;
+ ops.ooboffs = 0;
+ ops.datbuf = NULL;
+ ops.mode = MTD_OOB_PLACE;
+
++
+ for (j = 0; j < len; j++) {
++
+ /*
+ * Read the full oob until read_oob is fixed to
+ * handle single byte reads for 16 bit
+ * buswidth
+ */
+ ret = mtd->read_oob(mtd, offs, &ops);
++
+ if (ret)
+ return ret;
+
+ if (check_short_pattern(buf, bd))
++ {
+ return 1;
+-
++ }
+ offs += mtd->writesize;
+ }
+ return 0;
+@@ -372,11 +390,12 @@
+ struct nand_bbt_descr *bd, int chip)
+ {
+ struct nand_chip *this = mtd->priv;
+- int i, numblocks, len, scanlen;
++ int i,numblocks, len, scanlen;
+ int startblock;
+ loff_t from;
+ size_t readlen;
+
++
+ printk(KERN_INFO "Scanning device for bad blocks\n");
+
+ if (bd->options & NAND_BBT_SCANALLPAGES)
+@@ -395,7 +414,7 @@
+ } else {
+ /* Full page content should be read */
+ scanlen = mtd->writesize + mtd->oobsize;
+- readlen = len * mtd->writesize;
++ readlen = len * mtd->writesize;
+ }
+
+ if (chip == -1) {
+@@ -424,23 +443,42 @@
+ scanlen, len);
+ else
+ ret = scan_block_fast(mtd, bd, from, buf, len);
+-
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
++ bad_blocks_count++;
++
+ this->bbt[i >> 3] |= 0x03 << (i & 0x6);
++#if !CONFIG_MACH_REGULUS
+ printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
+ i >> 1, (unsigned int)from);
++#endif
+ mtd->ecc_stats.badblocks++;
++
++ }
++ else
++ {
++ good_blocks_count++;
+ }
++
+
+ i += 2;
+ from += (1 << this->bbt_erase_shift);
+ }
++#if CONFIG_MACH_REGULUS
++ if(bad_blocks_count)
++ {
++ printk(" %d Bad eraseblock%s found in Nand Flash \n",bad_blocks_count,(bad_blocks_count==1)?" is":"s are");
++ }
++#endif
++
+ return 0;
+ }
+
++
++
++
+ /**
+ * search_bbt - [GENERIC] scan the device for a specific bad block table
+ * @mtd: MTD device structure
+@@ -460,6 +498,7 @@
+ */
+ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int i, chips;
+ int bits, startblock, block, dir;
+@@ -533,6 +572,7 @@
+ */
+ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+ {
++
+ /* Search the primary table */
+ search_bbt(mtd, buf, td);
+
+@@ -560,6 +600,7 @@
+ struct nand_bbt_descr *td, struct nand_bbt_descr *md,
+ int chipsel)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ struct erase_info einfo;
+ int i, j, res, chip = 0;
+@@ -759,6 +800,7 @@
+
+ bd->options &= ~NAND_BBT_SCANEMPTY;
+ return create_bbt(mtd, this->buffers->databuf, bd, -1);
++
+ }
+
+ /**
+@@ -775,6 +817,7 @@
+ */
+ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
+ {
++
+ int i, chips, writeops, chipsel, res;
+ struct nand_chip *this = mtd->priv;
+ struct nand_bbt_descr *td = this->bbt_td;
+@@ -888,6 +931,7 @@
+ */
+ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int i, j, chips, block, nrblocks, update;
+ uint8_t oldval, newval;
+@@ -953,6 +997,7 @@
+ */
+ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int len, res = 0;
+ uint8_t *buf;
+@@ -1019,6 +1064,7 @@
+ */
+ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int len, res = 0, writeops = 0;
+ int chip, chipsel;
+@@ -1146,6 +1192,7 @@
+ */
+ int nand_default_bbt(struct mtd_info *mtd)
+ {
++
+ struct nand_chip *this = mtd->priv;
+
+ /* Default for AG-AND. We must use a flash based
+@@ -1195,6 +1242,7 @@
+ */
+ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
+ {
++
+ struct nand_chip *this = mtd->priv;
+ int block;
+ uint8_t res;
+@@ -1219,3 +1267,4 @@
+
+ EXPORT_SYMBOL(nand_scan_bbt);
+ EXPORT_SYMBOL(nand_default_bbt);
++
+diff -Naur linux-2.6.25_original/drivers/mtd/nand/regulus_nand.c linux-2.6.25/drivers/mtd/nand/regulus_nand.c
+--- linux-2.6.25_original/drivers/mtd/nand/regulus_nand.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/mtd/nand/regulus_nand.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,405 @@
++/*
++ * drivers/mtd/nand/regulus_nand.c
++ *
++ * Derived from drivers/mtd/nand/h1900.c
++ * Copyright (C) 2002 Marius Gr?ger (mag@sysgo.de)
++ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
++ *
++ * 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.
++ *
++ * Overview:
++ * This is a device driver for the NAND flash device found on the
++ * Regulus Reference Platform from E-con Systems (www.e-consystems.com).
++ * Regulus uses Micron NAND flash memory of size 4Gbit interfaced in x8
++ * configuration, directly on to the PCMCIA interface of PXA270. For more details
++ * visit www.e-consystems.com
++ */
++
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++#include <asm/io.h>
++#include <asm/sizes.h>
++#include <asm/irq.h>
++#include <linux/irq.h>
++#include <asm/arch/pxa-regs.h>
++#include <linux/interrupt.h>
++#ifdef CONFIG_PXA27x
++#include <asm/arch/pxa2xx-regs.h>
++#endif
++
++/*
++ REGULUS NAND Flash interfacing:
++ Phy Base Address: 0x2C000000 (PCMCIA Socket 0)
++ ALE: A22
++ CLE: A21
++ RDY/BY - GPIO97
++*/
++
++#define NAND_DEBUG 0
++
++#define GPIO97_FOR_NAND_CHIP_READY 97
++#define GPIO97_NAND_READYnBUSY ( GPIO97_FOR_NAND_CHIP_READY | GPIO_IN )
++
++
++#define UINT8 unsigned char
++#define PHY_NAND_BASE 0x2C000000
++#define CLE_SHIFT_BITS 21
++#define ALE_SHIFT_BITS 22
++
++#define GPIO_PCMCIA 79
++#define GPIO_PCMCIA_MD (GPIO_PCMCIA | GPIO_ALT_FN_1_OUT)
++
++#define GPIO_nPOE 48
++#define GPIO_nPOE_MD (GPIO_nPOE | GPIO_ALT_FN_2_OUT)
++
++#define GPIO_nWE 49
++#define GPIO_nWE_MD (GPIO_nWE | GPIO_ALT_FN_2_OUT)
++
++#define GPIO_nPWAIT 56
++#define GPIO_nPWAIT_MD (GPIO_nPWAIT | GPIO_ALT_FN_1_IN)
++
++#define GPIO_nIOIS16 57
++#define GPIO_nIOIS16_MD (GPIO_nIOIS16 | GPIO_ALT_FN_1_IN)
++
++
++
++
++// GPIO & Mem Ctrl,Pwr Man. Gen. Register Config Definitions
++#define PCFR_ADDR 0x40F0001C
++#define MCMEM0_SET (0x0 << 0)
++#define MCMEM0_ASST (0x2 << 7)
++#define MCMEM0_HOLD (0x2 << 14)
++#define MCMEM0_VALUE (MCMEM0_ASST | MCMEM0_SET | MCMEM0_HOLD)
++//#define MCMEM0_VALUE (0x0000C102)
++#define MECR_VALUE 0x00000002
++#define PCFR_FP_BIT 0x00000002
++
++#define SETREGW(addr,data) *((volatile UINT8 *)addr) = ((UINT8)data)
++#define GETREGW(addr) *((volatile UINT8 *)addr)
++
++#define nand_writew(addr,data) SETREGW(addr,data)
++#define nand_readw(addr) GETREGW(addr)
++//------------------------------------------------------------------------------
++// Status bit pattern
++
++#define NAND_STATUS_READY 0x40 // Ready
++#define NAND_STATUS_ERROR 0x01 // Error
++
++
++
++/*
++ * MTD structure for Sirius board
++ */
++static struct mtd_info *regulus_nand_mtd = NULL;
++void __iomem *nandaddr_for_cle, *nandaddr_for_ale,*nandaddr_for_data;
++
++/*
++ * Module stuff
++ */
++
++#ifdef CONFIG_MTD_PARTITIONS
++#define NUM_PARTITIONS 2
++
++/*
++ * Define static partitions for flash device
++ */
++#if (NUM_PARTITIONS == 2)
++static struct mtd_partition partition_info[] = {
++ { name: "GUI partition in Regulus NAND Flash ",
++ offset: 0,
++ size: 64*1024*1024 /* 64MB */
++ },
++ { name: "User Database in Regulus NAND Flash ",
++ offset: MTDPART_OFS_NXTBLK,
++ size: MTDPART_SIZ_FULL
++ }
++};
++
++#else
++static struct mtd_partition partition_info[] = {
++ { name: "Regulus NAND Flash #1",
++ offset: 0,
++ size: MTDPART_SIZ_FULL
++ }
++};
++#endif
++#endif
++
++
++/*
++ * hardware specific access to control-lines
++ * ctrl:
++ * NAND_CNE: bit 0 -> ! bit 0 & 4
++ * NAND_CLE: bit 1 -> bit 1
++ * NAND_ALE: bit 2 -> bit 2
++ *
++ */
++static void regulus_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *chip = mtd->priv;
++
++ if (ctrl & NAND_CTRL_CHANGE)
++ {
++ unsigned char bits = ctrl & 0x07;
++ switch(bits)
++ {
++ case NAND_CTRL_CLE:
++ chip->IO_ADDR_R = nandaddr_for_cle;
++ chip->IO_ADDR_W = nandaddr_for_cle;
++ break;
++ case NAND_CTRL_ALE:
++ chip->IO_ADDR_R = nandaddr_for_ale;
++ chip->IO_ADDR_W = nandaddr_for_ale;
++ break;
++ default :
++ chip->IO_ADDR_R = nandaddr_for_data;
++ chip->IO_ADDR_W = nandaddr_for_data;
++ break;
++ }
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ writeb(cmd, chip->IO_ADDR_W);
++}
++
++/*
++ * read device ready pin
++ */
++
++static int regulus_device_ready(struct mtd_info *mtd)
++{
++#if 1
++ int readynbusy_status=0;
++ //printk("GPLR Value is 0x%08X \n",GPLR(GPIO97_FOR_NAND_CHIP_READY));
++ readynbusy_status = (((GPLR(GPIO97_FOR_NAND_CHIP_READY)&GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))==GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))?1:0);
++ //printk("readynbusy_status is %d \n",readynbusy_status);
++ return readynbusy_status;
++#else
++ return (((GPLR(GPIO97_FOR_NAND_CHIP_READY)&GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))==GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))?1:0);
++#endif
++}
++
++/*
++ * Main initialization routine
++ */
++static int __init regulus_nand_init (void)
++{
++
++ struct nand_chip *this;
++ const char *part_type = 0;
++ int mtd_parts_nb = 0;
++ struct mtd_partition *mtd_parts = 0;
++ short int nand_mid, nand_did;
++
++#if NAND_DEBUG
++ printk("MCMEM0_VALUE is 0x%08X \n",MCMEM0_VALUE);
++#endif
++
++ MCMEM0 = MCMEM0_VALUE;
++ MECR |= MECR_VALUE;
++
++ PCFR &= (~PCFR_FP_BIT);
++
++
++ //Initialize GPIO for NAND flash interface
++ pxa_gpio_mode(GPIO79_pSKTSEL_MD);
++ pxa_gpio_mode(GPIO48_nPOE_MD);
++ pxa_gpio_mode(GPIO49_nPWE_MD);
++ pxa_gpio_mode(GPIO56_nPWAIT_MD);
++ pxa_gpio_mode(GPIO57_nIOIS16_MD);
++ pxa_gpio_mode(GPIO97_NAND_READYnBUSY);
++
++ //Remap the Phys area to virtual.
++ nandaddr_for_cle = ioremap((PHY_NAND_BASE |(1<<CLE_SHIFT_BITS)),PAGE_SIZE);
++
++ if (!nandaddr_for_cle)
++ {
++ printk("Failed to ioremap nand flash.\n");
++ return -ENOMEM;
++ }
++ else
++ {
++#if NAND_DEBUG
++ printk("nandaddr_for_cle is 0x%08X \n",(unsigned int)nandaddr_for_cle);
++#endif
++ }
++ nandaddr_for_ale = ioremap((PHY_NAND_BASE |(1<<ALE_SHIFT_BITS)),PAGE_SIZE);
++
++ if (!nandaddr_for_ale)
++ {
++ printk("Failed to ioremap nand flash.\n");
++ iounmap((void *) nandaddr_for_cle);
++ return -ENOMEM;
++ }
++ else
++ {
++#if NAND_DEBUG
++ printk("nandaddr_for_ale is 0x%08X \n",(unsigned int)nandaddr_for_ale);
++#endif
++ }
++ nandaddr_for_data = ioremap((PHY_NAND_BASE),PAGE_SIZE);
++
++ if (!nandaddr_for_data)
++ {
++ printk("Failed to ioremap nand flash.\n");
++ iounmap((void *) nandaddr_for_cle);
++ iounmap((void *) nandaddr_for_ale);
++ return -ENOMEM;
++ }
++ else
++ {
++#if NAND_DEBUG
++ printk("nandaddr_for_data is 0x%08X \n",(unsigned int)nandaddr_for_data);
++#endif
++ }
++#if NAND_DEBUG
++ printk(" Write RESET command to NAND Flash \n");
++#endif
++ // Write RESET command to NAND Flash
++ nand_writew(nandaddr_for_cle,NAND_CMD_RESET);
++#if NAND_DEBUG
++ printk(" Wait for READY Status \n");
++#endif
++ // Wait for READY Status
++ regulus_device_ready(NULL);
++
++
++ //Write the READ ID command
++ nand_writew(nandaddr_for_cle,NAND_CMD_READID);
++ nand_writew(nandaddr_for_ale,0x00);
++
++ nand_mid = nand_readw(nandaddr_for_data);
++ nand_did = nand_readw(nandaddr_for_data);
++#if NAND_DEBUG
++ printk("Mfg ID 0x%x, Dev ID 0x%x\n", nand_mid, nand_did);
++#endif
++
++ /* Allocate memory for MTD device structure and private data */
++ regulus_nand_mtd = kmalloc(sizeof(struct mtd_info) +
++ sizeof(struct nand_chip),
++ GFP_KERNEL);
++ if (!regulus_nand_mtd) {
++ printk("Unable to allocate Sirius NAND MTD device structure.\n");
++ iounmap ((void *) nandaddr_for_data);
++ iounmap((void *) nandaddr_for_cle);
++ iounmap((void *) nandaddr_for_ale);
++ return -ENOMEM;
++ }
++
++ /* Get pointer to private data */
++ this = (struct nand_chip *) (®ulus_nand_mtd[1]);
++
++ /* Initialize structures */
++ memset((char *) regulus_nand_mtd, 0, sizeof(struct mtd_info));
++ memset((char *) this, 0, sizeof(struct nand_chip));
++
++ /* Link the private data with the MTD structure */
++ regulus_nand_mtd->priv = this;
++ regulus_nand_mtd->owner = THIS_MODULE;
++
++ /* insert callbacks */
++ this->IO_ADDR_R = nandaddr_for_data;
++ this->IO_ADDR_W = nandaddr_for_data;
++ this->cmd_ctrl = regulus_hwcontrol;
++#if 0
++ this->dev_ready = regulus_device_ready; /* unknown whether that was correct or not so we will just do it like this */
++#else
++ this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */
++#endif
++ if((this->dev_ready))
++ {
++#if NAND_DEBUG
++ printk("dev_ready is assigned to regulus_device_ready \n");
++ printk(" NAND_RDY is interfaced in GPIO97 of PXA270 \n");
++#endif
++ }
++ /* 35 us command delay time */
++ this->chip_delay = 35;
++ if(!(this->chip_delay))
++ {
++#if NAND_DEBUG
++ printk(" No value is assigned to the chip_delay in the low level driver routine \n");
++ printk(" This vaule will be assigned in nand_base level \n");
++#endif
++ }
++ else
++ {
++#if NAND_DEBUG
++ printk("chip_delay is %d micro seconds \n",this->chip_delay);
++#endif
++ }
++ this->ecc.mode = NAND_ECC_SOFT;
++
++#if NAND_DEBUG
++ printk(" NAND_ECC_SOFT is set for ecc.mode \n");
++#endif
++ this->options = (NAND_NO_AUTOINCR);
++
++ /* Scan to find existence of the device */
++#if NAND_DEBUG
++ printk(" Scan to find existence of the device \n");
++#endif
++ if (nand_scan (regulus_nand_mtd, 1)) {
++ printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
++ printk("***\tnand_scan returns no device found\n");
++ kfree (regulus_nand_mtd);
++ iounmap ((void *) nandaddr_for_data);
++ iounmap((void *) nandaddr_for_cle);
++ iounmap((void *) nandaddr_for_ale);
++ return -ENXIO;
++ }
++
++#ifdef CONFIG_MTD_CMDLINE_PARTS
++ mtd_parts_nb = parse_cmdline_partitions(regulus_nand_mtd, &mtd_parts,
++ "regulus-nand");
++ if (mtd_parts_nb > 0)
++ part_type = "command line";
++ else
++ mtd_parts_nb = 0;
++#endif
++ if (mtd_parts_nb == 0)
++ {
++ mtd_parts = partition_info;
++ mtd_parts_nb = NUM_PARTITIONS;
++ part_type = "static";
++ }
++
++ /* Register the partitions */
++#if NAND_DEBUG
++ printk(KERN_NOTICE "Using %s partition definition\n", part_type);
++#endif
++ add_mtd_partitions(regulus_nand_mtd, mtd_parts, mtd_parts_nb);
++
++#if NAND_DEBUG
++ printk("%s() : Low Level Driver for NAND Flash in regulus is successfully initialized \n",__FUNCTION__);
++#endif
++
++ /* Return happy */
++ return 0;
++}
++module_init(regulus_nand_init);
++
++/*
++ * Clean up routine
++ */
++static void __exit regulus_nand_cleanup (void)
++{
++
++ /* Release io resource */
++ iounmap ((void *) nandaddr_for_data);
++ iounmap ((void *) nandaddr_for_ale);
++ iounmap ((void *) nandaddr_for_cle);
++ del_mtd_partitions(regulus_nand_mtd);
++
++}
++module_exit(regulus_nand_cleanup);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Tharma <tharma at e-consystems dot com>");
++MODULE_DESCRIPTION("NAND flash driver for Regulus Reference Platform");
+diff -Naur linux-2.6.25_original/drivers/net/ax88796.c linux-2.6.25/drivers/net/ax88796.c
+--- linux-2.6.25_original/drivers/net/ax88796.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/ax88796.c 2009-05-16 18:43:58.000000000 +0530
+@@ -31,6 +31,15 @@
+ #include <asm/system.h>
+ #include <asm/io.h>
+
++
++#define ECON_DEBUG 1
++#if ECON_DEBUG
++#define dprintk(msg, args...) printk("FUNC %s(): LINE %d: "msg, __FUNCTION__,__LINE__,##args)
++#else
++#define dprintk(msg, args...) do{}while(0)
++#endif
++
++static struct net_device dev_ax;
+ static int phy_debug = 0;
+
+ /* Rename the lib8390.c functions to show that they are in this driver */
+@@ -53,6 +62,7 @@
+
+ /* define EI_SHIFT() to take into account our register offsets */
+ #define EI_SHIFT(x) (ei_local->reg_offset[(x)])
++#define EI_SHIFT(x) ((x)<<1)
+
+ /* Ensure we have our RCR base value */
+ #define AX88796_PLATFORM
+@@ -94,6 +104,49 @@
+ u32 reg_offsets[0x20];
+ };
+
++
++#ifdef CONFIG_MACH_REGULUS
++#include <asm/arch/pxa-regs.h>
++#define GPIO_FOR_ASIX_IRQ 37
++#define IRQ_EINT11 IRQ_GPIO(GPIO_FOR_ASIX_IRQ)
++#define GPIO_FOX_ASIX_IRQ_MD ( GPIO_FOR_ASIX_IRQ | GPIO_IN)
++#define GPIO80_GPIO_OUT (80 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define IMCR_GPIO_x (1<<10)
++#define ICLR_GPIO_x (1<<10)
++#define IRQ_FALLING_EDGE 1
++
++static struct resource ax88796_resources[] = {
++ [0]= {
++ .start = (PXA_CS4_PHYS),
++ .end = (PXA_CS4_PHYS + 0xFFFFF),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_GPIO(GPIO_FOR_ASIX_IRQ),
++ .end = IRQ_GPIO(GPIO_FOR_ASIX_IRQ),
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
++ }
++
++};
++
++
++
++static struct platform_device ax88796_device = {
++ .name = "ax88796",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ax88796_resources),
++ .resource = ax88796_resources,
++};
++
++
++
++static struct platform_device *platform_devices1[] __initdata = {
++ &ax88796_device,
++};
++
++#endif
++
++
+ static inline struct ax_device *to_ax_dev(struct net_device *dev)
+ {
+ struct ei_device *ei_local = netdev_priv(dev);
+@@ -819,24 +872,35 @@
+ size_t size;
+ int ret;
+
++ pdev = &ax88796_device;
++
+ dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
+ if (dev == NULL)
++ {
++ dprintk("Failed to allocate memory \n");
+ return -ENOMEM;
+-
++ }
+ /* ok, let's setup our device */
++ dprintk("ok, let's setup our device \n");
++
+ ax = to_ax_dev(dev);
+
++
++ dprintk("filling the structure ax with zero values \n");
+ memset(ax, 0, sizeof(struct ax_device));
+
+ spin_lock_init(&ax->mii_lock);
+
+ ax->dev = pdev;
+ ax->plat = pdev->dev.platform_data;
++ dprintk("calling platfrom_set_drvdata\n");
++#if 0
+ platform_set_drvdata(pdev, dev);
+-
+ ei_status.rxcr_base = ax->plat->rcr_val;
++#endif
+
+ /* find the platform resources */
++ dprintk(" find the platform resources \n");
+
+ dev->irq = platform_get_irq(pdev, 0);
+ if (dev->irq < 0) {
+@@ -856,7 +920,10 @@
+
+ /* setup the register offsets from either the platform data
+ * or by using the size of the resource provided */
++
++ dprintk(" setup the register offsets from either the platform data or by using the size of the resource provided \n");
+
++#if 0
+ if (ax->plat->reg_offsets)
+ ei_status.reg_offset = ax->plat->reg_offsets;
+ else {
+@@ -864,6 +931,7 @@
+ for (ret = 0; ret < 0x18; ret++)
+ ax->reg_offsets[ret] = (size / 0x18) * ret;
+ }
++#endif
+
+ ax->mem = request_mem_region(res->start, size, pdev->name);
+ if (ax->mem == NULL) {
+@@ -885,14 +953,18 @@
+ }
+
+ /* look for reset area */
++
++ dprintk("look for reset area \n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res == NULL) {
++
++#if 0
+ if (!ax->plat->reg_offsets) {
+ for (ret = 0; ret < 0x20; ret++)
+ ax->reg_offsets[ret] = (size / 0x20) * ret;
+ }
+-
++#endif
+ ax->map2 = NULL;
+ } else {
+ size = (res->end - res->start) + 1;
+@@ -911,10 +983,14 @@
+ goto exit_mem2;
+ }
+
++#if 0
+ ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
++#endif
+ }
+
+ /* got resources, now initialise and register device */
++
++ dprintk(" got resources, now initialise and register device \n");
+
+ ret = ax_init_dev(dev, 1);
+ if (!ret)
+@@ -989,8 +1065,12 @@
+ .resume = ax_resume,
+ };
+
++
++
++
+ static int __init axdrv_init(void)
+ {
++ platform_add_devices(platform_devices1, ARRAY_SIZE(platform_devices1));
+ return platform_driver_register(&axdrv);
+ }
+
+diff -Naur linux-2.6.25_original/drivers/net/Kconfig linux-2.6.25/drivers/net/Kconfig
+--- linux-2.6.25_original/drivers/net/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -228,6 +228,13 @@
+
+ source "drivers/net/arm/Kconfig"
+
++config REGULUS_AX88796B
++ tristate "ASIX AX88796B driver support for esom270 based reference boards "
++ depends on ARM || MACH_REGULUS
++ select CRC32
++ select MII
++ help
++ ******* Need to be updated **********
+ config AX88796
+ tristate "ASIX AX88796 NE2000 clone support"
+ depends on ARM || MIPS || SUPERH
+diff -Naur linux-2.6.25_original/drivers/net/Makefile linux-2.6.25/drivers/net/Makefile
+--- linux-2.6.25_original/drivers/net/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -3,6 +3,7 @@
+ #
+
+ obj-$(CONFIG_E1000) += e1000/
++obj-$(CONFIG_REGULUS_AX88796B) += regulus_ax88796b/
+ obj-$(CONFIG_E1000E) += e1000e/
+ obj-$(CONFIG_IBM_EMAC) += ibm_emac/
+ obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
+@@ -123,7 +124,6 @@
+ obj-$(CONFIG_FORCEDETH) += forcedeth.o
+ obj-$(CONFIG_NE_H8300) += ne-h8300.o
+ obj-$(CONFIG_AX88796) += ax88796.o
+-
+ obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
+ obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+ obj-$(CONFIG_QLA3XXX) += qla3xxx.o
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_08jan2009.c linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_08jan2009.c
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_08jan2009.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_08jan2009.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,2176 @@
++/*
++ ==================================================================================
++ ax88796b.c: A SAMSUNG S3C2440 Linux2.6.x Ethernet device driver for ASIX AX88796B chips.
++
++ This program is free software; you can distrine_block_inputbute 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.,
++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++
++ This program is based on
++
++ ne.c: A general non-shared-memory NS8390 ethernet driver for linux
++ Written 1992-94 by Donald Becker.
++
++ 8390.c: A general NS8390 ethernet driver core for linux.
++ Written 1992-94 by Donald Becker.
++
++ Version history:
++
++ Version 1.0.0 06/02/2006
++
++ * Initial release
++
++ Version 1.0.0 27/03/2006
++
++ * Fixups Transmit Queue functions.
++
++ Version 1.1.0 20/09/2006
++
++ * Ported to support kernel 2.6.x.
++
++ Version 1.2.0 09/09/2008
++
++ * 1. Added 8-bit support.
++ * 2. Added EEPROM support.
++ * 3. Added PHY power process function.
++
++ ==================================================================================
++ Driver Overview
++ ==================================================================================
++ ASIX AX88796B 3-in-1 Local Bus 8/16-bit Fast Ethernet Linux Driver
++
++ The AX88796B Ethernet controller is a high performance and highly integrated
++ local CPU bus Ethernet controllers with embedded 10/100Mbps PHY/Transceiver
++ 16K bytes SRAM and supports both 8-bit and 16-bit local CPU interfaces for any
++ embedded systems.
++
++ If you look for more details, please visit ASIX's web site (http://www.asix.com.tw).
++
++
++ ==================================================================================
++ COMPILING DRIVER
++ ==================================================================================
++ Prepare:
++
++ AX88796B Linux Driver.
++ Linux Kernel source code.
++ Cross-Compiler.
++
++ Getting Start:
++
++ 1.Extracting the AX88796B source file by executing the following command.
++ [root@localhost]# tar jxvf ax88796b-arm-linux2.4.tar.bz2
++
++ 2.Edit the makefile to specifie the path of target platform Linux Kernel source.
++ EX:
++ KDIR := /work/linux-2.6.17.11
++
++ 3.Executing 'make' command to compiler AX88796B Driver.
++
++ 4.If the compilation well, the ax88796.ko will be created under the current directory.
++
++
++ ==================================================================================
++ DRIVER PARAMETERS
++ ==================================================================================
++ The following parameters can be set when using insmod.
++ EX: [root@localhost ax88796b]# insmod ax88796.ko mem=0x08000000
++
++ mem=0xNNNNNNNN
++ specifies the physical base address that AX88796B can be accessed.
++ Default value '0x08000000'.
++
++ irq=N
++ specifies the irq number. Default value '0x27'.
++
++ media=(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)
++ Media mode control. Default value 'auto'.
++*/
++
++
++
++
++#include "ax88796b.h"
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/pxa2xx-regs.h>
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
++#include <linux/irq.h>
++#endif
++
++
++
++/* Local Function Prototypes */
++static int ax_probe (struct net_device *dev);
++static int ax_open (struct net_device *dev);
++static int ax_close (struct net_device *dev);
++static void ax_reset (struct net_device *dev);
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr,
++ int ring_page);
++static void ax_block_input (struct net_device *dev, int count,
++ struct sk_buff *skb, int ring_offset);
++static void ax_block_output (struct net_device *dev, const int count,
++ const unsigned char *buf, const int start_page);
++static int ethdev_init (struct net_device *dev);
++static void ax_init (struct net_device *dev, int startp);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++int set_external_irq (int irq, int edge, int pullup);
++# endif
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#endif
++static void ax_tx_intr (struct net_device *dev);
++static void ax_tx_err (struct net_device *dev);
++static void ax_receive (struct net_device *dev);
++static void ax_rx_overrun (struct net_device *dev);
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page);
++static void set_multicast_list (struct net_device *dev);
++static void do_set_multicast_list (struct net_device *dev);
++static void ax_watchdog (unsigned long arg);
++
++static void ax_vlan_rx_add_vid (struct net_device *netdev, u16 vid);
++static void ax_vlan_rx_kill_vid (struct net_device *netdev, u16 vid);
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc);
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value);
++static inline u16 READ_FIFO (void *membase);
++static inline void WRITE_FIFO (void *membase, u16 data);
++
++/* NAMING CONSTANT DECLARATIONS */
++#define DRV_NAME "AX88796B"
++#define ADP_NAME "ASIX AX88796B Ethernet Adapter"
++#define DRV_VERSION "1.2.0"
++#define PFX DRV_NAME ": "
++
++#define PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printk(args)
++#define ECON_DEBUG 0
++#if ECON_DEBUG
++#define eprintk(msg,args...) printk(msg,## args)
++#else
++#define eprintk(msg,args...) do{}while(0)
++#endif
++
++
++#define CRITICAL_DEBUG 0
++#if CRITICAL_DEBUG
++#define cprintk(msg,args...) printk(msg,## args)
++#else
++#define cprintk(msg,args...) do{}while(0)
++#endif
++
++//#define USE_ASSERT 1
++//#define USE_TRACE 1
++//#define USE_WARNING 1
++
++#ifdef USE_ASSERT
++# define ASIX_ASSERT(condition) \
++ if(!(condition)) { \
++ printk("ASIX_ASSERTION_FAILURE: File=" __FILE__ ", Line=%d\n",__LINE__); \
++ while(1); \
++ }
++#else
++# define ASIX_ASSERT(condition)
++#endif
++
++
++#ifdef USE_TRACE
++#ifndef USE_WARNING
++#define USE_WARNING
++#endif
++# define ASIX_TRACE(msg,args...) \
++ if(0x01UL) { \
++ printk("ASIX: " msg "\n", ## args); \
++ }
++#else
++# define ASIX_TRACE(msg,args...)
++#endif
++
++
++#ifdef USE_WARNING
++#ifndef USE_ASSERT
++#define USE_ASSERT
++#endif
++# define ASIX_WARNING(msg, args...) \
++ if(0x02UL) { \
++ printk("ASIX_WARNING: " msg "\n",## args); \
++ }
++#else
++# define ASIX_WARNING(msg, args...)
++#endif
++
++
++
++
++
++#define CONFIG_AX88796B_USE_MEMCPY 1
++#define CONFIG_AX88796B_8BIT_WIDE 0
++#define CONFIG_AX88796B_EEPROM_READ_WRITE 0
++
++#ifndef ENBTCR_IRQ_TYPE_PUSH_PULL
++#define ENBTCR_IRQ_TYPE_PUSH_PULL 0x20 /* IRQ Output is Push Pull Driver */
++#endif
++
++
++#ifdef AX88796B_BASE
++#undef AX88796B_BASE
++#define AX88796B_BASE PXA_CS4_PHYS
++#endif
++
++#define MAC_ADDRESS_OFFSET_IN_NOR_FLASH 0x00008000
++#define MAC_ADDRESS_IN_NOR_FLASH (MAC_ADDRESS_OFFSET_IN_NOR_FLASH)
++#define MAC_ADDDRESS_LENGTH 6
++#define SIZE_1K 0x00000400 /* 1K */
++
++#if CONFIG_AX88796B_USE_MEMCPY
++#define FIFO_SEL_IS_A11 0
++#define FIFO_SEL_IS_A20 1
++#endif
++
++#if FIFO_SEL_IS_A11
++#warning "FIFO_SEL_IS_A11 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0xFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x0800
++ #endif
++
++#elif FIFO_SEL_IS_A20
++#warning "FIFO_SEL_IS_A20 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0x0FFFFFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x00100000
++ #endif
++
++#endif
++
++
++#if CONFIG_MACH_DENEB
++#warning "MACH_DENEB is defined"
++#define GPIO_FOR_ASIX_IRQ 74
++#elif (CONFIG_MACH_REGULUS|| CONFIG_MACH_SIRIUS)
++#warning "either MACH_REGULUS or MACH_SIRIUS is defined"
++#define GPIO_FOR_ASIX_IRQ 37
++#endif
++
++#define IRQ_EINT11 IRQ_GPIO(GPIO_FOR_ASIX_IRQ)
++#define GPIO_FOX_ASIX_IRQ_MD ( GPIO_FOR_ASIX_IRQ | GPIO_IN)
++#define IRQ_FALLING_EDGE 1
++
++
++#include "pxa270_dma_mode_for_asix.c"
++
++/* LOCAL VARIABLES DECLARATIONS */
++static char version[] =
++KERN_INFO ADP_NAME ":v" DRV_VERSION " " __TIME__ " " __DATE__ "\n"
++KERN_INFO " http://www.asix.com.tw\n";
++
++static unsigned int media = 0;
++
++static struct net_device dev_ax;
++static int mem;
++static int irq;
++
++volatile unsigned short int *nor_flash_addr=NULL;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++MODULE_PARM (mem, "i");
++MODULE_PARM (irq, "i");
++MODULE_PARM (media, "i");
++#else
++module_param (mem, int, 0);
++module_param (irq, int, 0);
++module_param (media, int, 0);
++#endif
++
++MODULE_PARM_DESC (mem, "MEMORY base address(es),required");
++MODULE_PARM_DESC (irq, "IRQ number(s)");
++MODULE_PARM_DESC (media, "Media Mode(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)");
++
++MODULE_DESCRIPTION ("ASIX AX88796B Fast Ethernet driver");
++MODULE_LICENSE ("GPL");
++
++
++void get_mac_from_nor_flash(unsigned char *addr)
++{
++ int i=0;
++ unsigned char *mac_addr= (unsigned char *)addr;
++ memcpy(mac_addr,nor_flash_addr,MAC_ADDDRESS_LENGTH);
++
++}
++
++
++
++void deneb_asix_gpio_initialize(void)
++{
++
++#define IMCR_GPIO_x (1<<10)
++#define ICLR_GPIO_x (1<<10)
++
++ pxa_gpio_mode(GPIO_FOX_ASIX_IRQ_MD);
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ GFER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ GRER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#endif
++ ICMR |= IMCR_GPIO_x;
++ ICLR &= ~(ICLR_GPIO_x);
++}
++
++
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: init_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++int deneb_ax88796b_init_module (void)
++{
++ struct net_device *dev = &dev_ax;
++
++
++ volatile unsigned int msc2_data=0;
++ volatile unsigned int ncs4_config_data = 0x7FF9; // Slower Device, Maximum ROM/SRAM Recovery Time, Maximum ROM Delay Next Access, Maximum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++ dev->nd_net = (struct net *)kmalloc(sizeof(struct net),GFP_KERNEL);
++ if (dev->nd_net == NULL)
++ return -ENOMEM;
++ memset (dev->nd_net, 0, sizeof (struct net));
++
++ printk("FUNC %s() : LINE %d : Driver for AX88796B Non-PCI Fast Ethernet Chip \n",__FUNCTION__,__LINE__);
++
++ printk("Configuring GPIO80 as GPIO and Drive Logic 1 on GPIO80 \n");
++#define GPIO80_GPIO_OUT (80 | GPIO_OUT | GPIO_DFLT_HIGH)
++ pxa_gpio_mode(GPIO80_GPIO_OUT);
++
++ printk("Configuring GPIO80 as nCS4 \n");
++ pxa_gpio_mode(GPIO80_nCS_4_MD);
++
++ printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ printk("Configuring the Memory Controller Register for nCS4 \n");
++ msc2_data = MSC2;
++ MSC2 = (ncs4_config_data & 0x0000FFFF) | (msc2_data & 0xFFFF0000);
++ printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ printk("Physical address of nCS4 is 0x%08X \n",PXA_CS4_PHYS);
++
++
++
++ dev->irq = irq;
++ dev->base_addr = mem;
++ dev->init = ax_probe;
++ sprintf (dev->name, "eth%d",0);
++ if (register_netdev (dev) == 0)
++ return 0;
++
++ if (mem != 0) {
++ PRINTK (WARNING_MSG, PFX " No AX88796B card found at memory = %#x\n", mem);
++ }
++ else {
++ PRINTK (WARNING_MSG, PFX " You must supply \"mem=0xNNNNNNN\" value(s) for AX88796B.\n");
++ }
++ return -ENXIO;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: cleanup_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void deneb_ax88796b_cleanup_module (void)
++{
++ struct net_device *dev = &dev_ax;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++
++#if (DMA_MODE_OPERATION==1)
++ rx_dma_uninitialize();
++ tx_dma_uninitialize();
++#endif
++
++ unregister_netdev (dev);
++ cprintk("FUNC %s() : LINE %d : Freeing irq for AX88796B Chip \n",__FUNCTION__,__LINE__);
++ free_irq (dev->irq, dev);
++ kfree(dev->nd_net);
++ dev->nd_net = NULL;
++ kfree (dev->priv);
++ dev->priv = NULL;
++ release_mem_region(AX88796B_BASE,NE_IO_EXTENT);
++ iounmap (ax_base);
++}
++
++
++
++module_init(deneb_ax88796b_init_module);
++module_exit(deneb_ax88796b_cleanup_module);
++
++
++
++
++
++
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++static inline u16 READ_FIFO (void *membase)
++{
++ return (readb (membase) | (((u16)readb (membase)) << 8));
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writeb ((u8)data , membase);
++ writeb ((u8)(data >> 8) , membase);
++}
++#else
++static inline u16 READ_FIFO (void *membase)
++{
++ return readw (membase);
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writew (data, membase);
++}
++#endif
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: config_2440_bank1
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void config_2440_bank1 (void)
++{
++ /* Configure SAMSUNG S3C2440A controller for AX88796B operation */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ BWSCON = BWSCON & 0xFFFFFFCF;
++# else
++ BWSCON = (BWSCON & 0xFFFFFFCF) | 0x00000010;
++# endif
++
++ BANKCON1 = DEFAULT_125MHZ_BANKCON1;
++
++ set_external_irq (IRQ_EINT11, EXT_LOWLEVEL, GPIO_PULLUP_DIS);
++ EINTMASK &= ~EINT11_MASK;
++ EXTINT1 &= ~0xf000;
++ EXTINT1 |= FLTEN11_LOWLEVEL;
++# endif /* CONFIG_BOARD_S3C2440_SMDK */
++#else
++# ifdef CONFIG_ARCH_S3C2410
++ {
++ unsigned long tmp;
++ tmp = __raw_readl (S3C2410_BWSCON);
++
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_8, S3C2410_BWSCON);
++# else
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_16, S3C2410_BWSCON);
++# endif
++
++ __raw_writel (S3C2410_BANKCON_Tcah1 | S3C2410_BANKCON_Tacc8, S3C2410_BANKCON1);
++ }
++# endif /* CONFIG_ARCH_S3C2410 */
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: load_macaddr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++load_macaddr (struct net_device *dev, unsigned char *pMac)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Read the 12 bytes of station address PROM. */
++ {
++ struct {unsigned char value, offset; } program_seq[] =
++ {
++ {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
++ {ax_local->bus_width, EN0_DCFG}, /* Set wide access. */
++ {0x00, EN0_RCNTLO}, /* Clear the count regs. */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_IMR}, /* Mask completion irq. */
++ {0xFF, EN0_ISR},
++ {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
++ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
++ {0x0C, EN0_RCNTLO}, /* 12 bytes of station address */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
++ {0x00, EN0_RSARHI},
++ {E8390_RREAD+E8390_START, E8390_CMD},
++ };
++
++ for (i = 0; i < sizeof (program_seq)/sizeof (program_seq[0]); i++)
++ writeb (program_seq[i].value, ax_base + program_seq[i].offset);
++ }
++
++ while (( readb (ax_base + EN0_SR) & 0x20) == 0);
++
++ for (i = 0; i < 6; i++) {
++ pMac[i] = (unsigned char) READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_probe
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_probe (struct net_device *dev)
++{
++ int i;
++ int reg0, ret;
++ unsigned long base_addr;
++ void *address;
++ struct ax_device *ax_local;
++
++ PRINTK (INIT_MSG, PFX " probe start ..........\n");
++
++ //SET_MODULE_OWNER (dev);
++
++ if (dev->base_addr == 0 )
++ dev->base_addr = AX88796B_BASE;
++
++ base_addr = dev->base_addr;
++
++ if (check_mem_region (base_addr , NE_IO_EXTENT))
++ return -ENODEV;
++ if (! request_mem_region (base_addr, NE_IO_EXTENT, DRV_NAME))
++ return -EBUSY;
++ address=ioremap_nocache (base_addr, NE_IO_EXTENT);
++ if (!address) {
++ PRINTK (ERROR_MSG, PFX " Unable to remap memory\n");
++ return -EBUSY;
++ }
++
++ nor_flash_addr=(unsigned short int *)ioremap_nocache(MAC_ADDRESS_IN_NOR_FLASH,SIZE_1K);
++
++ printk("ioremaped address is 0x%08X \n",(unsigned int)address);
++ printk("ioremaped not_flash_addr is 0x%08X \n",(unsigned int)nor_flash_addr);
++ CS4_VIRT_BASE = (unsigned long)address;
++
++ config_2440_bank1 ();
++
++ PRINTK (DRIVER_MSG, "%s: Calling deneb_asix_gpio_initialize() \n",DRV_NAME);
++ deneb_asix_gpio_initialize();
++
++ reg0 = readb (address);
++ if (reg0 == 0xFF) {
++ ret = -ENODEV;
++ goto err_out;
++ }
++
++ /* Do a preliminary verification that we have a 8390. */
++ {
++ int regd;
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, address + E8390_CMD);
++ regd = readb (address + EN0_COUNTER0);
++ writeb (0xff, address + EN0_COUNTER0);
++ writeb (E8390_NODMA+E8390_PAGE0, address + E8390_CMD);
++ readb (address + EN0_COUNTER0); /* Clear the counter by reading. */
++ if (readb (address + EN0_COUNTER0) != 0) {
++ writeb (reg0, address);
++ writeb (regd, address + EN0_COUNTER0); /* Restore the old values. */
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++
++ printk (version);
++
++ /* Reset card. Who knows what dain-bramaged state it was left in. */
++ {
++ unsigned long reset_start_time = jiffies;
++
++ readb (address + EN0_RESET);
++ while ((readb (address + EN0_ISR) & ENISR_RESET) == 0) {
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, " not found (no reset ack).\n");
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++ writeb (0xff, (address + EN0_ISR)); /* Ack all intr. */
++ }
++
++ if (dev->irq == 0)
++ dev->irq =IRQ_EINT11;
++
++ /* Allocate dev->priv and fill in 8390 specific dev fields. */
++ if (ethdev_init (dev))
++ {
++ PRINTK (ERROR_MSG, "unable to get memory for dev->priv.\n");
++ ret = -ENOMEM;
++ goto err_out;
++ }
++
++ ax_local = (struct ax_device *)dev->priv;
++ ax_local->name = DRV_NAME;
++ ax_local->membase = address;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->rx_start_page = NESM_RX_START_PG;
++ ax_local->stop_page = NESM_STOP_PG;
++ ax_local->media = media;
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ ax_local->bus_width = 0;
++#else
++ ax_local->bus_width = 1;
++#endif
++
++ load_macaddr (dev, dev->dev_addr);
++
++ /* Support for No EEPROM */
++ if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++
++ get_mac_from_nor_flash(dev->dev_addr);
++
++ printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ printk (" %2.2x", dev->dev_addr[i]);
++ }
++ printk("\n");
++
++ if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0xFF) && (dev->dev_addr[1] == 0xFF) &&
++ (dev->dev_addr[2] == 0xFF) && (dev->dev_addr[3] == 0xFF) &&
++ (dev->dev_addr[4] == 0xFF) && (dev->dev_addr[5] == 0xFF) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ }
++
++ PRINTK (DRIVER_MSG, "%s: MAC ADDRESS ",DRV_NAME);
++ for (i = 0; i < ETHER_ADDR_LEN; i++) {
++ PRINTK (DRIVER_MSG, " %2.2x", dev->dev_addr[i]);
++ }
++
++ sprintf (dev->name, "eth%d",0);
++ PRINTK (DRIVER_MSG, "\n%s: %s found at 0x%x, using IRQ %d.\n",
++ dev->name, DRV_NAME, AX88796B_BASE, dev->irq);
++
++ dev->open = &ax_open;
++ dev->stop = &ax_close;
++ dev->features |= NETIF_F_HW_VLAN_FILTER;
++ dev->vlan_rx_add_vid = ax_vlan_rx_add_vid;
++ dev->vlan_rx_kill_vid = ax_vlan_rx_kill_vid;
++
++ ax_init (dev, 0);
++ PRINTK (INIT_MSG, PFX " probe end ..........\n");
++ return 0;
++
++err_out:
++ iounmap (address);
++ iounmap (nor_flash_addr);
++ kfree (dev->priv);
++ dev->priv = NULL;
++ return ret;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_reset
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_reset (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long reset_start_time = jiffies;
++
++ readb (ax_base + EN0_RESET);
++
++ ax_local->dmaing = 0;
++
++ /* This check _should_not_ be necessary, omit eventually. */
++ while ((readb (ax_base+EN0_ISR) & ENISR_RESET) == 0)
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, "%s: ax_reset() did not complete.\n", dev->name);
++ break;
++ }
++
++ writeb (ENISR_RESET, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_get_hdr
++ * Purpose: Grab the 796b specific header
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr, int ring_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)hdr;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_get_8390_hdr "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (sizeof (struct ax_pkt_hdr), ax_base + EN0_RCNTLO);
++ writeb (0, ax_base + EN0_RCNTHI);
++ writeb (0, ax_base + EN0_RSARLO); /* On page boundary */
++ writeb (ring_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++ *(++buf) = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++
++ le16_to_cpus (&hdr->count);
++
++}
++
++
++#if (DMA_MODE_OPERATION==0)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_input
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)skb->data;
++ u16 i;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_input "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (ring_offset & 0xff, ax_base + EN0_RSARLO);
++ writeb (ring_offset >> 8, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ {
++
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & (0xFFFF8);
++ #endif
++
++ /* Read first 2 bytes */
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ /* The address of ++buf should be agigned on 32-bit boundary */
++ memcpy (++buf, ax_base+EN0_DATA_ADDR, i);
++ }
++#else
++ {
++ for (i = 0; i < count; i += 2) {
++ *buf++ = READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++ }
++#endif
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_output
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long dma_start;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_output."
++ "[DMAstat:%d][irqlock:%d]\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ /* We should already be in page 0, but to be safe... */
++ writeb (E8390_PAGE0+E8390_START+E8390_NODMA, ax_base + E8390_CMD);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ /* Now the normal output. */
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (0x00, ax_base + EN0_RSARLO);
++ writeb (start_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RWRITE+E8390_START, ax_base + E8390_CMD);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0x7F8));
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0xFFFF8));
++ #endif
++#else
++ {
++ u16 i;
++ for (i = 0; i < count; i += 2) {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + i)));
++ }
++ }
++#endif
++ dma_start = jiffies;
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0) {
++ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
++ PRINTK (ERROR_MSG, "%s: timeout waiting for Tx RDC.\n", dev->name);
++ ax_reset (dev);
++ ax_init (dev,1);
++ break;
++ }
++ }
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++ return;
++}
++
++#endif // end of DMA_MODE_OPERATION
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_open
++ * Purpose: Open/initialize 796b
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_open (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *membase = ax_local->membase;
++ int ret=0;
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open beginning ..........\n");
++ PRINTK (DEBUG_MSG, PFX " membase %p\n\r", membase);
++
++ ret = request_irq ((unsigned int)dev->irq, (irq_handler_t) &ax_interrupt, (unsigned long)0, (const char *)dev->name, (void *)dev);
++
++ if (ret) {
++ PRINTK (ERROR_MSG, "%s: unable to get IRQ %d (errno=%d).\n",dev->name, dev->irq, ret);
++ return -ENXIO;
++ }
++
++ PRINTK (DEBUG_MSG, PFX " Request IRQ success !!\n\r");
++
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ set_irq_type(dev->irq, IRQT_FALLING);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ set_irq_type(dev->irq, IRQT_RISING);
++#endif
++
++
++ /* This can't happen unless somebody forgot to call ethdev_init(). */
++ if (ax_local == NULL)
++ {
++ PRINTK (ERROR_MSG, "%s: ei_open passed a non-existent device!\n", dev->name);
++ return -ENXIO;
++ }
++
++ dev->tx_timeout = NULL;
++ dev->watchdog_timeo = 0;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_reset (dev);
++ ax_init (dev, 1);
++ netif_start_queue (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ ax_local->irqlock = 0;
++
++ init_timer (&ax_local->watchdog);
++ ax_local->watchdog.function = &ax_watchdog;
++ ax_local->watchdog.expires = jiffies + AX88796_WATCHDOG_PERIOD;
++ ax_local->watchdog.data = (unsigned long) dev;
++ add_timer (&ax_local->watchdog);
++
++#if (DMA_MODE_OPERATION==1)
++ rx_dma_initialize();
++ tx_dma_initialize();
++#endif
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open end ..........\n");
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_close
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_close (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ unsigned long flags;
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close beginning ..........\n");
++ del_timer (&ax_local->watchdog);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_init (dev, 0);
++
++ cprintk("FUNC %s() : LINE %d : Freeing irq for AX88796B Chip \n",__FUNCTION__,__LINE__);
++ free_irq (dev->irq, dev);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ netif_stop_queue (dev);
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close end ..........\n");
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_start_xmit
++ * Purpose: begin packet transmission
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int send_length;
++ unsigned long flags;
++ u8 ctepr=0, free_pages=0, need_pages;
++
++ /* check for link status */
++ if (!(readb (ax_base + EN0_SR) & ENSR_LINK)) {
++ dev_kfree_skb (skb);
++ return 0;
++ }
++
++ send_length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ spin_lock (&ax_local->page_lock);
++ ax_local->irqlock = 1;
++
++ need_pages = (send_length -1)/256 +1;
++ ctepr = readb (ax_base + EN0_CTEPR) & 0x7f;
++
++ if (ctepr == 0) {
++ if (ax_local->tx_curr_page == ax_local->tx_start_page && ax_local->tx_prev_ctepr == 0)
++ free_pages = TX_PAGES;
++ else
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page;
++ }
++ else if (ctepr < ax_local->tx_curr_page - 1) {
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page +
++ ctepr - ax_local->tx_start_page + 1;
++ }
++ else if (ctepr > ax_local->tx_curr_page - 1) {
++ free_pages = ctepr + 1 - ax_local->tx_curr_page;
++ }
++ else if (ctepr == ax_local->tx_curr_page - 1) {
++ if (ax_local->tx_full)
++ free_pages = 0;
++ else
++ free_pages = TX_PAGES;
++ }
++
++ if (free_pages < need_pages) {
++ PRINTK (DEBUG_MSG, "free_pages < need_pages\n\r");
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return 1;
++ }
++
++ ax_block_output (dev, send_length, skb->data, ax_local->tx_curr_page);
++ ax_trigger_send (dev, send_length, ax_local->tx_curr_page);
++ if (free_pages == need_pages) {
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ }
++ ax_local->tx_prev_ctepr = ctepr;
++ ax_local->tx_curr_page = ax_local->tx_curr_page + need_pages < ax_local->tx_stop_page ?
++ ax_local->tx_curr_page + need_pages :
++ need_pages - (ax_local->tx_stop_page - ax_local->tx_curr_page) + ax_local->tx_start_page;
++
++ dev_kfree_skb (skb);
++ dev->trans_start = jiffies;
++ ax_local->stat.tx_bytes += send_length;
++
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_intr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_intr (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int status = readb (ax_base + EN0_TSR);
++
++ ax_local->tx_full = 0;
++ if (netif_queue_stopped (dev))
++ netif_wake_queue (dev);
++
++ /* Minimize Tx latency: update the statistics after we restart TXing. */
++ if (status & ENTSR_COL)
++ ax_local->stat.collisions++;
++ if (status & ENTSR_PTX)
++ ax_local->stat.tx_packets++;
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (status & ENTSR_ABT)
++ {
++ ax_local->stat.tx_aborted_errors++;
++ ax_local->stat.collisions += 16;
++ }
++ if (status & ENTSR_CRS)
++ ax_local->stat.tx_carrier_errors++;
++ if (status & ENTSR_FU)
++ ax_local->stat.tx_fifo_errors++;
++ if (status & ENTSR_CDH)
++ ax_local->stat.tx_heartbeat_errors++;
++ if (status & ENTSR_OWC)
++ ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_interrupt
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#endif
++{
++ struct net_device *dev = dev_id;
++ int interrupts;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ if (dev == NULL)
++ {
++ PRINTK (ERROR_MSG, "net_interrupt(): irq %d for unknown device.\n", irq);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ if (ax_local->irqlock) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ spin_lock (&ax_local->page_lock);
++
++ while (1)
++ {
++
++ if ((interrupts = readb (ax_base + EN0_ISR)) == 0)
++ break;
++
++ writeb (interrupts, ax_base + EN0_ISR); /* Ack the interrupts */
++
++ if (interrupts & ENISR_TX)
++ ax_tx_intr (dev);
++
++ if (interrupts & ENISR_OVER)
++ ax_rx_overrun (dev);
++
++ if (interrupts & (ENISR_RX+ENISR_RX_ERR))
++ ax_receive (dev);
++
++ if (interrupts & ENISR_TX_ERR)
++ ax_tx_err (dev);
++
++ if (interrupts & ENISR_COUNTERS)
++ {
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++ writeb (ENISR_COUNTERS, ax_base + EN0_ISR); /* Ack intr. */
++ }
++
++ if (interrupts & ENISR_RDC)
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++ }
++
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return IRQ_HANDLED;
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_err
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_err (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned char txsr = readb (ax_base+EN0_TSR);
++ unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
++
++ if (tx_was_aborted)
++ ax_tx_intr (dev);
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (txsr & ENTSR_CRS) ax_local->stat.tx_carrier_errors++;
++ if (txsr & ENTSR_CDH) ax_local->stat.tx_heartbeat_errors++;
++ if (txsr & ENTSR_OWC) ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_receive
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_receive (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char rxing_page, this_frame, next_frame;
++ unsigned short current_offset;
++ struct ax_pkt_hdr rx_frame;
++ int num_rx_pages = ax_local->stop_page - ax_local->rx_start_page;
++ while (1)
++ {
++ int pkt_len, pkt_stat;
++
++ /* Get the rx page (incoming packet pointer). */
++ writeb (E8390_NODMA+E8390_PAGE1, ax_base + E8390_CMD);
++ rxing_page = readb (ax_base + EN1_CURPAG);
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ /* Remove one frame from the ring. Boundary is always a page behind. */
++ this_frame = readb (ax_base + EN0_BOUNDARY) + 1;
++ if (this_frame >= ax_local->stop_page)
++ this_frame = ax_local->rx_start_page;
++
++ if (this_frame != ax_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
++ PRINTK (RX_MSG, "%s: mismatched read page pointers %2x vs %2x.\n",
++ dev->name, this_frame, ax_local->current_page);
++
++ if (this_frame == rxing_page) { /* Read all the frames? */
++ break; /* Done for now */
++ }
++ current_offset = this_frame << 8;
++ ax_get_hdr (dev, &rx_frame, this_frame);
++
++ pkt_len = rx_frame.count - sizeof (struct ax_pkt_hdr);
++ pkt_stat = rx_frame.status;
++ next_frame = this_frame + 1 + ((pkt_len+4)>>8);
++
++ /* Check for bogosity warned by 3c503 book: the status byte is never
++ written. This happened a lot during testing! This code should be
++ cleaned up someday. */
++ if (rx_frame.next != next_frame
++ && rx_frame.next != next_frame + 1
++ && rx_frame.next != next_frame - num_rx_pages
++ && rx_frame.next != next_frame + 1 - num_rx_pages) {
++ ax_local->current_page = rxing_page;
++ writeb (ax_local->current_page-1, ax_base+EN0_BOUNDARY);
++ ax_local->stat.rx_errors++;
++ PRINTK (ERROR_MSG, "error occurred! Drop this packet!!\n");
++ continue;
++ }
++
++ if (pkt_len < 60 || pkt_len > 1518)
++ {
++ PRINTK (RX_MSG, "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
++ dev->name, rx_frame.count, rx_frame.status,
++ rx_frame.next);
++ ax_local->stat.rx_errors++;
++ ax_local->stat.rx_length_errors++;
++ }
++ else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
++ {
++ struct sk_buff *skb;
++ skb = dev_alloc_skb (pkt_len+2);
++ if (skb == NULL)
++ {
++ printk ("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
++ ax_local->stat.rx_dropped++;
++ break;
++ }
++ skb_reserve (skb, 2); /* IP headers on 16 byte boundaries */
++ skb->dev = dev;
++ skb_put (skb, pkt_len); /* Make room */
++ ax_block_input (dev, pkt_len, skb, current_offset + sizeof (rx_frame));
++ skb->protocol = eth_type_trans (skb,dev);
++ netif_rx (skb);
++ dev->last_rx = jiffies;
++ ax_local->stat.rx_packets++;
++ ax_local->stat.rx_bytes += pkt_len;
++ if (pkt_stat & ENRSR_PHY)
++ ax_local->stat.multicast++;
++ }
++ else
++ {
++ PRINTK (ERROR_MSG, "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
++ dev->name, rx_frame.status, rx_frame.next, rx_frame.count);
++ ax_local->stat.rx_errors++;
++ /* NB: The NIC counts CRC, frame and missed errors. */
++ if (pkt_stat & ENRSR_FO)
++ ax_local->stat.rx_fifo_errors++;
++ }
++ next_frame = rx_frame.next;
++
++ /* This _should_ never happen: it's here for avoiding bad clones. */
++ if (next_frame >= ax_local->stop_page) {
++ PRINTK (ERROR_MSG, "%s: next frame inconsistency, %#2x\n", dev->name, next_frame);
++ next_frame = ax_local->rx_start_page;
++ }
++ ax_local->current_page = next_frame;
++ writeb (next_frame-1, ax_base+EN0_BOUNDARY);
++ }
++
++ return;
++}
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_rx_overrun
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_rx_overrun (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char was_txing, must_resend = 0;
++
++
++ /*
++ * Record whether a Tx was in progress and then issue the
++ * stop command.
++ */
++ was_txing = readb (ax_base+E8390_CMD) & E8390_TRANS;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ PRINTK (RX_MSG, "%s: Receiver overrun.\n", dev->name);
++
++ ax_local->stat.rx_over_errors++;
++
++ udelay (2*1000);
++
++ writeb (0x00, ax_base+EN0_RCNTLO);
++ writeb (0x00, ax_base+EN0_RCNTHI);
++
++ /*
++ * See if any Tx was interrupted or not. According to NS, this
++ * step is vital, and skipping it will cause no end of havoc.
++ */
++
++ if (was_txing)
++ {
++ unsigned char tx_completed = readb (ax_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR);
++ if (!tx_completed)
++ must_resend = 1;
++ }
++
++ /*
++ * Have to enter loopback mode and then restart the NIC before
++ * you are allowed to slurp packets up off the ring.
++ */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR);
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START, ax_base + E8390_CMD);
++
++ /*
++ * Clear the Rx ring of all the debris, and ack the interrupt.
++ */
++ ax_receive (dev);
++
++ /*
++ * Leave loopback mode, and resend any packet that got stopped.
++ */
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR);
++ if (must_resend)
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, ax_base + E8390_CMD);
++
++}
++
++
++/*
++ * Collect the stats. This is called unlocked and from several contexts.
++ */
++static struct net_device_stats *get_stats (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ /* If the card is stopped, just return the present stats. */
++ if (!netif_running (dev))
++ return &ax_local->stat;
++
++ spin_lock_irqsave (&ax_local->page_lock,flags);
++ /* Read the counter registers, assuming we are in page 0. */
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return &ax_local->stat;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: make_mc_bits
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static inline void make_mc_bits (u8 *bits, struct net_device *dev)
++{
++ struct dev_mc_list *dmi;
++ for (dmi=dev->mc_list; dmi; dmi=dmi->next)
++ {
++ u32 crc;
++ if (dmi->dmi_addrlen != ETH_ALEN)
++ {
++ PRINTK (INIT_MSG, "%s: invalid multicast address length given.\n", dev->name);
++ continue;
++ }
++ crc = ether_crc (ETH_ALEN, dmi->dmi_addr);
++ /*
++ * The 8390 uses the 6 most significant bits of the
++ * CRC to index the multicast table.
++ */
++ bits[crc>>29] |= (1<<((crc>>26)&7));
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: do_set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void do_set_multicast_list (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++ if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
++ {
++ memset (ax_local->mcfilter, 0, 8);
++ if (dev->mc_list)
++ make_mc_bits (ax_local->mcfilter, dev);
++ }
++ else
++ memset (ax_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */
++
++ if (netif_running (dev))
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ writeb (E8390_NODMA + E8390_PAGE1, ax_base + E8390_CMD);
++ for (i = 0; i < 8; i++)
++ {
++ writeb (ax_local->mcfilter[i], ax_base + EN1_MULT_SHIFT (i));
++ }
++ writeb (E8390_NODMA + E8390_PAGE0, ax_base + E8390_CMD);
++
++ if (dev->flags&IFF_PROMISC)
++ writeb (E8390_RXCONFIG | 0x18, ax_base + EN0_RXCR);
++ else if (dev->flags&IFF_ALLMULTI || dev->mc_list)
++ writeb (E8390_RXCONFIG | 0x08, ax_base + EN0_RXCR);
++
++ else
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ }
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void set_multicast_list (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device*)dev->priv;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ do_set_multicast_list (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ethdev_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ethdev_init (struct net_device *dev)
++{
++
++ if (dev->priv == NULL)
++ {
++ struct ax_device *ax_local;
++
++ dev->priv = kmalloc (sizeof (struct ax_device), GFP_KERNEL);
++ if (dev->priv == NULL)
++ return -ENOMEM;
++ memset (dev->priv, 0, sizeof (struct ax_device));
++ ax_local = (struct ax_device *)dev->priv;
++ spin_lock_init (&ax_local->page_lock);
++ }
++
++ dev->hard_start_xmit = &ax_start_xmit;
++ dev->get_stats = get_stats;
++ dev->set_multicast_list = &set_multicast_list;
++
++ ether_setup (dev);
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax88796_PHY_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void ax88796_PHY_init (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 advertise;
++
++ /* Enable AX88796B FOLW CONTROL */
++ writeb (ENFLOW_ENABLE, ax_base+EN0_FLOW);
++
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE) & ~ADVERTISE_ALL;
++
++ switch (ax_local->media) {
++ case MEDIA_AUTO:
++ PRINTK (DRIVER_MSG, PFX " The media mode is autosense.\n");
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++
++ case MEDIA_100FULL:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 100full.\n");
++ advertise |= ADVERTISE_100FULL | 0x400;
++ break;
++
++ case MEDIA_100HALF:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 100half.\n");
++ advertise |= ADVERTISE_100HALF;
++ break;
++
++ case MEDIA_10FULL:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 10full.\n");
++ advertise |= ADVERTISE_10FULL;
++ break;
++
++ case MEDIA_10HALF:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 10half.\n");
++ advertise |= ADVERTISE_10HALF;
++ break;
++ default:
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++ }
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_init (struct net_device *dev, int startp)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Follow National Semi's recommendations for initing the DP83902. */
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD); /* 0x21 */
++ writeb (ax_local->bus_width, ax_base + EN0_DCFG);/* 8-bit or 16-bit */
++
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active low \n");
++ /* Set AX88796B interrupt active low */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++
++#elif IRW_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active high \n");
++ /* Set AX88796B interrupt active high */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_INT_ACT_HIGH | ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++#endif
++
++
++
++ /* Clear the remote byte count registers. */
++ writeb (0x00, ax_base + EN0_RCNTLO);
++ writeb (0x00, ax_base + EN0_RCNTHI);
++
++ /* Set to monitor and loopback mode -- this is vital!. */
++ writeb (E8390_RXOFF, ax_base + EN0_RXCR); /* 0x20 */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR); /* 0x02 */
++
++ /* Set the transmit page and receive ring. */
++ writeb (NESM_START_PG, ax_base + EN0_TPSR);
++ writeb (NESM_RX_START_PG, ax_base + EN0_STARTPG);
++ writeb (NESM_RX_START_PG, ax_base + EN0_BOUNDARY);
++
++ ax_local->current_page = NESM_RX_START_PG + 1; /* assert boundary+1 */
++ writeb (NESM_STOP_PG, ax_base + EN0_STOPPG);
++
++ ax_local->tx_prev_ctepr = 0;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->tx_curr_page = NESM_START_PG;
++ ax_local->tx_stop_page = NESM_START_PG + TX_PAGES;
++
++ /* Clear the pending interrupts and mask. */
++ writeb (0xFF, ax_base + EN0_ISR);
++ writeb (0x00, ax_base + EN0_IMR);
++
++ /* Copy the station address into the DS8390 registers. */
++ writeb (E8390_NODMA + E8390_PAGE1 + E8390_STOP, ax_base+E8390_CMD); /* 0x61 */
++ writeb (NESM_START_PG + TX_PAGES + 1, ax_base + EN1_CURPAG);
++ for (i = 0; i < 6; i++)
++ {
++ writeb (dev->dev_addr[i], ax_base + EN1_PHYS_SHIFT (i));
++ if (readb (ax_base + EN1_PHYS_SHIFT (i))!=dev->dev_addr[i])
++ PRINTK (ERROR_MSG, "Hw. address read/write mismap %d\n",i);
++ }
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ if (startp)
++ {
++ /* Enable AX88796B TQC */
++ writeb ((readb (ax_base+EN0_MCR) | ENTQC_ENABLE), ax_base+EN0_MCR);
++
++ /* Enable AX88796B Transmit Buffer Ring */
++ writeb (E8390_NODMA+E8390_PAGE3+E8390_STOP, ax_base+E8390_CMD);
++ writeb (ENTBR_ENABLE, ax_base+EN3_TBR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ ax_local->media_curr = 0xFF;
++ ax88796_PHY_init (dev);
++ writeb (0xff, ax_base + EN0_ISR);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+E8390_CMD);
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR); /* xmit on. */
++
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR); /* rx on, */
++ do_set_multicast_list (dev); /* (re)load the mcast table */
++ }
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_trigger_send
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base+E8390_CMD);
++ writeb (length & 0xff, ax_base + EN0_TCNTLO);
++ writeb (length >> 8, ax_base + EN0_TCNTHI);
++ writeb (start_page, ax_base + EN0_TPSR);
++ writeb ((E8390_NODMA|E8390_TRANS|E8390_START), ax_base+E8390_CMD);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_add_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_add_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ writeb ((u8)vid, ax_base+EN0_VID0);
++ writeb ((vid >> 9) & 0xF, ax_base+EN0_VID1);
++
++ /* Enable AX88796B Vlan filtering */
++ writeb (readb(ax_base+EN0_MCR) | ENVLAN_ENABLE, ax_base+EN0_MCR);
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_kill_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_kill_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ /* Disable AX88796B Vlan filtering */
++ writeb (readb (ax_base+EN0_MCR) & ~ENVLAN_ENABLE, ax_base+EN0_MCR);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_watchdog
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_watchdog (unsigned long arg)
++{
++ struct net_device *dev = (struct net_device *)(arg);
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u8 status;
++ u16 bmcr, advertise;
++
++ status = readb (ax_base + EN0_SR);
++
++ if (ax_local->media_curr != status) {
++
++ ax_local->media_curr = status;
++
++ if ((status & ENSR_LINK))
++ {
++ if (status & ENSR_SPEED_100) {
++ PRINTK (DRIVER_MSG, "%s Link mode : 100 Mb/s ", dev->name);
++ } else {
++ PRINTK (DRIVER_MSG, "%s Link mode : 10 Mb/s ", dev->name);
++ }
++
++ if (status & ENSR_DUPLEX_DULL) {
++ PRINTK (DRIVER_MSG, "Full Duplex.\n");
++ } else {
++ PRINTK (DRIVER_MSG, "Half Duplex.\n");
++ }
++
++ mdelay (200);
++ netif_carrier_on (dev);
++ netif_wake_queue (dev);
++ } else {
++ netif_stop_queue (dev);
++ netif_carrier_off (dev);
++ PRINTK (DRIVER_MSG, "%s Link down.\n", dev->name);
++ }
++ }
++
++ if (!(status & ENSR_LINK)) {
++
++ bmcr = mdio_read (dev, 0x10, MII_BMCR);
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE);
++
++ /* Power down PHY */
++ mdio_write (dev, 0x10, MII_BMCR, BMCR_PDOWN);
++ mdelay (1);
++ /* Power up PHY */
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ mdelay (60);
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ }
++
++ mod_timer (&ax_local->watchdog, jiffies + AX88796_WATCHDOG_PERIOD);
++ return ;
++}
++
++
++/*
++ * ======================================================================
++ * MII interface support
++ * ======================================================================
++ */
++#define MDIO_SHIFT_CLK 0x01
++#define MDIO_DATA_WRITE0 0x00
++#define MDIO_DATA_WRITE1 0x08
++#define MDIO_DATA_READ 0x04
++#define MDIO_MASK 0x0f
++#define MDIO_ENB_IN 0x02
++
++static void mdio_sync (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int bits;
++ for (bits = 0; bits < 32; bits++) {
++ writeb (MDIO_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static void mdio_clear (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ int bits;
++ for (bits = 0; bits < 16; bits++) {
++ writeb (MDIO_DATA_WRITE0, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE0 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0xf6<<10)|(phy_id<<5)|loc;
++ int i, retval = 0;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 14; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 19; i > 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ retval = (retval << 1) | ((readb (ax_base + AX88796_MII_EEPROM) & MDIO_DATA_READ) != 0);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ return (retval>>1) & 0xffff;
++}
++
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
++ int i;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 31; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 1; i >= 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++
++#if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1)
++/*
++ * ======================================================================
++ * EEPROM interface support
++ * ======================================================================
++ */
++#define EEPROM_SHIFT_CLK (0x80)
++#define EEPROM_DATA_READ1 (0x40)
++#define EEPROM_DATA_WRITE0 (0x00)
++#define EEPROM_DATA_WRITE1 (0x20)
++#define EEPROM_SELECT (0x10)
++#define EEPROM_DIR_IN (0x02)
++
++#define EEPROM_READ (0x02)
++#define EEPROM_EWEN (0x00)
++#define EEPROM_ERASE (0x03)
++#define EEPROM_WRITE (0x01)
++#define EEPROM_ERALL (0x00)
++#define EEPROM_WRAL (0x00)
++#define EEPROM_EWDS (0x00)
++#define EEPROM_93C46_OPCODE(x) ((x) << 6)
++#define EEPROM_93C46_STARTBIT (1 << 8)
++
++static void
++eeprom_write_en (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE(EEPROM_EWEN) | 0x30;
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static void
++eeprom_write_dis (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_EWDS);
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static int
++eeprom_write (struct net_device *dev, unsigned char loc, unsigned short nValue)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_WRITE) | loc;
++ unsigned char tmp;
++ int i;
++ int ret = 0;
++
++ // issue a "SB OP Addr" command
++ for(i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // writing the data
++ for (i = 15; i >= 0; i--) {
++ tmp = (nValue & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ //
++ // check busy
++ //
++
++ // Turn, wait two clocks
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++
++ // waiting for busy signal
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if ((tmp & EEPROM_DATA_READ1) == 0)
++ break;
++ }
++ if (i <= 0) {
++ printk ("Failed on waiting for bus busy\n\r");
++ ret = -1;
++ } else {
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ break;
++ }
++
++ if (i <= 0) {
++ printk ("Failed on waiting for write completion\n\r");
++ ret = -1;
++ }
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return ret;
++}
++
++static unsigned short
++eeprom_read (struct net_device *dev, unsigned char loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_READ) | loc;
++ unsigned char tmp;
++ unsigned short retValue = 0;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // Turn
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT | EEPROM_SHIFT_CLK | EEPROM_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++
++ // retriving the data
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ retValue |= (1 << i);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return retValue;
++}
++#endif /* #if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1) */
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b.c linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b.c
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,2416 @@
++/*
++ ==================================================================================
++ ax88796b.c: A SAMSUNG S3C2440 Linux2.6.x Ethernet device driver for ASIX AX88796B chips.
++
++ This program is free software; you can distrine_block_inputbute 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.,
++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++
++ This program is based on
++
++ ne.c: A general non-shared-memory NS8390 ethernet driver for linux
++ Written 1992-94 by Donald Becker.
++
++ 8390.c: A general NS8390 ethernet driver core for linux.
++ Written 1992-94 by Donald Becker.
++
++ Version history:
++
++ Version 1.0.0 06/02/2006
++
++ * Initial release
++
++ Version 1.0.0 27/03/2006
++
++ * Fixups Transmit Queue functions.
++
++ Version 1.1.0 20/09/2006
++
++ * Ported to support kernel 2.6.x.
++
++ Version 1.2.0 09/09/2008
++
++ * 1. Added 8-bit support.
++ * 2. Added EEPROM support.
++ * 3. Added PHY power process function.
++
++ ==================================================================================
++ Driver Overview
++ ==================================================================================
++ ASIX AX88796B 3-in-1 Local Bus 8/16-bit Fast Ethernet Linux Driver
++
++ The AX88796B Ethernet controller is a high performance and highly integrated
++ local CPU bus Ethernet controllers with embedded 10/100Mbps PHY/Transceiver
++ 16K bytes SRAM and supports both 8-bit and 16-bit local CPU interfaces for any
++ embedded systems.
++
++ If you look for more details, please visit ASIX's web site (http://www.asix.com.tw).
++
++
++ ==================================================================================
++ COMPILING DRIVER
++ ==================================================================================
++ Prepare:
++
++ AX88796B Linux Driver.
++ Linux Kernel source code.
++ Cross-Compiler.
++
++ Getting Start:
++
++ 1.Extracting the AX88796B source file by executing the following command.
++ [root@localhost]# tar jxvf ax88796b-arm-linux2.4.tar.bz2
++
++ 2.Edit the makefile to specifie the path of target platform Linux Kernel source.
++ EX:
++ KDIR := /work/linux-2.6.17.11
++
++ 3.Executing 'make' command to compiler AX88796B Driver.
++
++ 4.If the compilation well, the ax88796.ko will be created under the current directory.
++
++
++ ==================================================================================
++ DRIVER PARAMETERS
++ ==================================================================================
++ The following parameters can be set when using insmod.
++ EX: [root@localhost ax88796b]# insmod ax88796.ko mem=0x08000000
++
++ mem=0xNNNNNNNN
++ specifies the physical base address that AX88796B can be accessed.
++ Default value '0x08000000'.
++
++ irq=N
++ specifies the irq number. Default value '0x27'.
++
++ media=(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)
++ Media mode control. Default value 'auto'.
++*/
++
++
++
++
++#include "ax88796b.h"
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/pxa2xx-regs.h>
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
++#include <linux/irq.h>
++#endif
++
++#include <linux/if_link.h>
++#include <linux/netlink.h>
++#include <net/netlink.h>
++#include <net/rtnetlink.h>
++
++/* Local Function Prototypes */
++static int ax_probe (struct net_device *dev);
++static int ax_open (struct net_device *dev);
++static int ax_close (struct net_device *dev);
++static void ax_reset (struct net_device *dev);
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr,
++ int ring_page);
++static void ax_block_input (struct net_device *dev, int count,
++ struct sk_buff *skb, int ring_offset);
++static void ax_block_output (struct net_device *dev, const int count,
++ const unsigned char *buf, const int start_page);
++static int ethdev_init (struct net_device *dev);
++static void ax_init (struct net_device *dev, int startp);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++int set_external_irq (int irq, int edge, int pullup);
++# endif
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#endif
++static void ax_tx_intr (struct net_device *dev);
++static void ax_tx_err (struct net_device *dev);
++static void ax_receive (struct net_device *dev);
++static void ax_rx_overrun (struct net_device *dev);
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page);
++static void set_multicast_list (struct net_device *dev);
++static void do_set_multicast_list (struct net_device *dev);
++static void ax_watchdog (unsigned long arg);
++
++static void ax_vlan_rx_add_vid (struct net_device *netdev, u16 vid);
++static void ax_vlan_rx_kill_vid (struct net_device *netdev, u16 vid);
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc);
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value);
++static inline u16 READ_FIFO (void *membase);
++static inline void WRITE_FIFO (void *membase, u16 data);
++static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev);
++static struct net_device_stats *get_stats (struct net_device *dev);
++
++/* NAMING CONSTANT DECLARATIONS */
++#define DRV_NAME "AX88796B"
++#define ADP_NAME "ASIX AX88796B Ethernet Adapter"
++#define DRV_VERSION "1.2.0"
++#define PFX DRV_NAME ": "
++
++#define PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printk(args)
++#define ECON_DEBUG 0
++#if ECON_DEBUG
++#define eprintk(msg,args...) printk(msg,## args)
++#else
++#define eprintk(msg,args...) do{}while(0)
++#endif
++
++
++#define CRITICAL_DEBUG 0
++#if CRITICAL_DEBUG
++#define cprintk(msg,args...) printk(msg,## args)
++#else
++#define cprintk(msg,args...) do{}while(0)
++#endif
++
++//#define USE_ASSERT
++//#define USE_TRACE
++//#define USE_WARNING
++
++#ifdef USE_ASSERT
++# define ASIX_ASSERT(condition) \
++ if(!(condition)) { \
++ printk("ASIX_ASSERTION_FAILURE: File=" __FILE__ ", Line=%d\n",__LINE__); \
++ while(1); \
++ }
++#else
++# define ASIX_ASSERT(condition)
++#endif
++
++
++#ifdef USE_TRACE
++#ifndef USE_WARNING
++#define USE_WARNING
++#endif
++# define ASIX_TRACE(msg,args...) \
++ if(0x01UL) { \
++ printk("ASIX: " msg "\n", ## args); \
++ }
++#else
++# define ASIX_TRACE(msg,args...)
++#endif
++
++
++#ifdef USE_WARNING
++#ifndef USE_ASSERT
++#define USE_ASSERT
++#endif
++# define ASIX_WARNING(msg, args...) \
++ if(0x02UL) { \
++ printk("ASIX_WARNING: " msg "\n",## args); \
++ }
++#else
++# define ASIX_WARNING(msg, args...)
++#endif
++
++
++
++
++#define RTNL_LINK_REQUIRED 0
++#define CONFIG_AX88796B_USE_MEMCPY 1
++#define CONFIG_AX88796B_8BIT_WIDE 0
++#define CONFIG_AX88796B_EEPROM_READ_WRITE 0
++
++#ifndef ENBTCR_IRQ_TYPE_PUSH_PULL
++#define ENBTCR_IRQ_TYPE_PUSH_PULL 0x20 /* IRQ Output is Push Pull Driver */
++#endif
++
++
++#ifdef AX88796B_BASE
++#undef AX88796B_BASE
++#define AX88796B_BASE PXA_CS4_PHYS
++#endif
++
++#define MAC_ADDRESS_OFFSET_IN_NOR_FLASH 0x00008000
++#define MAC_ADDRESS_IN_NOR_FLASH (MAC_ADDRESS_OFFSET_IN_NOR_FLASH)
++#define MAC_ADDDRESS_LENGTH 6
++#define SIZE_1K 0x00000400 /* 1K */
++
++#if CONFIG_AX88796B_USE_MEMCPY
++#define FIFO_SEL_IS_A11 0
++#define FIFO_SEL_IS_A20 1
++#endif
++
++#if FIFO_SEL_IS_A11
++#warning "FIFO_SEL_IS_A11 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0xFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x0800
++ #endif
++
++#elif FIFO_SEL_IS_A20
++#warning "FIFO_SEL_IS_A20 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0x00FFFFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x00100000
++ #endif
++
++#endif
++
++
++#if CONFIG_MACH_DENEB
++#warning "MACH_DENEB is defined"
++#define GPIO_FOR_ASIX_IRQ 74
++#elif (CONFIG_MACH_REGULUS|| CONFIG_MACH_SIRIUS)
++#warning "either MACH_REGULUS or MACH_SIRIUS is defined"
++#define GPIO_FOR_ASIX_IRQ 37
++#endif
++
++#define IRQ_EINT11 IRQ_GPIO(GPIO_FOR_ASIX_IRQ)
++#define GPIO_FOX_ASIX_IRQ_MD ( GPIO_FOR_ASIX_IRQ | GPIO_IN)
++#define IRQ_FALLING_EDGE 1
++#define GPIO80_GPIO_OUT (80 | GPIO_OUT | GPIO_DFLT_HIGH)
++
++#define GPIO_FOR_ASIX_DEBUG 73
++unsigned char *test_tx_buffer=NULL,*test_rx_buffer=NULL;
++
++#include "pxa270_dma_mode_for_asix.c"
++
++/* LOCAL VARIABLES DECLARATIONS */
++#if 0
++static char version[] =
++KERN_INFO ADP_NAME ":v" DRV_VERSION " " __TIME__ " " __DATE__ "\n"
++KERN_INFO " http://www.asix.com.tw\n";
++#endif
++static unsigned int media = 0;
++
++static struct net_device *pdev_ax;
++static int mem;
++static int irq;
++
++volatile unsigned short int *nor_flash_addr=NULL;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++MODULE_PARM (mem, "i");
++MODULE_PARM (irq, "i");
++MODULE_PARM (media, "i");
++#else
++module_param (mem, int, 0);
++module_param (irq, int, 0);
++module_param (media, int, 0);
++#endif
++
++MODULE_PARM_DESC (mem, "MEMORY base address(es),required");
++MODULE_PARM_DESC (irq, "IRQ number(s)");
++MODULE_PARM_DESC (media, "Media Mode(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)");
++
++MODULE_DESCRIPTION ("ASIX AX88796B Fast Ethernet driver");
++MODULE_LICENSE ("GPL");
++
++
++void get_mac_from_nor_flash(unsigned char *addr)
++{
++ unsigned char *mac_addr= (unsigned char *)addr;
++ memcpy((void *)mac_addr,(void *)nor_flash_addr,MAC_ADDDRESS_LENGTH);
++
++}
++
++
++
++void deneb_asix_gpio_initialize(void)
++{
++
++#define IMCR_GPIO_x (1<<10)
++#define ICLR_GPIO_x (1<<10)
++
++ pxa_gpio_mode(GPIO_FOX_ASIX_IRQ_MD);
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ GFER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ GRER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#endif
++ ICMR |= IMCR_GPIO_x;
++ ICLR &= ~(ICLR_GPIO_x);
++}
++
++
++
++#if RTNL_LINK_REQUIRED
++static int ax88796b_validate(struct nlattr *tb[], struct nlattr *data[])
++{
++ if (tb[IFLA_ADDRESS]) {
++ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
++ return -EINVAL;
++ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
++ return -EADDRNOTAVAIL;
++ }
++ return 0;
++}
++#endif
++
++static int dummy_set_address(struct net_device *dev, void *p)
++{
++ struct sockaddr *sa = p;
++
++ if (!is_valid_ether_addr(sa->sa_data))
++ return -EADDRNOTAVAIL;
++
++ memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
++ return 0;
++}
++
++
++
++static void ax88796b_setup(struct net_device *dev)
++{
++ /* Initialize the device structure. */
++ dev->hard_start_xmit = &ax_start_xmit;
++ dev->set_mac_address = dummy_set_address;
++ dev->destructor = free_netdev;
++ dev->get_stats = get_stats;
++ dev->set_multicast_list = &set_multicast_list;
++
++ /* Fill in device structure with ethernet-generic values. */
++ ether_setup(dev);
++ dev->tx_queue_len = 0;
++ dev->change_mtu = NULL;
++ dev->flags |= IFF_NOARP;
++ dev->flags &= ~IFF_MULTICAST;
++ random_ether_addr(dev->dev_addr);
++}
++
++#if RTNL_LINK_REQUIRED
++static struct rtnl_link_ops ax88796b_link_ops __read_mostly = {
++ .kind = "ax88796b",
++ .setup = ax88796b_setup,
++ .validate = ax88796b_validate,
++};
++#endif
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: init_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++int deneb_ax88796b_init_module (void)
++{
++
++ int err = 0;
++ struct net_device *dev = NULL;
++ volatile unsigned int msc2_data=0;
++ //volatile unsigned int ncs4_config_data = 0x7FF9; // Slower Device, Maximum ROM/SRAM Recovery Time, Maximum ROM Delay Next Access, Maximum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++#define CS4_RBUFF(x) ((x) <<15)
++#define CS4_RRR(x) ((x) <<12)
++#define CS4_RDN(x) ((x) <<8)
++#define CS4_RDF(x) ((x) <<4)
++#define CS4_RBW(x) ((x) <<3)
++#define CS4_RT(x) ((x) <<0)
++
++ volatile unsigned int ncs4_config_data = (CS4_RBUFF(0) | CS4_RRR(0) |CS4_RDN(3) | CS4_RDF(5) | CS4_RBW(1) |CS4_RT(1)); // Slower Device, Minimum ROM/SRAM Recovery Time, Minimum ROM Delay Next Access, Minimum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++#if RTNL_LINK_REQUIRED
++ err = __rtnl_link_register(&ax88796b_link_ops);
++#endif
++ dev = alloc_netdev(0, "eth%d", ax88796b_setup);
++ if (!dev)
++ return -ENOMEM;
++
++ pdev_ax = dev;
++
++ err = dev_alloc_name(dev, dev->name);
++ if (err < 0)
++ goto err;
++
++ //printk("FUNC %s() : LINE %d : Driver for AX88796B Non-PCI Fast Ethernet Chip \n",__FUNCTION__,__LINE__);
++
++ //printk("Configuring GPIO80 as GPIO and Drive Logic 1 on GPIO80 \n");
++ pxa_gpio_mode(GPIO80_GPIO_OUT);
++
++ //printk("Configuring GPIO80 as nCS4 \n");
++ pxa_gpio_mode(GPIO80_nCS_4_MD);
++
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Configuring the Memory Controller Register for nCS4 \n");
++ msc2_data = MSC2;
++ MSC2 = (ncs4_config_data & 0x0000FFFF) | (msc2_data & 0xFFFF0000);
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Physical address of nCS4 is 0x%08X \n",PXA_CS4_PHYS);
++
++ dev->irq = irq;
++ dev->base_addr = mem;
++ dev->init = ax_probe;
++ sprintf (dev->name, "eth%d",0);
++#if RTNL_LINK_REQUIRED
++ dev->rtnl_link_ops = &ax88796b_link_ops;
++#endif
++ if (register_netdev (dev) == 0)
++ {
++ return 0;
++ }
++ else
++ {
++ return -ENXIO;
++ }
++
++
++ if (mem != 0) {
++ PRINTK (WARNING_MSG, PFX " No AX88796B card found at memory = %#x\n", mem);
++ }
++ else {
++ PRINTK (WARNING_MSG, PFX " You must supply \"mem=0xNNNNNNN\" value(s) for AX88796B.\n");
++ }
++err:
++ free_netdev(dev);
++ return err;
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: cleanup_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void deneb_ax88796b_cleanup_module (void)
++{
++ struct net_device *dev = pdev_ax;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++
++#if (DMA_MODE_OPERATION==1)
++ rx_dma_uninitialize();
++ tx_dma_uninitialize();
++#endif
++ unregister_netdev (dev);
++#if RTNL_LINK_REQUIRED
++ rtnl_link_unregister(&ax88796b_link_ops);
++#endif
++ cprintk("FUNC %s() : LINE %d : Freeing irq for AX88796B Chip \n",__FUNCTION__,__LINE__);
++ free_irq (dev->irq, dev);
++ kfree (dev->priv);
++ dev->priv = NULL;
++ kfree (dev);
++ dev = NULL;
++ release_mem_region(AX88796B_BASE,NE_IO_EXTENT);
++ iounmap (ax_base);
++}
++
++
++
++module_init(deneb_ax88796b_init_module);
++module_exit(deneb_ax88796b_cleanup_module);
++
++
++
++
++
++
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++static inline u16 READ_FIFO (void *membase)
++{
++ return (readb (membase) | (((u16)readb (membase)) << 8));
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writeb ((u8)data , membase);
++ writeb ((u8)(data >> 8) , membase);
++}
++#else
++static inline u16 READ_FIFO (void *membase)
++{
++ return readw (membase);
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writew (data, membase);
++}
++#endif
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: config_2440_bank1
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void config_2440_bank1 (void)
++{
++ /* Configure SAMSUNG S3C2440A controller for AX88796B operation */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ BWSCON = BWSCON & 0xFFFFFFCF;
++# else
++ BWSCON = (BWSCON & 0xFFFFFFCF) | 0x00000010;
++# endif
++
++ BANKCON1 = DEFAULT_125MHZ_BANKCON1;
++
++ set_external_irq (IRQ_EINT11, EXT_LOWLEVEL, GPIO_PULLUP_DIS);
++ EINTMASK &= ~EINT11_MASK;
++ EXTINT1 &= ~0xf000;
++ EXTINT1 |= FLTEN11_LOWLEVEL;
++# endif /* CONFIG_BOARD_S3C2440_SMDK */
++#else
++# ifdef CONFIG_ARCH_S3C2410
++ {
++ unsigned long tmp;
++ tmp = __raw_readl (S3C2410_BWSCON);
++
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_8, S3C2410_BWSCON);
++# else
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_16, S3C2410_BWSCON);
++# endif
++
++ __raw_writel (S3C2410_BANKCON_Tcah1 | S3C2410_BANKCON_Tacc8, S3C2410_BANKCON1);
++ }
++# endif /* CONFIG_ARCH_S3C2410 */
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: load_macaddr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++load_macaddr (struct net_device *dev, unsigned char *pMac)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Read the 12 bytes of station address PROM. */
++ {
++ struct {unsigned char value, offset; } program_seq[] =
++ {
++ {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
++ {ax_local->bus_width, EN0_DCFG}, /* Set wide access. */
++ {0x00, EN0_RCNTLO}, /* Clear the count regs. */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_IMR}, /* Mask completion irq. */
++ {0xFF, EN0_ISR},
++ {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
++ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
++ {0x0C, EN0_RCNTLO}, /* 12 bytes of station address */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
++ {0x00, EN0_RSARHI},
++ {E8390_RREAD+E8390_START, E8390_CMD},
++ };
++
++ for (i = 0; i < sizeof (program_seq)/sizeof (program_seq[0]); i++)
++ writeb (program_seq[i].value, ax_base + program_seq[i].offset);
++ }
++
++ while (( readb (ax_base + EN0_SR) & 0x20) == 0);
++
++ for (i = 0; i < 6; i++) {
++ pMac[i] = (unsigned char) READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_probe
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_probe (struct net_device *dev)
++{
++ int i;
++ int reg0, ret;
++ unsigned long base_addr;
++ void *address;
++ struct ax_device *ax_local;
++
++ PRINTK (INIT_MSG, PFX " probe start ..........\n");
++
++ //SET_MODULE_OWNER (dev);
++
++ if (dev->base_addr == 0 )
++ dev->base_addr = AX88796B_BASE;
++
++ base_addr = dev->base_addr;
++
++ if (check_mem_region (base_addr , NE_IO_EXTENT))
++ {
++ printk("FUNC %s() : LINE %d : check_mem_region is failed for base_addr = 0x%08X and NE_IO_EXTENT = 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)base_addr,(unsigned int)NE_IO_EXTENT);
++ return -ENODEV;
++ }
++ if (! request_mem_region (base_addr, NE_IO_EXTENT, DRV_NAME))
++ {
++ printk("FUNC %s() : LINE %d : check_mem_region is failed for base_addr = 0x%08X and NE_IO_EXTENT = 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)base_addr,(unsigned int)NE_IO_EXTENT);
++ return -EBUSY;
++ }
++ address=ioremap_nocache (base_addr, NE_IO_EXTENT);
++ if (!address) {
++ PRINTK (ERROR_MSG, PFX " Unable to remap memory\n");
++ release_mem_region(AX88796B_BASE,NE_IO_EXTENT);
++ return -EBUSY;
++ }
++
++ nor_flash_addr=(unsigned short int *)ioremap_nocache(MAC_ADDRESS_IN_NOR_FLASH,SIZE_1K);
++
++ //printk("ioremaped address is 0x%08X \n",(unsigned int)address);
++ //printk("ioremaped not_flash_addr is 0x%08X \n",(unsigned int)nor_flash_addr);
++ CS4_VIRT_BASE = (unsigned long)address;
++
++ config_2440_bank1 ();
++
++ //PRINTK (DRIVER_MSG, "%s: Calling deneb_asix_gpio_initialize() \n",DRV_NAME);
++ deneb_asix_gpio_initialize();
++
++ reg0 = readb (address);
++ if (reg0 == 0xFF) {
++ PRINTK (DRIVER_MSG, "%s: No device is found at address 0x%08X \n",DRV_NAME,(unsigned int)address);
++ ret = -ENODEV;
++ goto err_out;
++ }
++
++ /* Do a preliminary verification that we have a 8390. */
++ {
++ int regd;
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, address + E8390_CMD);
++ regd = readb (address + EN0_COUNTER0);
++ writeb (0xff, address + EN0_COUNTER0);
++ writeb (E8390_NODMA+E8390_PAGE0, address + E8390_CMD);
++ readb (address + EN0_COUNTER0); /* Clear the counter by reading. */
++ if (readb (address + EN0_COUNTER0) != 0) {
++ writeb (reg0, address);
++ writeb (regd, address + EN0_COUNTER0); /* Restore the old values. */
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++
++ //printk (version);
++
++ /* Reset card. Who knows what dain-bramaged state it was left in. */
++ //printk("FUNC %s(): LINE %d: Reset card. Who knows what dain-bramaged state it was left in. \n",__FUNCTION__,__LINE__);
++ {
++ unsigned long reset_start_time = jiffies;
++
++ readb (address + EN0_RESET);
++ while ((readb (address + EN0_ISR) & ENISR_RESET) == 0) {
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, " not found (no reset ack).\n");
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++ writeb (0xff, (address + EN0_ISR)); /* Ack all intr. */
++ }
++
++ if (dev->irq == 0)
++ dev->irq =IRQ_EINT11;
++
++ /* Allocate dev->priv and fill in 8390 specific dev fields. */
++ if (ethdev_init (dev))
++ {
++ PRINTK (ERROR_MSG, "unable to get memory for dev->priv.\n");
++ ret = -ENOMEM;
++ goto err_out;
++ }
++
++ ax_local = (struct ax_device *)dev->priv;
++ ax_local->name = DRV_NAME;
++ ax_local->membase = address;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->rx_start_page = NESM_RX_START_PG;
++ ax_local->stop_page = NESM_STOP_PG;
++ ax_local->media = media;
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ ax_local->bus_width = 0;
++#else
++ ax_local->bus_width = 1;
++#endif
++
++ load_macaddr (dev, dev->dev_addr);
++
++
++
++ /* Support for No EEPROM */
++ if(dev->dev_addr[0] != 0x00)
++ {
++ get_mac_from_nor_flash(dev->dev_addr);
++
++ //printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ //printk (" %2.2x", dev->dev_addr[i]);
++ }
++ printk("\n");
++
++ if( (dev->dev_addr[0] != 0x00))
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++
++ else if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0xFF) && (dev->dev_addr[1] == 0xFF) &&
++ (dev->dev_addr[2] == 0xFF) && (dev->dev_addr[3] == 0xFF) &&
++ (dev->dev_addr[4] == 0xFF) && (dev->dev_addr[5] == 0xFF) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++
++ }
++
++ else if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++
++ get_mac_from_nor_flash(dev->dev_addr);
++
++ //printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ //printk (" %2.2x", dev->dev_addr[i]);
++ }
++ printk("\n");
++ if( (dev->dev_addr[0] != 0x00))
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0xFF) && (dev->dev_addr[1] == 0xFF) &&
++ (dev->dev_addr[2] == 0xFF) && (dev->dev_addr[3] == 0xFF) &&
++ (dev->dev_addr[4] == 0xFF) && (dev->dev_addr[5] == 0xFF) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++
++ }
++ else if ( (dev->dev_addr[0] == 0xFF) && (dev->dev_addr[1] == 0xFF) &&
++ (dev->dev_addr[2] == 0xFF) && (dev->dev_addr[3] == 0xFF) &&
++ (dev->dev_addr[4] == 0xFF) && (dev->dev_addr[5] == 0xFF) )
++ {
++
++ get_mac_from_nor_flash(dev->dev_addr);
++
++ //printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ //printk (" %2.2x", dev->dev_addr[i]);
++ }
++ printk("\n");
++
++ if( (dev->dev_addr[0] != 0x00))
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++ else if ( (dev->dev_addr[0] == 0xFF) && (dev->dev_addr[1] == 0xFF) &&
++ (dev->dev_addr[2] == 0xFF) && (dev->dev_addr[3] == 0xFF) &&
++ (dev->dev_addr[4] == 0xFF) && (dev->dev_addr[5] == 0xFF) )
++ {
++ //printk("MAC Address read from NOR flash is INVALID \n");
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++
++ }
++
++
++ //PRINTK (DRIVER_MSG, "%s: MAC ADDRESS ",DRV_NAME);
++ for (i = 0; i < ETHER_ADDR_LEN; i++) {
++ //PRINTK (DRIVER_MSG, " %2.2x", dev->dev_addr[i]);
++ }
++
++ sprintf (dev->name, "eth%d",0);
++ //PRINTK (DRIVER_MSG, "\n%s: %s found at 0x%x, using IRQ %d.\n",dev->name, DRV_NAME, AX88796B_BASE, dev->irq);
++
++ dev->open = &ax_open;
++ dev->stop = &ax_close;
++ dev->features |= NETIF_F_HW_VLAN_FILTER;
++ dev->vlan_rx_add_vid = ax_vlan_rx_add_vid;
++ dev->vlan_rx_kill_vid = ax_vlan_rx_kill_vid;
++
++ ax_init (dev, 0);
++ PRINTK (INIT_MSG, PFX " probe end ..........\n");
++ return 0;
++
++err_out:
++ iounmap (address);
++ iounmap (nor_flash_addr);
++ release_mem_region(AX88796B_BASE,NE_IO_EXTENT);
++ kfree (dev->priv);
++ dev->priv = NULL;
++ return ret;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_reset
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_reset (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long reset_start_time = jiffies;
++
++ readb (ax_base + EN0_RESET);
++
++ ax_local->dmaing = 0;
++
++ /* This check _should_not_ be necessary, omit eventually. */
++ while ((readb (ax_base+EN0_ISR) & ENISR_RESET) == 0)
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, "%s: ax_reset() did not complete.\n", dev->name);
++ break;
++ }
++
++ writeb (ENISR_RESET, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_get_hdr
++ * Purpose: Grab the 796b specific header
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr, int ring_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)hdr;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_get_8390_hdr "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (sizeof (struct ax_pkt_hdr), ax_base + EN0_RCNTLO);
++ writeb (0, ax_base + EN0_RCNTHI);
++ writeb (0, ax_base + EN0_RSARLO); /* On page boundary */
++ writeb (ring_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++ *(++buf) = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++
++ le16_to_cpus (&hdr->count);
++
++}
++
++
++#if (DMA_MODE_OPERATION==0)
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_input
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)skb->data;
++ u16 i;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_input "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (ring_offset & 0xff, ax_base + EN0_RSARLO);
++ writeb (ring_offset >> 8, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ {
++
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & (0xFFFF8);
++ #endif
++
++ /* Read first 2 bytes */
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ /* The address of ++buf should be agigned on 32-bit boundary */
++ memcpy (++buf, ax_base+EN0_DATA_ADDR, i);
++ }
++#else
++ {
++ for (i = 0; i < count; i += 2) {
++ *buf++ = READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++ }
++#endif
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_output
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long dma_start;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_output."
++ "[DMAstat:%d][irqlock:%d]\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ /* We should already be in page 0, but to be safe... */
++ writeb (E8390_PAGE0+E8390_START+E8390_NODMA, ax_base + E8390_CMD);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ /* Now the normal output. */
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (0x00, ax_base + EN0_RSARLO);
++ writeb (start_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RWRITE+E8390_START, ax_base + E8390_CMD);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0x7F8));
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0xFFFF8));
++ #endif
++#else
++ {
++ u16 i;
++ for (i = 0; i < count; i += 2) {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + i)));
++ }
++ }
++#endif
++ dma_start = jiffies;
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0) {
++ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
++ PRINTK (ERROR_MSG, "%s: timeout waiting for Tx RDC.\n", dev->name);
++ ax_reset (dev);
++ ax_init (dev,1);
++ break;
++ }
++ }
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++ return;
++}
++
++#endif // end of DMA_MODE_OPERATION
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_open
++ * Purpose: Open/initialize 796b
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_open (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *membase = ax_local->membase;
++ int ret=0;
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open beginning ..........\n");
++ PRINTK (DEBUG_MSG, PFX " membase %p\n\r", membase);
++
++ ret = request_irq ((unsigned int)dev->irq, (irq_handler_t) &ax_interrupt, (unsigned long)0, (const char *)dev->name, (void *)dev);
++
++ if (ret) {
++ PRINTK (ERROR_MSG, "%s: unable to get IRQ %d (errno=%d).\n",dev->name, dev->irq, ret);
++ return -ENXIO;
++ }
++
++ PRINTK (DEBUG_MSG, PFX " Request IRQ success !!\n\r");
++
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ set_irq_type(dev->irq, IRQT_FALLING);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ set_irq_type(dev->irq, IRQT_RISING);
++#endif
++
++
++ /* This can't happen unless somebody forgot to call ethdev_init(). */
++ if (ax_local == NULL)
++ {
++ PRINTK (ERROR_MSG, "%s: ei_open passed a non-existent device!\n", dev->name);
++ return -ENXIO;
++ }
++
++ dev->tx_timeout = NULL;
++ dev->watchdog_timeo = 0;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_reset (dev);
++ ax_init (dev, 1);
++ netif_start_queue (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ ax_local->irqlock = 0;
++
++ init_timer (&ax_local->watchdog);
++ ax_local->watchdog.function = &ax_watchdog;
++ ax_local->watchdog.expires = jiffies + AX88796_WATCHDOG_PERIOD;
++ ax_local->watchdog.data = (unsigned long) dev;
++ add_timer (&ax_local->watchdog);
++
++#if (DMA_MODE_OPERATION==1)
++ rx_dma_initialize();
++ tx_dma_initialize();
++#endif
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open end ..........\n");
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_close
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_close (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ unsigned long flags;
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close beginning ..........\n");
++ del_timer (&ax_local->watchdog);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_init (dev, 0);
++
++ cprintk("FUNC %s() : LINE %d : Freeing irq for AX88796B Chip \n",__FUNCTION__,__LINE__);
++ free_irq (dev->irq, dev);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ netif_stop_queue (dev);
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close end ..........\n");
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_start_xmit
++ * Purpose: begin packet transmission
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int send_length;
++ unsigned long flags;
++ u8 ctepr=0, free_pages=0, need_pages;
++
++
++ /* check for link status */
++ if (!(readb (ax_base + EN0_SR) & ENSR_LINK))
++ {
++ //printk("FUNC %s() : LINE %d : LINK is DOWN \n",__FUNCTION__,__LINE__);
++ dev_kfree_skb (skb);
++ return 0;
++ }
++ else
++ {
++ //printk("FUNC %s() : LINE %d : LINK is UP \n",__FUNCTION__,__LINE__);
++ }
++
++ send_length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
++
++
++
++
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ spin_lock (&ax_local->page_lock);
++ ax_local->irqlock = 1;
++
++ need_pages = (send_length -1)/256 +1;
++ ctepr = readb (ax_base + EN0_CTEPR) & 0x7f;
++
++ if (ctepr == 0) {
++ if (ax_local->tx_curr_page == ax_local->tx_start_page && ax_local->tx_prev_ctepr == 0)
++ free_pages = TX_PAGES;
++ else
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page;
++ }
++ else if (ctepr < ax_local->tx_curr_page - 1) {
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page +
++ ctepr - ax_local->tx_start_page + 1;
++ }
++ else if (ctepr > ax_local->tx_curr_page - 1) {
++ free_pages = ctepr + 1 - ax_local->tx_curr_page;
++ }
++ else if (ctepr == ax_local->tx_curr_page - 1) {
++ if (ax_local->tx_full)
++ free_pages = 0;
++ else
++ free_pages = TX_PAGES;
++ }
++
++ if (free_pages < need_pages) {
++ PRINTK (DEBUG_MSG, "free_pages < need_pages\n\r");
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return 1;
++ }
++
++ ax_block_output (dev, send_length, skb->data, ax_local->tx_curr_page);
++ ax_trigger_send (dev, send_length, ax_local->tx_curr_page);
++ if (free_pages == need_pages) {
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ }
++ ax_local->tx_prev_ctepr = ctepr;
++ ax_local->tx_curr_page = ax_local->tx_curr_page + need_pages < ax_local->tx_stop_page ?
++ ax_local->tx_curr_page + need_pages :
++ need_pages - (ax_local->tx_stop_page - ax_local->tx_curr_page) + ax_local->tx_start_page;
++
++ dev_kfree_skb (skb);
++ dev->trans_start = jiffies;
++ ax_local->stat.tx_bytes += send_length;
++
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_intr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_intr (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int status = readb (ax_base + EN0_TSR);
++
++ ax_local->tx_full = 0;
++ if (netif_queue_stopped (dev))
++ netif_wake_queue (dev);
++
++ /* Minimize Tx latency: update the statistics after we restart TXing. */
++ if (status & ENTSR_COL)
++ ax_local->stat.collisions++;
++ if (status & ENTSR_PTX)
++ ax_local->stat.tx_packets++;
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (status & ENTSR_ABT)
++ {
++ ax_local->stat.tx_aborted_errors++;
++ ax_local->stat.collisions += 16;
++ }
++ if (status & ENTSR_CRS)
++ ax_local->stat.tx_carrier_errors++;
++ if (status & ENTSR_FU)
++ ax_local->stat.tx_fifo_errors++;
++ if (status & ENTSR_CDH)
++ ax_local->stat.tx_heartbeat_errors++;
++ if (status & ENTSR_OWC)
++ ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_interrupt
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#endif
++{
++ struct net_device *dev = dev_id;
++ int interrupts;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ cprintk("LINE %d : FUNCTION %s() : Entering into ISR \n",__LINE__,__FUNCTION__);
++ if (dev == NULL)
++ {
++ PRINTK (ERROR_MSG, "net_interrupt(): irq %d for unknown device.\n", irq);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ if (ax_local->irqlock) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ spin_lock (&ax_local->page_lock);
++
++ while (1)
++ {
++
++ if ((interrupts = readb (ax_base + EN0_ISR)) == 0)
++ {
++ cprintk("LINE %d : FUNCTION %s() : interrupt Status is ZERO \n",__LINE__,__FUNCTION__);
++ break;
++ }
++
++ writeb (interrupts, ax_base + EN0_ISR); /* Ack the interrupts */
++
++ if (interrupts & ENISR_TX)
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for TX \n",__LINE__,__FUNCTION__);
++ ax_tx_intr (dev);
++ }
++
++ if (interrupts & ENISR_OVER)
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for RECEIVE OVERRUN \n",__LINE__,__FUNCTION__);
++ ax_rx_overrun (dev);
++ }
++
++ if (interrupts & (ENISR_RX+ENISR_RX_ERR))
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for RECEIVE with/without ERROR \n",__LINE__,__FUNCTION__);
++ ax_receive (dev);
++ }
++
++ if (interrupts & ENISR_TX_ERR)
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for TX with ERROR \n",__LINE__,__FUNCTION__);
++ ax_tx_err (dev);
++ }
++
++ if (interrupts & ENISR_COUNTERS)
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for ERROR COUNTER OVERFLOW \n",__LINE__,__FUNCTION__);
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++ writeb (ENISR_COUNTERS, ax_base + EN0_ISR); /* Ack intr. */
++ }
++
++ if (interrupts & ENISR_RDC)
++ {
++ cprintk("LINE %d : FUNCTION %s() : Interrupt occured for RemoteDmaComplete \n",__LINE__,__FUNCTION__);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ }
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++ }
++
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++ cprintk("LINE %d : FUNCTION %s() : Exiting from ISR \n",__LINE__,__FUNCTION__);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return IRQ_HANDLED;
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_err
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_err (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned char txsr = readb (ax_base+EN0_TSR);
++ unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
++
++ if (tx_was_aborted)
++ ax_tx_intr (dev);
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (txsr & ENTSR_CRS) ax_local->stat.tx_carrier_errors++;
++ if (txsr & ENTSR_CDH) ax_local->stat.tx_heartbeat_errors++;
++ if (txsr & ENTSR_OWC) ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_receive
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_receive (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char rxing_page, this_frame, next_frame;
++ unsigned short current_offset;
++ struct ax_pkt_hdr rx_frame;
++ int num_rx_pages = ax_local->stop_page - ax_local->rx_start_page;
++ while (1)
++ {
++ int pkt_len, pkt_stat;
++
++ /* Get the rx page (incoming packet pointer). */
++ writeb (E8390_NODMA+E8390_PAGE1, ax_base + E8390_CMD);
++ rxing_page = readb (ax_base + EN1_CURPAG);
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ /* Remove one frame from the ring. Boundary is always a page behind. */
++ this_frame = readb (ax_base + EN0_BOUNDARY) + 1;
++ if (this_frame >= ax_local->stop_page)
++ this_frame = ax_local->rx_start_page;
++
++ if (this_frame != ax_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
++ PRINTK (RX_MSG, "%s: mismatched read page pointers %2x vs %2x.\n",
++ dev->name, this_frame, ax_local->current_page);
++
++ if (this_frame == rxing_page) { /* Read all the frames? */
++ break; /* Done for now */
++ }
++ current_offset = this_frame << 8;
++ ax_get_hdr (dev, &rx_frame, this_frame);
++
++ pkt_len = rx_frame.count - sizeof (struct ax_pkt_hdr);
++ pkt_stat = rx_frame.status;
++ next_frame = this_frame + 1 + ((pkt_len+4)>>8);
++
++ /* Check for bogosity warned by 3c503 book: the status byte is never
++ written. This happened a lot during testing! This code should be
++ cleaned up someday. */
++ if (rx_frame.next != next_frame
++ && rx_frame.next != next_frame + 1
++ && rx_frame.next != next_frame - num_rx_pages
++ && rx_frame.next != next_frame + 1 - num_rx_pages) {
++ ax_local->current_page = rxing_page;
++ writeb (ax_local->current_page-1, ax_base+EN0_BOUNDARY);
++ ax_local->stat.rx_errors++;
++ PRINTK (ERROR_MSG, "error occurred! Drop this packet!!\n");
++ continue;
++ }
++
++ if (pkt_len < 60 || pkt_len > 1518)
++ {
++ PRINTK (RX_MSG, "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
++ dev->name, rx_frame.count, rx_frame.status,
++ rx_frame.next);
++ ax_local->stat.rx_errors++;
++ ax_local->stat.rx_length_errors++;
++ }
++ else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
++ {
++ struct sk_buff *skb;
++ skb = dev_alloc_skb (pkt_len+2);
++ if (skb == NULL)
++ {
++ printk ("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
++ ax_local->stat.rx_dropped++;
++ break;
++ }
++ skb_reserve (skb, 2); /* IP headers on 16 byte boundaries */
++ skb->dev = dev;
++ skb_put (skb, pkt_len); /* Make room */
++ ax_block_input (dev, pkt_len, skb, current_offset + sizeof (rx_frame));
++ skb->protocol = eth_type_trans (skb,dev);
++ netif_rx (skb);
++ dev->last_rx = jiffies;
++ ax_local->stat.rx_packets++;
++ ax_local->stat.rx_bytes += pkt_len;
++ if (pkt_stat & ENRSR_PHY)
++ ax_local->stat.multicast++;
++ }
++ else
++ {
++ PRINTK (ERROR_MSG, "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
++ dev->name, rx_frame.status, rx_frame.next, rx_frame.count);
++ ax_local->stat.rx_errors++;
++ /* NB: The NIC counts CRC, frame and missed errors. */
++ if (pkt_stat & ENRSR_FO)
++ ax_local->stat.rx_fifo_errors++;
++ }
++ next_frame = rx_frame.next;
++
++ /* This _should_ never happen: it's here for avoiding bad clones. */
++ if (next_frame >= ax_local->stop_page) {
++ PRINTK (ERROR_MSG, "%s: next frame inconsistency, %#2x\n", dev->name, next_frame);
++ next_frame = ax_local->rx_start_page;
++ }
++ ax_local->current_page = next_frame;
++ writeb (next_frame-1, ax_base+EN0_BOUNDARY);
++ }
++
++ return;
++}
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_rx_overrun
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_rx_overrun (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char was_txing, must_resend = 0;
++
++
++ /*
++ * Record whether a Tx was in progress and then issue the
++ * stop command.
++ */
++ was_txing = readb (ax_base+E8390_CMD) & E8390_TRANS;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ PRINTK (RX_MSG, "%s: Receiver overrun.\n", dev->name);
++
++ ax_local->stat.rx_over_errors++;
++
++ udelay (2*1000);
++
++ writeb (0x00, ax_base+EN0_RCNTLO);
++ writeb (0x00, ax_base+EN0_RCNTHI);
++
++ /*
++ * See if any Tx was interrupted or not. According to NS, this
++ * step is vital, and skipping it will cause no end of havoc.
++ */
++
++ if (was_txing)
++ {
++ unsigned char tx_completed = readb (ax_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR);
++ if (!tx_completed)
++ must_resend = 1;
++ }
++
++ /*
++ * Have to enter loopback mode and then restart the NIC before
++ * you are allowed to slurp packets up off the ring.
++ */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR);
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START, ax_base + E8390_CMD);
++
++ /*
++ * Clear the Rx ring of all the debris, and ack the interrupt.
++ */
++ ax_receive (dev);
++
++ /*
++ * Leave loopback mode, and resend any packet that got stopped.
++ */
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR);
++ if (must_resend)
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, ax_base + E8390_CMD);
++
++}
++
++
++/*
++ * Collect the stats. This is called unlocked and from several contexts.
++ */
++static struct net_device_stats *get_stats (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ /* If the card is stopped, just return the present stats. */
++ if (!netif_running (dev))
++ return &ax_local->stat;
++
++ spin_lock_irqsave (&ax_local->page_lock,flags);
++ /* Read the counter registers, assuming we are in page 0. */
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return &ax_local->stat;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: make_mc_bits
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static inline void make_mc_bits (u8 *bits, struct net_device *dev)
++{
++ struct dev_mc_list *dmi;
++ for (dmi=dev->mc_list; dmi; dmi=dmi->next)
++ {
++ u32 crc;
++ if (dmi->dmi_addrlen != ETH_ALEN)
++ {
++ PRINTK (INIT_MSG, "%s: invalid multicast address length given.\n", dev->name);
++ continue;
++ }
++ crc = ether_crc (ETH_ALEN, dmi->dmi_addr);
++ /*
++ * The 8390 uses the 6 most significant bits of the
++ * CRC to index the multicast table.
++ */
++ bits[crc>>29] |= (1<<((crc>>26)&7));
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: do_set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void do_set_multicast_list (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++ if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
++ {
++ memset (ax_local->mcfilter, 0, 8);
++ if (dev->mc_list)
++ make_mc_bits (ax_local->mcfilter, dev);
++ }
++ else
++ memset (ax_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */
++
++ if (netif_running (dev))
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ writeb (E8390_NODMA + E8390_PAGE1, ax_base + E8390_CMD);
++ for (i = 0; i < 8; i++)
++ {
++ writeb (ax_local->mcfilter[i], ax_base + EN1_MULT_SHIFT (i));
++ }
++ writeb (E8390_NODMA + E8390_PAGE0, ax_base + E8390_CMD);
++
++ if (dev->flags&IFF_PROMISC)
++ writeb (E8390_RXCONFIG | 0x18, ax_base + EN0_RXCR);
++ else if (dev->flags&IFF_ALLMULTI || dev->mc_list)
++ writeb (E8390_RXCONFIG | 0x08, ax_base + EN0_RXCR);
++ else
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ }
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void set_multicast_list (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device*)dev->priv;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ do_set_multicast_list (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ethdev_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ethdev_init (struct net_device *dev)
++{
++
++ if (dev->priv == NULL)
++ {
++ struct ax_device *ax_local;
++
++ dev->priv = kmalloc (sizeof (struct ax_device), GFP_KERNEL);
++ if (dev->priv == NULL)
++ return -ENOMEM;
++ memset (dev->priv, 0, sizeof (struct ax_device));
++ ax_local = (struct ax_device *)dev->priv;
++ spin_lock_init (&ax_local->page_lock);
++ }
++
++ dev->hard_start_xmit = &ax_start_xmit;
++ dev->get_stats = get_stats;
++ dev->set_multicast_list = &set_multicast_list;
++
++ ether_setup (dev);
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax88796_PHY_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void ax88796_PHY_init (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 advertise;
++
++ /* Enable AX88796B FOLW CONTROL */
++ writeb (ENFLOW_ENABLE, ax_base+EN0_FLOW);
++
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE) & ~ADVERTISE_ALL;
++
++ switch (ax_local->media) {
++ case MEDIA_AUTO:
++ PRINTK (DEBUG_MSG, PFX " The media mode is autosense.\n");
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++
++ case MEDIA_100FULL:
++ PRINTK (DEBUG_MSG, PFX " The media mode is forced to 100full.\n");
++ advertise |= ADVERTISE_100FULL | 0x400;
++ break;
++
++ case MEDIA_100HALF:
++ PRINTK (DEBUG_MSG, PFX " The media mode is forced to 100half.\n");
++ advertise |= ADVERTISE_100HALF;
++ break;
++
++ case MEDIA_10FULL:
++ PRINTK (DEBUG_MSG, PFX " The media mode is forced to 10full.\n");
++ advertise |= ADVERTISE_10FULL;
++ break;
++
++ case MEDIA_10HALF:
++ PRINTK (DEBUG_MSG, PFX " The media mode is forced to 10half.\n");
++ advertise |= ADVERTISE_10HALF;
++ break;
++ default:
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++ }
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_init (struct net_device *dev, int startp)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Follow National Semi's recommendations for initing the DP83902. */
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD); /* 0x21 */
++ writeb (ax_local->bus_width, ax_base + EN0_DCFG);/* 8-bit or 16-bit */
++
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active low \n");
++ /* Set AX88796B interrupt active low */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++
++#elif IRW_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active high \n");
++ /* Set AX88796B interrupt active high */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_INT_ACT_HIGH | ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++#endif
++
++
++
++ /* Clear the remote byte count registers. */
++ writeb (0x00, ax_base + EN0_RCNTLO);
++ writeb (0x00, ax_base + EN0_RCNTHI);
++
++ /* Set to monitor and loopback mode -- this is vital!. */
++ writeb (E8390_RXOFF, ax_base + EN0_RXCR); /* 0x20 */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR); /* 0x02 */
++
++ /* Set the transmit page and receive ring. */
++ writeb (NESM_START_PG, ax_base + EN0_TPSR);
++ writeb (NESM_RX_START_PG, ax_base + EN0_STARTPG);
++ writeb (NESM_RX_START_PG, ax_base + EN0_BOUNDARY);
++
++ ax_local->current_page = NESM_RX_START_PG + 1; /* assert boundary+1 */
++ writeb (NESM_STOP_PG, ax_base + EN0_STOPPG);
++
++ ax_local->tx_prev_ctepr = 0;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->tx_curr_page = NESM_START_PG;
++ ax_local->tx_stop_page = NESM_START_PG + TX_PAGES;
++
++ /* Clear the pending interrupts and mask. */
++ writeb (0xFF, ax_base + EN0_ISR);
++ writeb (0x00, ax_base + EN0_IMR);
++
++ /* Copy the station address into the DS8390 registers. */
++ writeb (E8390_NODMA + E8390_PAGE1 + E8390_STOP, ax_base+E8390_CMD); /* 0x61 */
++ writeb (NESM_START_PG + TX_PAGES + 1, ax_base + EN1_CURPAG);
++ for (i = 0; i < 6; i++)
++ {
++ writeb (dev->dev_addr[i], ax_base + EN1_PHYS_SHIFT (i));
++ if (readb (ax_base + EN1_PHYS_SHIFT (i))!=dev->dev_addr[i])
++ PRINTK (ERROR_MSG, "Hw. address read/write mismap %d\n",i);
++ }
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ if (startp)
++ {
++ /* Enable AX88796B TQC */
++ writeb ((readb (ax_base+EN0_MCR) | ENTQC_ENABLE), ax_base+EN0_MCR);
++
++ /* Enable AX88796B Transmit Buffer Ring */
++ writeb (E8390_NODMA+E8390_PAGE3+E8390_STOP, ax_base+E8390_CMD);
++ writeb (ENTBR_ENABLE, ax_base+EN3_TBR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ ax_local->media_curr = 0xFF;
++ ax88796_PHY_init (dev);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+E8390_CMD);
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR); /* xmit on. */
++
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR); /* rx on, */
++ do_set_multicast_list (dev); /* (re)load the mcast table */
++ }
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_trigger_send
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base+E8390_CMD);
++ writeb (length & 0xff, ax_base + EN0_TCNTLO);
++ writeb (length >> 8, ax_base + EN0_TCNTHI);
++ writeb (start_page, ax_base + EN0_TPSR);
++ writeb ((E8390_NODMA|E8390_TRANS|E8390_START), ax_base+E8390_CMD);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_add_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_add_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ writeb ((u8)vid, ax_base+EN0_VID0);
++ writeb ((vid >> 9) & 0xF, ax_base+EN0_VID1);
++
++ /* Enable AX88796B Vlan filtering */
++ writeb (readb(ax_base+EN0_MCR) | ENVLAN_ENABLE, ax_base+EN0_MCR);
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_kill_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_kill_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ /* Disable AX88796B Vlan filtering */
++ writeb (readb (ax_base+EN0_MCR) & ~ENVLAN_ENABLE, ax_base+EN0_MCR);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_watchdog
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_watchdog (unsigned long arg)
++{
++ struct net_device *dev = (struct net_device *)(arg);
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u8 status;
++ u16 bmcr, advertise;
++
++ status = readb (ax_base + EN0_SR);
++
++ if (ax_local->media_curr != status) {
++
++ ax_local->media_curr = status;
++
++ if ((status & ENSR_LINK))
++ {
++ if (status & ENSR_SPEED_100) {
++ PRINTK (DRIVER_MSG, "%s Link mode : 100 Mb/s ", dev->name);
++ } else {
++ PRINTK (DRIVER_MSG, "%s Link mode : 10 Mb/s ", dev->name);
++ }
++
++ if (status & ENSR_DUPLEX_DULL) {
++ PRINTK (DRIVER_MSG, "Full Duplex.\n");
++ } else {
++ PRINTK (DRIVER_MSG, "Half Duplex.\n");
++ }
++
++ mdelay (200);
++ netif_carrier_on (dev);
++ netif_wake_queue (dev);
++ } else {
++ netif_stop_queue (dev);
++ netif_carrier_off (dev);
++ PRINTK (DRIVER_MSG, "%s Link down.\n", dev->name);
++ }
++ }
++
++ if (!(status & ENSR_LINK)) {
++
++ bmcr = mdio_read (dev, 0x10, MII_BMCR);
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE);
++
++ /* Power down PHY */
++ mdio_write (dev, 0x10, MII_BMCR, BMCR_PDOWN);
++ mdelay (1);
++ /* Power up PHY */
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ mdelay (60);
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ }
++
++ mod_timer (&ax_local->watchdog, jiffies + AX88796_WATCHDOG_PERIOD);
++ return ;
++}
++
++
++/*
++ * ======================================================================
++ * MII interface support
++ * ======================================================================
++ */
++#define MDIO_SHIFT_CLK 0x01
++#define MDIO_DATA_WRITE0 0x00
++#define MDIO_DATA_WRITE1 0x08
++#define MDIO_DATA_READ 0x04
++#define MDIO_MASK 0x0f
++#define MDIO_ENB_IN 0x02
++
++static void mdio_sync (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int bits;
++ for (bits = 0; bits < 32; bits++) {
++ writeb (MDIO_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static void mdio_clear (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ int bits;
++ for (bits = 0; bits < 16; bits++) {
++ writeb (MDIO_DATA_WRITE0, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE0 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0xf6<<10)|(phy_id<<5)|loc;
++ int i, retval = 0;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 14; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 19; i > 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ retval = (retval << 1) | ((readb (ax_base + AX88796_MII_EEPROM) & MDIO_DATA_READ) != 0);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ return (retval>>1) & 0xffff;
++}
++
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
++ int i;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 31; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 1; i >= 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++
++#if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1)
++/*
++ * ======================================================================
++ * EEPROM interface support
++ * ======================================================================
++ */
++#define EEPROM_SHIFT_CLK (0x80)
++#define EEPROM_DATA_READ1 (0x40)
++#define EEPROM_DATA_WRITE0 (0x00)
++#define EEPROM_DATA_WRITE1 (0x20)
++#define EEPROM_SELECT (0x10)
++#define EEPROM_DIR_IN (0x02)
++
++#define EEPROM_READ (0x02)
++#define EEPROM_EWEN (0x00)
++#define EEPROM_ERASE (0x03)
++#define EEPROM_WRITE (0x01)
++#define EEPROM_ERALL (0x00)
++#define EEPROM_WRAL (0x00)
++#define EEPROM_EWDS (0x00)
++#define EEPROM_93C46_OPCODE(x) ((x) << 6)
++#define EEPROM_93C46_STARTBIT (1 << 8)
++
++static void
++eeprom_write_en (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE(EEPROM_EWEN) | 0x30;
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static void
++eeprom_write_dis (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_EWDS);
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static int
++eeprom_write (struct net_device *dev, unsigned char loc, unsigned short nValue)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_WRITE) | loc;
++ unsigned char tmp;
++ int i;
++ int ret = 0;
++
++ // issue a "SB OP Addr" command
++ for(i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // writing the data
++ for (i = 15; i >= 0; i--) {
++ tmp = (nValue & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ //
++ // check busy
++ //
++
++ // Turn, wait two clocks
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++
++ // waiting for busy signal
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if ((tmp & EEPROM_DATA_READ1) == 0)
++ break;
++ }
++ if (i <= 0) {
++ printk ("Failed on waiting for bus busy\n\r");
++ ret = -1;
++ } else {
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ break;
++ }
++
++ if (i <= 0) {
++ printk ("Failed on waiting for write completion\n\r");
++ ret = -1;
++ }
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return ret;
++}
++
++static unsigned short
++eeprom_read (struct net_device *dev, unsigned char loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_READ) | loc;
++ unsigned char tmp;
++ unsigned short retValue = 0;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // Turn
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT | EEPROM_SHIFT_CLK | EEPROM_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++
++ // retriving the data
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ retValue |= (1 << i);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return retValue;
++}
++#endif /* #if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1) */
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b.h linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b.h
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,283 @@
++/* Generic AX88796B register definitions. */
++/* This file is part of AX88796B drivers, and is distributed
++ under the same license.*/
++
++#ifndef _ax88796_h
++#define _ax88796_h
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/version.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/crc32.h>
++#include <linux/mii.h>
++#include <linux/if_vlan.h>
++
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++# include <asm/irq.h>
++# include <asm/arch/S3C2440.h>
++# endif
++#else
++# ifdef CONFIG_ARCH_S3C2410
++# include <asm/arch/regs-mem.h>
++# include <asm/arch/regs-irq.h>
++# endif
++#endif
++
++#define TX_PAGES 12
++#define Tx_page_size 256
++
++#define NE_IO_EXTENT 0xFFF
++
++#define NESM_START_PG 0x40 /* First page of TX buffer */
++#define NESM_RX_START_PG (NESM_START_PG + TX_PAGES) /* First page of RX buffer */
++
++#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
++
++#define ETHER_ADDR_LEN 6
++
++#define AX88796B_BASE 0x08000000
++
++/* The 796b specific per-packet-header format. */
++struct ax_pkt_hdr {
++ unsigned char status; /* status */
++ unsigned char next; /* pointer to next packet. */
++ unsigned short count; /* header + packet length in bytes */
++};
++
++/* Most of these entries should be in 'struct net_device' (or most of the
++ things in there should be here!) */
++/* You have one of these per-board */
++struct ax_device {
++ const char *name;
++ void *membase;
++ unsigned char bus_width;
++ unsigned char mcfilter[8];
++ unsigned char media;
++ unsigned char media_curr;
++ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;
++ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;
++ unsigned char current_page; /* Read pointer in buffer */
++ spinlock_t page_lock; /* Page register locks */
++ struct timer_list watchdog;
++ struct net_device_stats stat; /* The new statistics table. */
++ unsigned irqlock:1;
++ unsigned dmaing:1;
++};
++
++#define AX88796_WATCHDOG_PERIOD (3*HZ)
++
++//#define ei_status (*(struct ei_device *)(dev->priv))
++
++/* Some generic ethernet register configurations. */
++
++#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
++#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
++#define E8390_TXCONFIG 0x80 /* EN0_TXCR: Normal transmit mode */
++#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
++
++/* Register accessed at EN_CMD, the 8390 base addr. */
++#define E8390_STOP 0x01 /* Stop and reset the chip */
++#define E8390_START 0x02 /* Start the chip, clear reset */
++#define E8390_TRANS 0x04 /* Transmit a frame */
++#define E8390_RREAD 0x08 /* Remote read */
++#define E8390_RWRITE 0x10 /* Remote write */
++#define E8390_NODMA 0x20 /* Remote DMA */
++#define E8390_PAGE0 0x00 /* Select page chip registers */
++#define E8390_PAGE1 0x40 /* using the two high-order bits */
++#define E8390_PAGE2 0x80 /* Page 2 is invalid. */
++#define E8390_PAGE3 0xc0 /* Page 3 for AX88796B */
++
++#define EI_SHIFT(x) ((x) << 1)
++
++#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
++/* Page 0 register offsets. */
++#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
++#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
++#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
++#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
++#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
++#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
++#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */
++#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */
++#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */
++#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */
++#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */
++#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */
++#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */
++#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */
++#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */
++#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */
++#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */
++#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */
++#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */
++#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */
++#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */
++#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */
++#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */
++#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */
++#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */
++#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */
++#define EN0_DATAPORT EI_SHIFT(0x10)
++#define EN0_PHYID EI_SHIFT(0x10)
++#define AX88796_MII_EEPROM EI_SHIFT(0x14)
++#define EN0_BTCR EI_SHIFT(0x15) /* Buffer Type Configure Register */
++#define EN0_SR EI_SHIFT(0X17) /* AX88796B Status Register */
++#define EN0_FLOW EI_SHIFT(0x1a) /* AX88796B Flow control register */
++#define EN0_MCR EI_SHIFT(0X1b) /* Mac configure register */
++#define EN0_CTEPR EI_SHIFT(0x1c) /* Current TX End Page */
++#define EN0_VID0 EI_SHIFT(0x1c) /* VLAN ID 0 */
++#define EN0_VID1 EI_SHIFT(0x1d) /* VLAN ID 1 */
++#define EN0_RESET EI_SHIFT(0X1f) /* Issue a read to reset, a write to clear. */
++
++#define EN0_DATA_ADDR 0x0800
++
++#define ENVLAN_ENABLE 0x08
++
++/* Bits in EN0_ISR - Interrupt status register */
++#define ENISR_RX 0x01 /* Receiver, no error */
++#define ENISR_TX 0x02 /* Transmitter, no error */
++#define ENISR_RX_ERR 0x04 /* Receiver, with error */
++#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
++#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
++#define ENISR_COUNTERS 0x20 /* Counters need emptying */
++#define ENISR_RDC 0x40 /* remote dma complete */
++#define ENISR_RESET 0x80 /* Reset completed */
++#define ENISR_ALL (ENISR_RX | ENISR_TX | ENISR_RX_ERR | ENISR_TX_ERR | ENISR_OVER | ENISR_COUNTERS)/* Interrupts we will enable */
++
++
++/* Bits in EN0_DCFG - Data config register */
++#define ENDCFG_WTS 0x01 /* word transfer mode selection */
++#define ENDCFG_BOS 0x02 /* byte order selection */
++
++#define ENFLOW_ENABLE 0xc7 /* Flow Control Control Register */
++#define ENTQC_ENABLE 0x20 /* Enable TXQ */
++
++#define EN3_TBR EI_SHIFT(0x0d) /* Transmit Buffer Ring Control Register */
++#define ENTBR_ENABLE 0x01 /* Enable Transmit Buffer Ring */
++
++/* Page 1 register offsets. */
++#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */
++#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */
++#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */
++#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */
++#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */
++
++/* Bits in received packet status byte and EN0_RSR*/
++#define ENRSR_RXOK 0x01 /* Received a good packet */
++#define ENRSR_CRC 0x02 /* CRC error */
++#define ENRSR_FAE 0x04 /* frame alignment error */
++#define ENRSR_FO 0x08 /* FIFO overrun */
++#define ENRSR_MPA 0x10 /* missed pkt */
++#define ENRSR_PHY 0x20 /* physical/multicast address */
++#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
++#define ENRSR_DEF 0x80 /* deferring */
++
++/* Transmitted packet status, EN0_TSR. */
++#define ENTSR_PTX 0x01 /* Packet transmitted without error */
++#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
++#define ENTSR_COL 0x04 /* The transmit collided at least once. */
++#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
++#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
++#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
++#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
++#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
++
++/* Bits in buffer type configure register */
++#define ENBTCR_PME_INT_EN 0x40 /* PME interrupt enable */
++#define ENBTCR_INT_ACT_HIGH 0x10
++
++/* Bits in device status register, EN0_SR */
++#define ENSR_DMA_DONE 0x40 /* Remote DMA completed */
++#define ENSR_DMA_READY 0x20 /* Remote DMA ready */
++#define ENSR_DEV_READY 0x10 /* Device ready */
++#define ENSR_SPEED_100 0x04 /* PHY link at 100 Mb/s */
++#define ENSR_DUPLEX_DULL 0x02 /* PHY link at full duplex */
++#define ENSR_LINK 0x01 /* PHY link up */
++
++/* Power Management register offsets. */
++#define EN3_BM0 EI_SHIFT(0x01)
++#define EN3_BM1 EI_SHIFT(0x02)
++#define EN3_BM2 EI_SHIFT(0x03)
++#define EN3_BM3 EI_SH2IFT(0x04)
++#define EN3_BM10CRC EI_SHIFT(0x05)
++#define EN3_BM32CRC EI_SHIFT(0x06)
++#define EN3_BMOFST EI_SHIFT(0x07)
++#define EN3_LSTBYT EI_SHIFT(0x08)
++#define EN3_BMCD EI_SHIFT(0x09)
++#define EN3_WUCS EI_SHIFT(0x0a)
++#define EN3_PMR EI_SHIFT(0x0b)
++
++/* Bits in Wake up Control */
++#define ENWUCS_MPEN 0x01
++#define ENWUCS_WUEN 0x02
++#define ENWUCS_LINK 0x04
++
++/* Bits in PM Control */
++#define ENPMR_D1 0x01
++#define ENPMR_D2 0x02
++
++/* SMDK2440 Registers Definition */
++/* SMDK2440 default clocks: FCLK=400MHZ, HCLK=125MHZ, PCLK=62.5MHZ */
++#define CLKDIVN_125MHZ 0x0000000F /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define CAMDIVN_125MHZ 0x00000000 /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define UBRDIV0_125MHZ 0x00000023 /* Set UART Baud Rate divisor for 125MHZ HCLK */
++
++#define CLKDIVN_100MHZ 0x0000000D /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define CAMDIVN_100MHZ 0x00000000 /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define UBRDIV0_100MHZ 0x0000001B /* Set UART Baud Rate divisor for 100MHZ HCLK */
++
++#define CLKDIVN_50MHZ 0x0000000D /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define CAMDIVN_50MHZ 0x00000200 /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define UBRDIV0_50MHZ 0x0000000D /* Set UART Baud Rate divisor for 50MHZ HCLK */
++
++#define DEFAULT_100MHZ_BANKCON1 0x00000400
++#define DEFAULT_125MHZ_BANKCON1 0x00000510
++#define BURST_BANKCON1 0x0000040f
++
++/* EINTMASK Register Bit Definition */
++#define EINT11_MASK 0x00000800 /* Clear this bit to enable EINT11 interrupt */
++
++/* EXTINT1 Register Bit Definition */
++#define FLTEN11_HIGHLEVEL 0x00009000
++#define FLTEN11_LOWLEVEL 0x00008000 /* Enable EINT11 signal with noise filter */
++/* End of SMDK2440 Registers Definition */
++
++
++#define MEDIA_AUTO 0
++#define MEDIA_100FULL 1
++#define MEDIA_100HALF 2
++#define MEDIA_10FULL 3
++#define MEDIA_10HALF 4
++
++/* Debug Message Display Level Definition */
++#define DRIVER_MSG 0x0001
++#define INIT_MSG 0x0002
++#define TX_MSG 0x0004
++#define RX_MSG 0x0008
++#define INT_MSG 0x0010
++#define ERROR_MSG 0x0020
++#define WARNING_MSG 0x0040
++#define DEBUG_MSG 0x0080
++#define OTHERS_MSG 0x0100
++#define ALL_MSG 0x01FF
++#define NO_MSG 0x0000
++#define DEFAULT_MSG (DRIVER_MSG | ERROR_MSG)
++#define DEBUG_FLAGS DEFAULT_MSG
++
++#endif /* _8390_h */
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_org.c linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_org.c
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_org.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_org.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1914 @@
++/*
++ ==================================================================================
++ ax88796b.c: A SAMSUNG S3C2440 Linux2.6.x Ethernet device driver for ASIX AX88796B chips.
++
++ This program is free software; you can distrine_block_inputbute 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.,
++ 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++
++ This program is based on
++
++ ne.c: A general non-shared-memory NS8390 ethernet driver for linux
++ Written 1992-94 by Donald Becker.
++
++ 8390.c: A general NS8390 ethernet driver core for linux.
++ Written 1992-94 by Donald Becker.
++
++ Version history:
++
++ Version 1.0.0 06/02/2006
++
++ * Initial release
++
++ Version 1.0.0 27/03/2006
++
++ * Fixups Transmit Queue functions.
++
++ Version 1.1.0 20/09/2006
++
++ * Ported to support kernel 2.6.x.
++
++ Version 1.2.0 09/09/2008
++
++ * 1. Added 8-bit support.
++ * 2. Added EEPROM support.
++ * 3. Added PHY power process function.
++
++ ==================================================================================
++ Driver Overview
++ ==================================================================================
++ ASIX AX88796B 3-in-1 Local Bus 8/16-bit Fast Ethernet Linux Driver
++
++ The AX88796B Ethernet controller is a high performance and highly integrated
++ local CPU bus Ethernet controllers with embedded 10/100Mbps PHY/Transceiver
++ 16K bytes SRAM and supports both 8-bit and 16-bit local CPU interfaces for any
++ embedded systems.
++
++ If you look for more details, please visit ASIX's web site (http://www.asix.com.tw).
++
++
++ ==================================================================================
++ COMPILING DRIVER
++ ==================================================================================
++ Prepare:
++
++ AX88796B Linux Driver.
++ Linux Kernel source code.
++ Cross-Compiler.
++
++ Getting Start:
++
++ 1.Extracting the AX88796B source file by executing the following command.
++ [root@localhost]# tar jxvf ax88796b-arm-linux2.4.tar.bz2
++
++ 2.Edit the makefile to specifie the path of target platform Linux Kernel source.
++ EX:
++ KDIR := /work/linux-2.6.17.11
++
++ 3.Executing 'make' command to compiler AX88796B Driver.
++
++ 4.If the compilation well, the ax88796.ko will be created under the current directory.
++
++
++ ==================================================================================
++ DRIVER PARAMETERS
++ ==================================================================================
++ The following parameters can be set when using insmod.
++ EX: [root@localhost ax88796b]# insmod ax88796.ko mem=0x08000000
++
++ mem=0xNNNNNNNN
++ specifies the physical base address that AX88796B can be accessed.
++ Default value '0x08000000'.
++
++ irq=N
++ specifies the irq number. Default value '0x27'.
++
++ media=(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)
++ Media mode control. Default value 'auto'.
++*/
++#include "ax88796b.h"
++
++
++/* Local Function Prototypes */
++static int ax_probe (struct net_device *dev);
++static int ax_open (struct net_device *dev);
++static int ax_close (struct net_device *dev);
++static void ax_reset (struct net_device *dev);
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr,
++ int ring_page);
++static void ax_block_input (struct net_device *dev, int count,
++ struct sk_buff *skb, int ring_offset);
++static void ax_block_output (struct net_device *dev, const int count,
++ const unsigned char *buf, const int start_page);
++static int ethdev_init (struct net_device *dev);
++static void ax_init (struct net_device *dev, int startp);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++int set_external_irq (int irq, int edge, int pullup);
++# endif
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs);
++#endif
++static void ax_tx_intr (struct net_device *dev);
++static void ax_tx_err (struct net_device *dev);
++static void ax_receive (struct net_device *dev);
++static void ax_rx_overrun (struct net_device *dev);
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page);
++static void set_multicast_list (struct net_device *dev);
++static void do_set_multicast_list (struct net_device *dev);
++static void ax_watchdog (unsigned long arg);
++
++static void ax_vlan_rx_add_vid (struct net_device *netdev, u16 vid);
++static void ax_vlan_rx_kill_vid (struct net_device *netdev, u16 vid);
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc);
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value);
++
++/* NAMING CONSTANT DECLARATIONS */
++#define DRV_NAME "AX88796B"
++#define ADP_NAME "ASIX AX88796B Ethernet Adapter"
++#define DRV_VERSION "1.2.0"
++#define PFX DRV_NAME ": "
++
++#define PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printk(args)
++
++#define CONFIG_AX88796B_USE_MEMCPY 0
++#define CONFIG_AX88796B_8BIT_WIDE 0
++#define CONFIG_AX88796B_EEPROM_READ_WRITE 0
++
++/* LOCAL VARIABLES DECLARATIONS */
++static char version[] __devinitdata =
++KERN_INFO ADP_NAME ":v" DRV_VERSION " " __TIME__ " " __DATE__ "\n"
++KERN_INFO " http://www.asix.com.tw\n";
++
++static unsigned int media = 0;
++
++#ifdef MODULE
++
++static struct net_device dev_ax;
++static int mem;
++static int irq;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++MODULE_PARM (mem, "i");
++MODULE_PARM (irq, "i");
++MODULE_PARM (media, "i");
++#else
++module_param (mem, int, 0);
++module_param (irq, int, 0);
++module_param (media, int, 0);
++#endif
++
++MODULE_PARM_DESC (mem, "MEMORY base address(es),required");
++MODULE_PARM_DESC (irq, "IRQ number(s)");
++MODULE_PARM_DESC (media, "Media Mode(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)");
++
++MODULE_DESCRIPTION ("ASIX AX88796B Fast Ethernet driver");
++MODULE_LICENSE ("GPL");
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: init_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++int init_module (void)
++{
++ struct net_device *dev = &dev_ax;
++
++ dev->irq = irq;
++ dev->base_addr = mem;
++ dev->init = ax_probe;
++ if (register_netdev (dev) == 0)
++ return 0;
++
++ if (mem != 0) {
++ PRINTK (WARNING_MSG, PFX " No AX88796B card found at memory = %#x\n", mem);
++ }
++ else {
++ PRINTK (WARNING_MSG, PFX " You must supply \"mem=0xNNNNNNN\" value(s) for AX88796B.\n");
++ }
++ return -ENXIO;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: cleanup_module
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void cleanup_module (void)
++{
++ struct net_device *dev = &dev_ax;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ free_irq (dev->irq, dev);
++ iounmap (ax_base);
++ unregister_netdev (dev);
++ kfree (dev->priv);
++ dev->priv = NULL;
++}
++#endif /* MODULE */
++
++
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++static inline u16 READ_FIFO (void *membase)
++{
++ return (readb (membase) | (((u16)readb (membase)) << 8));
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writeb ((u8)data , membase);
++ writeb ((u8)(data >> 8) , membase);
++}
++#else
++static inline u16 READ_FIFO (void *membase)
++{
++ return readw (membase);
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writew (data, membase);
++}
++#endif
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: config_2440_bank1
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void config_2440_bank1 (void)
++{
++ /* Configure SAMSUNG S3C2440A controller for AX88796B operation */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ BWSCON = BWSCON & 0xFFFFFFCF;
++# else
++ BWSCON = (BWSCON & 0xFFFFFFCF) | 0x00000010;
++# endif
++
++ BANKCON1 = DEFAULT_125MHZ_BANKCON1;
++
++ set_external_irq (IRQ_EINT11, EXT_LOWLEVEL, GPIO_PULLUP_DIS);
++ EINTMASK &= ~EINT11_MASK;
++ EXTINT1 &= ~0xf000;
++ EXTINT1 |= FLTEN11_LOWLEVEL;
++# endif /* CONFIG_BOARD_S3C2440_SMDK */
++#else
++# ifdef CONFIG_ARCH_S3C2410
++ {
++ unsigned long tmp;
++ tmp = __raw_readl (S3C2410_BWSCON);
++
++# if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_8, S3C2410_BWSCON);
++# else
++ __raw_writel ((tmp & ~0x30) | S3C2410_BWSCON_DW1_16, S3C2410_BWSCON);
++# endif
++
++ __raw_writel (S3C2410_BANKCON_Tcah1 | S3C2410_BANKCON_Tacc8, S3C2410_BANKCON1);
++ }
++# endif /* CONFIG_ARCH_S3C2410 */
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: load_macaddr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++load_macaddr (struct net_device *dev, unsigned char *pMac)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Read the 12 bytes of station address PROM. */
++ {
++ struct {unsigned char value, offset; } program_seq[] =
++ {
++ {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
++ {ax_local->bus_width, EN0_DCFG}, /* Set wide access. */
++ {0x00, EN0_RCNTLO}, /* Clear the count regs. */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_IMR}, /* Mask completion irq. */
++ {0xFF, EN0_ISR},
++ {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
++ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
++ {0x0C, EN0_RCNTLO}, /* 12 bytes of station address */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
++ {0x00, EN0_RSARHI},
++ {E8390_RREAD+E8390_START, E8390_CMD},
++ };
++
++ for (i = 0; i < sizeof (program_seq)/sizeof (program_seq[0]); i++)
++ writeb (program_seq[i].value, ax_base + program_seq[i].offset);
++ }
++
++ while (( readb (ax_base + EN0_SR) & 0x20) == 0);
++
++ for (i = 0; i < 6; i++) {
++ pMac[i] = (unsigned char) READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_probe
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_probe (struct net_device *dev)
++{
++ int i;
++ int reg0, ret;
++ unsigned long base_addr;
++ void *address;
++ struct ax_device *ax_local;
++
++ PRINTK (INIT_MSG, PFX " probe start ..........\n");
++
++ SET_MODULE_OWNER (dev);
++
++ if (dev->base_addr == 0 )
++ dev->base_addr = AX88796B_BASE;
++
++ base_addr = dev->base_addr;
++
++ if (check_mem_region (base_addr , NE_IO_EXTENT))
++ return -ENODEV;
++ if (! request_mem_region (base_addr, NE_IO_EXTENT, DRV_NAME))
++ return -EBUSY;
++ address=ioremap_nocache (base_addr, NE_IO_EXTENT);
++ if (!address) {
++ PRINTK (ERROR_MSG, PFX " Unable to remap memory\n");
++ return -EBUSY;
++ }
++
++ config_2440_bank1 ();
++
++ reg0 = readb (address);
++ if (reg0 == 0xFF) {
++ ret = -ENODEV;
++ goto err_out;
++ }
++
++ /* Do a preliminary verification that we have a 8390. */
++ {
++ int regd;
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, address + E8390_CMD);
++ regd = readb (address + EN0_COUNTER0);
++ writeb (0xff, address + EN0_COUNTER0);
++ writeb (E8390_NODMA+E8390_PAGE0, address + E8390_CMD);
++ readb (address + EN0_COUNTER0); /* Clear the counter by reading. */
++ if (readb (address + EN0_COUNTER0) != 0) {
++ writeb (reg0, address);
++ writeb (regd, address + EN0_COUNTER0); /* Restore the old values. */
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++
++ printk (version);
++
++ /* Reset card. Who knows what dain-bramaged state it was left in. */
++ {
++ unsigned long reset_start_time = jiffies;
++
++ readb (address + EN0_RESET);
++ while ((readb (address + EN0_ISR) & ENISR_RESET) == 0) {
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, " not found (no reset ack).\n");
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++ writeb (0xff, (address + EN0_ISR)); /* Ack all intr. */
++ }
++
++ if (dev->irq == 0)
++ dev->irq =IRQ_EINT11;
++
++ /* Allocate dev->priv and fill in 8390 specific dev fields. */
++ if (ethdev_init (dev))
++ {
++ PRINTK (ERROR_MSG, "unable to get memory for dev->priv.\n");
++ ret = -ENOMEM;
++ goto err_out;
++ }
++
++ ax_local = (struct ax_device *)dev->priv;
++ ax_local->name = DRV_NAME;
++ ax_local->membase = address;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->rx_start_page = NESM_RX_START_PG;
++ ax_local->stop_page = NESM_STOP_PG;
++ ax_local->media = media;
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ ax_local->bus_width = 0;
++#else
++ ax_local->bus_width = 1;
++#endif
++
++ load_macaddr (dev, dev->dev_addr);
++
++ /* Support for No EEPROM */
++ if ( (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0) &&
++ (dev->dev_addr[2] == 0) && (dev->dev_addr[3] == 0) &&
++ (dev->dev_addr[4] == 0) && (dev->dev_addr[5] == 0) )
++ {
++ dev->dev_addr[0] = 0x00;
++ dev->dev_addr[1] = 0x88;
++ dev->dev_addr[2] = 0x88;
++ dev->dev_addr[3] = 0x77;
++ dev->dev_addr[4] = 0x99;
++ dev->dev_addr[5] = 0x66;
++ }
++
++ PRINTK (DRIVER_MSG, "%s: MAC ADDRESS ",DRV_NAME);
++ for (i = 0; i < ETHER_ADDR_LEN; i++) {
++ PRINTK (DRIVER_MSG, " %2.2x", dev->dev_addr[i]);
++ }
++
++ PRINTK (DRIVER_MSG, "\n%s: %s found at 0x%x, using IRQ %d.\n",
++ dev->name, DRV_NAME, AX88796B_BASE, dev->irq);
++
++ dev->open = &ax_open;
++ dev->stop = &ax_close;
++ dev->features |= NETIF_F_HW_VLAN_FILTER;
++ dev->vlan_rx_add_vid = ax_vlan_rx_add_vid;
++ dev->vlan_rx_kill_vid = ax_vlan_rx_kill_vid;
++
++ ax_init (dev, 0);
++ PRINTK (INIT_MSG, PFX " probe end ..........\n");
++ return 0;
++
++err_out:
++ iounmap (address);
++ kfree (dev->priv);
++ dev->priv = NULL;
++ return ret;
++}
++
++
++#ifndef MODULE
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_kprobe
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++struct net_device * __init ax_kprobe (int unit)
++{
++ struct net_device *dev = alloc_ei_netdev ();
++ int err;
++
++ if (!dev)
++ return ERR_PTR (-ENOMEM);
++
++ sprintf (dev->name, "eth%d", unit);
++ netdev_boot_setup_check (dev);
++
++ err = ax_probe (dev);
++ if (err)
++ goto out;
++ return dev;
++out:
++ free_netdev (dev);
++ return ERR_PTR (err);
++}
++#endif
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_reset
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_reset (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long reset_start_time = jiffies;
++
++ readb (ax_base + EN0_RESET);
++
++ ax_local->dmaing = 0;
++
++ /* This check _should_not_ be necessary, omit eventually. */
++ while ((readb (ax_base+EN0_ISR) & ENISR_RESET) == 0)
++ if (jiffies - reset_start_time > 2*HZ/100) {
++ PRINTK (ERROR_MSG, "%s: ax_reset() did not complete.\n", dev->name);
++ break;
++ }
++
++ writeb (ENISR_RESET, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_get_hdr
++ * Purpose: Grab the 796b specific header
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr, int ring_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)hdr;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_get_8390_hdr "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (sizeof (struct ax_pkt_hdr), ax_base + EN0_RCNTLO);
++ writeb (0, ax_base + EN0_RCNTHI);
++ writeb (0, ax_base + EN0_RSARLO); /* On page boundary */
++ writeb (ring_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++ *(++buf) = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++
++ le16_to_cpus (&hdr->count);
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_input
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)skb->data;
++ u16 i;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_input "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (ring_offset & 0xff, ax_base + EN0_RSARLO);
++ writeb (ring_offset >> 8, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ {
++ /* make the burst length be divided for 32-bit */
++ i = ((count - 2) + 3) & 0x7FC;
++
++ /* Read first 2 bytes */
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ /* The address of ++buf should be agigned on 32-bit boundary */
++ memcpy (++buf, ax_base+EN0_DATA_ADDR, i);
++ }
++#else
++ {
++ for (i = 0; i < count; i += 2) {
++ *buf++ = READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++ }
++#endif
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_output
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long dma_start;
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_output."
++ "[DMAstat:%d][irqlock:%d]\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++ /* We should already be in page 0, but to be safe... */
++ writeb (E8390_PAGE0+E8390_START+E8390_NODMA, ax_base + E8390_CMD);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ /* Now the normal output. */
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (0x00, ax_base + EN0_RSARLO);
++ writeb (start_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RWRITE+E8390_START, ax_base + E8390_CMD);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 3) & 0x7FC));
++#else
++ {
++ u16 i;
++ for (i = 0; i < count; i += 2) {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + i)));
++ }
++ }
++#endif
++ dma_start = jiffies;
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0) {
++ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
++ PRINTK (ERROR_MSG, "%s: timeout waiting for Tx RDC.\n", dev->name);
++ ax_reset (dev);
++ ax_init (dev,1);
++ break;
++ }
++ }
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++ return;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_open
++ * Purpose: Open/initialize 796b
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_open (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *membase = ax_local->membase;
++ int ret=0;
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open beginning ..........\n");
++ PRINTK (DEBUG_MSG, PFX " membase %p\n\r", membase);
++
++ ret = request_irq (dev->irq, &ax_interrupt, 0, dev->name, dev);
++
++ if (ret) {
++ PRINTK (ERROR_MSG, "%s: unable to get IRQ %d (errno=%d).\n",dev->name, dev->irq, ret);
++ return -ENXIO;
++ }
++
++ PRINTK (DEBUG_MSG, PFX " Request IRQ success !!\n\r");
++
++ /* This can't happen unless somebody forgot to call ethdev_init(). */
++ if (ax_local == NULL)
++ {
++ PRINTK (ERROR_MSG, "%s: ei_open passed a non-existent device!\n", dev->name);
++ return -ENXIO;
++ }
++
++ dev->tx_timeout = NULL;
++ dev->watchdog_timeo = 0;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_reset (dev);
++ ax_init (dev, 1);
++ netif_start_queue (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ ax_local->irqlock = 0;
++
++ init_timer (&ax_local->watchdog);
++ ax_local->watchdog.function = &ax_watchdog;
++ ax_local->watchdog.expires = jiffies + AX88796_WATCHDOG_PERIOD;
++ ax_local->watchdog.data = (unsigned long) dev;
++ add_timer (&ax_local->watchdog);
++
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_open end ..........\n");
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_close
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_close (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ unsigned long flags;
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close beginning ..........\n");
++ del_timer (&ax_local->watchdog);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ ax_init (dev, 0);
++
++ free_irq (dev->irq, dev);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ netif_stop_queue (dev);
++ PRINTK (DEBUG_MSG, PFX " ax88796B ei_close end ..........\n");
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_start_xmit
++ * Purpose: begin packet transmission
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int send_length;
++ unsigned long flags;
++ u8 ctepr=0, free_pages=0, need_pages;
++
++ /* check for link status */
++ if (!(readb (ax_base + EN0_SR) & ENSR_LINK)) {
++ dev_kfree_skb (skb);
++ return 0;
++ }
++
++ send_length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ spin_lock (&ax_local->page_lock);
++ ax_local->irqlock = 1;
++
++ need_pages = (send_length -1)/256 +1;
++ ctepr = readb (ax_base + EN0_CTEPR) & 0x7f;
++
++ if (ctepr == 0) {
++ if (ax_local->tx_curr_page == ax_local->tx_start_page && ax_local->tx_prev_ctepr == 0)
++ free_pages = TX_PAGES;
++ else
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page;
++ }
++ else if (ctepr < ax_local->tx_curr_page - 1) {
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page +
++ ctepr - ax_local->tx_start_page + 1;
++ }
++ else if (ctepr > ax_local->tx_curr_page - 1) {
++ free_pages = ctepr + 1 - ax_local->tx_curr_page;
++ }
++ else if (ctepr == ax_local->tx_curr_page - 1) {
++ if (ax_local->tx_full)
++ free_pages = 0;
++ else
++ free_pages = TX_PAGES;
++ }
++
++ if (free_pages < need_pages) {
++ PRINTK (DEBUG_MSG, "free_pages < need_pages\n\r");
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return 1;
++ }
++
++ ax_block_output (dev, send_length, skb->data, ax_local->tx_curr_page);
++ ax_trigger_send (dev, send_length, ax_local->tx_curr_page);
++ if (free_pages == need_pages) {
++ netif_stop_queue (dev);
++ ax_local->tx_full = 1;
++ }
++ ax_local->tx_prev_ctepr = ctepr;
++ ax_local->tx_curr_page = ax_local->tx_curr_page + need_pages < ax_local->tx_stop_page ?
++ ax_local->tx_curr_page + need_pages :
++ need_pages - (ax_local->tx_stop_page - ax_local->tx_curr_page) + ax_local->tx_start_page;
++
++ dev_kfree_skb (skb);
++ dev->trans_start = jiffies;
++ ax_local->stat.tx_bytes += send_length;
++
++ ax_local->irqlock = 0;
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_intr
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_intr (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int status = readb (ax_base + EN0_TSR);
++
++ ax_local->tx_full = 0;
++ if (netif_queue_stopped (dev))
++ netif_wake_queue (dev);
++
++ /* Minimize Tx latency: update the statistics after we restart TXing. */
++ if (status & ENTSR_COL)
++ ax_local->stat.collisions++;
++ if (status & ENTSR_PTX)
++ ax_local->stat.tx_packets++;
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (status & ENTSR_ABT)
++ {
++ ax_local->stat.tx_aborted_errors++;
++ ax_local->stat.collisions += 16;
++ }
++ if (status & ENTSR_CRS)
++ ax_local->stat.tx_carrier_errors++;
++ if (status & ENTSR_FU)
++ ax_local->stat.tx_fifo_errors++;
++ if (status & ENTSR_CDH)
++ ax_local->stat.tx_heartbeat_errors++;
++ if (status & ENTSR_OWC)
++ ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_interrupt
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#else
++static irqreturn_t ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)
++#endif
++{
++ struct net_device *dev = dev_id;
++ int interrupts;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ if (dev == NULL)
++ {
++ PRINTK (ERROR_MSG, "net_interrupt(): irq %d for unknown device.\n", irq);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (0x00, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ if (ax_local->irqlock) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return 0;
++#endif
++ }
++
++ spin_lock (&ax_local->page_lock);
++
++ while (1)
++ {
++
++ if ((interrupts = readb (ax_base + EN0_ISR)) == 0)
++ break;
++
++ writeb (interrupts, ax_base + EN0_ISR); /* Ack the interrupts */
++
++ if (interrupts & ENISR_TX)
++ ax_tx_intr (dev);
++
++ if (interrupts & ENISR_OVER)
++ ax_rx_overrun (dev);
++
++ if (interrupts & (ENISR_RX+ENISR_RX_ERR))
++ ax_receive (dev);
++
++ if (interrupts & ENISR_TX_ERR)
++ ax_tx_err (dev);
++
++ if (interrupts & ENISR_COUNTERS)
++ {
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++ writeb (ENISR_COUNTERS, ax_base + EN0_ISR); /* Ack intr. */
++ }
++
++ if (interrupts & ENISR_RDC)
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++ }
++
++ spin_unlock (&ax_local->page_lock);
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base + E8390_CMD);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ return;
++#else
++ return IRQ_RETVAL (0);
++#endif
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_tx_err
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_tx_err (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned char txsr = readb (ax_base+EN0_TSR);
++ unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
++
++ if (tx_was_aborted)
++ ax_tx_intr (dev);
++ else
++ {
++ ax_local->stat.tx_errors++;
++ if (txsr & ENTSR_CRS) ax_local->stat.tx_carrier_errors++;
++ if (txsr & ENTSR_CDH) ax_local->stat.tx_heartbeat_errors++;
++ if (txsr & ENTSR_OWC) ax_local->stat.tx_window_errors++;
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_receive
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_receive (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char rxing_page, this_frame, next_frame;
++ unsigned short current_offset;
++ struct ax_pkt_hdr rx_frame;
++ int num_rx_pages = ax_local->stop_page - ax_local->rx_start_page;
++ while (1)
++ {
++ int pkt_len, pkt_stat;
++
++ /* Get the rx page (incoming packet pointer). */
++ writeb (E8390_NODMA+E8390_PAGE1, ax_base + E8390_CMD);
++ rxing_page = readb (ax_base + EN1_CURPAG);
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ /* Remove one frame from the ring. Boundary is always a page behind. */
++ this_frame = readb (ax_base + EN0_BOUNDARY) + 1;
++ if (this_frame >= ax_local->stop_page)
++ this_frame = ax_local->rx_start_page;
++
++ if (this_frame != ax_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
++ PRINTK (RX_MSG, "%s: mismatched read page pointers %2x vs %2x.\n",
++ dev->name, this_frame, ax_local->current_page);
++
++ if (this_frame == rxing_page) { /* Read all the frames? */
++ break; /* Done for now */
++ }
++ current_offset = this_frame << 8;
++ ax_get_hdr (dev, &rx_frame, this_frame);
++
++ pkt_len = rx_frame.count - sizeof (struct ax_pkt_hdr);
++ pkt_stat = rx_frame.status;
++ next_frame = this_frame + 1 + ((pkt_len+4)>>8);
++
++ /* Check for bogosity warned by 3c503 book: the status byte is never
++ written. This happened a lot during testing! This code should be
++ cleaned up someday. */
++ if (rx_frame.next != next_frame
++ && rx_frame.next != next_frame + 1
++ && rx_frame.next != next_frame - num_rx_pages
++ && rx_frame.next != next_frame + 1 - num_rx_pages) {
++ ax_local->current_page = rxing_page;
++ writeb (ax_local->current_page-1, ax_base+EN0_BOUNDARY);
++ ax_local->stat.rx_errors++;
++ PRINTK (ERROR_MSG, "error occurred! Drop this packet!!\n");
++ continue;
++ }
++
++ if (pkt_len < 60 || pkt_len > 1518)
++ {
++ PRINTK (RX_MSG, "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
++ dev->name, rx_frame.count, rx_frame.status,
++ rx_frame.next);
++ ax_local->stat.rx_errors++;
++ ax_local->stat.rx_length_errors++;
++ }
++ else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
++ {
++ struct sk_buff *skb;
++ skb = dev_alloc_skb (pkt_len+2);
++ if (skb == NULL)
++ {
++ printk ("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
++ ax_local->stat.rx_dropped++;
++ break;
++ }
++ skb_reserve (skb, 2); /* IP headers on 16 byte boundaries */
++ skb->dev = dev;
++ skb_put (skb, pkt_len); /* Make room */
++ ax_block_input (dev, pkt_len, skb, current_offset + sizeof (rx_frame));
++ skb->protocol = eth_type_trans (skb,dev);
++ netif_rx (skb);
++ dev->last_rx = jiffies;
++ ax_local->stat.rx_packets++;
++ ax_local->stat.rx_bytes += pkt_len;
++ if (pkt_stat & ENRSR_PHY)
++ ax_local->stat.multicast++;
++ }
++ else
++ {
++ PRINTK (ERROR_MSG, "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
++ dev->name, rx_frame.status, rx_frame.next, rx_frame.count);
++ ax_local->stat.rx_errors++;
++ /* NB: The NIC counts CRC, frame and missed errors. */
++ if (pkt_stat & ENRSR_FO)
++ ax_local->stat.rx_fifo_errors++;
++ }
++ next_frame = rx_frame.next;
++
++ /* This _should_ never happen: it's here for avoiding bad clones. */
++ if (next_frame >= ax_local->stop_page) {
++ PRINTK (ERROR_MSG, "%s: next frame inconsistency, %#2x\n", dev->name, next_frame);
++ next_frame = ax_local->rx_start_page;
++ }
++ ax_local->current_page = next_frame;
++ writeb (next_frame-1, ax_base+EN0_BOUNDARY);
++ }
++
++ return;
++}
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_rx_overrun
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_rx_overrun (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned char was_txing, must_resend = 0;
++
++
++ /*
++ * Record whether a Tx was in progress and then issue the
++ * stop command.
++ */
++ was_txing = readb (ax_base+E8390_CMD) & E8390_TRANS;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ PRINTK (RX_MSG, "%s: Receiver overrun.\n", dev->name);
++
++ ax_local->stat.rx_over_errors++;
++
++ udelay (2*1000);
++
++ writeb (0x00, ax_base+EN0_RCNTLO);
++ writeb (0x00, ax_base+EN0_RCNTHI);
++
++ /*
++ * See if any Tx was interrupted or not. According to NS, this
++ * step is vital, and skipping it will cause no end of havoc.
++ */
++
++ if (was_txing)
++ {
++ unsigned char tx_completed = readb (ax_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR);
++ if (!tx_completed)
++ must_resend = 1;
++ }
++
++ /*
++ * Have to enter loopback mode and then restart the NIC before
++ * you are allowed to slurp packets up off the ring.
++ */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR);
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START, ax_base + E8390_CMD);
++
++ /*
++ * Clear the Rx ring of all the debris, and ack the interrupt.
++ */
++ ax_receive (dev);
++
++ /*
++ * Leave loopback mode, and resend any packet that got stopped.
++ */
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR);
++ if (must_resend)
++ writeb (E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, ax_base + E8390_CMD);
++
++}
++
++
++/*
++ * Collect the stats. This is called unlocked and from several contexts.
++ */
++static struct net_device_stats *get_stats (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ unsigned long flags;
++
++ /* If the card is stopped, just return the present stats. */
++ if (!netif_running (dev))
++ return &ax_local->stat;
++
++ spin_lock_irqsave (&ax_local->page_lock,flags);
++ /* Read the counter registers, assuming we are in page 0. */
++ ax_local->stat.rx_frame_errors += readb (ax_base + EN0_COUNTER0);
++ ax_local->stat.rx_crc_errors += readb (ax_base + EN0_COUNTER1);
++ ax_local->stat.rx_missed_errors+= readb (ax_base + EN0_COUNTER2);
++
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++ return &ax_local->stat;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: make_mc_bits
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static inline void make_mc_bits (u8 *bits, struct net_device *dev)
++{
++ struct dev_mc_list *dmi;
++ for (dmi=dev->mc_list; dmi; dmi=dmi->next)
++ {
++ u32 crc;
++ if (dmi->dmi_addrlen != ETH_ALEN)
++ {
++ PRINTK (INIT_MSG, "%s: invalid multicast address length given.\n", dev->name);
++ continue;
++ }
++ crc = ether_crc (ETH_ALEN, dmi->dmi_addr);
++ /*
++ * The 8390 uses the 6 most significant bits of the
++ * CRC to index the multicast table.
++ */
++ bits[crc>>29] |= (1<<((crc>>26)&7));
++ }
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: do_set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void do_set_multicast_list (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++ if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
++ {
++ memset (ax_local->mcfilter, 0, 8);
++ if (dev->mc_list)
++ make_mc_bits (ax_local->mcfilter, dev);
++ }
++ else
++ memset (ax_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */
++
++ if (netif_running (dev))
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ writeb (E8390_NODMA + E8390_PAGE1, ax_base + E8390_CMD);
++ for (i = 0; i < 8; i++)
++ {
++ writeb (ax_local->mcfilter[i], ax_base + EN1_MULT_SHIFT (i));
++ }
++ writeb (E8390_NODMA + E8390_PAGE0, ax_base + E8390_CMD);
++
++ if (dev->flags&IFF_PROMISC)
++ writeb (E8390_RXCONFIG | 0x18, ax_base + EN0_RXCR);
++ else if (dev->flags&IFF_ALLMULTI || dev->mc_list)
++ writeb (E8390_RXCONFIG | 0x08, ax_base + EN0_RXCR);
++
++ else
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ }
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: set_multicast_list
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void set_multicast_list (struct net_device *dev)
++{
++ unsigned long flags;
++ struct ax_device *ax_local = (struct ax_device*)dev->priv;
++
++ spin_lock_irqsave (&ax_local->page_lock, flags);
++ do_set_multicast_list (dev);
++ spin_unlock_irqrestore (&ax_local->page_lock, flags);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ethdev_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static int ethdev_init (struct net_device *dev)
++{
++
++ if (dev->priv == NULL)
++ {
++ struct ax_device *ax_local;
++
++ dev->priv = kmalloc (sizeof (struct ax_device), GFP_KERNEL);
++ if (dev->priv == NULL)
++ return -ENOMEM;
++ memset (dev->priv, 0, sizeof (struct ax_device));
++ ax_local = (struct ax_device *)dev->priv;
++ spin_lock_init (&ax_local->page_lock);
++ }
++
++ dev->hard_start_xmit = &ax_start_xmit;
++ dev->get_stats = get_stats;
++ dev->set_multicast_list = &set_multicast_list;
++
++ ether_setup (dev);
++
++ return 0;
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax88796_PHY_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++void ax88796_PHY_init (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 advertise;
++
++ /* Enable AX88796B FOLW CONTROL */
++ writeb (ENFLOW_ENABLE, ax_base+EN0_FLOW);
++
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE) & ~ADVERTISE_ALL;
++
++ switch (ax_local->media) {
++ case MEDIA_AUTO:
++ PRINTK (DRIVER_MSG, PFX " The media mode is autosense.\n");
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++
++ case MEDIA_100FULL:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 100full.\n");
++ advertise |= ADVERTISE_100FULL | 0x400;
++ break;
++
++ case MEDIA_100HALF:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 100half.\n");
++ advertise |= ADVERTISE_100HALF;
++ break;
++
++ case MEDIA_10FULL:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 10full.\n");
++ advertise |= ADVERTISE_10FULL;
++ break;
++
++ case MEDIA_10HALF:
++ PRINTK (DRIVER_MSG, PFX " The media mode is forced to 10half.\n");
++ advertise |= ADVERTISE_10HALF;
++ break;
++ default:
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++ }
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_init
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_init (struct net_device *dev, int startp)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Follow National Semi's recommendations for initing the DP83902. */
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD); /* 0x21 */
++ writeb (ax_local->bus_width, ax_base + EN0_DCFG);/* 8-bit or 16-bit */
++
++ /* Set AX88796B interrupt active high */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb (ENBTCR_INT_ACT_HIGH, ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++
++ /* Clear the remote byte count registers. */
++ writeb (0x00, ax_base + EN0_RCNTLO);
++ writeb (0x00, ax_base + EN0_RCNTHI);
++
++ /* Set to monitor and loopback mode -- this is vital!. */
++ writeb (E8390_RXOFF, ax_base + EN0_RXCR); /* 0x20 */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR); /* 0x02 */
++
++ /* Set the transmit page and receive ring. */
++ writeb (NESM_START_PG, ax_base + EN0_TPSR);
++ writeb (NESM_RX_START_PG, ax_base + EN0_STARTPG);
++ writeb (NESM_RX_START_PG, ax_base + EN0_BOUNDARY);
++
++ ax_local->current_page = NESM_RX_START_PG + 1; /* assert boundary+1 */
++ writeb (NESM_STOP_PG, ax_base + EN0_STOPPG);
++
++ ax_local->tx_prev_ctepr = 0;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->tx_curr_page = NESM_START_PG;
++ ax_local->tx_stop_page = NESM_START_PG + TX_PAGES;
++
++ /* Clear the pending interrupts and mask. */
++ writeb (0xFF, ax_base + EN0_ISR);
++ writeb (0x00, ax_base + EN0_IMR);
++
++ /* Copy the station address into the DS8390 registers. */
++ writeb (E8390_NODMA + E8390_PAGE1 + E8390_STOP, ax_base+E8390_CMD); /* 0x61 */
++ writeb (NESM_START_PG + TX_PAGES + 1, ax_base + EN1_CURPAG);
++ for (i = 0; i < 6; i++)
++ {
++ writeb (dev->dev_addr[i], ax_base + EN1_PHYS_SHIFT (i));
++ if (readb (ax_base + EN1_PHYS_SHIFT (i))!=dev->dev_addr[i])
++ PRINTK (ERROR_MSG, "Hw. address read/write mismap %d\n",i);
++ }
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ if (startp)
++ {
++ /* Enable AX88796B TQC */
++ writeb ((readb (ax_base+EN0_MCR) | ENTQC_ENABLE), ax_base+EN0_MCR);
++
++ /* Enable AX88796B Transmit Buffer Ring */
++ writeb (E8390_NODMA+E8390_PAGE3+E8390_STOP, ax_base+E8390_CMD);
++ writeb (ENTBR_ENABLE, ax_base+EN3_TBR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ ax_local->media_curr = 0xFF;
++ ax88796_PHY_init (dev);
++ writeb (0xff, ax_base + EN0_ISR);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+E8390_CMD);
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR); /* xmit on. */
++
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR); /* rx on, */
++ do_set_multicast_list (dev); /* (re)load the mcast table */
++ }
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_trigger_send
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base+E8390_CMD);
++ writeb (length & 0xff, ax_base + EN0_TCNTLO);
++ writeb (length >> 8, ax_base + EN0_TCNTHI);
++ writeb (start_page, ax_base + EN0_TPSR);
++ writeb ((E8390_NODMA|E8390_TRANS|E8390_START), ax_base+E8390_CMD);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_add_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_add_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ writeb ((u8)vid, ax_base+EN0_VID0);
++ writeb ((vid >> 9) & 0xF, ax_base+EN0_VID1);
++
++ /* Enable AX88796B Vlan filtering */
++ writeb (readb(ax_base+EN0_MCR) | ENVLAN_ENABLE, ax_base+EN0_MCR);
++
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_vlan_rx_kill_vid
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void
++ax_vlan_rx_kill_vid (struct net_device *dev, u16 vid)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ /* Disable AX88796B Vlan filtering */
++ writeb (readb (ax_base+EN0_MCR) & ~ENVLAN_ENABLE, ax_base+EN0_MCR);
++}
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_watchdog
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_watchdog (unsigned long arg)
++{
++ struct net_device *dev = (struct net_device *)(arg);
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u8 status;
++ u16 bmcr, advertise;
++
++ status = readb (ax_base + EN0_SR);
++
++ if (ax_local->media_curr != status) {
++
++ ax_local->media_curr = status;
++
++ if ((status & ENSR_LINK))
++ {
++ if (status & ENSR_SPEED_100) {
++ PRINTK (DRIVER_MSG, "%s Link mode : 100 Mb/s ", dev->name);
++ } else {
++ PRINTK (DRIVER_MSG, "%s Link mode : 10 Mb/s ", dev->name);
++ }
++
++ if (status & ENSR_DUPLEX_DULL) {
++ PRINTK (DRIVER_MSG, "Full Duplex.\n");
++ } else {
++ PRINTK (DRIVER_MSG, "Half Duplex.\n");
++ }
++
++ mdelay (200);
++ netif_carrier_on (dev);
++ netif_wake_queue (dev);
++ } else {
++ netif_stop_queue (dev);
++ netif_carrier_off (dev);
++ PRINTK (DRIVER_MSG, "%s Link down.\n", dev->name);
++ }
++ }
++
++ if (!(status & ENSR_LINK)) {
++
++ bmcr = mdio_read (dev, 0x10, MII_BMCR);
++ advertise = mdio_read (dev, 0x10, MII_ADVERTISE);
++
++ /* Power down PHY */
++ mdio_write (dev, 0x10, MII_BMCR, BMCR_PDOWN);
++ mdelay (1);
++ /* Power up PHY */
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ mdelay (60);
++ mdio_write (dev, 0x10, MII_ADVERTISE, advertise);
++ mdio_write (dev, 0x10, MII_BMCR, bmcr);
++ }
++
++ mod_timer (&ax_local->watchdog, jiffies + AX88796_WATCHDOG_PERIOD);
++ return ;
++}
++
++
++/*
++ * ======================================================================
++ * MII interface support
++ * ======================================================================
++ */
++#define MDIO_SHIFT_CLK 0x01
++#define MDIO_DATA_WRITE0 0x00
++#define MDIO_DATA_WRITE1 0x08
++#define MDIO_DATA_READ 0x04
++#define MDIO_MASK 0x0f
++#define MDIO_ENB_IN 0x02
++
++static void mdio_sync (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ int bits;
++ for (bits = 0; bits < 32; bits++) {
++ writeb (MDIO_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static void mdio_clear (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ int bits;
++ for (bits = 0; bits < 16; bits++) {
++ writeb (MDIO_DATA_WRITE0, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE0 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static int mdio_read (struct net_device *dev, int phy_id, int loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0xf6<<10)|(phy_id<<5)|loc;
++ int i, retval = 0;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 14; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 19; i > 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ retval = (retval << 1) | ((readb (ax_base + AX88796_MII_EEPROM) & MDIO_DATA_READ) != 0);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ return (retval>>1) & 0xffff;
++}
++
++static void mdio_write (struct net_device *dev, int phy_id, int loc, int value)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
++ int i;
++
++ mdio_clear (dev);
++ mdio_sync (dev);
++ for (i = 31; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 1; i >= 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++
++#if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1)
++/*
++ * ======================================================================
++ * EEPROM interface support
++ * ======================================================================
++ */
++#define EEPROM_SHIFT_CLK (0x80)
++#define EEPROM_DATA_READ1 (0x40)
++#define EEPROM_DATA_WRITE0 (0x00)
++#define EEPROM_DATA_WRITE1 (0x20)
++#define EEPROM_SELECT (0x10)
++#define EEPROM_DIR_IN (0x02)
++
++#define EEPROM_READ (0x02)
++#define EEPROM_EWEN (0x00)
++#define EEPROM_ERASE (0x03)
++#define EEPROM_WRITE (0x01)
++#define EEPROM_ERALL (0x00)
++#define EEPROM_WRAL (0x00)
++#define EEPROM_EWDS (0x00)
++#define EEPROM_93C46_OPCODE(x) ((x) << 6)
++#define EEPROM_93C46_STARTBIT (1 << 8)
++
++static void
++eeprom_write_en (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE(EEPROM_EWEN) | 0x30;
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static void
++eeprom_write_dis (struct net_device *dev)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_EWDS);
++ unsigned char tmp;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DATA_WRITE0 | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++}
++
++static int
++eeprom_write (struct net_device *dev, unsigned char loc, unsigned short nValue)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_WRITE) | loc;
++ unsigned char tmp;
++ int i;
++ int ret = 0;
++
++ // issue a "SB OP Addr" command
++ for(i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // writing the data
++ for (i = 15; i >= 0; i--) {
++ tmp = (nValue & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ //
++ // check busy
++ //
++
++ // Turn, wait two clocks
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SHIFT_CLK | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++
++ // waiting for busy signal
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if ((tmp & EEPROM_DATA_READ1) == 0)
++ break;
++ }
++ if (i <= 0) {
++ printk ("Failed on waiting for bus busy\n\r");
++ ret = -1;
++ } else {
++ i = 0xFFFF;
++ while (--i) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ break;
++ }
++
++ if (i <= 0) {
++ printk ("Failed on waiting for write completion\n\r");
++ ret = -1;
++ }
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return ret;
++}
++
++static unsigned short
++eeprom_read (struct net_device *dev, unsigned char loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ unsigned short cmd = EEPROM_93C46_STARTBIT | EEPROM_93C46_OPCODE (EEPROM_READ) | loc;
++ unsigned char tmp;
++ unsigned short retValue = 0;
++ int i;
++
++ // issue a "SB OP Addr" command
++ for (i = 8; i >= 0 ; i--) {
++ tmp = (cmd & (1 << i)) == 0 ? EEPROM_DATA_WRITE0 : EEPROM_DATA_WRITE1;
++ writeb (tmp | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (tmp | EEPROM_SELECT | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ // Turn
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT, ax_base + AX88796_MII_EEPROM);
++ writeb (EEPROM_DIR_IN | EEPROM_SELECT | EEPROM_SHIFT_CLK | EEPROM_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++
++ // retriving the data
++ for (i = 15; i >= 0; i--) {
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN, ax_base + AX88796_MII_EEPROM);
++ tmp = readb (ax_base + AX88796_MII_EEPROM);
++ if (tmp & EEPROM_DATA_READ1)
++ retValue |= (1 << i);
++ writeb (EEPROM_SELECT | EEPROM_DIR_IN | EEPROM_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++
++ writeb (0, ax_base + AX88796_MII_EEPROM);
++
++ return retValue;
++}
++#endif /* #if (CONFIG_AX88796B_EEPROM_READ_WRITE == 1) */
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_org.h linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_org.h
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/ax88796b_org.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/ax88796b_org.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,283 @@
++/* Generic AX88796B register definitions. */
++/* This file is part of AX88796B drivers, and is distributed
++ under the same license.*/
++
++#ifndef _ax88796_h
++#define _ax88796_h
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/version.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/crc32.h>
++#include <linux/mii.h>
++#include <linux/if_vlan.h>
++
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++# ifdef CONFIG_BOARD_S3C2440_SMDK
++# include <asm/irq.h>
++# include <asm/arch/S3C2440.h>
++# endif
++#else
++# ifdef CONFIG_ARCH_S3C2410
++# include <asm/arch/regs-mem.h>
++# include <asm/arch/regs-irq.h>
++# endif
++#endif
++
++#define TX_PAGES 12
++#define Tx_page_size 256
++
++#define NE_IO_EXTENT 0xFFF
++
++#define NESM_START_PG 0x40 /* First page of TX buffer */
++#define NESM_RX_START_PG (NESM_START_PG + TX_PAGES) /* First page of RX buffer */
++
++#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
++
++#define ETHER_ADDR_LEN 6
++
++#define AX88796B_BASE 0x08000000
++
++/* The 796b specific per-packet-header format. */
++struct ax_pkt_hdr {
++ unsigned char status; /* status */
++ unsigned char next; /* pointer to next packet. */
++ unsigned short count; /* header + packet length in bytes */
++};
++
++/* Most of these entries should be in 'struct net_device' (or most of the
++ things in there should be here!) */
++/* You have one of these per-board */
++struct ax_device {
++ const char *name;
++ void *membase;
++ unsigned char bus_width;
++ unsigned char mcfilter[8];
++ unsigned char media;
++ unsigned char media_curr;
++ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;
++ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;
++ unsigned char current_page; /* Read pointer in buffer */
++ spinlock_t page_lock; /* Page register locks */
++ struct timer_list watchdog;
++ struct net_device_stats stat; /* The new statistics table. */
++ unsigned irqlock:1;
++ unsigned dmaing:1;
++};
++
++#define AX88796_WATCHDOG_PERIOD (3*HZ)
++
++//#define ei_status (*(struct ei_device *)(dev->priv))
++
++/* Some generic ethernet register configurations. */
++
++#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
++#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
++#define E8390_TXCONFIG 0x80 /* EN0_TXCR: Normal transmit mode */
++#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
++
++/* Register accessed at EN_CMD, the 8390 base addr. */
++#define E8390_STOP 0x01 /* Stop and reset the chip */
++#define E8390_START 0x02 /* Start the chip, clear reset */
++#define E8390_TRANS 0x04 /* Transmit a frame */
++#define E8390_RREAD 0x08 /* Remote read */
++#define E8390_RWRITE 0x10 /* Remote write */
++#define E8390_NODMA 0x20 /* Remote DMA */
++#define E8390_PAGE0 0x00 /* Select page chip registers */
++#define E8390_PAGE1 0x40 /* using the two high-order bits */
++#define E8390_PAGE2 0x80 /* Page 2 is invalid. */
++#define E8390_PAGE3 0xc0 /* Page 3 for AX88796B */
++
++#define EI_SHIFT(x) ((x) << 1)
++
++#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
++/* Page 0 register offsets. */
++#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
++#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
++#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
++#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
++#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
++#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
++#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */
++#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */
++#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */
++#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */
++#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */
++#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */
++#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */
++#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */
++#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */
++#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */
++#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */
++#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */
++#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */
++#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */
++#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */
++#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */
++#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */
++#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */
++#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */
++#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */
++#define EN0_DATAPORT EI_SHIFT(0x10)
++#define EN0_PHYID EI_SHIFT(0x10)
++#define AX88796_MII_EEPROM EI_SHIFT(0x14)
++#define EN0_BTCR EI_SHIFT(0x15) /* Buffer Type Configure Register */
++#define EN0_SR EI_SHIFT(0X17) /* AX88796B Status Register */
++#define EN0_FLOW EI_SHIFT(0x1a) /* AX88796B Flow control register */
++#define EN0_MCR EI_SHIFT(0X1b) /* Mac configure register */
++#define EN0_CTEPR EI_SHIFT(0x1c) /* Current TX End Page */
++#define EN0_VID0 EI_SHIFT(0x1c) /* VLAN ID 0 */
++#define EN0_VID1 EI_SHIFT(0x1d) /* VLAN ID 1 */
++#define EN0_RESET EI_SHIFT(0X1f) /* Issue a read to reset, a write to clear. */
++
++#define EN0_DATA_ADDR 0x0800
++
++#define ENVLAN_ENABLE 0x08
++
++/* Bits in EN0_ISR - Interrupt status register */
++#define ENISR_RX 0x01 /* Receiver, no error */
++#define ENISR_TX 0x02 /* Transmitter, no error */
++#define ENISR_RX_ERR 0x04 /* Receiver, with error */
++#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
++#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
++#define ENISR_COUNTERS 0x20 /* Counters need emptying */
++#define ENISR_RDC 0x40 /* remote dma complete */
++#define ENISR_RESET 0x80 /* Reset completed */
++#define ENISR_ALL (ENISR_RX | ENISR_TX | ENISR_RX_ERR | ENISR_TX_ERR | ENISR_OVER | ENISR_COUNTERS)/* Interrupts we will enable */
++
++
++/* Bits in EN0_DCFG - Data config register */
++#define ENDCFG_WTS 0x01 /* word transfer mode selection */
++#define ENDCFG_BOS 0x02 /* byte order selection */
++
++#define ENFLOW_ENABLE 0xc7 /* Flow Control Control Register */
++#define ENTQC_ENABLE 0x20 /* Enable TXQ */
++
++#define EN3_TBR EI_SHIFT(0x0d) /* Transmit Buffer Ring Control Register */
++#define ENTBR_ENABLE 0x01 /* Enable Transmit Buffer Ring */
++
++/* Page 1 register offsets. */
++#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */
++#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */
++#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */
++#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */
++#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */
++
++/* Bits in received packet status byte and EN0_RSR*/
++#define ENRSR_RXOK 0x01 /* Received a good packet */
++#define ENRSR_CRC 0x02 /* CRC error */
++#define ENRSR_FAE 0x04 /* frame alignment error */
++#define ENRSR_FO 0x08 /* FIFO overrun */
++#define ENRSR_MPA 0x10 /* missed pkt */
++#define ENRSR_PHY 0x20 /* physical/multicast address */
++#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
++#define ENRSR_DEF 0x80 /* deferring */
++
++/* Transmitted packet status, EN0_TSR. */
++#define ENTSR_PTX 0x01 /* Packet transmitted without error */
++#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
++#define ENTSR_COL 0x04 /* The transmit collided at least once. */
++#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
++#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
++#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
++#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
++#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
++
++/* Bits in buffer type configure register */
++#define ENBTCR_PME_INT_EN 0x40 /* PME interrupt enable */
++#define ENBTCR_INT_ACT_HIGH 0x10
++
++/* Bits in device status register, EN0_SR */
++#define ENSR_DMA_DONE 0x40 /* Remote DMA completed */
++#define ENSR_DMA_READY 0x20 /* Remote DMA ready */
++#define ENSR_DEV_READY 0x10 /* Device ready */
++#define ENSR_SPEED_100 0x04 /* PHY link at 100 Mb/s */
++#define ENSR_DUPLEX_DULL 0x02 /* PHY link at full duplex */
++#define ENSR_LINK 0x01 /* PHY link up */
++
++/* Power Management register offsets. */
++#define EN3_BM0 EI_SHIFT(0x01)
++#define EN3_BM1 EI_SHIFT(0x02)
++#define EN3_BM2 EI_SHIFT(0x03)
++#define EN3_BM3 EI_SH2IFT(0x04)
++#define EN3_BM10CRC EI_SHIFT(0x05)
++#define EN3_BM32CRC EI_SHIFT(0x06)
++#define EN3_BMOFST EI_SHIFT(0x07)
++#define EN3_LSTBYT EI_SHIFT(0x08)
++#define EN3_BMCD EI_SHIFT(0x09)
++#define EN3_WUCS EI_SHIFT(0x0a)
++#define EN3_PMR EI_SHIFT(0x0b)
++
++/* Bits in Wake up Control */
++#define ENWUCS_MPEN 0x01
++#define ENWUCS_WUEN 0x02
++#define ENWUCS_LINK 0x04
++
++/* Bits in PM Control */
++#define ENPMR_D1 0x01
++#define ENPMR_D2 0x02
++
++/* SMDK2440 Registers Definition */
++/* SMDK2440 default clocks: FCLK=400MHZ, HCLK=125MHZ, PCLK=62.5MHZ */
++#define CLKDIVN_125MHZ 0x0000000F /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define CAMDIVN_125MHZ 0x00000000 /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define UBRDIV0_125MHZ 0x00000023 /* Set UART Baud Rate divisor for 125MHZ HCLK */
++
++#define CLKDIVN_100MHZ 0x0000000D /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define CAMDIVN_100MHZ 0x00000000 /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define UBRDIV0_100MHZ 0x0000001B /* Set UART Baud Rate divisor for 100MHZ HCLK */
++
++#define CLKDIVN_50MHZ 0x0000000D /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define CAMDIVN_50MHZ 0x00000200 /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define UBRDIV0_50MHZ 0x0000000D /* Set UART Baud Rate divisor for 50MHZ HCLK */
++
++#define DEFAULT_100MHZ_BANKCON1 0x00000400
++#define DEFAULT_125MHZ_BANKCON1 0x00000510
++#define BURST_BANKCON1 0x0000040f
++
++/* EINTMASK Register Bit Definition */
++#define EINT11_MASK 0x00000800 /* Clear this bit to enable EINT11 interrupt */
++
++/* EXTINT1 Register Bit Definition */
++#define FLTEN11_HIGHLEVEL 0x00009000
++#define FLTEN11_LOWLEVEL 0x00008000 /* Enable EINT11 signal with noise filter */
++/* End of SMDK2440 Registers Definition */
++
++
++#define MEDIA_AUTO 0
++#define MEDIA_100FULL 1
++#define MEDIA_100HALF 2
++#define MEDIA_10FULL 3
++#define MEDIA_10HALF 4
++
++/* Debug Message Display Level Definition */
++#define DRIVER_MSG 0x0001
++#define INIT_MSG 0x0002
++#define TX_MSG 0x0004
++#define RX_MSG 0x0008
++#define INT_MSG 0x0010
++#define ERROR_MSG 0x0020
++#define WARNING_MSG 0x0040
++#define DEBUG_MSG 0x0080
++#define OTHERS_MSG 0x0100
++#define ALL_MSG 0x01FF
++#define NO_MSG 0x0000
++#define DEFAULT_MSG (DRIVER_MSG | ERROR_MSG)
++#define DEBUG_FLAGS DEFAULT_MSG
++
++#endif /* _8390_h */
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/Makefile linux-2.6.25/drivers/net/regulus_ax88796b/Makefile
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/Makefile 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,28 @@
++# <path-to-your-target-Linux2.6.x-kernel>
++#KDIR = /root/project/sirius/asix_drivers/asix_linux-2.6.15.2
++#KDIR = /home/tharma/project/regulus/regulus_linux-2.6.25
++#KDIR = /home/tharma/project/deneb/kernel/deneb_linux-2.6.15.2
++# <specify-your-CrossCompiler-for-kernel-version-2.4.x>
++CROSS_COMPILE=/usr/local/arm/3.4.1/bin/arm-linux-
++PWD = $(shell pwd)
++#CONFIG_AS88796B = m
++
++#CONFIG_AX88796B=m
++
++obj-$(CONFIG_REGULUS_AX88796B) += regulus_ax88796b.o
++regulus_ax88796b-objs := ax88796b.o
++
++#all:
++# make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=/usr/local/arm/3.4.1/bin/arm-linux- modules
++#clean:
++# make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=/usr/local/arm/3.4.1/bin/arm-linux- clean
++# rm -rf .*.swp tags *.out
++
++#default:
++# make -C $(KDIR) SUBDIRS=$(PWD) modules
++
++#clean:
++# -rm -f *.o *.ko .*.cmd .*.flags *.mod.c
++
++#-include $(KDIR)/Rules.make
++
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/Makefile_org linux-2.6.25/drivers/net/regulus_ax88796b/Makefile_org
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/Makefile_org 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/Makefile_org 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,51 @@
++TARGET = ax88796b
++OBJS = ax88796b.o
++
++EXTRA_CFLAGS = -DEXPORT_SYMTAB
++
++# <path-to-your-target-Linux2.6.x-kernel>
++#KDIR = /mnt/asix/work/linux-2.6.17.11
++
++# <path-to-your-target-Linux2.4.x-kernel>
++KDIR = /work/2440/s3c2440_kernel2.4.20_cee31_rel1.0/include
++
++ifneq (,$(findstring 2.4.,$(KDIR)))
++# <specify-your-CrossCompiler-for-kernel-version-2.4.x>
++CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux-
++HOSTCC = gcc
++CC = $(CROSS_COMPILE)gcc
++
++CCFLAGS = -DMODULE
++CCFLAGS += -D__KERNEL__
++CCFLAGS += -I$(KDIR)
++CCFLAGS += -Wall
++CCFLAGS += -Wstrict-prototypes
++CCFLAGS += -Os
++CCFLAGS += -g
++CCFLAGS += -D__LINUX_ARM_ARCH__=4
++CCFLAGS += -march=armv4
++CCFLAGS += -mtune=arm9tdmi
++CCFLAGS += -DKBUILD_BASENAME=ax88796b
++else
++
++PWD = $(shell pwd)
++
++endif
++
++obj-m := $(TARGET).o
++
++ifneq (,$(findstring 2.4.,$(KDIR)))
++default:
++ @echo "Making $<"
++ $(CC) $(CCFLAGS) -c $< $(TARGET).c
++else
++default:
++ make -C $(KDIR) SUBDIRS=$(PWD) modules
++$(TARGET).o: $(OBJS)
++ $(LD) $(LD_RFLAG) -r -o $@ $(OBJS)
++endif
++
++clean:
++ -rm -f *.o *.ko .*.cmd .*.flags *.mod.c
++
++-include $(KDIR)/Rules.make
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/pxa270_dma_mode_for_asix.c linux-2.6.25/drivers/net/regulus_ax88796b/pxa270_dma_mode_for_asix.c
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/pxa270_dma_mode_for_asix.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/pxa270_dma_mode_for_asix.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1050 @@
++#define DCSR_ENRINTR (1 << 9) /* The end of Receive */
++
++#include <asm-arm/arch-pxa/dma.h>
++#include <asm-arm/page.h>
++#include <linux/device.h>
++#include <asm/dma.h>
++
++
++/******************vvvvvvv Added by e-con for DMA mode operation vvvvvvv********************************/
++
++#define DALGN __REG(0x400000a0) /* DMA Alignment Register */
++#define USE_STANDARD_LINUX_DMA_API 0
++#define DMA_MODE_OPERATION 1
++#define WAIT_TO_PXADMA_COMPLETE 0
++#define HARD_CODE_DMA_CHANNEL 0
++#define DMA_ADDRESS_USER_ALIGNMENT 0
++#define DMA_8BYTE 8
++#define DMA_8BYTE_ALIGNMENT_MASK (DMA_8BYTE-1)
++#define DMA_TEST_BYTE_COUNT 16
++typedef long TIME_SPAN;
++#define MAX_TIME_SPAN ((TIME_SPAN)(0x7FFFFFFFUL))
++typedef unsigned long DWORD;
++typedef unsigned short WORD;
++typedef unsigned char BYTE;
++typedef unsigned char BOOLEAN;
++#define TRUE ((BOOLEAN)1)
++#define FALSE ((BOOLEAN)0)
++#define PLATFORM_RX_DMA (3)
++#define PLATFORM_TX_DMA (4)
++#define PLATFORM_DMA_THRESHOLD 100 // Minimum value should be 100 bytes
++#define dma_free_writecombine(dev,size,cpu_addr,handle) dma_free_coherent(dev,size,cpu_addr,handle)
++
++// cache organization parameters
++#define CACHE_SIZE_KB 32UL
++#define CACHE_WAYS 32UL
++#define CACHE_LINE_BYTES 32UL
++#define CACHE_ALIGN_MASK (~(CACHE_LINE_BYTES - 1UL))
++#define CACHE_BYTES_PER_WAY ((CACHE_SIZE_KB * 1024UL) / CACHE_WAYS)
++
++#define PLATFORM_CACHE_LINE_BYTES (CACHE_LINE_BYTES)
++//#define USE_WARNING
++
++
++typedef struct _PLATFORM_DATA {
++ DWORD dwIdRev;
++ DWORD dwIrq;
++ void *dev_id;
++} PLATFORM_DATA, *PPLATFORM_DATA;
++
++
++typedef struct _DMA_XFER
++{
++ DWORD dwLanReg;
++ DWORD *pdwBuf;
++ DWORD dwDmaCh;
++ DWORD dwDwCnt;
++ BOOLEAN fMemWr;
++} DMA_XFER;
++
++typedef struct _FLOW_CONTROL_PARAMETERS
++{
++ DWORD MaxThroughput;
++ DWORD MaxPacketCount;
++ DWORD PacketCost;
++ DWORD BurstPeriod;
++ DWORD IntDeas;
++} FLOW_CONTROL_PARAMETERS, *PFLOW_CONTROL_PARAMETERS;
++
++
++DWORD CS4_VIRT_BASE = 0;
++
++DWORD Platform_DmaGetDwCnt( PPLATFORM_DATA platformData, const DWORD dwDmaCh);
++void Platform_DmaComplete(PPLATFORM_DATA platformData, const DWORD dwDmaCh);
++BOOLEAN Platform_DmaStartXfer(PPLATFORM_DATA platformData, const DMA_XFER * const pDmaXfer);
++static inline void DrainWriteBuffers(void);
++static inline void CleanCacheLine(DWORD addr);
++void Platform_CacheInvalidate(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes);
++void Platform_CachePurge(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes);
++void PurgeCache(const void * const pStartAddress, const DWORD dwLengthInBytes);
++BOOLEAN Platform_DmaDisable(PPLATFORM_DATA platformData, const DWORD dwDmaCh);
++DWORD CpuToPhysicalAddr(const void * const pvCpuAddr);
++void rx_dma_initialize(void);
++void tx_dma_initialize(void);
++void rx_dma_uninitialize(void);
++void tx_dma_uninitialize(void);
++int platform_dma_initialize(int dma_channel_number);
++int platform_dma_disable(int dma_ch);
++int pxa_request_dma (char *name, pxa_dma_prio prio,void (*irq_handler)(int, void *),void *data);
++int rx_dma_channel=0,tx_dma_channel=0;
++
++static void asix_dma_tx_irq(int chan, void *dev_id,struct pt_regs *regs)
++{
++
++ unsigned int dcsr_data=0;
++
++ dcsr_data = DCSR(tx_dma_channel);
++
++
++ //did we get an error Interrupt?
++ if (dcsr_data & DCSR_BUSERR)
++ {
++ dcsr_data |= DCSR_BUSERR;
++ }
++
++ //did we get an end interrupt?
++ if (dcsr_data & DCSR_ENDINTR) //if the channel stopped at the end of a buffer xfer
++ {
++ dcsr_data |= DCSR_ENDINTR;
++ }
++
++ //did we get an stop interrupt?
++ if (dcsr_data & DCSR_STOPSTATE)
++ {
++ dcsr_data &= (~DCSR_STOPIRQEN);
++ }
++
++ //did we get an end of receive interrupt?
++ if (dcsr_data & DCSR_ENRINTR)
++ {
++ dcsr_data &= (~DCSR_ENRINTR);
++ }
++
++ // Clear the Status
++ DCSR(tx_dma_channel) = dcsr_data;
++
++ return;
++
++}
++
++
++static void asix_dma_rx_irq(int chan, void *dev_id,struct pt_regs *regs)
++{
++
++ unsigned int dcsr_data=0;
++
++ dcsr_data = DCSR(rx_dma_channel);
++
++
++ //did we get an error Interrupt?
++ if (dcsr_data & DCSR_BUSERR)
++ {
++ dcsr_data |= DCSR_BUSERR;
++ }
++
++ //did we get an end interrupt?
++ if (dcsr_data & DCSR_ENDINTR) //if the channel stopped at the end of a buffer xfer
++ {
++ dcsr_data |= DCSR_ENDINTR;
++ }
++
++ //did we get an stop interrupt?
++ if (dcsr_data & DCSR_STOPSTATE)
++ {
++ dcsr_data &= (~DCSR_STOPIRQEN);
++ }
++
++ //did we get an end of receive interrupt?
++ if (dcsr_data & DCSR_ENRINTR)
++ {
++ dcsr_data &= (~DCSR_ENRINTR);
++ }
++
++ // Clear the Status
++ DCSR(rx_dma_channel) = dcsr_data;
++
++ return;
++
++}
++
++
++
++
++void rx_dma_initialize(void)
++{
++#define ASIX_DUMMY_ID 0xABCD
++#if HARD_CODE_DMA_CHANNEL
++ rx_dma_channel = PLATFORM_RX_DMA;
++#else
++
++ //Requesting the DMA Channel for RX
++ rx_dma_channel = pxa_request_dma((char *)"ASIX Ethernet RX",(pxa_dma_prio)DMA_PRIO_HIGH,(void *)asix_dma_rx_irq,(void *)ASIX_DUMMY_ID);
++#endif
++
++ if(rx_dma_channel < 0)
++ {
++ eprintk("Failed to allocate dma channel number\n");
++ return ;
++ }
++
++ platform_dma_initialize(rx_dma_channel);
++#if DMA_ADDRESS_USER_ALIGNMENT
++ DALGN |= GPIO_bit(rx_dma_channel);
++#else
++ DALGN &= ~(GPIO_bit(rx_dma_channel));
++#endif
++ return ;
++}
++
++void tx_dma_initialize(void)
++{
++#if HARD_CODE_DMA_CHANNEL
++ tx_dma_channel = PLATFORM_TX_DMA;
++#else
++ //Requesting the DMA Channel for TX
++ tx_dma_channel = pxa_request_dma((char *)"ASIX Ethernet TX",(pxa_dma_prio) DMA_PRIO_LOW,(void *)asix_dma_tx_irq,(void *)ASIX_DUMMY_ID);
++#endif
++
++ if(tx_dma_channel < 0)
++ {
++ eprintk("Failed to allocate dma channel number\n");
++ return ;
++ }
++
++ platform_dma_initialize(tx_dma_channel);
++#if DMA_ADDRESS_USER_ALIGNMENT
++ DALGN |= GPIO_bit(tx_dma_channel);
++#else
++ DALGN &= ~(GPIO_bit(tx_dma_channel));
++#endif
++ return ;
++}
++
++
++void rx_dma_uninitialize(void)
++{
++ platform_dma_disable(rx_dma_channel);
++#if HARD_CODE_DMA_CHANNEL
++#else
++ //Freeing the DMA Channel for RX
++ pxa_free_dma(rx_dma_channel);
++#endif
++ return ;
++}
++
++void tx_dma_uninitialize(void)
++{
++ platform_dma_disable(tx_dma_channel);
++#if HARD_CODE_DMA_CHANNEL
++#else
++ //Freeing the DMA Channel for TX
++ pxa_free_dma(tx_dma_channel);
++#endif
++ return ;
++}
++
++
++int platform_dma_initialize(int dma_channel_number)
++{
++ if(dma_channel_number<256)
++ {
++ if(!platform_dma_disable(dma_channel_number))
++ {
++ return FALSE;
++ }
++ }
++ return TRUE;
++}
++
++int platform_dma_disable(int dma_ch)
++{
++ DCSR(dma_ch) &= ~DCSR_RUN;
++ while (!(DCSR(dma_ch) & DCSR_STOPSTATE)) {};
++
++ return TRUE;
++
++}
++
++
++BOOLEAN Platform_DmaStartXfer(PPLATFORM_DATA platformData, const DMA_XFER * const pDmaXfer)
++{
++
++ DWORD dwDmaCmd;
++ DWORD dwLanPhysAddr, dwMemPhysAddr;
++ DWORD dwAlignMask;
++
++ platformData=platformData;//make lint happy
++
++ //Check if the channel is currently running
++ if (!(DCSR(pDmaXfer->dwDmaCh) & DCSR_STOPSTATE))
++ {
++ if (DCSR(pDmaXfer->dwDmaCh) & DCSR_RUN)
++ {
++ ASIX_TRACE("DmaStartXfer -- requested channel (%ld) is still running", pDmaXfer->dwDmaCh);
++ return FALSE;
++ }
++ else
++ {
++ // DMA is not running yet.
++ // Keep going..
++ ASIX_WARNING("DmaStartXfer -- requested channel (%ld) is weird status", pDmaXfer->dwDmaCh);
++ }
++ }
++
++ // calculate the physical transfer addresses
++ //ASIX_TRACE(" calculate the physical transfer addresses \n");
++ dwLanPhysAddr = CpuToPhysicalAddr((void *)pDmaXfer->dwLanReg);
++ dwMemPhysAddr = CpuToPhysicalAddr((void *)pDmaXfer->pdwBuf);
++
++ ASIX_TRACE("pDmaXfer->dwLanReg is 0x%08X . dwLanPhysAddr is 0x%08X \n",(unsigned int)pDmaXfer->dwLanReg,(unsigned int)dwLanPhysAddr);
++ ASIX_TRACE("pDmaXfer->pdwBuf is 0x%08X . dwMemPhysAddr is 0x%08X \n",(unsigned int)pDmaXfer->pdwBuf,(unsigned int)dwMemPhysAddr);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++#if FIFO_SEL_IS_A11
++#warning "FIFO_SEL_IS_A11 is defined"
++ dwLanPhysAddr |= 0x800; //Modified by econ forFIFO_SEL is A11
++#elif FIFO_SEL_IS_A20
++#warning "FIFO_SEL_IS_A20 is defined"
++ dwLanPhysAddr |= 0x100000; //Modified by econ forFIFO_SEL is A20
++#endif
++#else
++ dwLanPhysAddr = PXA_CS4_PHYS + EN0_DATAPORT;
++#endif
++ // need CL alignment for CL bursts
++ dwAlignMask = (CACHE_LINE_BYTES - 1UL);
++
++ if ((dwLanPhysAddr & dwAlignMask) != 0UL)
++ {
++ ASIX_WARNING("DmaStartXfer -- bad dwLanPhysAddr (0x%08lX) alignment",
++ dwLanPhysAddr);
++ return FALSE;
++ }
++
++ if ((dwMemPhysAddr & 0x03UL) != 0UL)
++ {
++ ASIX_WARNING("DmaStartXfer -- bad dwMemPhysAddr (0x%08lX) alignment",
++ dwMemPhysAddr);
++ return FALSE;
++ }
++
++ //validate the transfer size, On XScale Max size is 8k-1
++ if (pDmaXfer->dwDwCnt >= 8192UL)
++ {
++ ASIX_WARNING("DmaStartXfer -- dwDwCnt =%ld is too big (1^20 bytes max on panax)", pDmaXfer->dwDwCnt);
++ return FALSE;
++ }
++
++ //Note: The DCSR should be cleared, before writing the Target and Source addresses
++ DCSR(pDmaXfer->dwDmaCh) = DCSR_NODESC; //get ready for the DMA
++
++ //Set the Source and Target addresses
++ dwDmaCmd = 0UL;
++ if (pDmaXfer->fMemWr)
++ {
++ //RX
++ DTADR(pDmaXfer->dwDmaCh) = dwMemPhysAddr;
++ DSADR(pDmaXfer->dwDmaCh) = dwLanPhysAddr;
++ dwDmaCmd |= DCMD_INCTRGADDR; //always increment the memory address
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ dwDmaCmd |= DCMD_INCSRCADDR;
++#else
++ dwDmaCmd &= ~(DCMD_INCSRCADDR);
++#endif
++ cprintk("FUNC %s() : LINE %d : DMA Transfer for Source: Ethernet Chip, Target: SDRAM Memory \n",__FUNCTION__,__LINE__);
++ cprintk("FUNC %s() : LINE %d : PXA DMA Source: 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)(DSADR(pDmaXfer->dwDmaCh)));
++ cprintk("FUNC %s() : LINE %d : PXA DMA Target: 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)(DTADR(pDmaXfer->dwDmaCh)));
++
++ }
++ else
++ {
++ //TX
++ DTADR(pDmaXfer->dwDmaCh) = dwLanPhysAddr;
++ DSADR(pDmaXfer->dwDmaCh) = dwMemPhysAddr;
++ dwDmaCmd |= DCMD_INCSRCADDR; //always increment the memory address
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ dwDmaCmd |= DCMD_INCTRGADDR;
++#else
++ dwDmaCmd &= ~(DCMD_INCTRGADDR);
++#endif
++ cprintk("FUNC %s() : LINE %d : DMA Transfer for Source: SDRAM Memory, Target: Ethernet Chip \n",__FUNCTION__,__LINE__);
++ cprintk("FUNC %s() : LINE %d : PXA DMA Source: 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)(DSADR(pDmaXfer->dwDmaCh)));
++ cprintk("FUNC %s() : LINE %d : PXA DMA Target: 0x%08X \n",__FUNCTION__,__LINE__,(unsigned int)(DTADR(pDmaXfer->dwDmaCh)));
++ }
++
++ //Set the burst size, if cache line burst set to 32Bytes else set to the smallest
++ dwDmaCmd |= DCMD_BURST32;
++
++
++ // Set the Width of the On-Chip Peripheral as 16 bit
++ dwDmaCmd |= DCMD_WIDTH2;
++
++ dwDmaCmd |= (DCMD_LENGTH & (pDmaXfer->dwDwCnt << 2));
++ DCMD(pDmaXfer->dwDmaCh) = dwDmaCmd ;
++ if (pDmaXfer->fMemWr==0)
++ {
++ cprintk("FUNC %s() : LINE %d : PXA DMA Trasnfer byte length: %d \n",__FUNCTION__,__LINE__,(unsigned int)((DCMD(pDmaXfer->dwDmaCh))&DCMD_LENGTH));
++ }
++ else
++ {
++ cprintk("FUNC %s() : LINE %d : PXA DMA Trasnfer byte length: %d \n",__FUNCTION__,__LINE__,(unsigned int)((DCMD(pDmaXfer->dwDmaCh))&DCMD_LENGTH));
++ }
++ DCSR(pDmaXfer->dwDmaCh) |= DCSR_ENRINTR;
++ DCSR(pDmaXfer->dwDmaCh) |= DCSR_RUN;
++
++ return TRUE;
++}
++
++DWORD Platform_DmaGetDwCnt( PPLATFORM_DATA platformData, const DWORD dwDmaCh)
++{
++ platformData=platformData;//make lint happy
++ return (((DCMD_LENGTH & DCMD(dwDmaCh)) >> 2));
++}
++
++void Platform_DmaComplete(PPLATFORM_DATA platformData, const DWORD dwDmaCh)
++{
++ DWORD dwTimeOut=1000000;
++
++ platformData=platformData;//make lint happy
++
++ while((Platform_DmaGetDwCnt(platformData,dwDmaCh))&&(dwTimeOut))
++ {
++ udelay(1);
++ dwTimeOut--;
++ }
++
++ cprintk("FUNC %s() : LINE %d : Channel Number is %d \n",__FUNCTION__,__LINE__,(int)dwDmaCh);
++ cprintk("FUNC %s() : LINE %d : DCSR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCSR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DALGN is 0x%08X \n",__FUNCTION__,__LINE__,DALGN);
++ cprintk("FUNC %s() : LINE %d : DINT is 0x%08X \n",__FUNCTION__,__LINE__,DINT);
++ cprintk("FUNC %s() : LINE %d : DDADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DDADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DSADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DSADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DTADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DTADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DCMD%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCMD(dwDmaCh));
++ if(!Platform_DmaDisable(platformData,dwDmaCh)) {
++ ASIX_WARNING("Failed Platform_DmaDisable");
++ }
++ if(dwTimeOut==0) {
++ ASIX_WARNING("Platform_DmaComplete: Timed out");
++ }
++ else
++ {
++ ASIX_WARNING("Platform_DmaComplete: Successfully Done");
++ }
++}
++
++
++DWORD CpuToPhysicalAddr(const void * const pvCpuAddr)
++{
++ const DWORD dwVirtAddr = (DWORD) pvCpuAddr;
++ if ((dwVirtAddr >= CS4_VIRT_BASE) && (dwVirtAddr <= (CS4_VIRT_BASE+NE_IO_EXTENT)))
++ {
++ //Chip Select 4 (nCS4) Memory Region
++ return ((dwVirtAddr - CS4_VIRT_BASE) + PXA_CS4_PHYS);
++ }
++ if ((dwVirtAddr >= 0xC0000000UL) && (dwVirtAddr <= 0xC7FFFFFFUL))
++ {
++ // Linux SDRAM
++ return virt_to_bus(((void *)dwVirtAddr));
++ }
++
++ ASIX_WARNING("Wrong virtual address : 0x%08lx", dwVirtAddr);
++ return (0xFFFFFFFFUL); //invalid/unrecognized address
++}
++
++
++BOOLEAN Platform_DmaDisable(PPLATFORM_DATA platformData, const DWORD dwDmaCh)
++{
++ // To avoid Lint error
++ DWORD temp;
++ temp = dwDmaCh;
++ temp = temp;
++
++ platformData=platformData;//make lint happy
++
++ DCSR(dwDmaCh) &= ~DCSR_RUN;
++ while (!(DCSR(dwDmaCh) & DCSR_STOPSTATE)) {};
++
++ return TRUE;
++}
++
++
++void Platform_CacheInvalidate(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)
++{
++ platformData=platformData;//make lint happy
++ PurgeCache(pStartAddress, dwLengthInBytes);
++}
++
++void Platform_CachePurge(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)
++{
++ platformData=platformData;//make lint happy
++ PurgeCache(pStartAddress, dwLengthInBytes);
++}
++
++
++void PurgeCache(const void * const pStartAddress, const DWORD dwLengthInBytes)
++{
++ DWORD dwCurrAddr, dwEndAddr, dwLinesToGo;
++
++ dwCurrAddr = (DWORD)pStartAddress & CACHE_ALIGN_MASK;
++ dwEndAddr = (((DWORD)pStartAddress) + dwLengthInBytes + (CACHE_LINE_BYTES - 1UL)) & CACHE_ALIGN_MASK;
++
++ dwLinesToGo = (dwEndAddr - dwCurrAddr) / CACHE_LINE_BYTES;
++ while (dwLinesToGo)
++ {
++ CleanCacheLine(dwCurrAddr);
++ dwCurrAddr += CACHE_LINE_BYTES;
++ dwLinesToGo--;
++ }
++ DrainWriteBuffers();
++
++ return;
++}
++
++static inline void CleanCacheLine(DWORD addr)
++{
++ addr = addr; // let lint be happy :-)
++ __asm("mov r0, %0" : : "r" (addr): "r0");
++ __asm("mcr p15, 0, r0, c7, c10, 1");
++ __asm("mcr p15, 0, r0, c7, c6, 1");
++}
++
++static inline void DrainWriteBuffers(void)
++{
++ __asm("mcr p15, 0, r0, c7, c10, 4");
++}
++
++
++/* ################################################################################################### */
++
++
++#if (DMA_MODE_OPERATION==1)
++#warning "DMA_MODE_OPERATION is defined"
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_input
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
++{
++
++ DWORD dwDmaCh=rx_dma_channel;
++ DMA_XFER dmaXfer;
++ DWORD dwDwordCount =0;
++#if WAIT_TO_PXADMA_COMPLETE
++ DWORD dwTimeOut=1000000;
++#endif
++#if USE_STANDARD_LINUX_DMA_API
++ DWORD dwDmaCmd=0;
++#endif
++ unsigned int number_bytes_to_read_from_pio_port=0,number_of_bytes_transffered=0,remaining_bytes_to_be_transffered=0;
++ unsigned char isr_data=0;
++ unsigned long dma_start;
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)skb->data;
++ u16 i=count;
++ unsigned int current_dma_addr_start=0,current_dma_addr_end=0;
++#if USE_STANDARD_LINUX_DMA_API
++ u16 *local_buf=buf;
++ u8 *read_buffer = (u8 *)buf;
++ void *kernel_virt_buffer=NULL,*kernel_phys_buffer=NULL;
++#endif
++ unsigned int m=0;
++
++ cprintk("Entering into %s() **************************** \n'",__FUNCTION__);
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_input "
++ "[DMAstat:%d][irqlock:%d].\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++ ax_local->dmaing |= 0x01;
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (ring_offset & 0xff, ax_base + EN0_RSARLO);
++ writeb (ring_offset >> 8, ax_base + EN0_RSARHI);
++ current_dma_addr_start = readb(ax_base+EN0_CRDALO)|(readb(ax_base+EN0_CRDAHI)<<8);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++
++
++
++
++ number_bytes_to_read_from_pio_port = DMA_8BYTE - (((unsigned int)(buf)) & DMA_8BYTE_ALIGNMENT_MASK);
++
++ if(count<=PLATFORM_DMA_THRESHOLD)
++ {
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & (0xFFFF8);
++ #endif
++
++ /* Read first 2 bytes */
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ /* The address of ++buf should be agigned on 32-bit boundary */
++ memcpy (++buf, ax_base+EN0_DATA_ADDR, i);
++#else
++ for (i = 0; i < count; i += 2) {
++ *buf++ = READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++#endif
++
++ }
++ else
++ {
++
++#if USE_STANDARD_LINUX_DMA_API
++ //Allocate Kernel buffer and Descriptor Buffer for YUV Packed data
++ kernel_virt_buffer = (unsigned int *) dma_alloc_writecombine( NULL, i, (void *)&kernel_phys_buffer, GFP_KERNEL);
++ if(kernel_virt_buffer==NULL)
++ {
++ printk("Failed to allocate memory of 0x%08X size for kernel virtual buffer \n",i);
++ return;
++ }
++ else
++ {
++ }
++
++ //Note: The DCSR should be cleared, before writing the Target and Source addresses
++ DCSR(dwDmaCh) = DCSR_NODESC; //get ready for the DMA
++ DTADR(dwDmaCh) = kernel_phys_buffer;
++ DSADR(dwDmaCh) =PXA_CS4_PHYS | 0x100000;
++ dwDmaCmd |= DCMD_INCSRCADDR; //always increment the memory address
++ dwDmaCmd |= DCMD_INCTRGADDR;
++ //Set the burst size, if cache line burst set to 32Bytes else set to the smallest
++ dwDmaCmd |= DCMD_BURST32;
++
++
++ // Set the Width of the On-Chip Peripheral as 16 bit
++ dwDmaCmd |= DCMD_WIDTH2;
++
++ dwDmaCmd |= (DCMD_LENGTH & (i));
++ DCMD(dwDmaCh) = dwDmaCmd ;
++
++ DCSR(dwDmaCh) |= DCSR_ENRINTR;
++ DCSR(dwDmaCh) |= DCSR_RUN;
++
++ #if WAIT_TO_PXADMA_COMPLETE
++ //while waiting for dma to complete,
++ // check if another packet arrives
++ dwTimeOut=1000000;
++ while((Platform_DmaGetDwCnt(NULL,dwDmaCh))&&(dwTimeOut))
++ {
++ udelay(1);
++ dwTimeOut--;
++ }
++ if(dwTimeOut==0)
++ {
++ //printk("FUNC %s() : LINE %d : Timed out while waiting for final Dma to complete",__FUNCTION__,__LINE__);
++ }
++ else
++ {
++ //printk("FUNC %s(): LINE %d : DMA Operation Completed .dwTimeOut is %d \n",__FUNCTION__,__LINE__,(int)dwTimeOut );
++ Platform_DmaComplete(NULL,dwDmaCh);
++ }
++ #endif // end of WAIT_TO_PXADMA_COMPLETE
++ current_dma_addr_end = readb(ax_base+EN0_CRDALO)|(readb(ax_base+EN0_CRDAHI)<<8);
++ number_of_bytes_transffered = current_dma_addr_end-current_dma_addr_start;
++ remaining_bytes_to_be_transffered = (count-number_of_bytes_transffered);
++ memcpy(local_buf,kernel_virt_buffer,i);
++ dma_free_writecombine (NULL,i, kernel_virt_buffer,(int)kernel_phys_buffer);
++#else
++
++ number_bytes_to_read_from_pio_port = DMA_8BYTE - (((unsigned int)(buf)) & DMA_8BYTE_ALIGNMENT_MASK);
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++
++ /* make the burst length be divided for 64-bit */
++ i = ((count - number_bytes_to_read_from_pio_port) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - number_bytes_to_read_from_pio_port) + 7) & 0xFFFF8;
++ #endif
++
++ cprintk("FUNC %s() : LINE %d : number_bytes_to_read_from_pio_port is %d , buf is 0x%08X count is %d \n Bytes to be transferred in DMA mode is %d \n",__FUNCTION__,__LINE__,number_bytes_to_read_from_pio_port,(unsigned int)buf,count,i);
++
++ dmaXfer.dwLanReg=CS4_VIRT_BASE+EN0_DATA_ADDR;
++ dmaXfer.pdwBuf=NULL;// this will be reset per dma request
++ dmaXfer.dwDmaCh=dwDmaCh;
++ dmaXfer.dwDwCnt=0;// this will be reset per dma request
++ dmaXfer.fMemWr=TRUE;
++
++ for(m=0;m<number_bytes_to_read_from_pio_port;m += 2)
++ {
++ *(buf) = READ_FIFO (ax_base + EN0_DATAPORT);
++ buf++;
++ }
++
++ dwDwordCount = (i>>2);
++ Platform_CacheInvalidate(NULL,buf,dwDwordCount<<2);
++ cprintk("FUNC %s() : LINE %d : count is %d . i is %d .buf is 0x%08X \n",__FUNCTION__,__LINE__,count,i,(unsigned int)buf);
++ dmaXfer.pdwBuf=(DWORD *)(buf);
++
++
++ dmaXfer.dwDwCnt=dwDwordCount;
++ if(!Platform_DmaStartXfer(NULL,&dmaXfer))
++ {
++ ASIX_WARNING("Failed Platform_DmaStartXfer");
++ }
++
++ #if WAIT_TO_PXADMA_COMPLETE
++ //while waiting for dma to complete,
++ // check if another packet arrives
++ dwTimeOut=1000000;
++ while((Platform_DmaGetDwCnt(NULL,dwDmaCh))&&(dwTimeOut))
++ {
++ udelay(1);
++ dwTimeOut--;
++ }
++ if(dwTimeOut==0)
++ {
++ ASIX_WARNING("Timed out while waiting for final Dma to complete");
++ }
++ else
++ {
++ ASIX_TRACE("DMA Operation Completed .dwTimeOut is %d \n",(int)dwTimeOut );
++ Platform_DmaComplete(NULL,dwDmaCh);
++ }
++ #endif // end of WAIT_TO_PXADMA_COMPLETE
++ current_dma_addr_end = readb(ax_base+EN0_CRDALO)|(readb(ax_base+EN0_CRDAHI)<<8);
++ number_of_bytes_transffered = current_dma_addr_end-current_dma_addr_start;
++ remaining_bytes_to_be_transffered = (count-number_of_bytes_transffered);
++ cprintk("FUNC %s() : LINE %d : Number of remaining bytes to be transffered in RDMA Operation is %d \n",__FUNCTION__,__LINE__,remaining_bytes_to_be_transffered);
++
++#endif
++ cprintk("LINE %d: Actual Count value is %d. The Value written in the Remote Byte Count Reg is %d \n",__LINE__,count,(count&0xFFFF));
++ cprintk("FUNC %s() : LINE %d : Current Remote DMA address (start) is 0x%08X \n",__FUNCTION__,__LINE__,current_dma_addr_start);
++ cprintk("FUNC %s() : LINE %d : Current Remote DMA address (end) is 0x%08X \n",__FUNCTION__,__LINE__,current_dma_addr_end);
++ cprintk("FUNC %s() : LINE %d : Number of bytes transffered in RDMA Operation is %d \n",__FUNCTION__,__LINE__,number_of_bytes_transffered);
++ cprintk("FUNC %s() : LINE %d : Channel Number is %d \n",__FUNCTION__,__LINE__,(int)dwDmaCh);
++ cprintk("FUNC %s() : LINE %d : DCSR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCSR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DALGN is 0x%08X \n",__FUNCTION__,__LINE__,DALGN);
++ cprintk("FUNC %s() : LINE %d : DINT is 0x%08X \n",__FUNCTION__,__LINE__,DINT);
++ cprintk("FUNC %s() : LINE %d : DDADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DDADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DSADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DSADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DTADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DTADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DCMD%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCMD(dwDmaCh));
++
++ cprintk("FUNC %s() : LINE %d : Number of remaining bytes to be transffered in RDMA Operation is %d \n",__FUNCTION__,__LINE__,remaining_bytes_to_be_transffered);
++
++ }
++
++ dma_start = jiffies;
++ while(1)
++ {
++ isr_data = readb(ax_base + EN0_ISR);
++ if((isr_data&ENISR_RDC)==ENISR_RDC)
++ {
++ break;
++ }
++ else
++ {
++ if ((jiffies - dma_start) > (2*HZ/100))
++ { /* 20ms */
++ printk(" FUNC %s() : LINE %d : %s: timeout waiting for Tx RDC. ISR Value is 0x%02X \n",__FUNCTION__,__LINE__,dev->name,isr_data);
++ ax_reset (dev);
++ ax_init (dev,1);
++ break;
++ }
++ }
++ }
++
++ eprintk("FUNC %s() : LINE %d : Ack intr \n",__FUNCTION__,__LINE__);
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++
++
++ cprintk("<<<<<<<<<<<<<<<<<<<<<<Exiting from %s() \n'",__FUNCTION__);
++}
++
++
++
++/*
++ * ----------------------------------------------------------------------------
++ * Function Name: ax_block_output
++ * Purpose:
++ * Params:
++ * Returns:
++ * Note:
++ * ----------------------------------------------------------------------------
++ */
++static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)
++{
++
++ DWORD dwDmaCh=tx_dma_channel;
++ DMA_XFER dmaXfer;
++ DWORD dwDwordCount =0;
++ unsigned int number_bytes_to_write_to_pio_port=0;
++ unsigned long dma_start;
++ unsigned int current_dma_addr_start=0;
++ u16 m=0;
++
++ u32 i = count;
++
++
++
++#if USE_STANDARD_LINUX_DMA_API
++ DWORD dwTimeOut=1000000;
++ DWORD dwDmaCmd=0;
++ unsigned int current_dma_addr_end=0;
++ unsigned int number_of_bytes_transffered=0,remaining_bytes_to_be_transffered=0;
++ void *kernel_virt_buffer=NULL,*kernel_phys_buffer=NULL;
++ u16 *local_buf = (u16 *)buf;
++#endif
++
++ struct ax_device *ax_local = (struct ax_device *) dev->priv;
++ void *ax_base = ax_local->membase;
++
++ number_bytes_to_write_to_pio_port = DMA_8BYTE - (((unsigned int)(buf)) & DMA_8BYTE_ALIGNMENT_MASK);
++
++
++ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
++ if (ax_local->dmaing)
++ {
++ PRINTK (ERROR_MSG, "%s: DMAing conflict in ne_block_output."
++ "[DMAstat:%d][irqlock:%d]\n",
++ dev->name, ax_local->dmaing, ax_local->irqlock);
++ return;
++ }
++
++ ax_local->dmaing |= 0x01;
++
++
++
++
++ /* We should already be in page 0, but to be safe... */
++ writeb (E8390_PAGE0+E8390_START+E8390_NODMA, ax_base + E8390_CMD);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ /* Now the normal output. */
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (0x00, ax_base + EN0_RSARLO);
++ writeb (start_page, ax_base + EN0_RSARHI);
++ current_dma_addr_start = readb(ax_base+EN0_CRDALO)|(readb(ax_base+EN0_CRDAHI)<<8);
++ writeb (E8390_RWRITE+E8390_START, ax_base + E8390_CMD);
++
++ if(count<=PLATFORM_DMA_THRESHOLD)
++ {
++ cprintk("FUNC %s() : LINE %d : OSCR Value is 0x%08X \n",__FUNCTION__,__LINE__,OSCR);
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ cprintk("LINE %d: FUNC %s() : Setting the GPIO73 for DEBUG Before Starting PIO\n",__LINE__,__FUNCTION__);
++ GPSR(GPIO_FOR_ASIX_DEBUG) = GPIO_bit(GPIO_FOR_ASIX_DEBUG);
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0x7F8));
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0xFFFF8));
++ #endif
++ cprintk("LINE %d: FUNC %s() : Clearing the GPIO73 for DEBUG After Completing PIO\n",__LINE__,__FUNCTION__);
++ GPCR(GPIO_FOR_ASIX_DEBUG) = GPIO_bit(GPIO_FOR_ASIX_DEBUG);
++#else
++ for (i = 0; i < count; i += 2) {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + i)));
++ }
++#endif
++ cprintk("FUNC %s() : LINE %d : OSCR Value is 0x%08X \n",__FUNCTION__,__LINE__,OSCR);
++ }
++ else
++ {
++
++#if USE_STANDARD_LINUX_DMA_API
++ //Allocate Kernel buffer and Descriptor Buffer for YUV Packed data
++ kernel_virt_buffer = (unsigned int *) dma_alloc_writecombine( NULL, i, (void *)&kernel_phys_buffer, GFP_KERNEL);
++ if(kernel_virt_buffer==NULL)
++ {
++ printk("Failed to allocate memory of 0x%08X size for kernel virtual buffer \n",i);
++ return;
++ }
++ else
++ {
++ cprintk("kernel_virt_buffer is 0x%08X . kernel_phys_buffer is 0x%08X \n",kernel_virt_buffer,kernel_phys_buffer);
++ }
++ memcpy(kernel_virt_buffer,local_buf,i);
++
++ //Note: The DCSR should be cleared, before writing the Target and Source addresses
++ DCSR(dwDmaCh) = DCSR_NODESC; //get ready for the DMA
++ DTADR(dwDmaCh) =PXA_CS4_PHYS | 0x100000;
++ DSADR(dwDmaCh) = kernel_phys_buffer;
++ dwDmaCmd |= DCMD_INCSRCADDR; //always increment the memory address
++ dwDmaCmd |= DCMD_INCTRGADDR;
++ //Set the burst size, if cache line burst set to 32Bytes else set to the smallest
++ dwDmaCmd |= DCMD_BURST32;
++
++ // Set the Width of the On-Chip Peripheral as 16 bit
++ dwDmaCmd |= DCMD_WIDTH2;
++
++ dwDmaCmd |= (DCMD_LENGTH & (i));
++ DCMD(dwDmaCh) = dwDmaCmd ;
++
++ DCSR(dwDmaCh) |= DCSR_ENRINTR;
++
++ cprintk("LINE %d: FUNC %s() : Setting the GPIO73 for DEBUG Before Starting DMA\n",__LINE__,__FUNCTION__);
++ GPSR(GPIO_FOR_ASIX_DEBUG) = GPIO_bit(GPIO_FOR_ASIX_DEBUG);
++ DCSR(dwDmaCh) |= DCSR_RUN;
++
++ #if WAIT_TO_PXADMA_COMPLETE
++ //while waiting for dma to complete,
++ // check if another packet arrives
++ dwTimeOut=1000000;
++ while((Platform_DmaGetDwCnt(NULL,dwDmaCh))&&(dwTimeOut))
++ {
++ udelay(1);
++ dwTimeOut--;
++ }
++ if(dwTimeOut==0)
++ {
++ ASIX_WARNING("FUNC %s() : LINE %d : Timed out while waiting for final Dma to complete",__FUNCTION__,__LINE__);
++ }
++ else
++ {
++ Platform_DmaComplete(NULL,dwDmaCh);
++ }
++ #endif // end of WAIT_TO_PXADMA_COMPLETE
++ dma_start = jiffies;
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0)
++ {
++ if (jiffies - dma_start > 2*HZ/100)
++ { /* 20ms */
++ if(number_of_bytes_transffered<count)
++ {
++ cprintk("FUNC %s() : LINE %d : Improper Packet Tramsmission occured \n",__FUNCTION__,__LINE__);
++ }
++ break;
++ }
++ }
++
++ dma_free_writecombine (NULL,i, kernel_virt_buffer,(int)kernel_phys_buffer);
++ GPCR(GPIO_FOR_ASIX_DEBUG) = GPIO_bit(GPIO_FOR_ASIX_DEBUG);
++ //printk("FUNC %s() : LINE %d : OSCR Value is 0x%08X \n",__FUNCTION__,__LINE__,OSCR);
++
++ current_dma_addr_end = readb(ax_base+EN0_CRDALO)|(readb(ax_base+EN0_CRDAHI)<<8);
++ if(current_dma_addr_end < ((NESM_RX_START_PG)*Tx_page_size))
++ {
++ number_of_bytes_transffered = current_dma_addr_end-current_dma_addr_start;
++ }
++ else
++ {
++ number_of_bytes_transffered = (((NESM_RX_START_PG)*Tx_page_size) - current_dma_addr_start)+ (current_dma_addr_end - (NESM_START_PG*Tx_page_size));
++ }
++ remaining_bytes_to_be_transffered = (count-number_of_bytes_transffered);
++ cprintk("LINE %d: Actual Count value is %d. The Value written in the Remote Byte Count Reg is %d \n",__LINE__,count,(count&0xFFFF));
++ cprintk("FUNC %s() : LINE %d : Current Remote DMA address (start) is 0x%08X \n",__FUNCTION__,__LINE__,current_dma_addr_start);
++ cprintk("FUNC %s() : LINE %d : Current Remote DMA address (end) is 0x%08X \n",__FUNCTION__,__LINE__,current_dma_addr_end);
++
++ cprintk("FUNC %s() : LINE %d : Number of bytes transffered in RDMA Operation is %d \n",__FUNCTION__,__LINE__,number_of_bytes_transffered);
++ cprintk("FUNC %s() : LINE %d : Channel Number is %d \n",__FUNCTION__,__LINE__,(int)dwDmaCh);
++ cprintk("FUNC %s() : LINE %d : DCSR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCSR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DALGN is 0x%08X \n",__FUNCTION__,__LINE__,DALGN);
++ cprintk("FUNC %s() : LINE %d : DINT is 0x%08X \n",__FUNCTION__,__LINE__,DINT);
++ cprintk("FUNC %s() : LINE %d : DDADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DDADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DSADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DSADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DTADR%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DTADR(dwDmaCh));
++ cprintk("FUNC %s() : LINE %d : DCMD%d is 0x%08X \n",__FUNCTION__,__LINE__,(int)dwDmaCh,DCMD(dwDmaCh));
++
++ cprintk("FUNC %s() : LINE %d : Number of remaining bytes to be transffered in RDMA Operation is %d \n",__FUNCTION__,__LINE__,remaining_bytes_to_be_transffered);
++#else
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - number_bytes_to_write_to_pio_port) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - number_bytes_to_write_to_pio_port) + 7) & (0xFFFF8);
++ #endif
++
++
++ for(m=0;m<number_bytes_to_write_to_pio_port;m += 2)
++ {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + m)));
++ }
++
++ dmaXfer.dwLanReg=CS4_VIRT_BASE+EN0_DATA_ADDR;
++ dmaXfer.pdwBuf=NULL;// this will be reset per dma request
++ dmaXfer.dwDmaCh=dwDmaCh;
++ dmaXfer.dwDwCnt=0;// this will be reset per dma request
++ dmaXfer.fMemWr=FALSE;
++ dwDwordCount = i>>2;
++ cprintk("FUNC %s() : LINE %d : count is %d . i is %d .buf is 0x%08X \n",__FUNCTION__,__LINE__,count,i,(unsigned int)(buf+number_bytes_to_write_to_pio_port));
++ cprintk("FUNC %s() : LINE %d : count is %d . After calculation byte count for DMA is %d \n",__FUNCTION__,__LINE__,count,(dwDwordCount<<2));
++ Platform_CacheInvalidate(NULL,(buf+number_bytes_to_write_to_pio_port),dwDwordCount<<2);
++ dmaXfer.pdwBuf=(DWORD *)(buf+number_bytes_to_write_to_pio_port);
++ dmaXfer.dwDwCnt=dwDwordCount;
++
++ if(!Platform_DmaStartXfer(NULL,&dmaXfer))
++ {
++ ASIX_WARNING("Failed Platform_DmaStartXfer");
++ }
++
++ #if WAIT_TO_PXADMA_COMPLETE
++ //while waiting for dma to complete,
++ // check if another packet arrives
++ dwTimeOut=1000000;
++ while((Platform_DmaGetDwCnt(NULL,dwDmaCh))&&(dwTimeOut))
++ {
++ udelay(1);
++ dwTimeOut--;
++ }
++ if(dwTimeOut==0)
++ {
++ ASIX_WARNING("Timed out while waiting for final Dma to complete");
++ }
++ else
++ {
++ ASIX_TRACE("DMA Operation Completed .dwTimeOut is %d \n",(int)dwTimeOut );
++ Platform_DmaComplete(NULL,dwDmaCh);
++ }
++ #endif // end of WAIT_TO_PXADMA_COMPLETE
++#endif
++
++ }
++ cprintk("FUNC %s() : LINE %d : OSCR Value is 0x%08X \n",__FUNCTION__,__LINE__,OSCR);
++ dma_start = jiffies;
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0)
++ {
++ if (jiffies - dma_start > 2*HZ/100)
++ { /* 20ms */
++ printk("%s: LINE %d : timeout waiting for Tx RDC.\n", dev->name,__LINE__);
++ ax_reset (dev);
++ ax_init (dev,1);
++ break;
++ }
++ }
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ ax_local->dmaing = 0;
++ cprintk("<<<<<<<<<<<<<< End of %s() \n",__FUNCTION__);
++
++ return;
++}
++
++
++
++#endif // end of DMA_MODE_OPERATION
++
++
++/* ################################################################################################### */
++
++/****************^^^^^^^ Added by e-con for DMA mode operation ^^^^^^********************************/
++
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/readme linux-2.6.25/drivers/net/regulus_ax88796b/readme
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/readme 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/readme 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,95 @@
++==================================================================================
++Driver Overview
++==================================================================================
++AX88796B 3-in-1 Local Bus 8/16-bit Fast Ethernet Linux Kernel 2.4.x and 2.6.x Driver
++
++The AX88796B Ethernet controller is a high performance and highly integrated
++local CPU bus Ethernet controllers with embedded 10/100Mbps PHY/Transceiver
++16K bytes SRAM and supports both 8-bit and 16-bit local CPU interfaces for any
++embedded systems.
++
++If you look for more details, please visit ASIX's web site (http://www.asix.com.tw).
++
++Current Driver Version: 1.0.2.000
++Release Date: Aug 12, 2008
++
++==================================================================================
++Revision History
++==================================================================================
++
++ Version 1.0.0 06/02/2006
++
++ * Initial release
++
++ Version 1.0.0 27/03/2006
++
++ * Fixups Transmit Queue functions.
++
++ Version 1.1.0 20/09/2006
++
++ * Ported to support kernel 2.6.x.
++
++ Version 1.2.0 09/09/2008
++
++ * 1. Added 8-bit support.
++ * 2. Added EEPROM support.
++ * 3. Added PHY power process function.
++
++==================================================================================
++File Description
++==================================================================================
++README This file
++ax88796b.c AX88796B Linux driver main file
++ax88796b.h AX88796B Linux driver header file
++Makefile AX88796B driver make file
++COPYING GNU GENERAL PUBLIC LICENSE
++
++==================================================================================
++COMPILING DRIVER
++==================================================================================
++Prepare:
++
++ AX88796B Linux Driver Source.
++ Linux Kernel source code.
++ Cross-Compiler.
++
++Getting Start:
++
++ 1.Extracting the AX88796B source file by executing the following command.
++ [root@localhost]# tar jxvf ax88796b-arm-linux2.6.tar.bz2
++
++ 2.Edit the makefile to specifie the path of target platform Linux Kernel source.
++ example for kernel 2.6.x:
++ KDIR = /work/linux-2.6.x
++ example for kernel 2.4.x:
++ KDIR = /work/linux-2.4.x/include
++
++ 3.For kernel 2.4.x , you need to specify the path of Cross-Compiler
++ example
++ CROSS_COMPILE = /usr/local/arm/<versions>/bin/arm-linux-
++
++ 4.Executing 'make' command to compiler AX88796B Driver.
++
++ 5.If the compilation well, the ax88796b.ko(ax88796b.o) will be created under
++ the current directory.
++
++
++==================================================================================
++DRIVER PARAMETERS
++==================================================================================
++The following parameters can be set when using insmod.
++EX: [root@localhost ax88796b]# insmod ax88796.ko mem=0x08000000
++
++ mem=0xNNNNNNNN
++ specifies the physical base address that AX88796B can be accessed.
++ Default value '0x08000000'.
++
++ irq=N
++ specifies the irq number. Default value '0x27'.
++
++ media=N
++ Set media mode (0=auto, 1=100full, 2=100half, 3=10full, 4=10half).
++ Default is 0
++
++ example: insmod ax88796b.ko(ax88796b.o) media=1 mem=0x08000000 irq=0x27
++
+diff -Naur linux-2.6.25_original/drivers/net/regulus_ax88796b/tags linux-2.6.25/drivers/net/regulus_ax88796b/tags
+--- linux-2.6.25_original/drivers/net/regulus_ax88796b/tags 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/net/regulus_ax88796b/tags 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,647 @@
++!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
++!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
++!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
++!_TAG_PROGRAM_NAME Exuberant Ctags //
++!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
++!_TAG_PROGRAM_VERSION 5.5.4 //
++ADP_NAME ax88796b.c 150;" d file:
++ADP_NAME ax88796b_org.c 138;" d file:
++ALL_MSG ax88796b.h 278;" d
++ALL_MSG ax88796b_org.h 278;" d
++ARCH Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- clean$/;" m
++ARCH Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- modules$/;" m
++ASIX_ASSERT ax88796b.c 175;" d file:
++ASIX_ASSERT ax88796b.c 181;" d file:
++ASIX_DUMMY_ID pxa270_dma_mode_for_asix.c 171;" d file:
++ASIX_TRACE ax88796b.c 189;" d file:
++ASIX_TRACE ax88796b.c 194;" d file:
++ASIX_WARNING ax88796b.c 202;" d file:
++ASIX_WARNING ax88796b.c 207;" d file:
++AX88796B_BASE ax88796b.c 224;" d file:
++AX88796B_BASE ax88796b.c 225;" d file:
++AX88796B_BASE ax88796b.h 54;" d
++AX88796B_BASE ax88796b_org.h 54;" d
++AX88796_MII_EEPROM ax88796b.h 138;" d
++AX88796_MII_EEPROM ax88796b_org.h 138;" d
++AX88796_WATCHDOG_PERIOD ax88796b.h 83;" d
++AX88796_WATCHDOG_PERIOD ax88796b_org.h 83;" d
++BOOLEAN pxa270_dma_mode_for_asix.c /^typedef unsigned char BOOLEAN;$/;" t file:
++BURST_BANKCON1 ax88796b.h 251;" d
++BURST_BANKCON1 ax88796b_org.h 251;" d
++BYTE pxa270_dma_mode_for_asix.c /^typedef unsigned char BYTE;$/;" t file:
++BurstPeriod pxa270_dma_mode_for_asix.c /^ DWORD BurstPeriod;$/;" m struct:_FLOW_CONTROL_PARAMETERS file:
++CACHE_ALIGN_MASK pxa270_dma_mode_for_asix.c 33;" d file:
++CACHE_BYTES_PER_WAY pxa270_dma_mode_for_asix.c 34;" d file:
++CACHE_LINE_BYTES pxa270_dma_mode_for_asix.c 32;" d file:
++CACHE_SIZE_KB pxa270_dma_mode_for_asix.c 30;" d file:
++CACHE_WAYS pxa270_dma_mode_for_asix.c 31;" d file:
++CAMDIVN_100MHZ ax88796b.h 242;" d
++CAMDIVN_100MHZ ax88796b_org.h 242;" d
++CAMDIVN_125MHZ ax88796b.h 238;" d
++CAMDIVN_125MHZ ax88796b_org.h 238;" d
++CAMDIVN_50MHZ ax88796b.h 246;" d
++CAMDIVN_50MHZ ax88796b_org.h 246;" d
++CLKDIVN_100MHZ ax88796b.h 241;" d
++CLKDIVN_100MHZ ax88796b_org.h 241;" d
++CLKDIVN_125MHZ ax88796b.h 237;" d
++CLKDIVN_125MHZ ax88796b_org.h 237;" d
++CLKDIVN_50MHZ ax88796b.h 245;" d
++CLKDIVN_50MHZ ax88796b_org.h 245;" d
++CONFIG_AX88796B Makefile /^CONFIG_AX88796B=m$/;" m
++CONFIG_AX88796B_8BIT_WIDE ax88796b.c 215;" d file:
++CONFIG_AX88796B_8BIT_WIDE ax88796b_org.c 145;" d file:
++CONFIG_AX88796B_EEPROM_READ_WRITE ax88796b.c 216;" d file:
++CONFIG_AX88796B_EEPROM_READ_WRITE ax88796b_org.c 146;" d file:
++CONFIG_AX88796B_USE_MEMCPY ax88796b.c 214;" d file:
++CONFIG_AX88796B_USE_MEMCPY ax88796b_org.c 144;" d file:
++CRITICAL_DEBUG ax88796b.c 163;" d file:
++CROSS_COMPILE Makefile /^CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux-$/;" m
++CS4_VIRT_BASE pxa270_dma_mode_for_asix.c /^DWORD CS4_VIRT_BASE = 0;$/;" v
++CleanCacheLine pxa270_dma_mode_for_asix.c /^static inline void CleanCacheLine(DWORD addr)$/;" f file:
++CpuToPhysicalAddr pxa270_dma_mode_for_asix.c /^DWORD CpuToPhysicalAddr(const void * const pvCpuAddr)$/;" f
++DALGN pxa270_dma_mode_for_asix.c 11;" d file:
++DCSR_ENRINTR pxa270_dma_mode_for_asix.c 1;" d file:
++DEBUG_FLAGS ax88796b.h 281;" d
++DEBUG_FLAGS ax88796b_org.h 281;" d
++DEBUG_MSG ax88796b.h 276;" d
++DEBUG_MSG ax88796b_org.h 276;" d
++DEFAULT_100MHZ_BANKCON1 ax88796b.h 249;" d
++DEFAULT_100MHZ_BANKCON1 ax88796b_org.h 249;" d
++DEFAULT_125MHZ_BANKCON1 ax88796b.h 250;" d
++DEFAULT_125MHZ_BANKCON1 ax88796b_org.h 250;" d
++DEFAULT_MSG ax88796b.h 280;" d
++DEFAULT_MSG ax88796b_org.h 280;" d
++DMA_8BYTE pxa270_dma_mode_for_asix.c 15;" d file:
++DMA_8BYTE_ALIGNMENT_MASK pxa270_dma_mode_for_asix.c 16;" d file:
++DMA_ADDRESS_USER_ALIGNMENT pxa270_dma_mode_for_asix.c 14;" d file:
++DMA_MODE_OPERATION pxa270_dma_mode_for_asix.c 12;" d file:
++DMA_XFER pxa270_dma_mode_for_asix.c /^} DMA_XFER;$/;" t file:
++DRIVER_MSG ax88796b.h 269;" d
++DRIVER_MSG ax88796b_org.h 269;" d
++DRV_NAME ax88796b.c 149;" d file:
++DRV_NAME ax88796b_org.c 137;" d file:
++DRV_VERSION ax88796b.c 151;" d file:
++DRV_VERSION ax88796b_org.c 139;" d file:
++DWORD pxa270_dma_mode_for_asix.c /^typedef unsigned long DWORD;$/;" t file:
++DrainWriteBuffers pxa270_dma_mode_for_asix.c /^static inline void DrainWriteBuffers(void)$/;" f file:
++E8390_CMD ax88796b.h 108;" d
++E8390_CMD ax88796b_org.h 108;" d
++E8390_NODMA ax88796b.h 100;" d
++E8390_NODMA ax88796b_org.h 100;" d
++E8390_PAGE0 ax88796b.h 101;" d
++E8390_PAGE0 ax88796b_org.h 101;" d
++E8390_PAGE1 ax88796b.h 102;" d
++E8390_PAGE1 ax88796b_org.h 102;" d
++E8390_PAGE2 ax88796b.h 103;" d
++E8390_PAGE2 ax88796b_org.h 103;" d
++E8390_PAGE3 ax88796b.h 104;" d
++E8390_PAGE3 ax88796b_org.h 104;" d
++E8390_RREAD ax88796b.h 98;" d
++E8390_RREAD ax88796b_org.h 98;" d
++E8390_RWRITE ax88796b.h 99;" d
++E8390_RWRITE ax88796b_org.h 99;" d
++E8390_RXCONFIG ax88796b.h 89;" d
++E8390_RXCONFIG ax88796b_org.h 89;" d
++E8390_RXOFF ax88796b.h 90;" d
++E8390_RXOFF ax88796b_org.h 90;" d
++E8390_START ax88796b.h 96;" d
++E8390_START ax88796b_org.h 96;" d
++E8390_STOP ax88796b.h 95;" d
++E8390_STOP ax88796b_org.h 95;" d
++E8390_TRANS ax88796b.h 97;" d
++E8390_TRANS ax88796b_org.h 97;" d
++E8390_TXCONFIG ax88796b.h 91;" d
++E8390_TXCONFIG ax88796b_org.h 91;" d
++E8390_TXOFF ax88796b.h 92;" d
++E8390_TXOFF ax88796b_org.h 92;" d
++ECON_DEBUG ax88796b.c 155;" d file:
++EEPROM_93C46_OPCODE ax88796b.c 2020;" d file:
++EEPROM_93C46_OPCODE ax88796b_org.c 1758;" d file:
++EEPROM_93C46_STARTBIT ax88796b.c 2021;" d file:
++EEPROM_93C46_STARTBIT ax88796b_org.c 1759;" d file:
++EEPROM_DATA_READ1 ax88796b.c 2007;" d file:
++EEPROM_DATA_READ1 ax88796b_org.c 1745;" d file:
++EEPROM_DATA_WRITE0 ax88796b.c 2008;" d file:
++EEPROM_DATA_WRITE0 ax88796b_org.c 1746;" d file:
++EEPROM_DATA_WRITE1 ax88796b.c 2009;" d file:
++EEPROM_DATA_WRITE1 ax88796b_org.c 1747;" d file:
++EEPROM_DIR_IN ax88796b.c 2011;" d file:
++EEPROM_DIR_IN ax88796b_org.c 1749;" d file:
++EEPROM_ERALL ax88796b.c 2017;" d file:
++EEPROM_ERALL ax88796b_org.c 1755;" d file:
++EEPROM_ERASE ax88796b.c 2015;" d file:
++EEPROM_ERASE ax88796b_org.c 1753;" d file:
++EEPROM_EWDS ax88796b.c 2019;" d file:
++EEPROM_EWDS ax88796b_org.c 1757;" d file:
++EEPROM_EWEN ax88796b.c 2014;" d file:
++EEPROM_EWEN ax88796b_org.c 1752;" d file:
++EEPROM_READ ax88796b.c 2013;" d file:
++EEPROM_READ ax88796b_org.c 1751;" d file:
++EEPROM_SELECT ax88796b.c 2010;" d file:
++EEPROM_SELECT ax88796b_org.c 1748;" d file:
++EEPROM_SHIFT_CLK ax88796b.c 2006;" d file:
++EEPROM_SHIFT_CLK ax88796b_org.c 1744;" d file:
++EEPROM_WRAL ax88796b.c 2018;" d file:
++EEPROM_WRAL ax88796b_org.c 1756;" d file:
++EEPROM_WRITE ax88796b.c 2016;" d file:
++EEPROM_WRITE ax88796b_org.c 1754;" d file:
++EINT11_MASK ax88796b.h 254;" d
++EINT11_MASK ax88796b_org.h 254;" d
++EI_SHIFT ax88796b.h 106;" d
++EI_SHIFT ax88796b_org.h 106;" d
++EN0_BOUNDARY ax88796b.h 114;" d
++EN0_BOUNDARY ax88796b_org.h 114;" d
++EN0_BTCR ax88796b.h 139;" d
++EN0_BTCR ax88796b_org.h 139;" d
++EN0_CLDAHI ax88796b.h 112;" d
++EN0_CLDAHI ax88796b_org.h 112;" d
++EN0_CLDALO ax88796b.h 110;" d
++EN0_CLDALO ax88796b_org.h 110;" d
++EN0_COUNTER0 ax88796b.h 131;" d
++EN0_COUNTER0 ax88796b_org.h 131;" d
++EN0_COUNTER1 ax88796b.h 133;" d
++EN0_COUNTER1 ax88796b_org.h 133;" d
++EN0_COUNTER2 ax88796b.h 135;" d
++EN0_COUNTER2 ax88796b_org.h 135;" d
++EN0_CRDAHI ax88796b.h 124;" d
++EN0_CRDAHI ax88796b_org.h 124;" d
++EN0_CRDALO ax88796b.h 122;" d
++EN0_CRDALO ax88796b_org.h 122;" d
++EN0_CTEPR ax88796b.h 143;" d
++EN0_CTEPR ax88796b_org.h 143;" d
++EN0_DATAPORT ax88796b.h 136;" d
++EN0_DATAPORT ax88796b_org.h 136;" d
++EN0_DATA_ADDR ax88796b.c 245;" d file:
++EN0_DATA_ADDR ax88796b.c 246;" d file:
++EN0_DATA_ADDR ax88796b.c 256;" d file:
++EN0_DATA_ADDR ax88796b.c 257;" d file:
++EN0_DATA_ADDR ax88796b.h 148;" d
++EN0_DATA_ADDR ax88796b_org.h 148;" d
++EN0_DCFG ax88796b.h 132;" d
++EN0_DCFG ax88796b_org.h 132;" d
++EN0_FIFO ax88796b.h 119;" d
++EN0_FIFO ax88796b_org.h 119;" d
++EN0_FLOW ax88796b.h 141;" d
++EN0_FLOW ax88796b_org.h 141;" d
++EN0_IMR ax88796b.h 134;" d
++EN0_IMR ax88796b_org.h 134;" d
++EN0_ISR ax88796b.h 121;" d
++EN0_ISR ax88796b_org.h 121;" d
++EN0_MCR ax88796b.h 142;" d
++EN0_MCR ax88796b_org.h 142;" d
++EN0_NCR ax88796b.h 117;" d
++EN0_NCR ax88796b_org.h 117;" d
++EN0_PHYID ax88796b.h 137;" d
++EN0_PHYID ax88796b_org.h 137;" d
++EN0_RCNTHI ax88796b.h 127;" d
++EN0_RCNTHI ax88796b_org.h 127;" d
++EN0_RCNTLO ax88796b.h 126;" d
++EN0_RCNTLO ax88796b_org.h 126;" d
++EN0_RESET ax88796b.h 146;" d
++EN0_RESET ax88796b_org.h 146;" d
++EN0_RSARHI ax88796b.h 125;" d
++EN0_RSARHI ax88796b_org.h 125;" d
++EN0_RSARLO ax88796b.h 123;" d
++EN0_RSARLO ax88796b_org.h 123;" d
++EN0_RSR ax88796b.h 128;" d
++EN0_RSR ax88796b_org.h 128;" d
++EN0_RXCR ax88796b.h 129;" d
++EN0_RXCR ax88796b_org.h 129;" d
++EN0_SR ax88796b.h 140;" d
++EN0_SR ax88796b_org.h 140;" d
++EN0_STARTPG ax88796b.h 111;" d
++EN0_STARTPG ax88796b_org.h 111;" d
++EN0_STOPPG ax88796b.h 113;" d
++EN0_STOPPG ax88796b_org.h 113;" d
++EN0_TCNTHI ax88796b.h 120;" d
++EN0_TCNTHI ax88796b_org.h 120;" d
++EN0_TCNTLO ax88796b.h 118;" d
++EN0_TCNTLO ax88796b_org.h 118;" d
++EN0_TPSR ax88796b.h 116;" d
++EN0_TPSR ax88796b_org.h 116;" d
++EN0_TSR ax88796b.h 115;" d
++EN0_TSR ax88796b_org.h 115;" d
++EN0_TXCR ax88796b.h 130;" d
++EN0_TXCR ax88796b_org.h 130;" d
++EN0_VID0 ax88796b.h 144;" d
++EN0_VID0 ax88796b_org.h 144;" d
++EN0_VID1 ax88796b.h 145;" d
++EN0_VID1 ax88796b_org.h 145;" d
++EN1_CURPAG ax88796b.h 177;" d
++EN1_CURPAG ax88796b_org.h 177;" d
++EN1_MULT ax88796b.h 178;" d
++EN1_MULT ax88796b_org.h 178;" d
++EN1_MULT_SHIFT ax88796b.h 179;" d
++EN1_MULT_SHIFT ax88796b_org.h 179;" d
++EN1_PHYS ax88796b.h 175;" d
++EN1_PHYS ax88796b_org.h 175;" d
++EN1_PHYS_SHIFT ax88796b.h 176;" d
++EN1_PHYS_SHIFT ax88796b_org.h 176;" d
++EN3_BM0 ax88796b.h 214;" d
++EN3_BM0 ax88796b_org.h 214;" d
++EN3_BM1 ax88796b.h 215;" d
++EN3_BM1 ax88796b_org.h 215;" d
++EN3_BM10CRC ax88796b.h 218;" d
++EN3_BM10CRC ax88796b_org.h 218;" d
++EN3_BM2 ax88796b.h 216;" d
++EN3_BM2 ax88796b_org.h 216;" d
++EN3_BM3 ax88796b.h 217;" d
++EN3_BM3 ax88796b_org.h 217;" d
++EN3_BM32CRC ax88796b.h 219;" d
++EN3_BM32CRC ax88796b_org.h 219;" d
++EN3_BMCD ax88796b.h 222;" d
++EN3_BMCD ax88796b_org.h 222;" d
++EN3_BMOFST ax88796b.h 220;" d
++EN3_BMOFST ax88796b_org.h 220;" d
++EN3_LSTBYT ax88796b.h 221;" d
++EN3_LSTBYT ax88796b_org.h 221;" d
++EN3_PMR ax88796b.h 224;" d
++EN3_PMR ax88796b_org.h 224;" d
++EN3_TBR ax88796b.h 171;" d
++EN3_TBR ax88796b_org.h 171;" d
++EN3_WUCS ax88796b.h 223;" d
++EN3_WUCS ax88796b_org.h 223;" d
++ENBTCR_INT_ACT_HIGH ax88796b.h 203;" d
++ENBTCR_INT_ACT_HIGH ax88796b_org.h 203;" d
++ENBTCR_IRQ_TYPE_PUSH_PULL ax88796b.c 219;" d file:
++ENBTCR_PME_INT_EN ax88796b.h 202;" d
++ENBTCR_PME_INT_EN ax88796b_org.h 202;" d
++ENDCFG_BOS ax88796b.h 166;" d
++ENDCFG_BOS ax88796b_org.h 166;" d
++ENDCFG_WTS ax88796b.h 165;" d
++ENDCFG_WTS ax88796b_org.h 165;" d
++ENFLOW_ENABLE ax88796b.h 168;" d
++ENFLOW_ENABLE ax88796b_org.h 168;" d
++ENISR_ALL ax88796b.h 161;" d
++ENISR_ALL ax88796b_org.h 161;" d
++ENISR_COUNTERS ax88796b.h 158;" d
++ENISR_COUNTERS ax88796b_org.h 158;" d
++ENISR_OVER ax88796b.h 157;" d
++ENISR_OVER ax88796b_org.h 157;" d
++ENISR_RDC ax88796b.h 159;" d
++ENISR_RDC ax88796b_org.h 159;" d
++ENISR_RESET ax88796b.h 160;" d
++ENISR_RESET ax88796b_org.h 160;" d
++ENISR_RX ax88796b.h 153;" d
++ENISR_RX ax88796b_org.h 153;" d
++ENISR_RX_ERR ax88796b.h 155;" d
++ENISR_RX_ERR ax88796b_org.h 155;" d
++ENISR_TX ax88796b.h 154;" d
++ENISR_TX ax88796b_org.h 154;" d
++ENISR_TX_ERR ax88796b.h 156;" d
++ENISR_TX_ERR ax88796b_org.h 156;" d
++ENPMR_D1 ax88796b.h 232;" d
++ENPMR_D1 ax88796b_org.h 232;" d
++ENPMR_D2 ax88796b.h 233;" d
++ENPMR_D2 ax88796b_org.h 233;" d
++ENRSR_CRC ax88796b.h 183;" d
++ENRSR_CRC ax88796b_org.h 183;" d
++ENRSR_DEF ax88796b.h 189;" d
++ENRSR_DEF ax88796b_org.h 189;" d
++ENRSR_DIS ax88796b.h 188;" d
++ENRSR_DIS ax88796b_org.h 188;" d
++ENRSR_FAE ax88796b.h 184;" d
++ENRSR_FAE ax88796b_org.h 184;" d
++ENRSR_FO ax88796b.h 185;" d
++ENRSR_FO ax88796b_org.h 185;" d
++ENRSR_MPA ax88796b.h 186;" d
++ENRSR_MPA ax88796b_org.h 186;" d
++ENRSR_PHY ax88796b.h 187;" d
++ENRSR_PHY ax88796b_org.h 187;" d
++ENRSR_RXOK ax88796b.h 182;" d
++ENRSR_RXOK ax88796b_org.h 182;" d
++ENSR_DEV_READY ax88796b.h 208;" d
++ENSR_DEV_READY ax88796b_org.h 208;" d
++ENSR_DMA_DONE ax88796b.h 206;" d
++ENSR_DMA_DONE ax88796b_org.h 206;" d
++ENSR_DMA_READY ax88796b.h 207;" d
++ENSR_DMA_READY ax88796b_org.h 207;" d
++ENSR_DUPLEX_DULL ax88796b.h 210;" d
++ENSR_DUPLEX_DULL ax88796b_org.h 210;" d
++ENSR_LINK ax88796b.h 211;" d
++ENSR_LINK ax88796b_org.h 211;" d
++ENSR_SPEED_100 ax88796b.h 209;" d
++ENSR_SPEED_100 ax88796b_org.h 209;" d
++ENTBR_ENABLE ax88796b.h 172;" d
++ENTBR_ENABLE ax88796b_org.h 172;" d
++ENTQC_ENABLE ax88796b.h 169;" d
++ENTQC_ENABLE ax88796b_org.h 169;" d
++ENTSR_ABT ax88796b.h 195;" d
++ENTSR_ABT ax88796b_org.h 195;" d
++ENTSR_CDH ax88796b.h 198;" d
++ENTSR_CDH ax88796b_org.h 198;" d
++ENTSR_COL ax88796b.h 194;" d
++ENTSR_COL ax88796b_org.h 194;" d
++ENTSR_CRS ax88796b.h 196;" d
++ENTSR_CRS ax88796b_org.h 196;" d
++ENTSR_FU ax88796b.h 197;" d
++ENTSR_FU ax88796b_org.h 197;" d
++ENTSR_ND ax88796b.h 193;" d
++ENTSR_ND ax88796b_org.h 193;" d
++ENTSR_OWC ax88796b.h 199;" d
++ENTSR_OWC ax88796b_org.h 199;" d
++ENTSR_PTX ax88796b.h 192;" d
++ENTSR_PTX ax88796b_org.h 192;" d
++ENVLAN_ENABLE ax88796b.h 150;" d
++ENVLAN_ENABLE ax88796b_org.h 150;" d
++ENWUCS_LINK ax88796b.h 229;" d
++ENWUCS_LINK ax88796b_org.h 229;" d
++ENWUCS_MPEN ax88796b.h 227;" d
++ENWUCS_MPEN ax88796b_org.h 227;" d
++ENWUCS_WUEN ax88796b.h 228;" d
++ENWUCS_WUEN ax88796b_org.h 228;" d
++ERROR_MSG ax88796b.h 274;" d
++ERROR_MSG ax88796b_org.h 274;" d
++ETHER_ADDR_LEN ax88796b.h 52;" d
++ETHER_ADDR_LEN ax88796b_org.h 52;" d
++FALSE pxa270_dma_mode_for_asix.c 24;" d file:
++FIFO_SEL_IS_A11 ax88796b.c 234;" d file:
++FIFO_SEL_IS_A20 ax88796b.c 235;" d file:
++FLOW_CONTROL_PARAMETERS pxa270_dma_mode_for_asix.c /^} FLOW_CONTROL_PARAMETERS, *PFLOW_CONTROL_PARAMETERS;$/;" t file:
++FLTEN11_HIGHLEVEL ax88796b.h 257;" d
++FLTEN11_HIGHLEVEL ax88796b_org.h 257;" d
++FLTEN11_LOWLEVEL ax88796b.h 258;" d
++FLTEN11_LOWLEVEL ax88796b_org.h 258;" d
++GPIO80_GPIO_OUT ax88796b.c 365;" d file:
++GPIO_FOR_ASIX_IRQ ax88796b.c 265;" d file:
++GPIO_FOR_ASIX_IRQ ax88796b.c 268;" d file:
++GPIO_FOX_ASIX_IRQ_MD ax88796b.c 272;" d file:
++HARD_CODE_DMA_CHANNEL pxa270_dma_mode_for_asix.c 13;" d file:
++ICLR_GPIO_x ax88796b.c 323;" d file:
++IMCR_GPIO_x ax88796b.c 322;" d file:
++INIT_MSG ax88796b.h 270;" d
++INIT_MSG ax88796b_org.h 270;" d
++INT_MSG ax88796b.h 273;" d
++INT_MSG ax88796b_org.h 273;" d
++IRQ_EINT11 ax88796b.c 271;" d file:
++IRQ_FALLING_EDGE ax88796b.c 273;" d file:
++IntDeas pxa270_dma_mode_for_asix.c /^ DWORD IntDeas;$/;" m struct:_FLOW_CONTROL_PARAMETERS file:
++KDIR Makefile /^KDIR = \/home\/tharma\/project\/regulus\/regulus_linux-2.6.25$/;" m
++M Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- clean$/;" m
++M Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- modules$/;" m
++MAC_ADDDRESS_LENGTH ax88796b.c 230;" d file:
++MAC_ADDRESS_IN_NOR_FLASH ax88796b.c 229;" d file:
++MAC_ADDRESS_OFFSET_IN_NOR_FLASH ax88796b.c 228;" d file:
++MAX_TIME_SPAN pxa270_dma_mode_for_asix.c 18;" d file:
++MDIO_DATA_READ ax88796b.c 1930;" d file:
++MDIO_DATA_READ ax88796b_org.c 1668;" d file:
++MDIO_DATA_WRITE0 ax88796b.c 1928;" d file:
++MDIO_DATA_WRITE0 ax88796b_org.c 1666;" d file:
++MDIO_DATA_WRITE1 ax88796b.c 1929;" d file:
++MDIO_DATA_WRITE1 ax88796b_org.c 1667;" d file:
++MDIO_ENB_IN ax88796b.c 1932;" d file:
++MDIO_ENB_IN ax88796b_org.c 1670;" d file:
++MDIO_MASK ax88796b.c 1931;" d file:
++MDIO_MASK ax88796b_org.c 1669;" d file:
++MDIO_SHIFT_CLK ax88796b.c 1927;" d file:
++MDIO_SHIFT_CLK ax88796b_org.c 1665;" d file:
++MEDIA_100FULL ax88796b.h 263;" d
++MEDIA_100FULL ax88796b_org.h 263;" d
++MEDIA_100HALF ax88796b.h 264;" d
++MEDIA_100HALF ax88796b_org.h 264;" d
++MEDIA_10FULL ax88796b.h 265;" d
++MEDIA_10FULL ax88796b_org.h 265;" d
++MEDIA_10HALF ax88796b.h 266;" d
++MEDIA_10HALF ax88796b_org.h 266;" d
++MEDIA_AUTO ax88796b.h 262;" d
++MEDIA_AUTO ax88796b_org.h 262;" d
++MaxPacketCount pxa270_dma_mode_for_asix.c /^ DWORD MaxPacketCount;$/;" m struct:_FLOW_CONTROL_PARAMETERS file:
++MaxThroughput pxa270_dma_mode_for_asix.c /^ DWORD MaxThroughput;$/;" m struct:_FLOW_CONTROL_PARAMETERS file:
++NESM_RX_START_PG ax88796b.h 48;" d
++NESM_RX_START_PG ax88796b_org.h 48;" d
++NESM_START_PG ax88796b.h 47;" d
++NESM_START_PG ax88796b_org.h 47;" d
++NESM_STOP_PG ax88796b.h 50;" d
++NESM_STOP_PG ax88796b_org.h 50;" d
++NE_IO_EXTENT ax88796b.c 241;" d file:
++NE_IO_EXTENT ax88796b.c 242;" d file:
++NE_IO_EXTENT ax88796b.c 252;" d file:
++NE_IO_EXTENT ax88796b.c 253;" d file:
++NE_IO_EXTENT ax88796b.h 45;" d
++NE_IO_EXTENT ax88796b_org.h 45;" d
++NO_MSG ax88796b.h 279;" d
++NO_MSG ax88796b_org.h 279;" d
++OTHERS_MSG ax88796b.h 277;" d
++OTHERS_MSG ax88796b_org.h 277;" d
++PFLOW_CONTROL_PARAMETERS pxa270_dma_mode_for_asix.c /^} FLOW_CONTROL_PARAMETERS, *PFLOW_CONTROL_PARAMETERS;$/;" t file:
++PFX ax88796b.c 152;" d file:
++PFX ax88796b_org.c 140;" d file:
++PLATFORM_CACHE_LINE_BYTES pxa270_dma_mode_for_asix.c 36;" d file:
++PLATFORM_DATA pxa270_dma_mode_for_asix.c /^} PLATFORM_DATA, *PPLATFORM_DATA;$/;" t file:
++PLATFORM_DMA_THRESHOLD pxa270_dma_mode_for_asix.c 27;" d file:
++PLATFORM_RX_DMA pxa270_dma_mode_for_asix.c 25;" d file:
++PLATFORM_TX_DMA pxa270_dma_mode_for_asix.c 26;" d file:
++PPLATFORM_DATA pxa270_dma_mode_for_asix.c /^} PLATFORM_DATA, *PPLATFORM_DATA;$/;" t file:
++PRINTK ax88796b.c 154;" d file:
++PRINTK ax88796b_org.c 142;" d file:
++PWD Makefile /^PWD = $(shell pwd)$/;" m
++PacketCost pxa270_dma_mode_for_asix.c /^ DWORD PacketCost;$/;" m struct:_FLOW_CONTROL_PARAMETERS file:
++Platform_CacheInvalidate pxa270_dma_mode_for_asix.c /^void Platform_CacheInvalidate(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)$/;" f
++Platform_CachePurge pxa270_dma_mode_for_asix.c /^void Platform_CachePurge(PPLATFORM_DATA platformData, const void * const pStartAddress, const DWORD dwLengthInBytes)$/;" f
++Platform_DmaComplete pxa270_dma_mode_for_asix.c /^void Platform_DmaComplete(PPLATFORM_DATA platformData, const DWORD dwDmaCh)$/;" f
++Platform_DmaDisable pxa270_dma_mode_for_asix.c /^BOOLEAN Platform_DmaDisable(PPLATFORM_DATA platformData, const DWORD dwDmaCh)$/;" f
++Platform_DmaGetDwCnt pxa270_dma_mode_for_asix.c /^DWORD Platform_DmaGetDwCnt( PPLATFORM_DATA platformData, const DWORD dwDmaCh)$/;" f
++Platform_DmaStartXfer pxa270_dma_mode_for_asix.c /^BOOLEAN Platform_DmaStartXfer(PPLATFORM_DATA platformData, const DMA_XFER * const pDmaXfer)$/;" f
++PurgeCache pxa270_dma_mode_for_asix.c /^void PurgeCache(const void * const pStartAddress, const DWORD dwLengthInBytes)$/;" f
++READ_FIFO ax88796b.c /^static inline u16 READ_FIFO (void *membase)$/;" f file:
++READ_FIFO ax88796b_org.c /^static inline u16 READ_FIFO (void *membase)$/;" f file:
++ROSS_COMPILE Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- clean$/;" m
++ROSS_COMPILE Makefile /^ make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=\/usr\/local\/arm\/3.4.1\/bin\/arm-linux- modules$/;" m
++RX_MSG ax88796b.h 272;" d
++RX_MSG ax88796b_org.h 272;" d
++SIZE_1K ax88796b.c 231;" d file:
++TIME_SPAN pxa270_dma_mode_for_asix.c /^typedef long TIME_SPAN;$/;" t file:
++TRUE pxa270_dma_mode_for_asix.c 23;" d file:
++TX_MSG ax88796b.h 271;" d
++TX_MSG ax88796b_org.h 271;" d
++TX_PAGES ax88796b.h 42;" d
++TX_PAGES ax88796b_org.h 42;" d
++Tx_page_size ax88796b.h 43;" d
++Tx_page_size ax88796b_org.h 43;" d
++UBRDIV0_100MHZ ax88796b.h 243;" d
++UBRDIV0_100MHZ ax88796b_org.h 243;" d
++UBRDIV0_125MHZ ax88796b.h 239;" d
++UBRDIV0_125MHZ ax88796b_org.h 239;" d
++UBRDIV0_50MHZ ax88796b.h 247;" d
++UBRDIV0_50MHZ ax88796b_org.h 247;" d
++USE_ASSERT ax88796b.c 200;" d file:
++USE_WARNING ax88796b.c 187;" d file:
++WARNING_MSG ax88796b.h 275;" d
++WARNING_MSG ax88796b_org.h 275;" d
++WORD pxa270_dma_mode_for_asix.c /^typedef unsigned short WORD;$/;" t file:
++WRITE_FIFO ax88796b.c /^static inline void WRITE_FIFO (void *membase, u16 data)$/;" f file:
++WRITE_FIFO ax88796b_org.c /^static inline void WRITE_FIFO (void *membase, u16 data)$/;" f file:
++_DMA_XFER pxa270_dma_mode_for_asix.c /^typedef struct _DMA_XFER $/;" s file:
++_FLOW_CONTROL_PARAMETERS pxa270_dma_mode_for_asix.c /^typedef struct _FLOW_CONTROL_PARAMETERS$/;" s file:
++_PLATFORM_DATA pxa270_dma_mode_for_asix.c /^typedef struct _PLATFORM_DATA {$/;" s file:
++__devinitdata ax88796b_org.c /^static char version[] __devinitdata =$/;" v file:
++__this_module built-in.mod.c /^struct module __this_module$/;" v
++__this_module deneb_ax88796b.mod.c /^struct module __this_module$/;" v
++__this_module regulus_ax88796b.mod.c /^struct module __this_module$/;" v
++__used built-in.mod.c /^__used$/;" v file:
++__used deneb_ax88796b.mod.c /^__used$/;" v file:
++__used regulus_ax88796b.mod.c /^__used$/;" v file:
++_ax88796_h ax88796b.h 6;" d
++_ax88796_h ax88796b_org.h 6;" d
++asix_dma_rx_irq pxa270_dma_mode_for_asix.c /^static void asix_dma_rx_irq(int chan, void *dev_id,struct pt_regs *regs)$/;" f file:
++asix_dma_tx_irq pxa270_dma_mode_for_asix.c /^static void asix_dma_tx_irq(int chan, void *dev_id,struct pt_regs *regs)$/;" f file:
++ax88796_PHY_init ax88796b.c /^void ax88796_PHY_init (struct net_device *dev)$/;" f
++ax88796_PHY_init ax88796b_org.c /^void ax88796_PHY_init (struct net_device *dev)$/;" f
++ax_block_input ax88796b.c /^static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)$/;" f file:
++ax_block_input ax88796b_org.c /^static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)$/;" f file:
++ax_block_input pxa270_dma_mode_for_asix.c /^static void ax_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)$/;" f file:
++ax_block_output ax88796b.c /^static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)$/;" f file:
++ax_block_output ax88796b_org.c /^static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)$/;" f file:
++ax_block_output pxa270_dma_mode_for_asix.c /^static void ax_block_output (struct net_device *dev, int count, const unsigned char *buf, const int start_page)$/;" f file:
++ax_close ax88796b.c /^static int ax_close (struct net_device *dev)$/;" f file:
++ax_close ax88796b_org.c /^static int ax_close (struct net_device *dev)$/;" f file:
++ax_device ax88796b.h /^struct ax_device {$/;" s
++ax_device ax88796b_org.h /^struct ax_device {$/;" s
++ax_get_hdr ax88796b.c /^static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr, int ring_page)$/;" f file:
++ax_get_hdr ax88796b_org.c /^static void ax_get_hdr (struct net_device *dev, struct ax_pkt_hdr *hdr, int ring_page)$/;" f file:
++ax_init ax88796b.c /^static void ax_init (struct net_device *dev, int startp)$/;" f file:
++ax_init ax88796b_org.c /^static void ax_init (struct net_device *dev, int startp)$/;" f file:
++ax_interrupt ax88796b.c /^static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)$/;" f file:
++ax_interrupt ax88796b_org.c /^static void ax_interrupt (int irq, void *dev_id, struct pt_regs * regs)$/;" f file:
++ax_kprobe ax88796b_org.c /^struct net_device * __init ax_kprobe (int unit)$/;" f
++ax_open ax88796b.c /^static int ax_open (struct net_device *dev)$/;" f file:
++ax_open ax88796b_org.c /^static int ax_open (struct net_device *dev)$/;" f file:
++ax_pkt_hdr ax88796b.h /^struct ax_pkt_hdr {$/;" s
++ax_pkt_hdr ax88796b_org.h /^struct ax_pkt_hdr {$/;" s
++ax_probe ax88796b.c /^static int ax_probe (struct net_device *dev)$/;" f file:
++ax_probe ax88796b_org.c /^static int ax_probe (struct net_device *dev)$/;" f file:
++ax_receive ax88796b.c /^static void ax_receive (struct net_device *dev)$/;" f file:
++ax_receive ax88796b_org.c /^static void ax_receive (struct net_device *dev)$/;" f file:
++ax_reset ax88796b.c /^static void ax_reset (struct net_device *dev)$/;" f file:
++ax_reset ax88796b_org.c /^static void ax_reset (struct net_device *dev)$/;" f file:
++ax_rx_overrun ax88796b.c /^static void ax_rx_overrun (struct net_device *dev)$/;" f file:
++ax_rx_overrun ax88796b_org.c /^static void ax_rx_overrun (struct net_device *dev)$/;" f file:
++ax_start_xmit ax88796b.c /^static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev)$/;" f file:
++ax_start_xmit ax88796b_org.c /^static int ax_start_xmit (struct sk_buff *skb, struct net_device *dev)$/;" f file:
++ax_trigger_send ax88796b.c /^static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page)$/;" f file:
++ax_trigger_send ax88796b_org.c /^static void ax_trigger_send (struct net_device *dev, unsigned int length, int start_page)$/;" f file:
++ax_tx_err ax88796b.c /^static void ax_tx_err (struct net_device *dev)$/;" f file:
++ax_tx_err ax88796b_org.c /^static void ax_tx_err (struct net_device *dev)$/;" f file:
++ax_tx_intr ax88796b.c /^static void ax_tx_intr (struct net_device *dev)$/;" f file:
++ax_tx_intr ax88796b_org.c /^static void ax_tx_intr (struct net_device *dev)$/;" f file:
++ax_vlan_rx_add_vid ax88796b.c /^ax_vlan_rx_add_vid (struct net_device *dev, u16 vid)$/;" f file:
++ax_vlan_rx_add_vid ax88796b_org.c /^ax_vlan_rx_add_vid (struct net_device *dev, u16 vid)$/;" f file:
++ax_vlan_rx_kill_vid ax88796b.c /^ax_vlan_rx_kill_vid (struct net_device *dev, u16 vid)$/;" f file:
++ax_vlan_rx_kill_vid ax88796b_org.c /^ax_vlan_rx_kill_vid (struct net_device *dev, u16 vid)$/;" f file:
++ax_watchdog ax88796b.c /^static void ax_watchdog (unsigned long arg)$/;" f file:
++ax_watchdog ax88796b_org.c /^static void ax_watchdog (unsigned long arg)$/;" f file:
++bus_width ax88796b.h /^ unsigned char bus_width;$/;" m struct:ax_device
++bus_width ax88796b_org.h /^ unsigned char bus_width;$/;" m struct:ax_device
++cleanup_module ax88796b_org.c /^void cleanup_module (void)$/;" f
++config_2440_bank1 ax88796b.c /^static void config_2440_bank1 (void)$/;" f file:
++config_2440_bank1 ax88796b_org.c /^static void config_2440_bank1 (void)$/;" f file:
++count ax88796b.h /^ unsigned short count; \/* header + packet length in bytes *\/$/;" m struct:ax_pkt_hdr
++count ax88796b_org.h /^ unsigned short count; \/* header + packet length in bytes *\/$/;" m struct:ax_pkt_hdr
++cprintk ax88796b.c 165;" d file:
++cprintk ax88796b.c 167;" d file:
++current_page ax88796b.h /^ unsigned char current_page; \/* Read pointer in buffer *\/$/;" m struct:ax_device
++current_page ax88796b_org.h /^ unsigned char current_page; \/* Read pointer in buffer *\/$/;" m struct:ax_device
++deneb_asix_gpio_initialize ax88796b.c /^void deneb_asix_gpio_initialize(void)$/;" f
++deneb_ax88796b_cleanup_module ax88796b.c /^module_exit(deneb_ax88796b_cleanup_module);$/;" v
++deneb_ax88796b_cleanup_module ax88796b.c /^void deneb_ax88796b_cleanup_module (void)$/;" f
++deneb_ax88796b_init_module ax88796b.c /^int deneb_ax88796b_init_module (void)$/;" f
++deneb_ax88796b_init_module ax88796b.c /^module_init(deneb_ax88796b_init_module);$/;" v
++dev_ax ax88796b.c /^static struct net_device dev_ax;$/;" v file:
++dev_ax ax88796b_org.c /^static struct net_device dev_ax;$/;" v file:
++dev_id pxa270_dma_mode_for_asix.c /^ void *dev_id;$/;" m struct:_PLATFORM_DATA file:
++dmaing ax88796b.h /^ unsigned dmaing:1;$/;" m struct:ax_device
++dmaing ax88796b_org.h /^ unsigned dmaing:1;$/;" m struct:ax_device
++do_set_multicast_list ax88796b.c /^static void do_set_multicast_list (struct net_device *dev)$/;" f file:
++do_set_multicast_list ax88796b_org.c /^static void do_set_multicast_list (struct net_device *dev)$/;" f file:
++dwDmaCh pxa270_dma_mode_for_asix.c /^ DWORD dwDmaCh;$/;" m struct:_DMA_XFER file:
++dwDwCnt pxa270_dma_mode_for_asix.c /^ DWORD dwDwCnt;$/;" m struct:_DMA_XFER file:
++dwIdRev pxa270_dma_mode_for_asix.c /^ DWORD dwIdRev;$/;" m struct:_PLATFORM_DATA file:
++dwIrq pxa270_dma_mode_for_asix.c /^ DWORD dwIrq;$/;" m struct:_PLATFORM_DATA file:
++dwLanReg pxa270_dma_mode_for_asix.c /^ DWORD dwLanReg;$/;" m struct:_DMA_XFER file:
++eeprom_read ax88796b.c /^eeprom_read (struct net_device *dev, unsigned char loc)$/;" f file:
++eeprom_read ax88796b_org.c /^eeprom_read (struct net_device *dev, unsigned char loc)$/;" f file:
++eeprom_write ax88796b.c /^eeprom_write (struct net_device *dev, unsigned char loc, unsigned short nValue)$/;" f file:
++eeprom_write ax88796b_org.c /^eeprom_write (struct net_device *dev, unsigned char loc, unsigned short nValue)$/;" f file:
++eeprom_write_dis ax88796b.c /^eeprom_write_dis (struct net_device *dev)$/;" f file:
++eeprom_write_dis ax88796b_org.c /^eeprom_write_dis (struct net_device *dev)$/;" f file:
++eeprom_write_en ax88796b.c /^eeprom_write_en (struct net_device *dev)$/;" f file:
++eeprom_write_en ax88796b_org.c /^eeprom_write_en (struct net_device *dev)$/;" f file:
++eprintk ax88796b.c 157;" d file:
++eprintk ax88796b.c 159;" d file:
++ethdev_init ax88796b.c /^static int ethdev_init (struct net_device *dev)$/;" f file:
++ethdev_init ax88796b_org.c /^static int ethdev_init (struct net_device *dev)$/;" f file:
++fMemWr pxa270_dma_mode_for_asix.c /^ BOOLEAN fMemWr;$/;" m struct:_DMA_XFER file:
++get_mac_from_nor_flash ax88796b.c /^void get_mac_from_nor_flash(unsigned char *addr)$/;" f
++get_stats ax88796b.c /^static struct net_device_stats *get_stats (struct net_device *dev)$/;" f file:
++get_stats ax88796b_org.c /^static struct net_device_stats *get_stats (struct net_device *dev)$/;" f file:
++init_module ax88796b_org.c /^int init_module (void)$/;" f
++irq ax88796b.c /^static int irq;$/;" v file:
++irq ax88796b_org.c /^static int irq;$/;" v file:
++irqlock ax88796b.h /^ unsigned irqlock:1;$/;" m struct:ax_device
++irqlock ax88796b_org.h /^ unsigned irqlock:1;$/;" m struct:ax_device
++load_macaddr ax88796b.c /^load_macaddr (struct net_device *dev, unsigned char *pMac)$/;" f file:
++load_macaddr ax88796b_org.c /^load_macaddr (struct net_device *dev, unsigned char *pMac)$/;" f file:
++make_mc_bits ax88796b.c /^static inline void make_mc_bits (u8 *bits, struct net_device *dev)$/;" f file:
++make_mc_bits ax88796b_org.c /^static inline void make_mc_bits (u8 *bits, struct net_device *dev)$/;" f file:
++mcfilter ax88796b.h /^ unsigned char mcfilter[8];$/;" m struct:ax_device
++mcfilter ax88796b_org.h /^ unsigned char mcfilter[8];$/;" m struct:ax_device
++mdio_clear ax88796b.c /^static void mdio_clear (struct net_device *dev)$/;" f file:
++mdio_clear ax88796b_org.c /^static void mdio_clear (struct net_device *dev)$/;" f file:
++mdio_read ax88796b.c /^static int mdio_read (struct net_device *dev, int phy_id, int loc)$/;" f file:
++mdio_read ax88796b_org.c /^static int mdio_read (struct net_device *dev, int phy_id, int loc)$/;" f file:
++mdio_sync ax88796b.c /^static void mdio_sync (struct net_device *dev)$/;" f file:
++mdio_sync ax88796b_org.c /^static void mdio_sync (struct net_device *dev)$/;" f file:
++mdio_write ax88796b.c /^static void mdio_write (struct net_device *dev, int phy_id, int loc, int value)$/;" f file:
++mdio_write ax88796b_org.c /^static void mdio_write (struct net_device *dev, int phy_id, int loc, int value)$/;" f file:
++media ax88796b.c /^static unsigned int media = 0;$/;" v file:
++media ax88796b.h /^ unsigned char media;$/;" m struct:ax_device
++media ax88796b_org.c /^static unsigned int media = 0;$/;" v file:
++media ax88796b_org.h /^ unsigned char media;$/;" m struct:ax_device
++media_curr ax88796b.h /^ unsigned char media_curr;$/;" m struct:ax_device
++media_curr ax88796b_org.h /^ unsigned char media_curr;$/;" m struct:ax_device
++mem ax88796b.c /^static int mem;$/;" v file:
++mem ax88796b_org.c /^static int mem;$/;" v file:
++membase ax88796b.h /^ void *membase;$/;" m struct:ax_device
++membase ax88796b_org.h /^ void *membase;$/;" m struct:ax_device
++name ax88796b.h /^ const char *name;$/;" m struct:ax_device
++name ax88796b_org.h /^ const char *name;$/;" m struct:ax_device
++next ax88796b.h /^ unsigned char next; \/* pointer to next packet. *\/$/;" m struct:ax_pkt_hdr
++next ax88796b_org.h /^ unsigned char next; \/* pointer to next packet. *\/$/;" m struct:ax_pkt_hdr
++nor_flash_addr ax88796b.c /^volatile unsigned short int *nor_flash_addr=NULL;$/;" v
++objs Makefile /^regulus_ax88796b-objs := ax88796b.o$/;" m
++page_lock ax88796b.h /^ spinlock_t page_lock; \/* Page register locks *\/$/;" m struct:ax_device
++page_lock ax88796b_org.h /^ spinlock_t page_lock; \/* Page register locks *\/$/;" m struct:ax_device
++pdwBuf pxa270_dma_mode_for_asix.c /^ DWORD *pdwBuf;$/;" m struct:_DMA_XFER file:
++platform_dma_disable pxa270_dma_mode_for_asix.c /^int platform_dma_disable(int dma_ch)$/;" f
++platform_dma_initialize pxa270_dma_mode_for_asix.c /^int platform_dma_initialize(int dma_channel_number)$/;" f
++rx_dma_channel pxa270_dma_mode_for_asix.c /^int rx_dma_channel=0,tx_dma_channel=0;$/;" v
++rx_dma_initialize pxa270_dma_mode_for_asix.c /^void rx_dma_initialize(void)$/;" f
++rx_dma_uninitialize pxa270_dma_mode_for_asix.c /^void rx_dma_uninitialize(void)$/;" f
++rx_start_page ax88796b.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++rx_start_page ax88796b_org.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++set_multicast_list ax88796b.c /^static void set_multicast_list (struct net_device *dev)$/;" f file:
++set_multicast_list ax88796b_org.c /^static void set_multicast_list (struct net_device *dev)$/;" f file:
++stat ax88796b.h /^ struct net_device_stats stat; \/* The new statistics table. *\/$/;" m struct:ax_device
++stat ax88796b_org.h /^ struct net_device_stats stat; \/* The new statistics table. *\/$/;" m struct:ax_device
++status ax88796b.h /^ unsigned char status; \/* status *\/$/;" m struct:ax_pkt_hdr
++status ax88796b_org.h /^ unsigned char status; \/* status *\/$/;" m struct:ax_pkt_hdr
++stop_page ax88796b.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++stop_page ax88796b_org.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++tx_curr_ctepr ax88796b.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_curr_ctepr ax88796b_org.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_curr_page ax88796b.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_curr_page ax88796b_org.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_dma_channel pxa270_dma_mode_for_asix.c /^int rx_dma_channel=0,tx_dma_channel=0;$/;" v
++tx_dma_initialize pxa270_dma_mode_for_asix.c /^void tx_dma_initialize(void)$/;" f
++tx_dma_uninitialize pxa270_dma_mode_for_asix.c /^void tx_dma_uninitialize(void)$/;" f
++tx_full ax88796b.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_full ax88796b_org.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_prev_ctepr ax88796b.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_prev_ctepr ax88796b_org.h /^ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;$/;" m struct:ax_device
++tx_start_page ax88796b.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++tx_start_page ax88796b_org.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++tx_stop_page ax88796b.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++tx_stop_page ax88796b_org.h /^ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;$/;" m struct:ax_device
++version ax88796b.c /^static char version[] =$/;" v file:
++watchdog ax88796b.h /^ struct timer_list watchdog;$/;" m struct:ax_device
++watchdog ax88796b_org.h /^ struct timer_list watchdog;$/;" m struct:ax_device
+diff -Naur linux-2.6.25_original/drivers/net/wireless/Kconfig linux-2.6.25/drivers/net/wireless/Kconfig
+--- linux-2.6.25_original/drivers/net/wireless/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/Kconfig 2009-08-11 17:41:43.000000000 +0530
+@@ -100,7 +100,6 @@
+ To compile this driver as a module, choose M here: the module will be
+ called netwave_cs. If unsure, say N.
+
+-
+ config WLAN_80211
+ bool "Wireless LAN (IEEE 802.11)"
+ depends on NETDEVICES
+@@ -284,11 +283,12 @@
+ A driver for Marvell Libertas 8385 CompactFlash devices.
+
+ config LIBERTAS_SDIO
+- tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
++# tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
++ tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
+ depends on LIBERTAS && MMC
+ ---help---
+- A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+-
++# A driver for Marvell Libertas 8385 and 8686 SDIO devices.
++ A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
+ config LIBERTAS_DEBUG
+ bool "Enable full debugging output in the Libertas module."
+ depends on LIBERTAS
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/assoc.c linux-2.6.25/drivers/net/wireless/libertas/assoc.c
+--- linux-2.6.25_original/drivers/net/wireless/libertas/assoc.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/assoc.c 2009-08-11 17:41:43.000000000 +0530
+@@ -502,7 +502,7 @@
+
+ mutex_lock(&priv->lock);
+ assoc_req = priv->pending_assoc_req;
+- priv->pending_assoc_req = NULL;
++// priv->pending_assoc_req = NULL;
+ priv->in_progress_assoc_req = assoc_req;
+ mutex_unlock(&priv->lock);
+
+@@ -668,7 +668,7 @@
+ mutex_lock(&priv->lock);
+ priv->in_progress_assoc_req = NULL;
+ mutex_unlock(&priv->lock);
+- kfree(assoc_req);
++// kfree(assoc_req);
+
+ done:
+ lbs_deb_leave(LBS_DEB_ASSOC);
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/cmdresp.c linux-2.6.25/drivers/net/wireless/libertas/cmdresp.c
+--- linux-2.6.25_original/drivers/net/wireless/libertas/cmdresp.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/cmdresp.c 2009-08-11 17:41:43.000000000 +0530
+@@ -74,6 +74,13 @@
+ lbs_deb_cmd("disconnected, so exit PS mode\n");
+ lbs_ps_wakeup(priv, 0);
+ }
++
++ if (priv->pending_assoc_req) {
++ cancel_delayed_work(&priv->assoc_work);
++ queue_delayed_work(priv->work_thread,
++ &priv->assoc_work, HZ / 4);
++ }
++
+ lbs_deb_leave(LBS_DEB_CMD);
+ }
+
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/if_sdio.c linux-2.6.25/drivers/net/wireless/libertas/if_sdio.c
+--- linux-2.6.25_original/drivers/net/wireless/libertas/if_sdio.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/if_sdio.c 2009-08-11 17:41:43.000000000 +0530
+@@ -33,6 +33,7 @@
+ #include <linux/mmc/card.h>
+ #include <linux/mmc/sdio_func.h>
+ #include <linux/mmc/sdio_ids.h>
++#include <linux/vmalloc.h>
+
+ #include "host.h"
+ #include "decl.h"
+@@ -47,8 +48,14 @@
+ module_param_named(fw_name, lbs_fw_name, charp, 0644);
+
+ static const struct sdio_device_id if_sdio_ids[] = {
+- { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
+- { /* end: all zeroes */ },
++// { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
++// { /* end: all zeroes */ },
++ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
++ SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
++ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
++ SDIO_DEVICE_ID_MARVELL_8688WLAN) },
++ { /* end: all zeroes */ },
++
+ };
+
+ MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
+@@ -72,6 +79,12 @@
+ .helper = "sd8686_helper.bin",
+ .firmware = "sd8686.bin",
+ },
++ {
++ /* 8688 */
++ .model = 0x10,
++ .helper = "sd8688_helper.bin",
++ .firmware = "sd8688.bin",
++ },
+ };
+
+ struct if_sdio_packet {
+@@ -97,21 +110,43 @@
+ spinlock_t lock;
+ struct if_sdio_packet *packets;
+ struct work_struct packet_worker;
++
++ u8 rx_unit;
+ };
+
+ /********************************************************************/
+ /* I/O */
+ /********************************************************************/
+
++/*
++ * For SD8385/SD8686, this function reads firmware status after
++ * the image is downloaded, or reads RX packet length when
++ * interrupt (with IF_SDIO_H_INT_UPLD bit set) is received.
++ * For SD8688, this function reads firmware status only.
++ */
++
+ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
+ {
+ int ret, reg;
+ u16 scratch;
+
+- if (card->model == 0x04)
+- reg = IF_SDIO_SCRATCH_OLD;
+- else
+- reg = IF_SDIO_SCRATCH;
++// if (card->model == 0x04)
++// reg = IF_SDIO_SCRATCH_OLD;
++// else
++// reg = IF_SDIO_SCRATCH;
++
++ switch (card->model) {
++ case IF_SDIO_MODEL_8385:
++ reg = IF_SDIO_SCRATCH_OLD;
++ break;
++ case IF_SDIO_MODEL_8686:
++ reg = IF_SDIO_SCRATCH;
++ break;
++ case IF_SDIO_MODEL_8688:
++ default: /* for newer chipsets */
++ reg = IF_SDIO_FW_STATUS;
++ break;
++ }
+
+ scratch = sdio_readb(card->func, reg, &ret);
+ if (!ret)
+@@ -126,6 +161,46 @@
+ return scratch;
+ }
+
++static u8 if_sdio_read_rx_unit(struct if_sdio_card *card)
++{
++ int ret;
++ u8 rx_unit;
++
++ rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret);
++
++ if (ret)
++ rx_unit = 0;
++
++ return rx_unit;
++}
++
++static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
++{
++ int ret;
++ u16 rx_len;
++
++ switch (card->model) {
++ case IF_SDIO_MODEL_8385:
++ case IF_SDIO_MODEL_8686:
++ rx_len = if_sdio_read_scratch(card, &ret);
++ break;
++ case IF_SDIO_MODEL_8688:
++ default: /* for newer chipsets */
++ rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
++ if (!ret)
++ rx_len <<= card->rx_unit;
++ else
++ rx_len = 0xffff; /* invalid length */
++
++ break;
++ }
++
++ if (err)
++ *err = ret;
++
++ return rx_len;
++}
++
+ static int if_sdio_handle_cmd(struct if_sdio_card *card,
+ u8 *buffer, unsigned size)
+ {
+@@ -251,7 +326,8 @@
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+- size = if_sdio_read_scratch(card, &ret);
++// size = if_sdio_read_scratch(card, &ret);
++ size = if_sdio_read_rx_len(card, &ret);
+ if (ret)
+ goto out;
+
+@@ -391,6 +467,206 @@
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+ }
++/*******************************************************/
++#if 1 //wlan file operations
++
++#define WLAN_STATUS_SUCCESS (0)
++#define WLAN_STATUS_FAILURE (-1)
++#define WLAN_STATUS_NOT_ACCEPTED (-2)
++
++
++/**
++ * @brief This function opens/create a file in kernel mode.
++ *
++ * @param filename Name of the file to be opened
++ * @param flags File flags
++ * @param mode File permissions
++ * @return file pointer if successful or NULL if failed.
++ */
++static struct file * wlan_fopen(const char * filename, unsigned int flags, int mode)
++{
++ int orgfsuid, orgfsgid;
++ struct file * file_ret;
++
++ /* Save uid and gid used for filesystem access. */
++
++ orgfsuid = current->fsuid;
++ orgfsgid = current->fsgid;
++
++ /* Set user and group to 0 (root) */
++ current->fsuid = 0;
++ current->fsgid = 0;
++
++ /* Open the file in kernel mode */
++ file_ret = filp_open(filename, flags, mode);
++
++ /* Restore the uid and gid */
++ current->fsuid = orgfsuid;
++ current->fsgid = orgfsgid;
++
++ /* Check if the file was opened successfully
++ and return the file pointer of it was. */
++ return ((IS_ERR(file_ret)) ? NULL : file_ret);
++}
++
++
++
++/**
++ * @brief This function closes a file in kernel mode.
++ *
++ * @param file_ptr File pointer
++ * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
++ */
++static int wlan_fclose(struct file * file_ptr)
++{
++ int orgfsuid, orgfsgid;
++ int file_ret;
++
++ if((NULL == file_ptr) || (IS_ERR(file_ptr)))
++ return -ENOENT;
++
++ /* Save uid and gid used for filesystem access. */
++ orgfsuid = current->fsuid;
++ orgfsgid = current->fsgid;
++
++ /* Set user and group to 0 (root) */
++ current->fsuid = 0;
++ current->fsgid = 0;
++
++ /* Close the file in kernel mode (user_id = 0) */
++ file_ret = filp_close(file_ptr, 0);
++
++ /* Restore the uid and gid */
++ current->fsuid = orgfsuid;
++ current->fsgid = orgfsgid;
++
++ return (file_ret);
++}
++
++
++
++/**
++ * @brief This function reads data from files in kernel mode.
++ *
++ * @param file_ptr File pointer
++ * @param buf Buffers to read data into
++ * @param len Length of buffer
++ * @return number of characters read
++ */
++static int wlan_fread(struct file * file_ptr, char * buf, int len)
++{
++ int orgfsuid, orgfsgid;
++ int file_ret;
++ mm_segment_t orgfs;
++
++ /* Check if the file pointer is valid */
++ if((NULL == file_ptr) || (IS_ERR(file_ptr)))
++ return -ENOENT;
++
++ /* Check for a valid file read function */
++ if(file_ptr->f_op->read == NULL)
++ return -ENOSYS;
++
++ /* Check for access permissions */
++ if(((file_ptr->f_flags & O_ACCMODE) & (O_RDONLY | O_RDWR)) == 0)
++ return -EACCES;
++
++ /* Check if there is a valid length */
++ if(0 >= len)
++ return -EINVAL;
++
++ /* Save uid and gid used for filesystem access. */
++ orgfsuid = current->fsuid;
++ orgfsgid = current->fsgid;
++
++ /* Set user and group to 0 (root) */
++ current->fsuid = 0;
++ current->fsgid = 0;
++
++ /* Save FS register and set FS register to kernel
++ space, needed for read and write to accept
++ buffer in kernel space. */
++ orgfs = get_fs();
++
++ /* Set the FS register to KERNEL mode. */
++ set_fs(KERNEL_DS);
++
++ /* Read the actual data from the file */
++ file_ret = file_ptr->f_op->read(file_ptr, buf, len, &file_ptr->f_pos);
++
++ /* Restore the FS register */
++ set_fs(orgfs);
++
++ /* Restore the uid and gid */
++ current->fsuid = orgfsuid;
++ current->fsgid = orgfsgid;
++
++ return (file_ret);
++}
++
++
++/**
++ * @brief This function free FW/Helper buffer.
++ *
++ * @param addr Pointer to buffer storing FW/Helper
++ * @return None
++ */
++void fw_buffer_free( u8 *addr )
++{
++ vfree( addr );
++}
++
++
++
++/**
++ * @brief This function reads FW/Helper.
++ *
++ * @param name File name
++ * @param addr Pointer to buffer storing FW/Helper
++ * @param len Pointer to length of FW/Helper
++ * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
++ */
++int fw_read( char *name, u8 **addr, u32 *len )
++{
++ struct file *fp;
++ int ret;
++ u8 *ptr;
++
++ fp = wlan_fopen(name, O_RDWR, 0 );
++
++ if ( fp == NULL ) {
++ printk("Could not open file:%s\n", name );
++ return WLAN_STATUS_FAILURE;
++ }
++
++ /*calculate file length*/
++ *len = fp->f_dentry->d_inode->i_size - fp->f_pos;
++
++ ptr= (u8 *)vmalloc( *len+1023 );
++ if ( ptr == NULL ) {
++ printk("vmalloc failure\n");
++ return WLAN_STATUS_FAILURE;
++ }
++ if(wlan_fread(fp, ptr,*len) > 0)
++ {
++ *addr = ptr;
++ ret = WLAN_STATUS_SUCCESS;
++ }
++ else
++ {
++ fw_buffer_free(ptr);
++ *addr = NULL;
++ printk("fail to read the file %s \n", name);
++ ret = WLAN_STATUS_FAILURE;
++ }
++
++ wlan_fclose( fp );
++ return ret;
++}
++
++
++#endif
++
+
+ /********************************************************************/
+ /* Firmware */
+@@ -400,7 +676,8 @@
+ {
+ int ret;
+ u8 status;
+- const struct firmware *fw;
++ //const struct firmware *fw;
++ struct firmware *fw;
+ unsigned long timeout;
+ u8 *chunk_buffer;
+ u32 chunk_size;
+@@ -408,13 +685,37 @@
+ size_t size;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+-
++#if 0
+ ret = request_firmware(&fw, card->helper, &card->func->dev);
+ if (ret) {
+ lbs_pr_err("can't load helper firmware\n");
+ goto out;
+ }
+
++
++#endif
++#if 1
++ u8 *ptr = NULL;
++ u32 len = 0;
++
++ if ( card->helper != NULL ) {
++ if( fw_read( "/lib/firmware/helper_sd.bin", &ptr, &len ) != WLAN_STATUS_FAILURE ) {
++ //printk("After calling************\n");
++ // fw->data = ptr;
++ // fw->size = len;
++ // printk( "helper read success, len=%x\n", len);
++ }
++ else {
++ printk("helper %s read fail.\n", card->helper);
++ ret = WLAN_STATUS_FAILURE;
++ goto out;
++ }
++ }
++
++
++#endif
++
++
+ chunk_buffer = kzalloc(64, GFP_KERNEL);
+ if (!chunk_buffer) {
+ ret = -ENOMEM;
+@@ -427,8 +728,10 @@
+ if (ret)
+ goto release;
+
+- firmware = fw->data;
+- size = fw->size;
++// firmware = fw->data;
++// size = fw->size;
++ firmware =ptr ;
++ size = len;
+
+ while (size) {
+ timeout = jiffies + HZ;
+@@ -497,11 +800,13 @@
+ ret = 0;
+
+ release:
+- sdio_set_block_size(card->func, 0);
++// sdio_set_block_size(card->func, 0);
++ sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
+ sdio_release_host(card->func);
+ kfree(chunk_buffer);
+ release_fw:
+- release_firmware(fw);
++// release_firmware(fw);
++ vfree(ptr);
+
+ out:
+ if (ret)
+@@ -524,12 +829,32 @@
+ size_t size, req_size;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+-
++#if 0
+ ret = request_firmware(&fw, card->firmware, &card->func->dev);
+ if (ret) {
+ lbs_pr_err("can't load firmware\n");
+ goto out;
+ }
++#endif
++
++ u8 *ptr = NULL;
++ u32 len = 0;
++
++ if ( card->firmware != NULL ) {
++ if( fw_read( "/lib/firmware/sd8688.bin", &ptr, &len ) != WLAN_STATUS_FAILURE ) {
++// printk("After calling************\n");
++ // fw->data = ptr;
++ // fw->size = len;
++// printk( "firmware read success, len=%x\n", len);
++ }
++ else {
++ printk("firmware %s read fail.\n", card->firmware);
++ ret = WLAN_STATUS_FAILURE;
++ goto out;
++ }
++ }
++
++
+
+ chunk_buffer = kzalloc(512, GFP_KERNEL);
+ if (!chunk_buffer) {
+@@ -543,8 +868,12 @@
+ if (ret)
+ goto release;
+
+- firmware = fw->data;
+- size = fw->size;
++// firmware = fw->data;
++// size = fw->size;
++
++ firmware = ptr;
++ size = len;
++
+
+ while (size) {
+ timeout = jiffies + HZ;
+@@ -633,11 +962,13 @@
+ ret = 0;
+
+ release:
+- sdio_set_block_size(card->func, 0);
++// sdio_set_block_size(card->func, 0);
++ sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
+ sdio_release_host(card->func);
+ kfree(chunk_buffer);
+ release_fw:
+- release_firmware(fw);
++// release_firmware(fw);
++ vfree(ptr);
+
+ out:
+ if (ret)
+@@ -662,6 +993,8 @@
+ if (ret)
+ goto out;
+
++ lbs_deb_sdio("firmware status = %#x\n", scratch);
++
+ if (scratch == IF_SDIO_FIRMWARE_OK) {
+ lbs_deb_sdio("firmware already loaded\n");
+ goto success;
+@@ -958,10 +1291,22 @@
+
+ priv->fw_ready = 1;
+
++ sdio_claim_host(func);
++
++ /*
++ * Get rx_unit if the chip is SD8688 or newer.
++ * SD8385 & SD8686 do not have rx_unit.
++ */
++ if ((card->model != IF_SDIO_MODEL_8385)
++ && (card->model != IF_SDIO_MODEL_8686))
++ card->rx_unit = if_sdio_read_rx_unit(card);
++ else
++ card->rx_unit = 0;
++
+ /*
+ * Enable interrupts now that everything is set up
+ */
+- sdio_claim_host(func);
++// sdio_claim_host(func);
+ sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
+ sdio_release_host(func);
+ if (ret)
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/if_sdio.h linux-2.6.25/drivers/net/wireless/libertas/if_sdio.h
+--- linux-2.6.25_original/drivers/net/wireless/libertas/if_sdio.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/if_sdio.h 2009-08-11 17:41:43.000000000 +0530
+@@ -12,6 +12,10 @@
+ #ifndef _LBS_IF_SDIO_H
+ #define _LBS_IF_SDIO_H
+
++#define IF_SDIO_MODEL_8385 0x04
++#define IF_SDIO_MODEL_8686 0x0b
++#define IF_SDIO_MODEL_8688 0x10
++
+ #define IF_SDIO_IOPORT 0x00
+
+ #define IF_SDIO_H_INT_MASK 0x04
+@@ -38,8 +42,14 @@
+
+ #define IF_SDIO_SCRATCH 0x34
+ #define IF_SDIO_SCRATCH_OLD 0x80fe
++#define IF_SDIO_FW_STATUS 0x40
+ #define IF_SDIO_FIRMWARE_OK 0xfedc
+
++#define IF_SDIO_RX_LEN 0x42
++#define IF_SDIO_RX_UNIT 0x43
++
+ #define IF_SDIO_EVENT 0x80fc
++#define IF_SDIO_BLOCK_SIZE 256
++
+
+ #endif
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/main.c linux-2.6.25/drivers/net/wireless/libertas/main.c
+--- linux-2.6.25_original/drivers/net/wireless/libertas/main.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/main.c 2009-08-11 17:41:43.000000000 +0530
+@@ -457,7 +457,11 @@
+ lbs_deb_enter(LBS_DEB_NET);
+
+ spin_lock_irq(&priv->driver_lock);
++ mutex_lock(&priv->lock);
+ priv->infra_open = 0;
++ priv->connect_status = LBS_DISCONNECTED;
++ priv->pending_assoc_req = NULL;
++ mutex_unlock(&priv->lock);
+ netif_stop_queue(dev);
+ spin_unlock_irq(&priv->driver_lock);
+
+diff -Naur linux-2.6.25_original/drivers/net/wireless/libertas/rx.c linux-2.6.25/drivers/net/wireless/libertas/rx.c
+--- linux-2.6.25_original/drivers/net/wireless/libertas/rx.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/net/wireless/libertas/rx.c 2009-08-11 17:41:43.000000000 +0530
+@@ -25,7 +25,7 @@
+ } __attribute__ ((packed));
+
+ struct rxpackethdr {
+- struct rxpd rx_pd;
++// struct rxpd rx_pd;
+ struct eth803hdr eth803_hdr;
+ struct rfc1042hdr rfc1042_hdr;
+ } __attribute__ ((packed));
+@@ -158,8 +158,11 @@
+ if (priv->monitormode != LBS_MONITOR_OFF)
+ return process_rxed_802_11_packet(priv, skb);
+
+- p_rx_pkt = (struct rxpackethdr *) skb->data;
+- p_rx_pd = &p_rx_pkt->rx_pd;
++// p_rx_pkt = (struct rxpackethdr *) skb->data;
++// p_rx_pd = &p_rx_pkt->rx_pd;
++ p_rx_pd = (struct rxpd *) skb->data;
++ p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
++ le32_to_cpu(p_rx_pd->pkt_ptr));
+ if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
+ dev = priv->mesh_dev;
+
+@@ -184,8 +187,12 @@
+ goto done;
+ }
+
+- lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
+- skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
++// lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
++// skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
++
++ lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
++ skb->len, le32_to_cpu(p_rx_pd->pkt_ptr),
++ skb->len - le32_to_cpu(p_rx_pd->pkt_ptr));
+
+ lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
+ sizeof(p_rx_pkt->eth803_hdr.dest_addr));
+@@ -219,14 +226,16 @@
+ /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
+ * that was removed
+ */
+- hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
++// hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
++ hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
+ } else {
+ lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
+ (u8 *) & p_rx_pkt->rfc1042_hdr,
+ sizeof(p_rx_pkt->rfc1042_hdr));
+
+ /* Chop off the rxpd */
+- hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
++// hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
++ hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd;
+ }
+
+ /* Chop off the leading header bytes so the skb points to the start of
+diff -Naur linux-2.6.25_original/drivers/rtc/rtc-ds1307.c linux-2.6.25/drivers/rtc/rtc-ds1307.c
+--- linux-2.6.25_original/drivers/rtc/rtc-ds1307.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/rtc/rtc-ds1307.c 2009-05-16 18:43:58.000000000 +0530
+@@ -336,17 +336,32 @@
+
+ chip = find_chip(client->name);
+ if (!chip) {
++ printk("%s : unknown chip type '%s' \n",__FILE__,client->name);
+ dev_err(&client->dev, "unknown chip type '%s'\n",
+ client->name);
+ return -ENODEV;
+ }
++ else
++ {
++ //printk("%s : Known Chip type is found \n",__FILE__);
++ }
+
+ if (!i2c_check_functionality(adapter,
+ I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
++ {
++ printk("%s : I2C Functionality Check is failed \n",__FILE__);
+ return -EIO;
++ }
++ else
++ {
++ //printk("%s : I2C Functionality Check is Success \n",__FILE__);
++ }
+
+ if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
++ {
++ printk("%s : Memory allocating is failed for ds1307 \n",__FILE__);
+ return -ENOMEM;
++ }
+
+ ds1307->client = client;
+ i2c_set_clientdata(client, ds1307);
+@@ -362,6 +377,8 @@
+ ds1307->msg[1].buf = ds1307->regs;
+
+ ds1307->type = chip->type;
++
++ //printk("%s : ds1307->type is %d \n",__FILE__,ds1307->type);
+
+ switch (ds1307->type) {
+ case ds_1337:
+diff -Naur linux-2.6.25_original/drivers/serial/8250.c linux-2.6.25/drivers/serial/8250.c
+--- linux-2.6.25_original/drivers/serial/8250.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/8250.c 2009-05-16 18:43:58.000000000 +0530
+@@ -94,19 +94,82 @@
+
+ #include <asm/serial.h>
+
++#ifdef CONFIG_MACH_SIRIUS
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x15000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00400000
++#define QUAD_UART_C_OFFSET_ADDR 0x00800000
++#define QUAD_UART_D_OFFSET_ADDR 0x00C00000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 19
++#define GPIO_FOR_QUAD_UART_B_IRQ 11
++#define GPIO_FOR_QUAD_UART_C_IRQ 13
++#define GPIO_FOR_QUAD_UART_D_IRQ 14
++#elif defined(CONFIG_MACH_REGULUS)
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x14000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00200000
++#define QUAD_UART_C_OFFSET_ADDR 0x00400000
++#define QUAD_UART_D_OFFSET_ADDR 0x00600000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 29
++#define GPIO_FOR_QUAD_UART_B_IRQ 115
++#define GPIO_FOR_QUAD_UART_C_IRQ 14
++#define GPIO_FOR_QUAD_UART_D_IRQ 114
++#endif
++#define GPIO_FOR_QUAD_UART_A_IRQ_MD (GPIO_FOR_QUAD_UART_A_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_B_IRQ_MD (GPIO_FOR_QUAD_UART_B_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_C_IRQ_MD (GPIO_FOR_QUAD_UART_C_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_D_IRQ_MD (GPIO_FOR_QUAD_UART_D_IRQ | GPIO_IN)
++#define QUAD_UART_A_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_A_IRQ)
++#define QUAD_UART_B_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_B_IRQ)
++#define QUAD_UART_C_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_C_IRQ)
++#define QUAD_UART_D_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_D_IRQ)
++
++
++
++
++
++#undef BASE_BAUD
++#define BASE_BAUD ( 11059200 / 16 )
+ /*
+ * SERIAL_PORT_DFNS tells us about built-in ports that have no
+ * standard enumeration mechanism. Platforms that can find all
+ * serial ports via mechanisms like ACPI or PCI need not supply it.
+ */
++#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+ #ifndef SERIAL_PORT_DFNS
+-#define SERIAL_PORT_DFNS
++#warning "SERIAL_PORT_DFNS is not defined in include/asm/serial.h file"
++#define SERIAL_PORT_DFNS \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_A_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_A_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_A_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_B_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_A_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_C_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_A_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_D_VIRT_ADDR,1},
++
+ #endif
+
+ static const struct old_serial_port old_serial_port[] = {
+ SERIAL_PORT_DFNS /* defined in asm/serial.h */
+ };
+
++
++
+ #define UART_NR CONFIG_SERIAL_8250_NR_UARTS
+
+ #ifdef CONFIG_SERIAL_8250_RSA
+@@ -2589,9 +2652,9 @@
+ static struct uart_driver serial8250_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "serial",
+- .dev_name = "ttyS",
++ .dev_name = "ttyEQ",
+ .major = TTY_MAJOR,
+- .minor = 64,
++ .minor = 68,
+ .nr = UART_NR,
+ .cons = SERIAL8250_CONSOLE,
+ };
+@@ -2755,6 +2818,7 @@
+ * modems and PCI multiport cards.
+ */
+ static DEFINE_MUTEX(serial_mutex);
++static DECLARE_MUTEX(serial_sem);
+
+ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
+ {
+@@ -2862,6 +2926,27 @@
+ mutex_unlock(&serial_mutex);
+ }
+ EXPORT_SYMBOL(serial8250_unregister_port);
++
++/**
++ * serial8250_unregister_by_port - remove a 16x50 serial port
++ * at runtime.
++ * @port: A &struct uart_port that describes the port to remove.
++ *
++ * Remove one serial port. This may not be called from interrupt
++ * context. We hand the port back to the our control.
++ */
++void serial8250_unregister_by_port(struct uart_port *port)
++{
++ struct uart_8250_port *uart;
++
++ down(&serial_sem);
++ uart = serial8250_find_match_or_unused(port);
++ up(&serial_sem);
++
++ if (uart)
++ serial8250_unregister_port(uart->port.line);
++}
++EXPORT_SYMBOL(serial8250_unregister_by_port);
+
+ static int __init serial8250_init(void)
+ {
+@@ -2877,26 +2962,46 @@
+ for (i = 0; i < NR_IRQS; i++)
+ spin_lock_init(&irq_lists[i].lock);
+
++ printk("FUNC %s(): LINE %d: Registering uart_driver \n",__FUNCTION__,__LINE__);
++
+ ret = uart_register_driver(&serial8250_reg);
+ if (ret)
++ {
++ printk("FUNC %s(): LINE %d: Failed in Registering uart_driver \n",__FUNCTION__,__LINE__);
+ goto out;
++ }
++ printk("FUNC %s(): LINE %d: Allocating platform device \n",__FUNCTION__,__LINE__);
+
+ serial8250_isa_devs = platform_device_alloc("serial8250",
+ PLAT8250_DEV_LEGACY);
+ if (!serial8250_isa_devs) {
++ printk("FUNC %s(): LINE %d: serial8250_isa_devs is NULL \n",__FUNCTION__,__LINE__);
+ ret = -ENOMEM;
+ goto unreg_uart_drv;
+ }
++ printk("FUNC %s(): LINE %d: Adding platform device \n",__FUNCTION__,__LINE__);
+
+ ret = platform_device_add(serial8250_isa_devs);
+ if (ret)
++ {
++ printk("FUNC %s(): LINE %d: Failed in Adding platform device \n",__FUNCTION__,__LINE__);
+ goto put_dev;
+-
++ }
++
++ printk("FUNC %s(): LINE %d: Registeting serial8250 ports \n",__FUNCTION__,__LINE__);
+ serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
+
++ printk("FUNC %s(): LINE %d: Registeting platform driver \n",__FUNCTION__,__LINE__);
+ ret = platform_driver_register(&serial8250_isa_driver);
+ if (ret == 0)
++ {
++ printk("FUNC %s(): LINE %d: Success in Registeting platform driver \n",__FUNCTION__,__LINE__);
+ goto out;
++ }
++ else
++ {
++ printk("FUNC %s(): LINE %d: Failed in Registeting platform driver \n",__FUNCTION__,__LINE__);
++ }
+
+ platform_device_del(serial8250_isa_devs);
+ put_dev:
+diff -Naur linux-2.6.25_original/drivers/serial/8250_kgdb.c linux-2.6.25/drivers/serial/8250_kgdb.c
+--- linux-2.6.25_original/drivers/serial/8250_kgdb.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/serial/8250_kgdb.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,521 @@
++/*
++ * 8250 interface for kgdb.
++ *
++ * This is a merging of many different drivers, and all of the people have
++ * had an impact in some form or another:
++ *
++ * 2004-2005 (c) MontaVista Software, Inc.
++ * 2005-2006 (c) Wind River Systems, Inc.
++ *
++ * Amit Kale <amitkale@emsyssoft.com>, David Grothe <dave@gcom.com>,
++ * Scott Foehner <sfoehner@engr.sgi.com>, George Anzinger <george@mvista.com>,
++ * Robert Walsh <rjwalsh@durables.org>, wangdi <wangdi@clusterfs.com>,
++ * San Mehat, Tom Rini <trini@mvista.com>,
++ * Jason Wessel <jason.wessel@windriver.com>
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/kgdb.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/serialP.h>
++#include <linux/ioport.h>
++
++#include <asm/io.h>
++#include <asm/serial.h> /* For BASE_BAUD and SERIAL_PORT_DFNS */
++
++#include "8250.h"
++
++#define GDB_BUF_SIZE 512 /* power of 2, please */
++
++MODULE_DESCRIPTION("KGDB driver for the 8250");
++MODULE_LICENSE("GPL");
++/* These will conflict with early_param otherwise. */
++#ifdef CONFIG_KGDB_8250_MODULE
++static char config[256];
++module_param_string(kgdb8250, config, 256, 0);
++MODULE_PARM_DESC(kgdb8250,
++ " kgdb8250=<io or mmio>,<address>,<baud rate>,<irq>\n");
++static struct kgdb_io local_kgdb_io_ops;
++#endif /* CONFIG_KGDB_8250_MODULE */
++
++/* Speed of the UART. */
++static int kgdb8250_baud;
++
++/* Flag for if we need to call request_mem_region */
++static int kgdb8250_needs_request_mem_region;
++
++static char kgdb8250_buf[GDB_BUF_SIZE];
++static atomic_t kgdb8250_buf_in_cnt;
++static int kgdb8250_buf_out_inx;
++
++/* Old-style serial definitions, if existant, and a counter. */
++#ifdef CONFIG_KGDB_SIMPLE_SERIAL
++static int __initdata should_copy_rs_table = 1;
++static struct serial_state old_rs_table[] __initdata = {
++#ifdef SERIAL_PORT_DFNS
++ SERIAL_PORT_DFNS
++#endif
++};
++#endif
++
++/* Our internal table of UARTS. */
++#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
++static struct uart_port kgdb8250_ports[UART_NR];
++
++static struct uart_port *current_port;
++
++/* Base of the UART. */
++static void *kgdb8250_addr;
++
++/* Forward declarations. */
++static int kgdb8250_uart_init(void);
++static int __init kgdb_init_io(void);
++static int __init kgdb8250_opt(char *str);
++
++/* These are much shorter calls to ioread8/iowrite8 that take into
++ * account our shifts, etc. */
++static inline unsigned int kgdb_ioread(u8 mask)
++{
++ return ioread8(kgdb8250_addr + (mask << current_port->regshift));
++}
++
++static inline void kgdb_iowrite(u8 val, u8 mask)
++{
++ iowrite8(val, kgdb8250_addr + (mask << current_port->regshift));
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void kgdb_put_debug_char(u8 chr)
++{
++ while (!(kgdb_ioread(UART_LSR) & UART_LSR_THRE)) ;
++
++ kgdb_iowrite(chr, UART_TX);
++}
++
++/*
++ * Get a byte from the hardware data buffer and return it
++ */
++static int read_data_bfr(void)
++{
++ char it = kgdb_ioread(UART_LSR);
++
++ if (it & UART_LSR_DR)
++ return kgdb_ioread(UART_RX);
++
++ /*
++ * If we have a framing error assume somebody messed with
++ * our uart. Reprogram it and send '-' both ways...
++ */
++ if (it & 0xc) {
++ kgdb8250_uart_init();
++ kgdb_put_debug_char('-');
++ return '-';
++ }
++
++ return -1;
++}
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++ */
++static int kgdb_get_debug_char(void)
++{
++ int retchr;
++
++ /* intr routine has q'd chars */
++ if (atomic_read(&kgdb8250_buf_in_cnt) != 0) {
++ retchr = kgdb8250_buf[kgdb8250_buf_out_inx++];
++ kgdb8250_buf_out_inx &= (GDB_BUF_SIZE - 1);
++ atomic_dec(&kgdb8250_buf_in_cnt);
++ return retchr;
++ }
++
++ do {
++ retchr = read_data_bfr();
++ } while (retchr < 0);
++
++ return retchr;
++}
++
++/*
++ * This is the receiver interrupt routine for the GDB stub.
++ * All that we need to do is verify that the interrupt happened on the
++ * line we're in charge of. If this is true, schedule a breakpoint and
++ * return.
++ */
++static irqreturn_t
++kgdb8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++ if (kgdb_ioread(UART_IIR) & UART_IIR_RDI) {
++ /* Throw away the data if another I/O routine is active. */
++ if (kgdb_io_ops.read_char != kgdb_get_debug_char &&
++ (kgdb_ioread(UART_LSR) & UART_LSR_DR))
++ kgdb_ioread(UART_RX);
++ else
++ breakpoint();
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Initializes the UART.
++ * Returns:
++ * 0 on success, 1 on failure.
++ */
++static int
++kgdb8250_uart_init (void)
++{
++ unsigned int ier, base_baud = current_port->uartclk ?
++ current_port->uartclk / 16 : BASE_BAUD;
++
++ /* test uart existance */
++ if(kgdb_ioread(UART_LSR) == 0xff)
++ return -1;
++
++ /* disable interrupts */
++ kgdb_iowrite(0, UART_IER);
++
++#if defined(CONFIG_ARCH_OMAP1510)
++ /* Workaround to enable 115200 baud on OMAP1510 internal ports */
++ if (cpu_is_omap1510() && is_omap_port((void *)kgdb8250_addr)) {
++ if (kgdb8250_baud == 115200) {
++ base_baud = 1;
++ kgdb8250_baud = 1;
++ kgdb_iowrite(1, UART_OMAP_OSC_12M_SEL);
++ } else
++ kgdb_iowrite(0, UART_OMAP_OSC_12M_SEL);
++ }
++#endif
++ /* set DLAB */
++ kgdb_iowrite(UART_LCR_DLAB, UART_LCR);
++
++ /* set baud */
++ kgdb_iowrite((base_baud / kgdb8250_baud) & 0xff, UART_DLL);
++ kgdb_iowrite((base_baud / kgdb8250_baud) >> 8, UART_DLM);
++
++ /* reset DLAB, set LCR */
++ kgdb_iowrite(UART_LCR_WLEN8, UART_LCR);
++
++ /* set DTR and RTS */
++ kgdb_iowrite(UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS, UART_MCR);
++
++ /* setup fifo */
++ kgdb_iowrite(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR
++ | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_8,
++ UART_FCR);
++
++ /* clear pending interrupts */
++ kgdb_ioread(UART_IIR);
++ kgdb_ioread(UART_RX);
++ kgdb_ioread(UART_LSR);
++ kgdb_ioread(UART_MSR);
++
++ /* turn on RX interrupt only */
++ kgdb_iowrite(UART_IER_RDI, UART_IER);
++
++ /*
++ * Borrowed from the main 8250 driver.
++ * Try writing and reading the UART_IER_UUE bit (b6).
++ * If it works, this is probably one of the Xscale platform's
++ * internal UARTs.
++ * We're going to explicitly set the UUE bit to 0 before
++ * trying to write and read a 1 just to make sure it's not
++ * already a 1 and maybe locked there before we even start start.
++ */
++ ier = kgdb_ioread(UART_IER);
++ kgdb_iowrite(ier & ~UART_IER_UUE, UART_IER);
++ if (!(kgdb_ioread(UART_IER) & UART_IER_UUE)) {
++ /*
++ * OK it's in a known zero state, try writing and reading
++ * without disturbing the current state of the other bits.
++ */
++ kgdb_iowrite(ier | UART_IER_UUE, UART_IER);
++ if (kgdb_ioread(UART_IER) & UART_IER_UUE)
++ /*
++ * It's an Xscale.
++ */
++ ier |= UART_IER_UUE | UART_IER_RTOIE;
++ }
++ kgdb_iowrite(ier, UART_IER);
++ return 0;
++}
++
++/*
++ * Copy the old serial_state table to our uart_port table if we haven't
++ * had values specifically configured in. We need to make sure this only
++ * happens once.
++ */
++static void __init kgdb8250_copy_rs_table(void)
++{
++#ifdef CONFIG_KGDB_SIMPLE_SERIAL
++ int i;
++
++ if (!should_copy_rs_table)
++ return;
++
++ for (i = 0; i < ARRAY_SIZE(old_rs_table); i++) {
++ kgdb8250_ports[i].iobase = old_rs_table[i].port;
++ kgdb8250_ports[i].irq = irq_canonicalize(old_rs_table[i].irq);
++ kgdb8250_ports[i].uartclk = old_rs_table[i].baud_base * 16;
++ kgdb8250_ports[i].membase = old_rs_table[i].iomem_base;
++ kgdb8250_ports[i].iotype = old_rs_table[i].io_type;
++ kgdb8250_ports[i].regshift = old_rs_table[i].iomem_reg_shift;
++ kgdb8250_ports[i].line = i;
++ }
++
++ should_copy_rs_table = 0;
++#endif
++}
++
++/*
++ * Hookup our IRQ line now that it is safe to do so, after we grab any
++ * memory regions we might need to. If we haven't been initialized yet,
++ * go ahead and copy the old_rs_table in.
++ */
++#define SA_SHIRQ 0x04000000
++static void __init kgdb8250_late_init(void)
++{
++ /* Try and copy the old_rs_table. */
++ kgdb8250_copy_rs_table();
++
++#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
++ /* Take the port away from the main driver. */
++ serial8250_unregister_by_port(current_port);
++
++ /* Now reinit the port as the above has disabled things. */
++ kgdb8250_uart_init();
++#endif
++ /* We may need to call request_mem_region() first. */
++ if (kgdb8250_needs_request_mem_region)
++ request_mem_region(current_port->mapbase,
++ 8 << current_port->regshift, "kgdb");
++ if (request_irq(current_port->irq, kgdb8250_interrupt, IRQF_SHARED,
++ "GDB-stub", current_port) < 0)
++ printk(KERN_ERR "KGDB failed to request the serial IRQ (%d)\n",
++ current_port->irq);
++}
++
++static __init int kgdb_init_io(void)
++{
++ /* Give us the basic table of uarts. */
++ kgdb8250_copy_rs_table();
++printk("8250_kgdb.c: initialising IO\n");
++ /* We're either a module and parse a config string, or we have a
++ * semi-static config. */
++#ifdef CONFIG_KGDB_8250_MODULE
++ if (strlen(config)) {
++ if (kgdb8250_opt(config))
++ return -EINVAL;
++ } else {
++ printk(KERN_ERR "kgdb8250: argument error, usage: "
++ "kgdb8250=<io or mmio>,<address>,<baud rate>,<irq>\n");
++ return -EINVAL;
++ }
++printk("8250_kgdb.c: initialising IO CONFIG_KGDB_8250_MODULE\n");
++#elif defined(CONFIG_KGDB_SIMPLE_SERIAL)
++ kgdb8250_baud = CONFIG_KGDB_BAUDRATE;
++
++ /* Setup our pointer to the serial port now. */
++ current_port = &kgdb8250_ports[CONFIG_KGDB_PORT_NUM];
++printk("8250_kgdb.c: initialising IO CONFIG_KGDB_SIMPLE_SERIAL\n");
++#else
++printk("8250_kgdb.c: initialising IO else\n");
++ if (kgdb8250_opt(CONFIG_KGDB_8250_CONF_STRING))
++ return -EINVAL;
++#endif
++
++
++ /* Internal driver setup. */
++ switch (current_port->iotype) {
++ case UPIO_MEM:
++ if (current_port->mapbase)
++ kgdb8250_needs_request_mem_region = 1;
++ if (current_port->flags & UPF_IOREMAP) {
++ current_port->membase = ioremap(current_port->mapbase,
++ 8 << current_port->regshift);
++ if (!current_port->membase)
++ return -EIO; /* Failed. */
++ }
++ kgdb8250_addr = current_port->membase;
++ break;
++ case UPIO_PORT:
++ default:
++ kgdb8250_addr = ioport_map(current_port->iobase,
++ 8 << current_port->regshift);
++ if (!kgdb8250_addr)
++ return -EIO; /* Failed. */
++ }
++
++ if (kgdb8250_uart_init() == -1) {
++ printk(KERN_ERR "kgdb8250: init failed\n");
++ return -EIO;
++ }
++#ifdef CONFIG_KGDB_8250_MODULE
++ /* Attach the kgdb irq. When this is built into the kernel, it
++ * is called as a part of late_init sequence.
++ */
++ kgdb8250_late_init();
++ if (kgdb_register_io_module(&local_kgdb_io_ops))
++ return -EINVAL;
++
++ printk(KERN_INFO "kgdb8250: debugging enabled\n");
++#endif /* CONFIG_KGD_8250_MODULE */
++
++ return 0;
++}
++
++#ifdef CONFIG_KGDB_8250_MODULE
++/* If it is a module the kgdb_io_ops should be a static which
++ * is passed to the KGDB I/O initialization
++ */
++static struct kgdb_io local_kgdb_io_ops = {
++#else /* ! CONFIG_KGDB_8250_MODULE */
++struct kgdb_io kgdb_io_ops = {
++#endif /* ! CONFIG_KGD_8250_MODULE */
++ .read_char = kgdb_get_debug_char,
++ .write_char = kgdb_put_debug_char,
++ .init = kgdb_init_io,
++ .late_init = kgdb8250_late_init,
++};
++
++/**
++ * kgdb8250_add_port - Define a serial port for use with KGDB
++ * @i: The index of the port being added
++ * @serial_req: The &struct uart_port describing the port
++ *
++ * On platforms where we must register the serial device
++ * dynamically, this is the best option if a platform also normally
++ * calls early_serial_setup().
++ */
++void __init kgdb8250_add_port(int i, struct uart_port *serial_req)
++{
++ /* Make sure we've got the built-in data before we override. */
++ kgdb8250_copy_rs_table();
++
++ /* Copy the whole thing over. */
++ if (current_port != &kgdb8250_ports[i])
++ memcpy(&kgdb8250_ports[i], serial_req, sizeof(struct uart_port));
++}
++
++/**
++ * kgdb8250_add_platform_port - Define a serial port for use with KGDB
++ * @i: The index of the port being added
++ * @p: The &struct plat_serial8250_port describing the port
++ *
++ * On platforms where we must register the serial device
++ * dynamically, this is the best option if a platform normally
++ * handles uart setup with an array of &struct plat_serial8250_port.
++ */
++void __init kgdb8250_add_platform_port(int i, struct plat_serial8250_port *p)
++{
++ /* Make sure we've got the built-in data before we override. */
++ kgdb8250_copy_rs_table();
++
++ kgdb8250_ports[i].iobase = p->iobase;
++ kgdb8250_ports[i].membase = p->membase;
++ kgdb8250_ports[i].irq = p->irq;
++ kgdb8250_ports[i].uartclk = p->uartclk;
++ kgdb8250_ports[i].regshift = p->regshift;
++ kgdb8250_ports[i].iotype = p->iotype;
++ kgdb8250_ports[i].flags = p->flags;
++ kgdb8250_ports[i].mapbase = p->mapbase;
++}
++
++/*
++ * Syntax for this cmdline option is:
++ * kgdb8250=<io or mmio>,<address>,<baud rate>,<irq>"
++ */
++static int __init kgdb8250_opt(char *str)
++{
++ /* We'll fill out and use the first slot. */
++ current_port = &kgdb8250_ports[0];
++
++ if (!strncmp(str, "io", 2)) {
++ current_port->iotype = UPIO_PORT;
++ str += 2;
++ } else if (!strncmp(str, "mmap", 4)) {
++ current_port->iotype = UPIO_MEM;
++ current_port->flags |= UPF_IOREMAP;
++ str += 4;
++ } else if (!strncmp(str, "mmio", 4)) {
++ current_port->iotype = UPIO_MEM;
++ current_port->flags &= ~UPF_IOREMAP;
++ str += 4;
++ } else
++ goto errout;
++
++ if (*str != ',')
++ goto errout;
++ str++;
++
++ if (current_port->iotype == UPIO_PORT)
++ current_port->iobase = simple_strtoul(str, &str, 16);
++ else {
++ if (current_port->flags & UPF_IOREMAP)
++ current_port->mapbase =
++ (unsigned long) simple_strtoul(str, &str, 16);
++ else
++ current_port->membase =
++ (void *) simple_strtoul(str, &str, 16);
++ }
++
++ if (*str != ',')
++ goto errout;
++ str++;
++
++ kgdb8250_baud = simple_strtoul(str, &str, 10);
++ if (!kgdb8250_baud)
++ goto errout;
++
++ if (*str != ',')
++ goto errout;
++ str++;
++
++ current_port->irq = simple_strtoul(str, &str, 10);
++
++#ifdef CONFIG_KGDB_SIMPLE_SERIAL
++ should_copy_rs_table = 0;
++#endif
++
++ return 0;
++
++ errout:
++ printk(KERN_ERR "Invalid syntax for option kgdb8250=\n");
++ return 1;
++}
++
++#ifdef CONFIG_KGDB_8250_MODULE
++static void cleanup_kgdb8250(void)
++{
++ kgdb_unregister_io_module(&local_kgdb_io_ops);
++
++ /* Clean up the irq and memory */
++ free_irq(current_port->irq, current_port);
++
++ if (kgdb8250_needs_request_mem_region)
++ release_mem_region(current_port->mapbase,
++ 8 << current_port->regshift);
++ /* Hook up the serial port back to what it was previously
++ * hooked up to.
++ */
++#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
++ /* Give the port back to the 8250 driver. */
++ serial8250_register_port(current_port);
++#endif
++}
++
++module_init(kgdb_init_io);
++module_exit(cleanup_kgdb8250);
++#else /* ! CONFIG_KGDB_8250_MODULE */
++early_param("kgdb8250", kgdb8250_opt);
++#endif /* ! CONFIG_KGDB_8250_MODULE */
++
+diff -Naur linux-2.6.25_original/drivers/serial/8250_org.c linux-2.6.25/drivers/serial/8250_org.c
+--- linux-2.6.25_original/drivers/serial/8250_org.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/serial/8250_org.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,2947 @@
++/*
++ * linux/drivers/char/8250.c
++ *
++ * Driver for 8250/16550-type serial ports
++ *
++ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ * Copyright (C) 2001 Russell King.
++ *
++ * 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.
++ *
++ * $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $
++ *
++ * A note about mapbase / membase
++ *
++ * mapbase is the physical address of the IO port.
++ * membase is an 'ioremapped' cookie.
++ */
++
++#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_core.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/nmi.h>
++#include <linux/mutex.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "8250.h"
++
++/*
++ * Configuration:
++ * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
++ * is unsafe when used on edge-triggered interrupts.
++ */
++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
++
++static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
++
++/*
++ * Debugging.
++ */
++#if 0
++#define DEBUG_AUTOCONF(fmt...) printk(fmt)
++#else
++#define DEBUG_AUTOCONF(fmt...) do { } while (0)
++#endif
++
++#if 0
++#define DEBUG_INTR(fmt...) printk(fmt)
++#else
++#define DEBUG_INTR(fmt...) do { } while (0)
++#endif
++
++#define PASS_LIMIT 256
++
++/*
++ * We default to IRQ0 for the "no irq" hack. Some
++ * machine types want others as well - they're free
++ * to redefine this in their header file.
++ */
++#define is_real_interrupt(irq) ((irq) != 0)
++
++#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
++#define CONFIG_SERIAL_DETECT_IRQ 1
++#endif
++#ifdef CONFIG_SERIAL_8250_MANY_PORTS
++#define CONFIG_SERIAL_MANY_PORTS 1
++#endif
++
++/*
++ * HUB6 is always on. This will be removed once the header
++ * files have been cleaned.
++ */
++#define CONFIG_HUB6 1
++
++#include <asm/serial.h>
++
++/*
++ * SERIAL_PORT_DFNS tells us about built-in ports that have no
++ * standard enumeration mechanism. Platforms that can find all
++ * serial ports via mechanisms like ACPI or PCI need not supply it.
++ */
++#ifndef SERIAL_PORT_DFNS
++#define SERIAL_PORT_DFNS
++#endif
++
++static const struct old_serial_port old_serial_port[] = {
++ SERIAL_PORT_DFNS /* defined in asm/serial.h */
++};
++
++#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
++
++#ifdef CONFIG_SERIAL_8250_RSA
++
++#define PORT_RSA_MAX 4
++static unsigned long probe_rsa[PORT_RSA_MAX];
++static unsigned int probe_rsa_count;
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++struct uart_8250_port {
++ struct uart_port port;
++ struct timer_list timer; /* "no irq" timer */
++ struct list_head list; /* ports on this IRQ */
++ unsigned short capabilities; /* port capabilities */
++ unsigned short bugs; /* port bugs */
++ unsigned int tx_loadsz; /* transmit fifo load size */
++ unsigned char acr;
++ unsigned char ier;
++ unsigned char lcr;
++ unsigned char mcr;
++ unsigned char mcr_mask; /* mask of user bits */
++ unsigned char mcr_force; /* mask of forced bits */
++
++ /*
++ * Some bits in registers are cleared on a read, so they must
++ * be saved whenever the register is read but the bits will not
++ * be immediately processed.
++ */
++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
++ unsigned char lsr_saved_flags;
++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
++ unsigned char msr_saved_flags;
++
++ /*
++ * We provide a per-port pm hook.
++ */
++ void (*pm)(struct uart_port *port,
++ unsigned int state, unsigned int old);
++};
++
++struct irq_info {
++ spinlock_t lock;
++ struct list_head *head;
++};
++
++static struct irq_info irq_lists[NR_IRQS];
++
++/*
++ * Here we define the default xmit fifo size used for each type of UART.
++ */
++static const struct serial8250_config uart_config[] = {
++ [PORT_UNKNOWN] = {
++ .name = "unknown",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_8250] = {
++ .name = "8250",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16450] = {
++ .name = "16450",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550] = {
++ .name = "16550",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550A] = {
++ .name = "16550A",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_CIRRUS] = {
++ .name = "Cirrus",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16650] = {
++ .name = "ST16650",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16650V2] = {
++ .name = "ST16650V2",
++ .fifo_size = 32,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++ UART_FCR_T_TRIG_00,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16750] = {
++ .name = "TI16750",
++ .fifo_size = 64,
++ .tx_loadsz = 64,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
++ UART_FCR7_64BYTE,
++ .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
++ },
++ [PORT_STARTECH] = {
++ .name = "Startech",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16C950] = {
++ .name = "16C950/954",
++ .fifo_size = 128,
++ .tx_loadsz = 128,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_16654] = {
++ .name = "ST16654",
++ .fifo_size = 64,
++ .tx_loadsz = 32,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++ UART_FCR_T_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16850] = {
++ .name = "XR16850",
++ .fifo_size = 128,
++ .tx_loadsz = 128,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_RSA] = {
++ .name = "RSA",
++ .fifo_size = 2048,
++ .tx_loadsz = 2048,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_NS16550A] = {
++ .name = "NS16550A",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_NATSEMI,
++ },
++ [PORT_XSCALE] = {
++ .name = "XScale",
++ .fifo_size = 32,
++ .tx_loadsz = 32,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_UUE,
++ },
++ [PORT_RM9000] = {
++ .name = "RM9000",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++};
++
++#if defined (CONFIG_SERIAL_8250_AU1X00)
++
++/* Au1x00 UART hardware has a weird register layout */
++static const u8 au_io_in_map[] = {
++ [UART_RX] = 0,
++ [UART_IER] = 2,
++ [UART_IIR] = 3,
++ [UART_LCR] = 5,
++ [UART_MCR] = 6,
++ [UART_LSR] = 7,
++ [UART_MSR] = 8,
++};
++
++static const u8 au_io_out_map[] = {
++ [UART_TX] = 1,
++ [UART_IER] = 2,
++ [UART_FCR] = 4,
++ [UART_LCR] = 5,
++ [UART_MCR] = 6,
++};
++
++/* sane hardware needs no mapping */
++static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_AU)
++ return offset;
++ return au_io_in_map[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_AU)
++ return offset;
++ return au_io_out_map[offset];
++}
++
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++
++static const u8
++ regmap_in[8] = {
++ [UART_RX] = 0x00,
++ [UART_IER] = 0x0c,
++ [UART_IIR] = 0x14,
++ [UART_LCR] = 0x1c,
++ [UART_MCR] = 0x20,
++ [UART_LSR] = 0x24,
++ [UART_MSR] = 0x28,
++ [UART_SCR] = 0x2c
++ },
++ regmap_out[8] = {
++ [UART_TX] = 0x04,
++ [UART_IER] = 0x0c,
++ [UART_FCR] = 0x18,
++ [UART_LCR] = 0x1c,
++ [UART_MCR] = 0x20,
++ [UART_LSR] = 0x24,
++ [UART_MSR] = 0x28,
++ [UART_SCR] = 0x2c
++ };
++
++static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_RM9000)
++ return offset;
++ return regmap_in[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_RM9000)
++ return offset;
++ return regmap_out[offset];
++}
++
++#else
++
++/* sane hardware needs no mapping */
++#define map_8250_in_reg(up, offset) (offset)
++#define map_8250_out_reg(up, offset) (offset)
++
++#endif
++
++static unsigned int serial_in(struct uart_8250_port *up, int offset)
++{
++ unsigned int tmp;
++ offset = map_8250_in_reg(up, offset) << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ outb(up->port.hub6 - 1 + offset, up->port.iobase);
++ return inb(up->port.iobase + 1);
++
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ return readb(up->port.membase + offset);
++
++ case UPIO_RM9000:
++ case UPIO_MEM32:
++ return readl(up->port.membase + offset);
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++ return __raw_readl(up->port.membase + offset);
++#endif
++
++ case UPIO_TSI:
++ if (offset == UART_IIR) {
++ tmp = readl(up->port.membase + (UART_IIR & ~3));
++ return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
++ } else
++ return readb(up->port.membase + offset);
++
++ default:
++ return inb(up->port.iobase + offset);
++ }
++}
++
++static void
++serial_out(struct uart_8250_port *up, int offset, int value)
++{
++ /* Save the offset before it's remapped */
++ int save_offset = offset;
++ offset = map_8250_out_reg(up, offset) << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ outb(up->port.hub6 - 1 + offset, up->port.iobase);
++ outb(value, up->port.iobase + 1);
++ break;
++
++ case UPIO_MEM:
++ writeb(value, up->port.membase + offset);
++ break;
++
++ case UPIO_RM9000:
++ case UPIO_MEM32:
++ writel(value, up->port.membase + offset);
++ break;
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++ __raw_writel(value, up->port.membase + offset);
++ break;
++#endif
++ case UPIO_TSI:
++ if (!((offset == UART_IER) && (value & UART_IER_UUE)))
++ writeb(value, up->port.membase + offset);
++ break;
++
++ case UPIO_DWAPB:
++ /* Save the LCR value so it can be re-written when a
++ * Busy Detect interrupt occurs. */
++ if (save_offset == UART_LCR)
++ up->lcr = value;
++ writeb(value, up->port.membase + offset);
++ /* Read the IER to ensure any interrupt is cleared before
++ * returning from ISR. */
++ if (save_offset == UART_TX || save_offset == UART_IER)
++ value = serial_in(up, UART_IER);
++ break;
++
++ default:
++ outb(value, up->port.iobase + offset);
++ }
++}
++
++static void
++serial_out_sync(struct uart_8250_port *up, int offset, int value)
++{
++ switch (up->port.iotype) {
++ case UPIO_MEM:
++ case UPIO_MEM32:
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++#endif
++ case UPIO_DWAPB:
++ serial_out(up, offset, value);
++ serial_in(up, UART_LCR); /* safe, no side-effects */
++ break;
++ default:
++ serial_out(up, offset, value);
++ }
++}
++
++/*
++ * We used to support using pause I/O for certain machines. We
++ * haven't supported this for a while, but just in case it's badly
++ * needed for certain old 386 machines, I've left these #define's
++ * in....
++ */
++#define serial_inp(up, offset) serial_in(up, offset)
++#define serial_outp(up, offset, value) serial_out(up, offset, value)
++
++/* Uart divisor latch read */
++static inline int _serial_dl_read(struct uart_8250_port *up)
++{
++ return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static inline void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++ serial_outp(up, UART_DLL, value & 0xff);
++ serial_outp(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#if defined(CONFIG_SERIAL_8250_AU1X00)
++/* Au1x00 haven't got a standard divisor latch */
++static int serial_dl_read(struct uart_8250_port *up)
++{
++ if (up->port.iotype == UPIO_AU)
++ return __raw_readl(up->port.membase + 0x28);
++ else
++ return _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_AU)
++ __raw_writel(value, up->port.membase + 0x28);
++ else
++ _serial_dl_write(up, value);
++}
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++static int serial_dl_read(struct uart_8250_port *up)
++{
++ return (up->port.iotype == UPIO_RM9000) ?
++ (((__raw_readl(up->port.membase + 0x10) << 8) |
++ (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
++ _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_RM9000) {
++ __raw_writel(value, up->port.membase + 0x08);
++ __raw_writel(value >> 8, up->port.membase + 0x10);
++ } else {
++ _serial_dl_write(up, value);
++ }
++}
++#else
++#define serial_dl_read(up) _serial_dl_read(up)
++#define serial_dl_write(up, value) _serial_dl_write(up, value)
++#endif
++
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++ serial_out(up, UART_SCR, offset);
++ serial_out(up, UART_ICR, value);
++}
++
++static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
++{
++ unsigned int value;
++
++ serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++ serial_out(up, UART_SCR, offset);
++ value = serial_in(up, UART_ICR);
++ serial_icr_write(up, UART_ACR, up->acr);
++
++ return value;
++}
++
++/*
++ * FIFO support.
++ */
++static inline void serial8250_clear_fifos(struct uart_8250_port *p)
++{
++ if (p->capabilities & UART_CAP_FIFO) {
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++ serial_outp(p, UART_FCR, 0);
++ }
++}
++
++/*
++ * IER sleep support. UARTs which have EFRs need the "extended
++ * capability" bit enabled. Note that on XR16C850s, we need to
++ * reset LCR to write to IER.
++ */
++static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
++{
++ if (p->capabilities & UART_CAP_SLEEP) {
++ if (p->capabilities & UART_CAP_EFR) {
++ serial_outp(p, UART_LCR, 0xBF);
++ serial_outp(p, UART_EFR, UART_EFR_ECB);
++ serial_outp(p, UART_LCR, 0);
++ }
++ serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
++ if (p->capabilities & UART_CAP_EFR) {
++ serial_outp(p, UART_LCR, 0xBF);
++ serial_outp(p, UART_EFR, 0);
++ serial_outp(p, UART_LCR, 0);
++ }
++ }
++}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++/*
++ * Attempts to turn on the RSA FIFO. Returns zero on failure.
++ * We set the port uart clock rate if we succeed.
++ */
++static int __enable_rsa(struct uart_8250_port *up)
++{
++ unsigned char mode;
++ int result;
++
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = mode & UART_RSA_MSR_FIFO;
++
++ if (!result) {
++ serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = mode & UART_RSA_MSR_FIFO;
++ }
++
++ if (result)
++ up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
++
++ return result;
++}
++
++static void enable_rsa(struct uart_8250_port *up)
++{
++ if (up->port.type == PORT_RSA) {
++ if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
++ spin_lock_irq(&up->port.lock);
++ __enable_rsa(up);
++ spin_unlock_irq(&up->port.lock);
++ }
++ if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
++ serial_outp(up, UART_RSA_FRR, 0);
++ }
++}
++
++/*
++ * Attempts to turn off the RSA FIFO. Returns zero on failure.
++ * It is unknown why interrupts were disabled in here. However,
++ * the caller is expected to preserve this behaviour by grabbing
++ * the spinlock before calling this function.
++ */
++static void disable_rsa(struct uart_8250_port *up)
++{
++ unsigned char mode;
++ int result;
++
++ if (up->port.type == PORT_RSA &&
++ up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
++ spin_lock_irq(&up->port.lock);
++
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = !(mode & UART_RSA_MSR_FIFO);
++
++ if (!result) {
++ serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = !(mode & UART_RSA_MSR_FIFO);
++ }
++
++ if (result)
++ up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
++ spin_unlock_irq(&up->port.lock);
++ }
++}
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++/*
++ * This is a quickie test to see how big the FIFO is.
++ * It doesn't work at all the time, more's the pity.
++ */
++static int size_fifo(struct uart_8250_port *up)
++{
++ unsigned char old_fcr, old_mcr, old_lcr;
++ unsigned short old_dl;
++ int count;
++
++ old_lcr = serial_inp(up, UART_LCR);
++ serial_outp(up, UART_LCR, 0);
++ old_fcr = serial_inp(up, UART_FCR);
++ old_mcr = serial_inp(up, UART_MCR);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++ serial_outp(up, UART_MCR, UART_MCR_LOOP);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ old_dl = serial_dl_read(up);
++ serial_dl_write(up, 0x0001);
++ serial_outp(up, UART_LCR, 0x03);
++ for (count = 0; count < 256; count++)
++ serial_outp(up, UART_TX, count);
++ mdelay(20);/* FIXME - schedule_timeout */
++ for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
++ (count < 256); count++)
++ serial_inp(up, UART_RX);
++ serial_outp(up, UART_FCR, old_fcr);
++ serial_outp(up, UART_MCR, old_mcr);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ serial_dl_write(up, old_dl);
++ serial_outp(up, UART_LCR, old_lcr);
++
++ return count;
++}
++
++/*
++ * Read UART ID using the divisor method - set DLL and DLM to zero
++ * and the revision will be in DLL and device type in DLM. We
++ * preserve the device state across this.
++ */
++static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
++{
++ unsigned char old_dll, old_dlm, old_lcr;
++ unsigned int id;
++
++ old_lcr = serial_inp(p, UART_LCR);
++ serial_outp(p, UART_LCR, UART_LCR_DLAB);
++
++ old_dll = serial_inp(p, UART_DLL);
++ old_dlm = serial_inp(p, UART_DLM);
++
++ serial_outp(p, UART_DLL, 0);
++ serial_outp(p, UART_DLM, 0);
++
++ id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
++
++ serial_outp(p, UART_DLL, old_dll);
++ serial_outp(p, UART_DLM, old_dlm);
++ serial_outp(p, UART_LCR, old_lcr);
++
++ return id;
++}
++
++/*
++ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
++ * When this function is called we know it is at least a StarTech
++ * 16650 V2, but it might be one of several StarTech UARTs, or one of
++ * its clones. (We treat the broken original StarTech 16650 V1 as a
++ * 16550, and why not? Startech doesn't seem to even acknowledge its
++ * existence.)
++ *
++ * What evil have men's minds wrought...
++ */
++static void autoconfig_has_efr(struct uart_8250_port *up)
++{
++ unsigned int id1, id2, id3, rev;
++
++ /*
++ * Everything with an EFR has SLEEP
++ */
++ up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++
++ /*
++ * First we check to see if it's an Oxford Semiconductor UART.
++ *
++ * If we have to do this here because some non-National
++ * Semiconductor clone chips lock up if you try writing to the
++ * LSR register (which serial_icr_read does)
++ */
++
++ /*
++ * Check for Oxford Semiconductor 16C950.
++ *
++ * EFR [4] must be set else this test fails.
++ *
++ * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
++ * claims that it's needed for 952 dual UART's (which are not
++ * recommended for new designs).
++ */
++ up->acr = 0;
++ serial_out(up, UART_LCR, 0xBF);
++ serial_out(up, UART_EFR, UART_EFR_ECB);
++ serial_out(up, UART_LCR, 0x00);
++ id1 = serial_icr_read(up, UART_ID1);
++ id2 = serial_icr_read(up, UART_ID2);
++ id3 = serial_icr_read(up, UART_ID3);
++ rev = serial_icr_read(up, UART_REV);
++
++ DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
++
++ if (id1 == 0x16 && id2 == 0xC9 &&
++ (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
++ up->port.type = PORT_16C950;
++
++ /*
++ * Enable work around for the Oxford Semiconductor 952 rev B
++ * chip which causes it to seriously miscalculate baud rates
++ * when DLL is 0.
++ */
++ if (id3 == 0x52 && rev == 0x01)
++ up->bugs |= UART_BUG_QUOT;
++ return;
++ }
++
++ /*
++ * We check for a XR16C850 by setting DLL and DLM to 0, and then
++ * reading back DLL and DLM. The chip type depends on the DLM
++ * value read back:
++ * 0x10 - XR16C850 and the DLL contains the chip revision.
++ * 0x12 - XR16C2850.
++ * 0x14 - XR16C854.
++ */
++ id1 = autoconfig_read_divisor_id(up);
++ DEBUG_AUTOCONF("850id=%04x ", id1);
++
++ id2 = id1 >> 8;
++ if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
++ up->port.type = PORT_16850;
++ return;
++ }
++
++ /*
++ * It wasn't an XR16C850.
++ *
++ * We distinguish between the '654 and the '650 by counting
++ * how many bytes are in the FIFO. I'm using this for now,
++ * since that's the technique that was sent to me in the
++ * serial driver update, but I'm not convinced this works.
++ * I've had problems doing this in the past. -TYT
++ */
++ if (size_fifo(up) == 64)
++ up->port.type = PORT_16654;
++ else
++ up->port.type = PORT_16650V2;
++}
++
++/*
++ * We detected a chip without a FIFO. Only two fall into
++ * this category - the original 8250 and the 16450. The
++ * 16450 has a scratch register (accessible with LCR=0)
++ */
++static void autoconfig_8250(struct uart_8250_port *up)
++{
++ unsigned char scratch, status1, status2;
++
++ up->port.type = PORT_8250;
++
++ scratch = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, 0xa5);
++ status1 = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, 0x5a);
++ status2 = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, scratch);
++
++ if (status1 == 0xa5 && status2 == 0x5a)
++ up->port.type = PORT_16450;
++}
++
++static int broken_efr(struct uart_8250_port *up)
++{
++ /*
++ * Exar ST16C2550 "A2" devices incorrectly detect as
++ * having an EFR, and report an ID of 0x0201. See
++ * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
++ */
++ if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
++ return 1;
++
++ return 0;
++}
++
++/*
++ * We know that the chip has FIFOs. Does it have an EFR? The
++ * EFR is located in the same register position as the IIR and
++ * we know the top two bits of the IIR are currently set. The
++ * EFR should contain zero. Try to read the EFR.
++ */
++static void autoconfig_16550a(struct uart_8250_port *up)
++{
++ unsigned char status1, status2;
++ unsigned int iersave;
++
++ up->port.type = PORT_16550A;
++ up->capabilities |= UART_CAP_FIFO;
++
++ /*
++ * Check for presence of the EFR when DLAB is set.
++ * Only ST16C650V1 UARTs pass this test.
++ */
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ if (serial_in(up, UART_EFR) == 0) {
++ serial_outp(up, UART_EFR, 0xA8);
++ if (serial_in(up, UART_EFR) != 0) {
++ DEBUG_AUTOCONF("EFRv1 ");
++ up->port.type = PORT_16650;
++ up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++ } else {
++ DEBUG_AUTOCONF("Motorola 8xxx DUART ");
++ }
++ serial_outp(up, UART_EFR, 0);
++ return;
++ }
++
++ /*
++ * Maybe it requires 0xbf to be written to the LCR.
++ * (other ST16C650V2 UARTs, TI16C752A, etc)
++ */
++ serial_outp(up, UART_LCR, 0xBF);
++ if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
++ DEBUG_AUTOCONF("EFRv2 ");
++ autoconfig_has_efr(up);
++ return;
++ }
++
++ /*
++ * Check for a National Semiconductor SuperIO chip.
++ * Attempt to switch to bank 2, read the value of the LOOP bit
++ * from EXCR1. Switch back to bank 0, change it in MCR. Then
++ * switch back to bank 2, read it from EXCR1 again and check
++ * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
++ */
++ serial_outp(up, UART_LCR, 0);
++ status1 = serial_in(up, UART_MCR);
++ serial_outp(up, UART_LCR, 0xE0);
++ status2 = serial_in(up, 0x02); /* EXCR1 */
++
++ if (!((status2 ^ status1) & UART_MCR_LOOP)) {
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
++ serial_outp(up, UART_LCR, 0xE0);
++ status2 = serial_in(up, 0x02); /* EXCR1 */
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_MCR, status1);
++
++ if ((status2 ^ status1) & UART_MCR_LOOP) {
++ unsigned short quot;
++
++ serial_outp(up, UART_LCR, 0xE0);
++
++ quot = serial_dl_read(up);
++ quot <<= 3;
++
++ status1 = serial_in(up, 0x04); /* EXCR2 */
++ status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
++ serial_outp(up, 0x04, status1);
++
++ serial_dl_write(up, quot);
++
++ serial_outp(up, UART_LCR, 0);
++
++ up->port.uartclk = 921600*16;
++ up->port.type = PORT_NS16550A;
++ up->capabilities |= UART_NATSEMI;
++ return;
++ }
++ }
++
++ /*
++ * No EFR. Try to detect a TI16750, which only sets bit 5 of
++ * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
++ * Try setting it with and without DLAB set. Cheap clones
++ * set bit 5 without DLAB set.
++ */
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++ status1 = serial_in(up, UART_IIR) >> 5;
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++ status2 = serial_in(up, UART_IIR) >> 5;
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(up, UART_LCR, 0);
++
++ DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
++
++ if (status1 == 6 && status2 == 7) {
++ up->port.type = PORT_16750;
++ up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
++ return;
++ }
++
++ /*
++ * Try writing and reading the UART_IER_UUE bit (b6).
++ * If it works, this is probably one of the Xscale platform's
++ * internal UARTs.
++ * We're going to explicitly set the UUE bit to 0 before
++ * trying to write and read a 1 just to make sure it's not
++ * already a 1 and maybe locked there before we even start start.
++ */
++ iersave = serial_in(up, UART_IER);
++ serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
++ if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
++ /*
++ * OK it's in a known zero state, try writing and reading
++ * without disturbing the current state of the other bits.
++ */
++ serial_outp(up, UART_IER, iersave | UART_IER_UUE);
++ if (serial_in(up, UART_IER) & UART_IER_UUE) {
++ /*
++ * It's an Xscale.
++ * We'll leave the UART_IER_UUE bit set to 1 (enabled).
++ */
++ DEBUG_AUTOCONF("Xscale ");
++ up->port.type = PORT_XSCALE;
++ up->capabilities |= UART_CAP_UUE;
++ return;
++ }
++ } else {
++ /*
++ * If we got here we couldn't force the IER_UUE bit to 0.
++ * Log it and continue.
++ */
++ DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
++ }
++ serial_outp(up, UART_IER, iersave);
++}
++
++/*
++ * This routine is called by rs_init() to initialize a specific serial
++ * port. It determines what type of UART chip this serial port is
++ * using: 8250, 16450, 16550, 16550A. The important question is
++ * whether or not this UART is a 16550A or not, since this will
++ * determine whether or not we can use its FIFO features or not.
++ */
++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
++{
++ unsigned char status1, scratch, scratch2, scratch3;
++ unsigned char save_lcr, save_mcr;
++ unsigned long flags;
++
++ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
++ return;
++
++ DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
++ up->port.line, up->port.iobase, up->port.membase);
++
++ /*
++ * We really do need global IRQs disabled here - we're going to
++ * be frobbing the chips IRQ enable register to see if it exists.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ up->capabilities = 0;
++ up->bugs = 0;
++
++ if (!(up->port.flags & UPF_BUGGY_UART)) {
++ /*
++ * Do a simple existence test first; if we fail this,
++ * there's no point trying anything else.
++ *
++ * 0x80 is used as a nonsense port to prevent against
++ * false positives due to ISA bus float. The
++ * assumption is that 0x80 is a non-existent port;
++ * which should be safe since include/asm/io.h also
++ * makes this assumption.
++ *
++ * Note: this is safe as long as MCR bit 4 is clear
++ * and the device is in "PC" mode.
++ */
++ scratch = serial_inp(up, UART_IER);
++ serial_outp(up, UART_IER, 0);
++#ifdef __i386__
++ outb(0xff, 0x080);
++#endif
++ /*
++ * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
++ * 16C754B) allow only to modify them if an EFR bit is set.
++ */
++ scratch2 = serial_inp(up, UART_IER) & 0x0f;
++ serial_outp(up, UART_IER, 0x0F);
++#ifdef __i386__
++ outb(0, 0x080);
++#endif
++ scratch3 = serial_inp(up, UART_IER) & 0x0f;
++ serial_outp(up, UART_IER, scratch);
++ if (scratch2 != 0 || scratch3 != 0x0F) {
++ /*
++ * We failed; there's nothing here
++ */
++ DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
++ scratch2, scratch3);
++ goto out;
++ }
++ }
++
++ save_mcr = serial_in(up, UART_MCR);
++ save_lcr = serial_in(up, UART_LCR);
++
++ /*
++ * Check to see if a UART is really there. Certain broken
++ * internal modems based on the Rockwell chipset fail this
++ * test, because they apparently don't implement the loopback
++ * test mode. So this test is skipped on the COM 1 through
++ * COM 4 ports. This *should* be safe, since no board
++ * manufacturer would be stupid enough to design a board
++ * that conflicts with COM 1-4 --- we hope!
++ */
++ if (!(up->port.flags & UPF_SKIP_TEST)) {
++ serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
++ status1 = serial_inp(up, UART_MSR) & 0xF0;
++ serial_outp(up, UART_MCR, save_mcr);
++ if (status1 != 0x90) {
++ DEBUG_AUTOCONF("LOOP test failed (%02x) ",
++ status1);
++ goto out;
++ }
++ }
++
++ /*
++ * We're pretty sure there's a port here. Lets find out what
++ * type of port it is. The IIR top two bits allows us to find
++ * out if it's 8250 or 16450, 16550, 16550A or later. This
++ * determines what we test for next.
++ *
++ * We also initialise the EFR (if any) to zero for later. The
++ * EFR occupies the same register location as the FCR and IIR.
++ */
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, 0);
++ serial_outp(up, UART_LCR, 0);
++
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ scratch = serial_in(up, UART_IIR) >> 6;
++
++ DEBUG_AUTOCONF("iir=%d ", scratch);
++
++ switch (scratch) {
++ case 0:
++ autoconfig_8250(up);
++ break;
++ case 1:
++ up->port.type = PORT_UNKNOWN;
++ break;
++ case 2:
++ up->port.type = PORT_16550;
++ break;
++ case 3:
++ autoconfig_16550a(up);
++ break;
++ }
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * Only probe for RSA ports if we got the region.
++ */
++ if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
++ int i;
++
++ for (i = 0 ; i < probe_rsa_count; ++i) {
++ if (probe_rsa[i] == up->port.iobase &&
++ __enable_rsa(up)) {
++ up->port.type = PORT_RSA;
++ break;
++ }
++ }
++ }
++#endif
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ /* if access method is AU, it is a 16550 with a quirk */
++ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
++ up->bugs |= UART_BUG_NOMSR;
++#endif
++
++ serial_outp(up, UART_LCR, save_lcr);
++
++ if (up->capabilities != uart_config[up->port.type].flags) {
++ printk(KERN_WARNING
++ "ttyS%d: detected caps %08x should be %08x\n",
++ up->port.line, up->capabilities,
++ uart_config[up->port.type].flags);
++ }
++
++ up->port.fifosize = uart_config[up->port.type].fifo_size;
++ up->capabilities = uart_config[up->port.type].flags;
++ up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
++
++ if (up->port.type == PORT_UNKNOWN)
++ goto out;
++
++ /*
++ * Reset the UART.
++ */
++#ifdef CONFIG_SERIAL_8250_RSA
++ if (up->port.type == PORT_RSA)
++ serial_outp(up, UART_RSA_FRR, 0);
++#endif
++ serial_outp(up, UART_MCR, save_mcr);
++ serial8250_clear_fifos(up);
++ serial_in(up, UART_RX);
++ if (up->capabilities & UART_CAP_UUE)
++ serial_outp(up, UART_IER, UART_IER_UUE);
++ else
++ serial_outp(up, UART_IER, 0);
++
++ out:
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
++}
++
++static void autoconfig_irq(struct uart_8250_port *up)
++{
++ unsigned char save_mcr, save_ier;
++ unsigned char save_ICP = 0;
++ unsigned int ICP = 0;
++ unsigned long irqs;
++ int irq;
++
++ if (up->port.flags & UPF_FOURPORT) {
++ ICP = (up->port.iobase & 0xfe0) | 0x1f;
++ save_ICP = inb_p(ICP);
++ outb_p(0x80, ICP);
++ (void) inb_p(ICP);
++ }
++
++ /* forget possible initially masked and pending IRQ */
++ probe_irq_off(probe_irq_on());
++ save_mcr = serial_inp(up, UART_MCR);
++ save_ier = serial_inp(up, UART_IER);
++ serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
++
++ irqs = probe_irq_on();
++ serial_outp(up, UART_MCR, 0);
++ udelay(10);
++ if (up->port.flags & UPF_FOURPORT) {
++ serial_outp(up, UART_MCR,
++ UART_MCR_DTR | UART_MCR_RTS);
++ } else {
++ serial_outp(up, UART_MCR,
++ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
++ }
++ serial_outp(up, UART_IER, 0x0f); /* enable all intrs */
++ (void)serial_inp(up, UART_LSR);
++ (void)serial_inp(up, UART_RX);
++ (void)serial_inp(up, UART_IIR);
++ (void)serial_inp(up, UART_MSR);
++ serial_outp(up, UART_TX, 0xFF);
++ udelay(20);
++ irq = probe_irq_off(irqs);
++
++ serial_outp(up, UART_MCR, save_mcr);
++ serial_outp(up, UART_IER, save_ier);
++
++ if (up->port.flags & UPF_FOURPORT)
++ outb_p(save_ICP, ICP);
++
++ up->port.irq = (irq > 0) ? irq : 0;
++}
++
++static inline void __stop_tx(struct uart_8250_port *p)
++{
++ if (p->ier & UART_IER_THRI) {
++ p->ier &= ~UART_IER_THRI;
++ serial_out(p, UART_IER, p->ier);
++ }
++}
++
++static void serial8250_stop_tx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ __stop_tx(up);
++
++ /*
++ * We really want to stop the transmitter from sending.
++ */
++ if (up->port.type == PORT_16C950) {
++ up->acr |= UART_ACR_TXDIS;
++ serial_icr_write(up, UART_ACR, up->acr);
++ }
++}
++
++static void transmit_chars(struct uart_8250_port *up);
++
++static void serial8250_start_tx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ if (!(up->ier & UART_IER_THRI)) {
++ up->ier |= UART_IER_THRI;
++ serial_out(up, UART_IER, up->ier);
++
++ if (up->bugs & UART_BUG_TXEN) {
++ unsigned char lsr, iir;
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ iir = serial_in(up, UART_IIR) & 0x0f;
++ if ((up->port.type == PORT_RM9000) ?
++ (lsr & UART_LSR_THRE &&
++ (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
++ (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
++ transmit_chars(up);
++ }
++ }
++
++ /*
++ * Re-enable the transmitter if we disabled it.
++ */
++ if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
++ up->acr &= ~UART_ACR_TXDIS;
++ serial_icr_write(up, UART_ACR, up->acr);
++ }
++}
++
++static void serial8250_stop_rx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ up->ier &= ~UART_IER_RLSI;
++ up->port.read_status_mask &= ~UART_LSR_DR;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void serial8250_enable_ms(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ /* no MSR capabilities */
++ if (up->bugs & UART_BUG_NOMSR)
++ return;
++
++ up->ier |= UART_IER_MSI;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void
++receive_chars(struct uart_8250_port *up, unsigned int *status)
++{
++ struct tty_struct *tty = up->port.info->tty;
++ unsigned char ch, lsr = *status;
++ int max_count = 256;
++ char flag;
++
++ do {
++ ch = serial_inp(up, UART_RX);
++ flag = TTY_NORMAL;
++ up->port.icount.rx++;
++
++ lsr |= up->lsr_saved_flags;
++ up->lsr_saved_flags = 0;
++
++ if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
++ /*
++ * For statistics only
++ */
++ if (lsr & UART_LSR_BI) {
++ lsr &= ~(UART_LSR_FE | UART_LSR_PE);
++ up->port.icount.brk++;
++ /*
++ * We do the SysRQ and SAK checking
++ * here because otherwise the break
++ * may get masked by ignore_status_mask
++ * or read_status_mask.
++ */
++ if (uart_handle_break(&up->port))
++ goto ignore_char;
++ } else if (lsr & UART_LSR_PE)
++ up->port.icount.parity++;
++ else if (lsr & UART_LSR_FE)
++ up->port.icount.frame++;
++ if (lsr & UART_LSR_OE)
++ up->port.icount.overrun++;
++
++ /*
++ * Mask off conditions which should be ignored.
++ */
++ lsr &= up->port.read_status_mask;
++
++ if (lsr & UART_LSR_BI) {
++ DEBUG_INTR("handling break....");
++ flag = TTY_BREAK;
++ } else if (lsr & UART_LSR_PE)
++ flag = TTY_PARITY;
++ else if (lsr & UART_LSR_FE)
++ flag = TTY_FRAME;
++ }
++ if (uart_handle_sysrq_char(&up->port, ch))
++ goto ignore_char;
++
++ uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
++
++ignore_char:
++ lsr = serial_inp(up, UART_LSR);
++ } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
++ spin_unlock(&up->port.lock);
++ tty_flip_buffer_push(tty);
++ spin_lock(&up->port.lock);
++ *status = lsr;
++}
++
++static void transmit_chars(struct uart_8250_port *up)
++{
++ struct circ_buf *xmit = &up->port.info->xmit;
++ int count;
++
++ if (up->port.x_char) {
++ serial_outp(up, UART_TX, up->port.x_char);
++ up->port.icount.tx++;
++ up->port.x_char = 0;
++ return;
++ }
++ if (uart_tx_stopped(&up->port)) {
++ serial8250_stop_tx(&up->port);
++ return;
++ }
++ if (uart_circ_empty(xmit)) {
++ __stop_tx(up);
++ return;
++ }
++
++ count = up->tx_loadsz;
++ do {
++ serial_out(up, UART_TX, xmit->buf[xmit->tail]);
++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++ up->port.icount.tx++;
++ if (uart_circ_empty(xmit))
++ break;
++ } while (--count > 0);
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&up->port);
++
++ DEBUG_INTR("THRE...");
++
++ if (uart_circ_empty(xmit))
++ __stop_tx(up);
++}
++
++static unsigned int check_modem_status(struct uart_8250_port *up)
++{
++ unsigned int status = serial_in(up, UART_MSR);
++
++ status |= up->msr_saved_flags;
++ up->msr_saved_flags = 0;
++ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
++ up->port.info != NULL) {
++ if (status & UART_MSR_TERI)
++ up->port.icount.rng++;
++ if (status & UART_MSR_DDSR)
++ up->port.icount.dsr++;
++ if (status & UART_MSR_DDCD)
++ uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
++ if (status & UART_MSR_DCTS)
++ uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
++
++ wake_up_interruptible(&up->port.info->delta_msr_wait);
++ }
++
++ return status;
++}
++
++/*
++ * This handles the interrupt from one port.
++ */
++static inline void
++serial8250_handle_port(struct uart_8250_port *up)
++{
++ unsigned int status;
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ status = serial_inp(up, UART_LSR);
++
++ DEBUG_INTR("status = %x...", status);
++
++ if (status & UART_LSR_DR)
++ receive_chars(up, &status);
++ check_modem_status(up);
++ if (status & UART_LSR_THRE)
++ transmit_chars(up);
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++/*
++ * This is the serial driver's interrupt routine.
++ *
++ * Arjan thinks the old way was overly complex, so it got simplified.
++ * Alan disagrees, saying that need the complexity to handle the weird
++ * nature of ISA shared interrupts. (This is a special exception.)
++ *
++ * In order to handle ISA shared interrupts properly, we need to check
++ * that all ports have been serviced, and therefore the ISA interrupt
++ * line has been de-asserted.
++ *
++ * This means we need to loop through all ports. checking that they
++ * don't have an interrupt pending.
++ */
++static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
++{
++ struct irq_info *i = dev_id;
++ struct list_head *l, *end = NULL;
++ int pass_counter = 0, handled = 0;
++
++ DEBUG_INTR("serial8250_interrupt(%d)...", irq);
++
++ spin_lock(&i->lock);
++
++ l = i->head;
++ do {
++ struct uart_8250_port *up;
++ unsigned int iir;
++
++ up = list_entry(l, struct uart_8250_port, list);
++
++ iir = serial_in(up, UART_IIR);
++ if (!(iir & UART_IIR_NO_INT)) {
++ serial8250_handle_port(up);
++
++ handled = 1;
++
++ end = NULL;
++ } else if (up->port.iotype == UPIO_DWAPB &&
++ (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
++ /* The DesignWare APB UART has an Busy Detect (0x07)
++ * interrupt meaning an LCR write attempt occured while the
++ * UART was busy. The interrupt must be cleared by reading
++ * the UART status register (USR) and the LCR re-written. */
++ unsigned int status;
++ status = *(volatile u32 *)up->port.private_data;
++ serial_out(up, UART_LCR, up->lcr);
++
++ handled = 1;
++
++ end = NULL;
++ } else if (end == NULL)
++ end = l;
++
++ l = l->next;
++
++ if (l == i->head && pass_counter++ > PASS_LIMIT) {
++ /* If we hit this, we're dead. */
++ printk(KERN_ERR "serial8250: too much work for "
++ "irq%d\n", irq);
++ break;
++ }
++ } while (l != end);
++
++ spin_unlock(&i->lock);
++
++ DEBUG_INTR("end.\n");
++
++ return IRQ_RETVAL(handled);
++}
++
++/*
++ * To support ISA shared interrupts, we need to have one interrupt
++ * handler that ensures that the IRQ line has been deasserted
++ * before returning. Failing to do this will result in the IRQ
++ * line being stuck active, and, since ISA irqs are edge triggered,
++ * no more IRQs will be seen.
++ */
++static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
++{
++ spin_lock_irq(&i->lock);
++
++ if (!list_empty(i->head)) {
++ if (i->head == &up->list)
++ i->head = i->head->next;
++ list_del(&up->list);
++ } else {
++ BUG_ON(i->head != &up->list);
++ i->head = NULL;
++ }
++
++ spin_unlock_irq(&i->lock);
++}
++
++static int serial_link_irq_chain(struct uart_8250_port *up)
++{
++ struct irq_info *i = irq_lists + up->port.irq;
++ int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
++
++ spin_lock_irq(&i->lock);
++
++ if (i->head) {
++ list_add(&up->list, i->head);
++ spin_unlock_irq(&i->lock);
++
++ ret = 0;
++ } else {
++ INIT_LIST_HEAD(&up->list);
++ i->head = &up->list;
++ spin_unlock_irq(&i->lock);
++
++ ret = request_irq(up->port.irq, serial8250_interrupt,
++ irq_flags, "serial", i);
++ if (ret < 0)
++ serial_do_unlink(i, up);
++ }
++
++ return ret;
++}
++
++static void serial_unlink_irq_chain(struct uart_8250_port *up)
++{
++ struct irq_info *i = irq_lists + up->port.irq;
++
++ BUG_ON(i->head == NULL);
++
++ if (list_empty(i->head))
++ free_irq(up->port.irq, i);
++
++ serial_do_unlink(i, up);
++}
++
++/* Base timer interval for polling */
++static inline int poll_timeout(int timeout)
++{
++ return timeout > 6 ? (timeout / 2 - 2) : 1;
++}
++
++/*
++ * This function is used to handle ports that do not have an
++ * interrupt. This doesn't work very well for 16450's, but gives
++ * barely passable results for a 16550A. (Although at the expense
++ * of much CPU overhead).
++ */
++static void serial8250_timeout(unsigned long data)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)data;
++ unsigned int iir;
++
++ iir = serial_in(up, UART_IIR);
++ if (!(iir & UART_IIR_NO_INT))
++ serial8250_handle_port(up);
++ mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++}
++
++static void serial8250_backup_timeout(unsigned long data)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)data;
++ unsigned int iir, ier = 0, lsr;
++ unsigned long flags;
++
++ /*
++ * Must disable interrupts or else we risk racing with the interrupt
++ * based handler.
++ */
++ if (is_real_interrupt(up->port.irq)) {
++ ier = serial_in(up, UART_IER);
++ serial_out(up, UART_IER, 0);
++ }
++
++ iir = serial_in(up, UART_IIR);
++
++ /*
++ * This should be a safe test for anyone who doesn't trust the
++ * IIR bits on their UART, but it's specifically designed for
++ * the "Diva" UART used on the management processor on many HP
++ * ia64 and parisc boxes.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
++ (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
++ (lsr & UART_LSR_THRE)) {
++ iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
++ iir |= UART_IIR_THRI;
++ }
++
++ if (!(iir & UART_IIR_NO_INT))
++ serial8250_handle_port(up);
++
++ if (is_real_interrupt(up->port.irq))
++ serial_out(up, UART_IER, ier);
++
++ /* Standard timer interval plus 0.2s to keep the port running */
++ mod_timer(&up->timer,
++ jiffies + poll_timeout(up->port.timeout) + HZ / 5);
++}
++
++static unsigned int serial8250_tx_empty(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ unsigned int lsr;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int serial8250_get_mctrl(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned int status;
++ unsigned int ret;
++
++ status = check_modem_status(up);
++
++ ret = 0;
++ if (status & UART_MSR_DCD)
++ ret |= TIOCM_CAR;
++ if (status & UART_MSR_RI)
++ ret |= TIOCM_RNG;
++ if (status & UART_MSR_DSR)
++ ret |= TIOCM_DSR;
++ if (status & UART_MSR_CTS)
++ ret |= TIOCM_CTS;
++ return ret;
++}
++
++static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned char mcr = 0;
++
++ if (mctrl & TIOCM_RTS)
++ mcr |= UART_MCR_RTS;
++ if (mctrl & TIOCM_DTR)
++ mcr |= UART_MCR_DTR;
++ if (mctrl & TIOCM_OUT1)
++ mcr |= UART_MCR_OUT1;
++ if (mctrl & TIOCM_OUT2)
++ mcr |= UART_MCR_OUT2;
++ if (mctrl & TIOCM_LOOP)
++ mcr |= UART_MCR_LOOP;
++
++ mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
++
++ serial_out(up, UART_MCR, mcr);
++}
++
++static void serial8250_break_ctl(struct uart_port *port, int break_state)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (break_state == -1)
++ up->lcr |= UART_LCR_SBC;
++ else
++ up->lcr &= ~UART_LCR_SBC;
++ serial_out(up, UART_LCR, up->lcr);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
++/*
++ * Wait for transmitter & holding register to empty
++ */
++static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
++{
++ unsigned int status, tmout = 10000;
++
++ /* Wait up to 10ms for the character(s) to be sent. */
++ do {
++ status = serial_in(up, UART_LSR);
++
++ up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
++
++ if (--tmout == 0)
++ break;
++ udelay(1);
++ } while ((status & bits) != bits);
++
++ /* Wait up to 1s for flow control if necessary */
++ if (up->port.flags & UPF_CONS_FLOW) {
++ unsigned int tmout;
++ for (tmout = 1000000; tmout; tmout--) {
++ unsigned int msr = serial_in(up, UART_MSR);
++ up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
++ if (msr & UART_MSR_CTS)
++ break;
++ udelay(1);
++ touch_nmi_watchdog();
++ }
++ }
++}
++
++static int serial8250_startup(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ unsigned char lsr, iir;
++ int retval;
++
++ up->capabilities = uart_config[up->port.type].flags;
++ up->mcr = 0;
++
++ if (up->port.type == PORT_16C950) {
++ /* Wake up and initialize UART */
++ up->acr = 0;
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, UART_EFR_ECB);
++ serial_outp(up, UART_IER, 0);
++ serial_outp(up, UART_LCR, 0);
++ serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, UART_EFR_ECB);
++ serial_outp(up, UART_LCR, 0);
++ }
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * If this is an RSA port, see if we can kick it up to the
++ * higher speed clock.
++ */
++ enable_rsa(up);
++#endif
++
++ /*
++ * Clear the FIFO buffers and disable them.
++ * (they will be reenabled in set_termios())
++ */
++ serial8250_clear_fifos(up);
++
++ /*
++ * Clear the interrupt registers.
++ */
++ (void) serial_inp(up, UART_LSR);
++ (void) serial_inp(up, UART_RX);
++ (void) serial_inp(up, UART_IIR);
++ (void) serial_inp(up, UART_MSR);
++
++ /*
++ * At this point, there's no way the LSR could still be 0xff;
++ * if it is, then bail out, because there's likely no UART
++ * here.
++ */
++ if (!(up->port.flags & UPF_BUGGY_UART) &&
++ (serial_inp(up, UART_LSR) == 0xff)) {
++ printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
++ return -ENODEV;
++ }
++
++ /*
++ * For a XR16C850, we need to set the trigger levels
++ */
++ if (up->port.type == PORT_16850) {
++ unsigned char fctr;
++
++ serial_outp(up, UART_LCR, 0xbf);
++
++ fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
++ serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
++ serial_outp(up, UART_TRG, UART_TRG_96);
++ serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX);
++ serial_outp(up, UART_TRG, UART_TRG_96);
++
++ serial_outp(up, UART_LCR, 0);
++ }
++
++ if (is_real_interrupt(up->port.irq)) {
++ /*
++ * Test for UARTs that do not reassert THRE when the
++ * transmitter is idle and the interrupt has already
++ * been cleared. Real 16550s should always reassert
++ * this interrupt whenever the transmitter is idle and
++ * the interrupt is enabled. Delays are necessary to
++ * allow register changes to become visible.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ wait_for_xmitr(up, UART_LSR_THRE);
++ serial_out_sync(up, UART_IER, UART_IER_THRI);
++ udelay(1); /* allow THRE to set */
++ serial_in(up, UART_IIR);
++ serial_out(up, UART_IER, 0);
++ serial_out_sync(up, UART_IER, UART_IER_THRI);
++ udelay(1); /* allow a working UART time to re-assert THRE */
++ iir = serial_in(up, UART_IIR);
++ serial_out(up, UART_IER, 0);
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * If the interrupt is not reasserted, setup a timer to
++ * kick the UART on a regular basis.
++ */
++ if (iir & UART_IIR_NO_INT) {
++ pr_debug("ttyS%d - using backup timer\n", port->line);
++ up->timer.function = serial8250_backup_timeout;
++ up->timer.data = (unsigned long)up;
++ mod_timer(&up->timer, jiffies +
++ poll_timeout(up->port.timeout) + HZ / 5);
++ }
++ }
++
++ /*
++ * If the "interrupt" for this port doesn't correspond with any
++ * hardware interrupt, we use a timer-based system. The original
++ * driver used to do this with IRQ0.
++ */
++ if (!is_real_interrupt(up->port.irq)) {
++ up->timer.data = (unsigned long)up;
++ mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++ } else {
++ retval = serial_link_irq_chain(up);
++ if (retval)
++ return retval;
++ }
++
++ /*
++ * Now, initialize the UART
++ */
++ serial_outp(up, UART_LCR, UART_LCR_WLEN8);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (up->port.flags & UPF_FOURPORT) {
++ if (!is_real_interrupt(up->port.irq))
++ up->port.mctrl |= TIOCM_OUT1;
++ } else
++ /*
++ * Most PC uarts need OUT2 raised to enable interrupts.
++ */
++ if (is_real_interrupt(up->port.irq))
++ up->port.mctrl |= TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++
++ /*
++ * Do a quick test to see if we receive an
++ * interrupt when we enable the TX irq.
++ */
++ serial_outp(up, UART_IER, UART_IER_THRI);
++ lsr = serial_in(up, UART_LSR);
++ iir = serial_in(up, UART_IIR);
++ serial_outp(up, UART_IER, 0);
++
++ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
++ if (!(up->bugs & UART_BUG_TXEN)) {
++ up->bugs |= UART_BUG_TXEN;
++ pr_debug("ttyS%d - enabling bad tx status workarounds\n",
++ port->line);
++ }
++ } else {
++ up->bugs &= ~UART_BUG_TXEN;
++ }
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Clear the interrupt registers again for luck, and clear the
++ * saved flags to avoid getting false values from polling
++ * routines or the previous session.
++ */
++ serial_inp(up, UART_LSR);
++ serial_inp(up, UART_RX);
++ serial_inp(up, UART_IIR);
++ serial_inp(up, UART_MSR);
++ up->lsr_saved_flags = 0;
++ up->msr_saved_flags = 0;
++
++ /*
++ * Finally, enable interrupts. Note: Modem status interrupts
++ * are set via set_termios(), which will be occurring imminently
++ * anyway, so we don't enable them here.
++ */
++ up->ier = UART_IER_RLSI | UART_IER_RDI;
++ serial_outp(up, UART_IER, up->ier);
++
++ if (up->port.flags & UPF_FOURPORT) {
++ unsigned int icp;
++ /*
++ * Enable interrupts on the AST Fourport board
++ */
++ icp = (up->port.iobase & 0xfe0) | 0x01f;
++ outb_p(0x80, icp);
++ (void) inb_p(icp);
++ }
++
++ return 0;
++}
++
++static void serial8250_shutdown(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++
++ /*
++ * Disable interrupts from this port
++ */
++ up->ier = 0;
++ serial_outp(up, UART_IER, 0);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (up->port.flags & UPF_FOURPORT) {
++ /* reset interrupts on the AST Fourport board */
++ inb((up->port.iobase & 0xfe0) | 0x1f);
++ up->port.mctrl |= TIOCM_OUT1;
++ } else
++ up->port.mctrl &= ~TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Disable break condition and FIFOs
++ */
++ serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
++ serial8250_clear_fifos(up);
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * Reset the RSA board back to 115kbps compat mode.
++ */
++ disable_rsa(up);
++#endif
++
++ /*
++ * Read data port to reset things, and then unlink from
++ * the IRQ chain.
++ */
++ (void) serial_in(up, UART_RX);
++
++ del_timer_sync(&up->timer);
++ up->timer.function = serial8250_timeout;
++ if (is_real_interrupt(up->port.irq))
++ serial_unlink_irq_chain(up);
++}
++
++static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
++{
++ unsigned int quot;
++
++ /*
++ * Handle magic divisors for baud rates above baud_base on
++ * SMSC SuperIO chips.
++ */
++ if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++ baud == (port->uartclk/4))
++ quot = 0x8001;
++ else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++ baud == (port->uartclk/8))
++ quot = 0x8002;
++ else
++ quot = uart_get_divisor(port, baud);
++
++ return quot;
++}
++
++static void
++serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
++ struct ktermios *old)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned char cval, fcr = 0;
++ unsigned long flags;
++ unsigned int baud, quot;
++
++ switch (termios->c_cflag & CSIZE) {
++ case CS5:
++ cval = UART_LCR_WLEN5;
++ break;
++ case CS6:
++ cval = UART_LCR_WLEN6;
++ break;
++ case CS7:
++ cval = UART_LCR_WLEN7;
++ break;
++ default:
++ case CS8:
++ cval = UART_LCR_WLEN8;
++ break;
++ }
++
++ if (termios->c_cflag & CSTOPB)
++ cval |= UART_LCR_STOP;
++ if (termios->c_cflag & PARENB)
++ cval |= UART_LCR_PARITY;
++ if (!(termios->c_cflag & PARODD))
++ cval |= UART_LCR_EPAR;
++#ifdef CMSPAR
++ if (termios->c_cflag & CMSPAR)
++ cval |= UART_LCR_SPAR;
++#endif
++
++ /*
++ * Ask the core to calculate the divisor for us.
++ */
++ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
++ quot = serial8250_get_divisor(port, baud);
++
++ /*
++ * Oxford Semi 952 rev B workaround
++ */
++ if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
++ quot++;
++
++ if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
++ if (baud < 2400)
++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
++ else
++ fcr = uart_config[up->port.type].fcr;
++ }
++
++ /*
++ * MCR-based auto flow control. When AFE is enabled, RTS will be
++ * deasserted when the receive FIFO contains more characters than
++ * the trigger, or the MCR RTS bit is cleared. In the case where
++ * the remote UART is not using CTS auto flow control, we must
++ * have sufficient FIFO entries for the latency of the remote
++ * UART to respond. IOW, at least 32 bytes of FIFO.
++ */
++ if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {
++ up->mcr &= ~UART_MCR_AFE;
++ if (termios->c_cflag & CRTSCTS)
++ up->mcr |= UART_MCR_AFE;
++ }
++
++ /*
++ * Ok, we're now changing the port state. Do it with
++ * interrupts disabled.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ /*
++ * Update the per-port timeout.
++ */
++ uart_update_timeout(port, termios->c_cflag, baud);
++
++ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++ if (termios->c_iflag & INPCK)
++ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & (BRKINT | PARMRK))
++ up->port.read_status_mask |= UART_LSR_BI;
++
++ /*
++ * Characteres to ignore
++ */
++ up->port.ignore_status_mask = 0;
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++ if (termios->c_iflag & IGNBRK) {
++ up->port.ignore_status_mask |= UART_LSR_BI;
++ /*
++ * If we're ignoring parity and break indicators,
++ * ignore overruns too (for real raw support).
++ */
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_OE;
++ }
++
++ /*
++ * ignore all characters if CREAD is not set
++ */
++ if ((termios->c_cflag & CREAD) == 0)
++ up->port.ignore_status_mask |= UART_LSR_DR;
++
++ /*
++ * CTS flow control flag and modem status interrupts
++ */
++ up->ier &= ~UART_IER_MSI;
++ if (!(up->bugs & UART_BUG_NOMSR) &&
++ UART_ENABLE_MS(&up->port, termios->c_cflag))
++ up->ier |= UART_IER_MSI;
++ if (up->capabilities & UART_CAP_UUE)
++ up->ier |= UART_IER_UUE | UART_IER_RTOIE;
++
++ serial_out(up, UART_IER, up->ier);
++
++ if (up->capabilities & UART_CAP_EFR) {
++ unsigned char efr = 0;
++ /*
++ * TI16C752/Startech hardware flow control. FIXME:
++ * - TI16C752 requires control thresholds to be set.
++ * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
++ */
++ if (termios->c_cflag & CRTSCTS)
++ efr |= UART_EFR_CTS;
++
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, efr);
++ }
++
++#ifdef CONFIG_ARCH_OMAP15XX
++ /* Workaround to enable 115200 baud on OMAP1510 internal ports */
++ if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
++ if (baud == 115200) {
++ quot = 1;
++ serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
++ } else
++ serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
++ }
++#endif
++
++ if (up->capabilities & UART_NATSEMI) {
++ /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
++ serial_outp(up, UART_LCR, 0xe0);
++ } else {
++ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
++ }
++
++ serial_dl_write(up, quot);
++
++ /*
++ * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
++ * is written without DLAB set, this mode will be disabled.
++ */
++ if (up->port.type == PORT_16750)
++ serial_outp(up, UART_FCR, fcr);
++
++ serial_outp(up, UART_LCR, cval); /* reset DLAB */
++ up->lcr = cval; /* Save LCR */
++ if (up->port.type != PORT_16750) {
++ if (fcr & UART_FCR_ENABLE_FIFO) {
++ /* emulated UARTs (Lucent Venus 167x) need two steps */
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ }
++ serial_outp(up, UART_FCR, fcr); /* set fcr */
++ }
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ tty_termios_encode_baud_rate(termios, baud, baud);
++}
++
++static void
++serial8250_pm(struct uart_port *port, unsigned int state,
++ unsigned int oldstate)
++{
++ struct uart_8250_port *p = (struct uart_8250_port *)port;
++
++ serial8250_set_sleep(p, state != 0);
++
++ if (p->pm)
++ p->pm(port, state, oldstate);
++}
++
++/*
++ * Resource handling.
++ */
++static int serial8250_request_std_resource(struct uart_8250_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++ int ret = 0;
++
++ switch (up->port.iotype) {
++ case UPIO_AU:
++ size = 0x100000;
++ /* fall thru */
++ case UPIO_TSI:
++ case UPIO_MEM32:
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ if (!up->port.mapbase)
++ break;
++
++ if (!request_mem_region(up->port.mapbase, size, "serial")) {
++ ret = -EBUSY;
++ break;
++ }
++
++ if (up->port.flags & UPF_IOREMAP) {
++ up->port.membase = ioremap(up->port.mapbase, size);
++ if (!up->port.membase) {
++ release_mem_region(up->port.mapbase, size);
++ ret = -ENOMEM;
++ }
++ }
++ break;
++
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ if (!request_region(up->port.iobase, size, "serial"))
++ ret = -EBUSY;
++ break;
++ }
++ return ret;
++}
++
++static void serial8250_release_std_resource(struct uart_8250_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_AU:
++ size = 0x100000;
++ /* fall thru */
++ case UPIO_TSI:
++ case UPIO_MEM32:
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ if (!up->port.mapbase)
++ break;
++
++ if (up->port.flags & UPF_IOREMAP) {
++ iounmap(up->port.membase);
++ up->port.membase = NULL;
++ }
++
++ release_mem_region(up->port.mapbase, size);
++ break;
++
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ release_region(up->port.iobase, size);
++ break;
++ }
++}
++
++static int serial8250_request_rsa_resource(struct uart_8250_port *up)
++{
++ unsigned long start = UART_RSA_BASE << up->port.regshift;
++ unsigned int size = 8 << up->port.regshift;
++ int ret = -EINVAL;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ start += up->port.iobase;
++ if (request_region(start, size, "serial-rsa"))
++ ret = 0;
++ else
++ ret = -EBUSY;
++ break;
++ }
++
++ return ret;
++}
++
++static void serial8250_release_rsa_resource(struct uart_8250_port *up)
++{
++ unsigned long offset = UART_RSA_BASE << up->port.regshift;
++ unsigned int size = 8 << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ release_region(up->port.iobase + offset, size);
++ break;
++ }
++}
++
++static void serial8250_release_port(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ serial8250_release_std_resource(up);
++ if (up->port.type == PORT_RSA)
++ serial8250_release_rsa_resource(up);
++}
++
++static int serial8250_request_port(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ int ret = 0;
++
++ ret = serial8250_request_std_resource(up);
++ if (ret == 0 && up->port.type == PORT_RSA) {
++ ret = serial8250_request_rsa_resource(up);
++ if (ret < 0)
++ serial8250_release_std_resource(up);
++ }
++
++ return ret;
++}
++
++static void serial8250_config_port(struct uart_port *port, int flags)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ int probeflags = PROBE_ANY;
++ int ret;
++
++ /*
++ * Find the region that we can probe for. This in turn
++ * tells us whether we can probe for the type of port.
++ */
++ ret = serial8250_request_std_resource(up);
++ if (ret < 0)
++ return;
++
++ ret = serial8250_request_rsa_resource(up);
++ if (ret < 0)
++ probeflags &= ~PROBE_RSA;
++
++ if (flags & UART_CONFIG_TYPE)
++ autoconfig(up, probeflags);
++ if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
++ autoconfig_irq(up);
++
++ if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
++ serial8250_release_rsa_resource(up);
++ if (up->port.type == PORT_UNKNOWN)
++ serial8250_release_std_resource(up);
++}
++
++static int
++serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++ if (ser->irq >= NR_IRQS || ser->irq < 0 ||
++ ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
++ ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
++ ser->type == PORT_STARTECH)
++ return -EINVAL;
++ return 0;
++}
++
++static const char *
++serial8250_type(struct uart_port *port)
++{
++ int type = port->type;
++
++ if (type >= ARRAY_SIZE(uart_config))
++ type = 0;
++ return uart_config[type].name;
++}
++
++static struct uart_ops serial8250_pops = {
++ .tx_empty = serial8250_tx_empty,
++ .set_mctrl = serial8250_set_mctrl,
++ .get_mctrl = serial8250_get_mctrl,
++ .stop_tx = serial8250_stop_tx,
++ .start_tx = serial8250_start_tx,
++ .stop_rx = serial8250_stop_rx,
++ .enable_ms = serial8250_enable_ms,
++ .break_ctl = serial8250_break_ctl,
++ .startup = serial8250_startup,
++ .shutdown = serial8250_shutdown,
++ .set_termios = serial8250_set_termios,
++ .pm = serial8250_pm,
++ .type = serial8250_type,
++ .release_port = serial8250_release_port,
++ .request_port = serial8250_request_port,
++ .config_port = serial8250_config_port,
++ .verify_port = serial8250_verify_port,
++};
++
++static struct uart_8250_port serial8250_ports[UART_NR];
++
++static void __init serial8250_isa_init_ports(void)
++{
++ struct uart_8250_port *up;
++ static int first = 1;
++ int i;
++
++ if (!first)
++ return;
++ first = 0;
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ up->port.line = i;
++ spin_lock_init(&up->port.lock);
++
++ init_timer(&up->timer);
++ up->timer.function = serial8250_timeout;
++
++ /*
++ * ALPHA_KLUDGE_MCR needs to be killed.
++ */
++ up->mcr_mask = ~ALPHA_KLUDGE_MCR;
++ up->mcr_force = ALPHA_KLUDGE_MCR;
++
++ up->port.ops = &serial8250_pops;
++ }
++
++ for (i = 0, up = serial8250_ports;
++ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
++ i++, up++) {
++ up->port.iobase = old_serial_port[i].port;
++ up->port.irq = irq_canonicalize(old_serial_port[i].irq);
++ up->port.uartclk = old_serial_port[i].baud_base * 16;
++ up->port.flags = old_serial_port[i].flags;
++ up->port.hub6 = old_serial_port[i].hub6;
++ up->port.membase = old_serial_port[i].iomem_base;
++ up->port.iotype = old_serial_port[i].io_type;
++ up->port.regshift = old_serial_port[i].iomem_reg_shift;
++ if (share_irqs)
++ up->port.flags |= UPF_SHARE_IRQ;
++ }
++}
++
++static void __init
++serial8250_register_ports(struct uart_driver *drv, struct device *dev)
++{
++ int i;
++
++ serial8250_isa_init_ports();
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ up->port.dev = dev;
++ uart_add_one_port(drv, &up->port);
++ }
++}
++
++#ifdef CONFIG_SERIAL_8250_CONSOLE
++
++static void serial8250_console_putchar(struct uart_port *port, int ch)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ wait_for_xmitr(up, UART_LSR_THRE);
++ serial_out(up, UART_TX, ch);
++}
++
++/*
++ * Print a string to the serial port trying not to disturb
++ * any possible real use of the port...
++ *
++ * The console_lock must be held when we get here.
++ */
++static void
++serial8250_console_write(struct console *co, const char *s, unsigned int count)
++{
++ struct uart_8250_port *up = &serial8250_ports[co->index];
++ unsigned long flags;
++ unsigned int ier;
++ int locked = 1;
++
++ touch_nmi_watchdog();
++
++ local_irq_save(flags);
++ if (up->port.sysrq) {
++ /* serial8250_handle_port() already took the lock */
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&up->port.lock);
++ } else
++ spin_lock(&up->port.lock);
++
++ /*
++ * First save the IER then disable the interrupts
++ */
++ ier = serial_in(up, UART_IER);
++
++ if (up->capabilities & UART_CAP_UUE)
++ serial_out(up, UART_IER, UART_IER_UUE);
++ else
++ serial_out(up, UART_IER, 0);
++
++ uart_console_write(&up->port, s, count, serial8250_console_putchar);
++
++ /*
++ * Finally, wait for transmitter to become empty
++ * and restore the IER
++ */
++ wait_for_xmitr(up, BOTH_EMPTY);
++ serial_out(up, UART_IER, ier);
++
++ /*
++ * The receive handling will happen properly because the
++ * receive ready bit will still be set; it is not cleared
++ * on read. However, modem control will not, we must
++ * call it if we have saved something in the saved flags
++ * while processing with interrupts off.
++ */
++ if (up->msr_saved_flags)
++ check_modem_status(up);
++
++ if (locked)
++ spin_unlock(&up->port.lock);
++ local_irq_restore(flags);
++}
++
++static int __init serial8250_console_setup(struct console *co, char *options)
++{
++ struct uart_port *port;
++ int baud = 9600;
++ int bits = 8;
++ int parity = 'n';
++ int flow = 'n';
++
++ /*
++ * Check whether an invalid uart number has been specified, and
++ * if so, search for the first available port that does have
++ * console support.
++ */
++ if (co->index >= nr_uarts)
++ co->index = 0;
++ port = &serial8250_ports[co->index].port;
++ if (!port->iobase && !port->membase)
++ return -ENODEV;
++
++ if (options)
++ uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++ return uart_set_options(port, co, baud, parity, bits, flow);
++}
++
++static int serial8250_console_early_setup(void)
++{
++ return serial8250_find_port_for_earlycon();
++}
++
++static struct uart_driver serial8250_reg;
++static struct console serial8250_console = {
++ .name = "ttyS",
++ .write = serial8250_console_write,
++ .device = uart_console_device,
++ .setup = serial8250_console_setup,
++ .early_setup = serial8250_console_early_setup,
++ .flags = CON_PRINTBUFFER,
++ .index = -1,
++ .data = &serial8250_reg,
++};
++
++static int __init serial8250_console_init(void)
++{
++ serial8250_isa_init_ports();
++ register_console(&serial8250_console);
++ return 0;
++}
++console_initcall(serial8250_console_init);
++
++int serial8250_find_port(struct uart_port *p)
++{
++ int line;
++ struct uart_port *port;
++
++ for (line = 0; line < nr_uarts; line++) {
++ port = &serial8250_ports[line].port;
++ if (uart_match_port(p, port))
++ return line;
++ }
++ return -ENODEV;
++}
++
++#define SERIAL8250_CONSOLE &serial8250_console
++#else
++#define SERIAL8250_CONSOLE NULL
++#endif
++
++static struct uart_driver serial8250_reg = {
++ .owner = THIS_MODULE,
++ .driver_name = "serial",
++ .dev_name = "ttyS",
++ .major = TTY_MAJOR,
++ .minor = 64,
++ .nr = UART_NR,
++ .cons = SERIAL8250_CONSOLE,
++};
++
++/*
++ * early_serial_setup - early registration for 8250 ports
++ *
++ * Setup an 8250 port structure prior to console initialisation. Use
++ * after console initialisation will cause undefined behaviour.
++ */
++int __init early_serial_setup(struct uart_port *port)
++{
++ if (port->line >= ARRAY_SIZE(serial8250_ports))
++ return -ENODEV;
++
++ serial8250_isa_init_ports();
++ serial8250_ports[port->line].port = *port;
++ serial8250_ports[port->line].port.ops = &serial8250_pops;
++ return 0;
++}
++
++/**
++ * serial8250_suspend_port - suspend one serial port
++ * @line: serial line number
++ *
++ * Suspend one serial port.
++ */
++void serial8250_suspend_port(int line)
++{
++ uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
++}
++
++/**
++ * serial8250_resume_port - resume one serial port
++ * @line: serial line number
++ *
++ * Resume one serial port.
++ */
++void serial8250_resume_port(int line)
++{
++ struct uart_8250_port *up = &serial8250_ports[line];
++
++ if (up->capabilities & UART_NATSEMI) {
++ unsigned char tmp;
++
++ /* Ensure it's still in high speed mode */
++ serial_outp(up, UART_LCR, 0xE0);
++
++ tmp = serial_in(up, 0x04); /* EXCR2 */
++ tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++ tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
++ serial_outp(up, 0x04, tmp);
++
++ serial_outp(up, UART_LCR, 0);
++ }
++ uart_resume_port(&serial8250_reg, &up->port);
++}
++
++/*
++ * Register a set of serial devices attached to a platform device. The
++ * list is terminated with a zero flags entry, which means we expect
++ * all entries to have at least UPF_BOOT_AUTOCONF set.
++ */
++static int __devinit serial8250_probe(struct platform_device *dev)
++{
++ struct plat_serial8250_port *p = dev->dev.platform_data;
++ struct uart_port port;
++ int ret, i;
++
++ memset(&port, 0, sizeof(struct uart_port));
++
++ for (i = 0; p && p->flags != 0; p++, i++) {
++ port.iobase = p->iobase;
++ port.membase = p->membase;
++ port.irq = p->irq;
++ port.uartclk = p->uartclk;
++ port.regshift = p->regshift;
++ port.iotype = p->iotype;
++ port.flags = p->flags;
++ port.mapbase = p->mapbase;
++ port.hub6 = p->hub6;
++ port.private_data = p->private_data;
++ port.dev = &dev->dev;
++ if (share_irqs)
++ port.flags |= UPF_SHARE_IRQ;
++ ret = serial8250_register_port(&port);
++ if (ret < 0) {
++ dev_err(&dev->dev, "unable to register port at index %d "
++ "(IO%lx MEM%llx IRQ%d): %d\n", i,
++ p->iobase, (unsigned long long)p->mapbase,
++ p->irq, ret);
++ }
++ }
++ return 0;
++}
++
++/*
++ * Remove serial ports registered against a platform device.
++ */
++static int __devexit serial8250_remove(struct platform_device *dev)
++{
++ int i;
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.dev == &dev->dev)
++ serial8250_unregister_port(i);
++ }
++ return 0;
++}
++
++static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
++{
++ int i;
++
++ for (i = 0; i < UART_NR; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ uart_suspend_port(&serial8250_reg, &up->port);
++ }
++
++ return 0;
++}
++
++static int serial8250_resume(struct platform_device *dev)
++{
++ int i;
++
++ for (i = 0; i < UART_NR; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ serial8250_resume_port(i);
++ }
++
++ return 0;
++}
++
++static struct platform_driver serial8250_isa_driver = {
++ .probe = serial8250_probe,
++ .remove = __devexit_p(serial8250_remove),
++ .suspend = serial8250_suspend,
++ .resume = serial8250_resume,
++ .driver = {
++ .name = "serial8250",
++ .owner = THIS_MODULE,
++ },
++};
++
++/*
++ * This "device" covers _all_ ISA 8250-compatible serial devices listed
++ * in the table in include/asm/serial.h
++ */
++static struct platform_device *serial8250_isa_devs;
++
++/*
++ * serial8250_register_port and serial8250_unregister_port allows for
++ * 16x50 serial ports to be configured at run-time, to support PCMCIA
++ * modems and PCI multiport cards.
++ */
++static DEFINE_MUTEX(serial_mutex);
++
++static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
++{
++ int i;
++
++ /*
++ * First, find a port entry which matches.
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (uart_match_port(&serial8250_ports[i].port, port))
++ return &serial8250_ports[i];
++
++ /*
++ * We didn't find a matching entry, so look for the first
++ * free entry. We look for one which hasn't been previously
++ * used (indicated by zero iobase).
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
++ serial8250_ports[i].port.iobase == 0)
++ return &serial8250_ports[i];
++
++ /*
++ * That also failed. Last resort is to find any entry which
++ * doesn't have a real port associated with it.
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (serial8250_ports[i].port.type == PORT_UNKNOWN)
++ return &serial8250_ports[i];
++
++ return NULL;
++}
++
++/**
++ * serial8250_register_port - register a serial port
++ * @port: serial port template
++ *
++ * Configure the serial port specified by the request. If the
++ * port exists and is in use, it is hung up and unregistered
++ * first.
++ *
++ * The port is then probed and if necessary the IRQ is autodetected
++ * If this fails an error is returned.
++ *
++ * On success the port is ready to use and the line number is returned.
++ */
++int serial8250_register_port(struct uart_port *port)
++{
++ struct uart_8250_port *uart;
++ int ret = -ENOSPC;
++
++ if (port->uartclk == 0)
++ return -EINVAL;
++
++ mutex_lock(&serial_mutex);
++
++ uart = serial8250_find_match_or_unused(port);
++ if (uart) {
++ uart_remove_one_port(&serial8250_reg, &uart->port);
++
++ uart->port.iobase = port->iobase;
++ uart->port.membase = port->membase;
++ uart->port.irq = port->irq;
++ uart->port.uartclk = port->uartclk;
++ uart->port.fifosize = port->fifosize;
++ uart->port.regshift = port->regshift;
++ uart->port.iotype = port->iotype;
++ uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
++ uart->port.mapbase = port->mapbase;
++ uart->port.private_data = port->private_data;
++ if (port->dev)
++ uart->port.dev = port->dev;
++
++ ret = uart_add_one_port(&serial8250_reg, &uart->port);
++ if (ret == 0)
++ ret = uart->port.line;
++ }
++ mutex_unlock(&serial_mutex);
++
++ return ret;
++}
++EXPORT_SYMBOL(serial8250_register_port);
++
++/**
++ * serial8250_unregister_port - remove a 16x50 serial port at runtime
++ * @line: serial line number
++ *
++ * Remove one serial port. This may not be called from interrupt
++ * context. We hand the port back to the our control.
++ */
++void serial8250_unregister_port(int line)
++{
++ struct uart_8250_port *uart = &serial8250_ports[line];
++
++ mutex_lock(&serial_mutex);
++ uart_remove_one_port(&serial8250_reg, &uart->port);
++ if (serial8250_isa_devs) {
++ uart->port.flags &= ~UPF_BOOT_AUTOCONF;
++ uart->port.type = PORT_UNKNOWN;
++ uart->port.dev = &serial8250_isa_devs->dev;
++ uart_add_one_port(&serial8250_reg, &uart->port);
++ } else {
++ uart->port.dev = NULL;
++ }
++ mutex_unlock(&serial_mutex);
++}
++EXPORT_SYMBOL(serial8250_unregister_port);
++
++static int __init serial8250_init(void)
++{
++ int ret, i;
++
++ if (nr_uarts > UART_NR)
++ nr_uarts = UART_NR;
++
++ printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
++ "%d ports, IRQ sharing %sabled\n", nr_uarts,
++ share_irqs ? "en" : "dis");
++
++ for (i = 0; i < NR_IRQS; i++)
++ spin_lock_init(&irq_lists[i].lock);
++
++ ret = uart_register_driver(&serial8250_reg);
++ if (ret)
++ goto out;
++
++ serial8250_isa_devs = platform_device_alloc("serial8250",
++ PLAT8250_DEV_LEGACY);
++ if (!serial8250_isa_devs) {
++ ret = -ENOMEM;
++ goto unreg_uart_drv;
++ }
++
++ ret = platform_device_add(serial8250_isa_devs);
++ if (ret)
++ goto put_dev;
++
++ serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
++
++ ret = platform_driver_register(&serial8250_isa_driver);
++ if (ret == 0)
++ goto out;
++
++ platform_device_del(serial8250_isa_devs);
++ put_dev:
++ platform_device_put(serial8250_isa_devs);
++ unreg_uart_drv:
++ uart_unregister_driver(&serial8250_reg);
++ out:
++ return ret;
++}
++
++static void __exit serial8250_exit(void)
++{
++ struct platform_device *isa_dev = serial8250_isa_devs;
++
++ /*
++ * This tells serial8250_unregister_port() not to re-register
++ * the ports (thereby making serial8250_isa_driver permanently
++ * in use.)
++ */
++ serial8250_isa_devs = NULL;
++
++ platform_driver_unregister(&serial8250_isa_driver);
++ platform_device_unregister(isa_dev);
++
++ uart_unregister_driver(&serial8250_reg);
++}
++
++module_init(serial8250_init);
++module_exit(serial8250_exit);
++
++EXPORT_SYMBOL(serial8250_suspend_port);
++EXPORT_SYMBOL(serial8250_resume_port);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $");
++
++module_param(share_irqs, uint, 0644);
++MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
++ " (unsafe)");
++
++module_param(nr_uarts, uint, 0644);
++MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
++
++#ifdef CONFIG_SERIAL_8250_RSA
++module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
++MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
++#endif
++MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+diff -Naur linux-2.6.25_original/drivers/serial/amba-pl011.c linux-2.6.25/drivers/serial/amba-pl011.c
+--- linux-2.6.25_original/drivers/serial/amba-pl011.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/amba-pl011.c 2009-05-16 18:43:58.000000000 +0530
+@@ -332,7 +332,8 @@
+ /*
+ * Allocate the IRQ
+ */
+- retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
++ retval = request_irq(uap->port.irq, pl011_int, SA_SHIRQ, "uart-pl011", uap);
++
+ if (retval)
+ goto clk_dis;
+
+diff -Naur linux-2.6.25_original/drivers/serial/e_conquad_8250_16c174b.c linux-2.6.25/drivers/serial/e_conquad_8250_16c174b.c
+--- linux-2.6.25_original/drivers/serial/e_conquad_8250_16c174b.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/serial/e_conquad_8250_16c174b.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,3177 @@
++/*
++ * linux/drivers/char/8250.c
++ *
++ * Driver for 8250/16550-type serial ports
++ *
++ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ * Copyright (C) 2001 Russell King.
++ *
++ * 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.
++ *
++ * $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $
++ *
++ * A note about mapbase / membase
++ *
++ * mapbase is the physical address of the IO port.
++ * membase is an 'ioremapped' cookie.
++ */
++
++#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_core.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/nmi.h>
++#include <linux/mutex.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "8250.h"
++
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/pxa2xx-regs.h>
++#include <linux/irq.h>
++#include <asm/irq.h>
++
++
++#ifdef CONFIG_MACH_SIRIUS
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x15000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00400000
++#define QUAD_UART_C_OFFSET_ADDR 0x00800000
++#define QUAD_UART_D_OFFSET_ADDR 0x00C00000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 19
++#define GPIO_FOR_QUAD_UART_B_IRQ 11
++#define GPIO_FOR_QUAD_UART_C_IRQ 13
++#define GPIO_FOR_QUAD_UART_D_IRQ 14
++#elif defined(CONFIG_MACH_REGULUS)
++#define QUAD_UART_VIRT_ADDR 0xFD000000
++#define QUAD_UART_PHYS_ADDR 0x14000000
++#define QUAD_UART_A_OFFSET_ADDR 0x00000000
++#define QUAD_UART_B_OFFSET_ADDR 0x00200000
++#define QUAD_UART_C_OFFSET_ADDR 0x00400000
++#define QUAD_UART_D_OFFSET_ADDR 0x00600000
++#define QUAD_UART_A_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_VIRT_ADDR (QUAD_UART_VIRT_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define QUAD_UART_A_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_A_OFFSET_ADDR)
++#define QUAD_UART_B_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_B_OFFSET_ADDR)
++#define QUAD_UART_C_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_C_OFFSET_ADDR)
++#define QUAD_UART_D_PHYS_ADDR (QUAD_UART_PHYS_ADDR+QUAD_UART_D_OFFSET_ADDR)
++#define GPIO_FOR_QUAD_UART_A_IRQ 29
++#define GPIO_FOR_QUAD_UART_B_IRQ 115
++#define GPIO_FOR_QUAD_UART_C_IRQ 14
++#define GPIO_FOR_QUAD_UART_D_IRQ 114
++#endif
++#define GPIO_FOR_QUAD_UART_A_IRQ_MD (GPIO_FOR_QUAD_UART_A_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_B_IRQ_MD (GPIO_FOR_QUAD_UART_B_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_C_IRQ_MD (GPIO_FOR_QUAD_UART_C_IRQ | GPIO_IN)
++#define GPIO_FOR_QUAD_UART_D_IRQ_MD (GPIO_FOR_QUAD_UART_D_IRQ | GPIO_IN)
++#define QUAD_UART_A_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_A_IRQ)
++#define QUAD_UART_B_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_B_IRQ)
++#define QUAD_UART_C_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_C_IRQ)
++#define QUAD_UART_D_IRQ IRQ_GPIO(GPIO_FOR_QUAD_UART_D_IRQ)
++
++
++
++
++
++
++
++#ifndef CONFIG_SERIAL_8250_RUNTIME_UARTS
++#define CONFIG_SERIAL_8250_RUNTIME_UARTS 4
++#endif
++/*
++ * Configuration:
++ * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
++ * is unsafe when used on edge-triggered interrupts.
++ */
++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
++
++static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
++
++/*
++ * Debugging.
++ */
++#if 0
++#define DEBUG_AUTOCONF(fmt...) printk(fmt)
++#else
++#define DEBUG_AUTOCONF(fmt...) do { } while (0)
++#endif
++
++#if 0
++#define DEBUG_INTR(fmt...) printk(fmt)
++#else
++#define DEBUG_INTR(fmt...) do { } while (0)
++#endif
++
++#define PASS_LIMIT 256
++
++/*
++ * We default to IRQ0 for the "no irq" hack. Some
++ * machine types want others as well - they're free
++ * to redefine this in their header file.
++ */
++#define is_real_interrupt(irq) ((irq) != 0)
++
++#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
++#define CONFIG_SERIAL_DETECT_IRQ 1
++#endif
++#ifdef CONFIG_SERIAL_8250_MANY_PORTS
++#define CONFIG_SERIAL_MANY_PORTS 1
++#endif
++
++/*
++ * HUB6 is always on. This will be removed once the header
++ * files have been cleaned.
++ */
++#define CONFIG_HUB6 1
++
++#include <asm/serial.h>
++
++/*
++ * SERIAL_PORT_DFNS tells us about built-in ports that have no
++ * standard enumeration mechanism. Platforms that can find all
++ * serial ports via mechanisms like ACPI or PCI need not supply it.
++ */
++
++
++#undef BASE_BAUD
++#define BASE_BAUD ( 11059200 / 16 )
++/*
++ * SERIAL_PORT_DFNS tells us about built-in ports that have no
++ * standard enumeration mechanism. Platforms that can find all
++ * serial ports via mechanisms like ACPI or PCI need not supply it.
++ */
++#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
++#ifndef SERIAL_PORT_DFNS
++#define SERIAL_PORT_DFNS \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_A_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_A_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_B_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_B_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_C_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_C_VIRT_ADDR,1}, \
++ {PORT_PXA,BASE_BAUD,PORT_16654,QUAD_UART_D_IRQ,STD_COM_FLAGS,0,UPIO_MEM,(unsigned char *)QUAD_UART_D_VIRT_ADDR,1},
++
++#endif
++
++
++/*
++ * plat form data specific info
++ */
++
++ static struct plat_serial8250_port serial_quad_ports[] = {
++ [0] = {
++ .iobase = (unsigned long) QUAD_UART_A_PHYS_ADDR,
++ .mapbase = (unsigned long) QUAD_UART_A_PHYS_ADDR,
++ .irq =QUAD_UART_A_IRQ ,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 1,
++ .uartclk = 24000000,//3686400,
++ .membase =(void __iomem *)QUAD_UART_A_VIRT_ADDR,
++ },
++ [1] = {
++ .iobase = (unsigned long) QUAD_UART_B_PHYS_ADDR,
++ .mapbase = (unsigned long) QUAD_UART_B_PHYS_ADDR,
++ .irq = QUAD_UART_B_IRQ,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 1,
++ .uartclk = 24000000,//3686400,
++ .membase =(void __iomem *)QUAD_UART_B_VIRT_ADDR,
++
++ },
++ [2] = {
++ .iobase = (unsigned long) QUAD_UART_C_PHYS_ADDR,
++ .mapbase = (unsigned long) QUAD_UART_C_PHYS_ADDR,
++ .irq = QUAD_UART_C_IRQ,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 1,
++ .uartclk = 24000000,//3686400,
++ .membase =(void __iomem *)QUAD_UART_C_VIRT_ADDR,
++
++ },
++ [3] = {
++ .iobase = (unsigned long) QUAD_UART_D_PHYS_ADDR,
++ .mapbase = (unsigned long) QUAD_UART_D_PHYS_ADDR,
++ .irq = QUAD_UART_D_IRQ,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 1,
++ .uartclk = 24000000,//3686400,
++ .membase =(void __iomem *)QUAD_UART_D_VIRT_ADDR,
++
++ },
++ {},
++ };
++
++
++ /* defined in asm/serial.h */
++
++static const struct old_serial_port old_serial_port[] = {
++ SERIAL_PORT_DFNS /* defined in asm/serial.h */
++};
++
++#ifndef CONFIG_SERIAL_8250_NR_UARTS
++#define CONFIG_SERIAL_8250_NR_UARTS 8 //4 // Modified from 4 to 8 for getting the /dev/ttyS3 to /dev/ttyS6 entries for the Quad uart ports
++#endif
++
++
++#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
++
++#ifdef CONFIG_SERIAL_8250_RSA
++
++#define PORT_RSA_MAX 4
++static unsigned long probe_rsa[PORT_RSA_MAX];
++static unsigned int probe_rsa_count;
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++struct uart_8250_port {
++ struct uart_port port;
++ struct timer_list timer; /* "no irq" timer */
++ struct list_head list; /* ports on this IRQ */
++ unsigned short capabilities; /* port capabilities */
++ unsigned short bugs; /* port bugs */
++ unsigned int tx_loadsz; /* transmit fifo load size */
++ unsigned char acr;
++ unsigned char ier;
++ unsigned char lcr;
++ unsigned char mcr;
++ unsigned char mcr_mask; /* mask of user bits */
++ unsigned char mcr_force; /* mask of forced bits */
++
++ /*
++ * Some bits in registers are cleared on a read, so they must
++ * be saved whenever the register is read but the bits will not
++ * be immediately processed.
++ */
++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
++ unsigned char lsr_saved_flags;
++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
++ unsigned char msr_saved_flags;
++
++ /*
++ * We provide a per-port pm hook.
++ */
++ void (*pm)(struct uart_port *port,
++ unsigned int state, unsigned int old);
++};
++
++struct irq_info {
++ spinlock_t lock;
++ struct list_head *head;
++};
++
++static struct irq_info irq_lists[NR_IRQS];
++
++/*
++ * Here we define the default xmit fifo size used for each type of UART.
++ */
++static const struct serial8250_config uart_config[] = {
++ [PORT_UNKNOWN] = {
++ .name = "unknown",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_8250] = {
++ .name = "8250",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16450] = {
++ .name = "16450",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550] = {
++ .name = "16550",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550A] = {
++ .name = "16550A",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_CIRRUS] = {
++ .name = "Cirrus",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16650] = {
++ .name = "ST16650",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16650V2] = {
++ .name = "ST16650V2",
++ .fifo_size = 32,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++ UART_FCR_T_TRIG_00,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16750] = {
++ .name = "TI16750",
++ .fifo_size = 64,
++ .tx_loadsz = 64,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
++ UART_FCR7_64BYTE,
++ .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
++ },
++ [PORT_STARTECH] = {
++ .name = "Startech",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16C950] = {
++ .name = "16C950/954",
++ .fifo_size = 128,
++ .tx_loadsz = 128,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_16654] = {
++ .name = "ST16654",
++ .fifo_size = 64,
++ .tx_loadsz = 32,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++ UART_FCR_T_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_16850] = {
++ .name = "XR16850",
++ .fifo_size = 128,
++ .tx_loadsz = 128,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++ },
++ [PORT_RSA] = {
++ .name = "RSA",
++ .fifo_size = 2048,
++ .tx_loadsz = 2048,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
++ .flags = UART_CAP_FIFO,
++ },
++ [PORT_NS16550A] = {
++ .name = "NS16550A",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_NATSEMI,
++ },
++ [PORT_XSCALE] = {
++ .name = "XScale",
++ .fifo_size = 32,
++ .tx_loadsz = 32,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO | UART_CAP_UUE,
++ },
++ [PORT_RM9000] = {
++ .name = "RM9000",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .flags = UART_CAP_FIFO,
++ },
++};
++
++#if defined (CONFIG_SERIAL_8250_AU1X00)
++
++/* Au1x00 UART hardware has a weird register layout */
++static const u8 au_io_in_map[] = {
++ [UART_RX] = 0,
++ [UART_IER] = 2,
++ [UART_IIR] = 3,
++ [UART_LCR] = 5,
++ [UART_MCR] = 6,
++ [UART_LSR] = 7,
++ [UART_MSR] = 8,
++};
++
++static const u8 au_io_out_map[] = {
++ [UART_TX] = 1,
++ [UART_IER] = 2,
++ [UART_FCR] = 4,
++ [UART_LCR] = 5,
++ [UART_MCR] = 6,
++};
++
++/* sane hardware needs no mapping */
++static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_AU)
++ return offset;
++ return au_io_in_map[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_AU)
++ return offset;
++ return au_io_out_map[offset];
++}
++
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++
++static const u8
++ regmap_in[8] = {
++ [UART_RX] = 0x00,
++ [UART_IER] = 0x0c,
++ [UART_IIR] = 0x14,
++ [UART_LCR] = 0x1c,
++ [UART_MCR] = 0x20,
++ [UART_LSR] = 0x24,
++ [UART_MSR] = 0x28,
++ [UART_SCR] = 0x2c
++ },
++ regmap_out[8] = {
++ [UART_TX] = 0x04,
++ [UART_IER] = 0x0c,
++ [UART_FCR] = 0x18,
++ [UART_LCR] = 0x1c,
++ [UART_MCR] = 0x20,
++ [UART_LSR] = 0x24,
++ [UART_MSR] = 0x28,
++ [UART_SCR] = 0x2c
++ };
++
++static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_RM9000)
++ return offset;
++ return regmap_in[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
++{
++ if (up->port.iotype != UPIO_RM9000)
++ return offset;
++ return regmap_out[offset];
++}
++
++#else
++
++/* sane hardware needs no mapping */
++#define map_8250_in_reg(up, offset) (offset)
++#define map_8250_out_reg(up, offset) (offset)
++
++#endif
++
++static unsigned int serial_in(struct uart_8250_port *up, int offset)
++{
++ unsigned int tmp;
++ offset = map_8250_in_reg(up, offset) << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ outb(up->port.hub6 - 1 + offset, up->port.iobase);
++ return inb(up->port.iobase + 1);
++
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ return readb(up->port.membase + offset);
++
++ case UPIO_RM9000:
++ case UPIO_MEM32:
++ return readl(up->port.membase + offset);
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++ return __raw_readl(up->port.membase + offset);
++#endif
++
++ case UPIO_TSI:
++ if (offset == UART_IIR) {
++ tmp = readl(up->port.membase + (UART_IIR & ~3));
++ return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
++ } else
++ return readb(up->port.membase + offset);
++
++ default:
++ return inb(up->port.iobase + offset);
++ }
++}
++
++static void
++serial_out(struct uart_8250_port *up, int offset, int value)
++{
++ /* Save the offset before it's remapped */
++ int save_offset = offset;
++ offset = map_8250_out_reg(up, offset) << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ outb(up->port.hub6 - 1 + offset, up->port.iobase);
++ outb(value, up->port.iobase + 1);
++ break;
++
++ case UPIO_MEM:
++ writeb(value, up->port.membase + offset);
++ break;
++
++ case UPIO_RM9000:
++ case UPIO_MEM32:
++ writel(value, up->port.membase + offset);
++ break;
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++ __raw_writel(value, up->port.membase + offset);
++ break;
++#endif
++ case UPIO_TSI:
++ if (!((offset == UART_IER) && (value & UART_IER_UUE)))
++ writeb(value, up->port.membase + offset);
++ break;
++
++ case UPIO_DWAPB:
++ /* Save the LCR value so it can be re-written when a
++ * Busy Detect interrupt occurs. */
++ if (save_offset == UART_LCR)
++ up->lcr = value;
++ writeb(value, up->port.membase + offset);
++ /* Read the IER to ensure any interrupt is cleared before
++ * returning from ISR. */
++ if (save_offset == UART_TX || save_offset == UART_IER)
++ value = serial_in(up, UART_IER);
++ break;
++
++ default:
++ outb(value, up->port.iobase + offset);
++ }
++}
++
++static void
++serial_out_sync(struct uart_8250_port *up, int offset, int value)
++{
++ switch (up->port.iotype) {
++ case UPIO_MEM:
++ case UPIO_MEM32:
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ case UPIO_AU:
++#endif
++ case UPIO_DWAPB:
++ serial_out(up, offset, value);
++ serial_in(up, UART_LCR); /* safe, no side-effects */
++ break;
++ default:
++ serial_out(up, offset, value);
++ }
++}
++
++/*
++ * We used to support using pause I/O for certain machines. We
++ * haven't supported this for a while, but just in case it's badly
++ * needed for certain old 386 machines, I've left these #define's
++ * in....
++ */
++#define serial_inp(up, offset) serial_in(up, offset)
++#define serial_outp(up, offset, value) serial_out(up, offset, value)
++
++/* Uart divisor latch read */
++static inline int _serial_dl_read(struct uart_8250_port *up)
++{
++ return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static inline void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++ serial_outp(up, UART_DLL, value & 0xff);
++ serial_outp(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#if defined(CONFIG_SERIAL_8250_AU1X00)
++/* Au1x00 haven't got a standard divisor latch */
++static int serial_dl_read(struct uart_8250_port *up)
++{
++ if (up->port.iotype == UPIO_AU)
++ return __raw_readl(up->port.membase + 0x28);
++ else
++ return _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_AU)
++ __raw_writel(value, up->port.membase + 0x28);
++ else
++ _serial_dl_write(up, value);
++}
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++static int serial_dl_read(struct uart_8250_port *up)
++{
++ return (up->port.iotype == UPIO_RM9000) ?
++ (((__raw_readl(up->port.membase + 0x10) << 8) |
++ (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
++ _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++ if (up->port.iotype == UPIO_RM9000) {
++ __raw_writel(value, up->port.membase + 0x08);
++ __raw_writel(value >> 8, up->port.membase + 0x10);
++ } else {
++ _serial_dl_write(up, value);
++ }
++}
++#else
++#define serial_dl_read(up) _serial_dl_read(up)
++#define serial_dl_write(up, value) _serial_dl_write(up, value)
++#endif
++
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++ serial_out(up, UART_SCR, offset);
++ serial_out(up, UART_ICR, value);
++}
++
++static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
++{
++ unsigned int value;
++
++ serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++ serial_out(up, UART_SCR, offset);
++ value = serial_in(up, UART_ICR);
++ serial_icr_write(up, UART_ACR, up->acr);
++
++ return value;
++}
++
++/*
++ * FIFO support.
++ */
++static inline void serial8250_clear_fifos(struct uart_8250_port *p)
++{
++ if (p->capabilities & UART_CAP_FIFO) {
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++ serial_outp(p, UART_FCR, 0);
++ }
++}
++
++/*
++ * IER sleep support. UARTs which have EFRs need the "extended
++ * capability" bit enabled. Note that on XR16C850s, we need to
++ * reset LCR to write to IER.
++ */
++static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
++{
++ if (p->capabilities & UART_CAP_SLEEP) {
++ if (p->capabilities & UART_CAP_EFR) {
++ serial_outp(p, UART_LCR, 0xBF);
++ serial_outp(p, UART_EFR, UART_EFR_ECB);
++ serial_outp(p, UART_LCR, 0);
++ }
++ serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
++ if (p->capabilities & UART_CAP_EFR) {
++ serial_outp(p, UART_LCR, 0xBF);
++ serial_outp(p, UART_EFR, 0);
++ serial_outp(p, UART_LCR, 0);
++ }
++ }
++}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++/*
++ * Attempts to turn on the RSA FIFO. Returns zero on failure.
++ * We set the port uart clock rate if we succeed.
++ */
++static int __enable_rsa(struct uart_8250_port *up)
++{
++ unsigned char mode;
++ int result;
++
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = mode & UART_RSA_MSR_FIFO;
++
++ if (!result) {
++ serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = mode & UART_RSA_MSR_FIFO;
++ }
++
++ if (result)
++ up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
++
++ return result;
++}
++
++static void enable_rsa(struct uart_8250_port *up)
++{
++ if (up->port.type == PORT_RSA) {
++ if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
++ spin_lock_irq(&up->port.lock);
++ __enable_rsa(up);
++ spin_unlock_irq(&up->port.lock);
++ }
++ if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
++ serial_outp(up, UART_RSA_FRR, 0);
++ }
++}
++
++/*
++ * Attempts to turn off the RSA FIFO. Returns zero on failure.
++ * It is unknown why interrupts were disabled in here. However,
++ * the caller is expected to preserve this behaviour by grabbing
++ * the spinlock before calling this function.
++ */
++static void disable_rsa(struct uart_8250_port *up)
++{
++ unsigned char mode;
++ int result;
++
++ if (up->port.type == PORT_RSA &&
++ up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
++ spin_lock_irq(&up->port.lock);
++
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = !(mode & UART_RSA_MSR_FIFO);
++
++ if (!result) {
++ serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
++ mode = serial_inp(up, UART_RSA_MSR);
++ result = !(mode & UART_RSA_MSR_FIFO);
++ }
++
++ if (result)
++ up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
++ spin_unlock_irq(&up->port.lock);
++ }
++}
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++/*
++ * This is a quickie test to see how big the FIFO is.
++ * It doesn't work at all the time, more's the pity.
++ */
++static int size_fifo(struct uart_8250_port *up)
++{
++ unsigned char old_fcr, old_mcr, old_lcr;
++ unsigned short old_dl;
++ int count;
++
++ old_lcr = serial_inp(up, UART_LCR);
++ serial_outp(up, UART_LCR, 0);
++ old_fcr = serial_inp(up, UART_FCR);
++ old_mcr = serial_inp(up, UART_MCR);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++ serial_outp(up, UART_MCR, UART_MCR_LOOP);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ old_dl = serial_dl_read(up);
++ serial_dl_write(up, 0x0001);
++ serial_outp(up, UART_LCR, 0x03);
++ for (count = 0; count < 256; count++)
++ serial_outp(up, UART_TX, count);
++ mdelay(20);/* FIXME - schedule_timeout */
++ for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
++ (count < 256); count++)
++ serial_inp(up, UART_RX);
++ serial_outp(up, UART_FCR, old_fcr);
++ serial_outp(up, UART_MCR, old_mcr);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ serial_dl_write(up, old_dl);
++ serial_outp(up, UART_LCR, old_lcr);
++
++ return count;
++}
++
++/*
++ * Read UART ID using the divisor method - set DLL and DLM to zero
++ * and the revision will be in DLL and device type in DLM. We
++ * preserve the device state across this.
++ */
++static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
++{
++ unsigned char old_dll, old_dlm, old_lcr;
++ unsigned int id;
++
++ old_lcr = serial_inp(p, UART_LCR);
++ serial_outp(p, UART_LCR, UART_LCR_DLAB);
++
++ old_dll = serial_inp(p, UART_DLL);
++ old_dlm = serial_inp(p, UART_DLM);
++
++ serial_outp(p, UART_DLL, 0);
++ serial_outp(p, UART_DLM, 0);
++
++ id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
++
++ serial_outp(p, UART_DLL, old_dll);
++ serial_outp(p, UART_DLM, old_dlm);
++ serial_outp(p, UART_LCR, old_lcr);
++
++ return id;
++}
++
++/*
++ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
++ * When this function is called we know it is at least a StarTech
++ * 16650 V2, but it might be one of several StarTech UARTs, or one of
++ * its clones. (We treat the broken original StarTech 16650 V1 as a
++ * 16550, and why not? Startech doesn't seem to even acknowledge its
++ * existence.)
++ *
++ * What evil have men's minds wrought...
++ */
++static void autoconfig_has_efr(struct uart_8250_port *up)
++{
++ unsigned int id1, id2, id3, rev;
++
++ /*
++ * Everything with an EFR has SLEEP
++ */
++ up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++
++ /*
++ * First we check to see if it's an Oxford Semiconductor UART.
++ *
++ * If we have to do this here because some non-National
++ * Semiconductor clone chips lock up if you try writing to the
++ * LSR register (which serial_icr_read does)
++ */
++
++ /*
++ * Check for Oxford Semiconductor 16C950.
++ *
++ * EFR [4] must be set else this test fails.
++ *
++ * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
++ * claims that it's needed for 952 dual UART's (which are not
++ * recommended for new designs).
++ */
++ up->acr = 0;
++ serial_out(up, UART_LCR, 0xBF);
++ serial_out(up, UART_EFR, UART_EFR_ECB);
++ serial_out(up, UART_LCR, 0x00);
++ id1 = serial_icr_read(up, UART_ID1);
++ id2 = serial_icr_read(up, UART_ID2);
++ id3 = serial_icr_read(up, UART_ID3);
++ rev = serial_icr_read(up, UART_REV);
++
++ DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
++
++ if (id1 == 0x16 && id2 == 0xC9 &&
++ (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
++ up->port.type = PORT_16C950;
++
++ /*
++ * Enable work around for the Oxford Semiconductor 952 rev B
++ * chip which causes it to seriously miscalculate baud rates
++ * when DLL is 0.
++ */
++ if (id3 == 0x52 && rev == 0x01)
++ up->bugs |= UART_BUG_QUOT;
++ return;
++ }
++
++ /*
++ * We check for a XR16C850 by setting DLL and DLM to 0, and then
++ * reading back DLL and DLM. The chip type depends on the DLM
++ * value read back:
++ * 0x10 - XR16C850 and the DLL contains the chip revision.
++ * 0x12 - XR16C2850.
++ * 0x14 - XR16C854.
++ */
++ id1 = autoconfig_read_divisor_id(up);
++ DEBUG_AUTOCONF("850id=%04x ", id1);
++
++ id2 = id1 >> 8;
++ if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
++ up->port.type = PORT_16850;
++ return;
++ }
++
++ /*
++ * It wasn't an XR16C850.
++ *
++ * We distinguish between the '654 and the '650 by counting
++ * how many bytes are in the FIFO. I'm using this for now,
++ * since that's the technique that was sent to me in the
++ * serial driver update, but I'm not convinced this works.
++ * I've had problems doing this in the past. -TYT
++ */
++ if (size_fifo(up) == 64)
++ up->port.type = PORT_16654;
++ else
++ up->port.type = PORT_16650V2;
++}
++
++/*
++ * We detected a chip without a FIFO. Only two fall into
++ * this category - the original 8250 and the 16450. The
++ * 16450 has a scratch register (accessible with LCR=0)
++ */
++static void autoconfig_8250(struct uart_8250_port *up)
++{
++ unsigned char scratch, status1, status2;
++
++ up->port.type = PORT_8250;
++
++ scratch = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, 0xa5);
++ status1 = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, 0x5a);
++ status2 = serial_in(up, UART_SCR);
++ serial_outp(up, UART_SCR, scratch);
++
++ if (status1 == 0xa5 && status2 == 0x5a)
++ up->port.type = PORT_16450;
++}
++
++static int broken_efr(struct uart_8250_port *up)
++{
++ /*
++ * Exar ST16C2550 "A2" devices incorrectly detect as
++ * having an EFR, and report an ID of 0x0201. See
++ * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
++ */
++ if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
++ return 1;
++
++ return 0;
++}
++
++/*
++ * We know that the chip has FIFOs. Does it have an EFR? The
++ * EFR is located in the same register position as the IIR and
++ * we know the top two bits of the IIR are currently set. The
++ * EFR should contain zero. Try to read the EFR.
++ */
++static void autoconfig_16550a(struct uart_8250_port *up)
++{
++ unsigned char status1, status2;
++ unsigned int iersave;
++
++ up->port.type = PORT_16550A;
++ up->capabilities |= UART_CAP_FIFO;
++
++ /*
++ * Check for presence of the EFR when DLAB is set.
++ * Only ST16C650V1 UARTs pass this test.
++ */
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ if (serial_in(up, UART_EFR) == 0) {
++ serial_outp(up, UART_EFR, 0xA8);
++ if (serial_in(up, UART_EFR) != 0) {
++ DEBUG_AUTOCONF("EFRv1 ");
++ up->port.type = PORT_16650;
++ up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++ } else {
++ DEBUG_AUTOCONF("Motorola 8xxx DUART ");
++ }
++ serial_outp(up, UART_EFR, 0);
++ return;
++ }
++
++ /*
++ * Maybe it requires 0xbf to be written to the LCR.
++ * (other ST16C650V2 UARTs, TI16C752A, etc)
++ */
++ serial_outp(up, UART_LCR, 0xBF);
++ if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
++ DEBUG_AUTOCONF("EFRv2 ");
++ autoconfig_has_efr(up);
++ return;
++ }
++
++ /*
++ * Check for a National Semiconductor SuperIO chip.
++ * Attempt to switch to bank 2, read the value of the LOOP bit
++ * from EXCR1. Switch back to bank 0, change it in MCR. Then
++ * switch back to bank 2, read it from EXCR1 again and check
++ * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
++ */
++ serial_outp(up, UART_LCR, 0);
++ status1 = serial_in(up, UART_MCR);
++ serial_outp(up, UART_LCR, 0xE0);
++ status2 = serial_in(up, 0x02); /* EXCR1 */
++
++ if (!((status2 ^ status1) & UART_MCR_LOOP)) {
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
++ serial_outp(up, UART_LCR, 0xE0);
++ status2 = serial_in(up, 0x02); /* EXCR1 */
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_MCR, status1);
++
++ if ((status2 ^ status1) & UART_MCR_LOOP) {
++ unsigned short quot;
++
++ serial_outp(up, UART_LCR, 0xE0);
++
++ quot = serial_dl_read(up);
++ quot <<= 3;
++
++ status1 = serial_in(up, 0x04); /* EXCR2 */
++ status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
++ serial_outp(up, 0x04, status1);
++
++ serial_dl_write(up, quot);
++
++ serial_outp(up, UART_LCR, 0);
++
++ up->port.uartclk = 921600*16;
++ up->port.type = PORT_NS16550A;
++ up->capabilities |= UART_NATSEMI;
++ return;
++ }
++ }
++
++ /*
++ * No EFR. Try to detect a TI16750, which only sets bit 5 of
++ * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
++ * Try setting it with and without DLAB set. Cheap clones
++ * set bit 5 without DLAB set.
++ */
++ serial_outp(up, UART_LCR, 0);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++ status1 = serial_in(up, UART_IIR) >> 5;
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(up, UART_LCR, UART_LCR_DLAB);
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++ status2 = serial_in(up, UART_IIR) >> 5;
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(up, UART_LCR, 0);
++
++ DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
++
++ if (status1 == 6 && status2 == 7) {
++ up->port.type = PORT_16750;
++ up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
++ return;
++ }
++
++ /*
++ * Try writing and reading the UART_IER_UUE bit (b6).
++ * If it works, this is probably one of the Xscale platform's
++ * internal UARTs.
++ * We're going to explicitly set the UUE bit to 0 before
++ * trying to write and read a 1 just to make sure it's not
++ * already a 1 and maybe locked there before we even start start.
++ */
++ iersave = serial_in(up, UART_IER);
++ serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
++ if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
++ /*
++ * OK it's in a known zero state, try writing and reading
++ * without disturbing the current state of the other bits.
++ */
++ serial_outp(up, UART_IER, iersave | UART_IER_UUE);
++ if (serial_in(up, UART_IER) & UART_IER_UUE) {
++ /*
++ * It's an Xscale.
++ * We'll leave the UART_IER_UUE bit set to 1 (enabled).
++ */
++ DEBUG_AUTOCONF("Xscale ");
++ up->port.type = PORT_XSCALE;
++ up->capabilities |= UART_CAP_UUE;
++ return;
++ }
++ } else {
++ /*
++ * If we got here we couldn't force the IER_UUE bit to 0.
++ * Log it and continue.
++ */
++ DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
++ }
++ serial_outp(up, UART_IER, iersave);
++}
++
++/*
++ * This routine is called by rs_init() to initialize a specific serial
++ * port. It determines what type of UART chip this serial port is
++ * using: 8250, 16450, 16550, 16550A. The important question is
++ * whether or not this UART is a 16550A or not, since this will
++ * determine whether or not we can use its FIFO features or not.
++ */
++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
++{
++ unsigned char status1, scratch, scratch2, scratch3;
++ unsigned char save_lcr, save_mcr;
++ unsigned long flags;
++
++ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
++ return;
++
++ DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
++ up->port.line, up->port.iobase, up->port.membase);
++
++ /*
++ * We really do need global IRQs disabled here - we're going to
++ * be frobbing the chips IRQ enable register to see if it exists.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ up->capabilities = 0;
++ up->bugs = 0;
++
++ if (!(up->port.flags & UPF_BUGGY_UART)) {
++ /*
++ * Do a simple existence test first; if we fail this,
++ * there's no point trying anything else.
++ *
++ * 0x80 is used as a nonsense port to prevent against
++ * false positives due to ISA bus float. The
++ * assumption is that 0x80 is a non-existent port;
++ * which should be safe since include/asm/io.h also
++ * makes this assumption.
++ *
++ * Note: this is safe as long as MCR bit 4 is clear
++ * and the device is in "PC" mode.
++ */
++ scratch = serial_inp(up, UART_IER);
++ serial_outp(up, UART_IER, 0);
++#ifdef __i386__
++ outb(0xff, 0x080);
++#endif
++ /*
++ * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
++ * 16C754B) allow only to modify them if an EFR bit is set.
++ */
++ scratch2 = serial_inp(up, UART_IER) & 0x0f;
++ serial_outp(up, UART_IER, 0x0F);
++#ifdef __i386__
++ outb(0, 0x080);
++#endif
++ scratch3 = serial_inp(up, UART_IER) & 0x0f;
++ serial_outp(up, UART_IER, scratch);
++ if (scratch2 != 0 || scratch3 != 0x0F) {
++ /*
++ * We failed; there's nothing here
++ */
++ DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
++ scratch2, scratch3);
++ goto out;
++ }
++ }
++
++ save_mcr = serial_in(up, UART_MCR);
++ save_lcr = serial_in(up, UART_LCR);
++
++ /*
++ * Check to see if a UART is really there. Certain broken
++ * internal modems based on the Rockwell chipset fail this
++ * test, because they apparently don't implement the loopback
++ * test mode. So this test is skipped on the COM 1 through
++ * COM 4 ports. This *should* be safe, since no board
++ * manufacturer would be stupid enough to design a board
++ * that conflicts with COM 1-4 --- we hope!
++ */
++ if (!(up->port.flags & UPF_SKIP_TEST)) {
++ serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
++ status1 = serial_inp(up, UART_MSR) & 0xF0;
++ serial_outp(up, UART_MCR, save_mcr);
++ if (status1 != 0x90) {
++ DEBUG_AUTOCONF("LOOP test failed (%02x) ",
++ status1);
++ goto out;
++ }
++ }
++
++ /*
++ * We're pretty sure there's a port here. Lets find out what
++ * type of port it is. The IIR top two bits allows us to find
++ * out if it's 8250 or 16450, 16550, 16550A or later. This
++ * determines what we test for next.
++ *
++ * We also initialise the EFR (if any) to zero for later. The
++ * EFR occupies the same register location as the FCR and IIR.
++ */
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, 0);
++ serial_outp(up, UART_LCR, 0);
++
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ scratch = serial_in(up, UART_IIR) >> 6;
++
++ DEBUG_AUTOCONF("iir=%d ", scratch);
++
++ switch (scratch) {
++ case 0:
++ autoconfig_8250(up);
++ break;
++ case 1:
++ up->port.type = PORT_UNKNOWN;
++ break;
++ case 2:
++ up->port.type = PORT_16550;
++ break;
++ case 3:
++ autoconfig_16550a(up);
++ break;
++ }
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * Only probe for RSA ports if we got the region.
++ */
++ if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
++ int i;
++
++ for (i = 0 ; i < probe_rsa_count; ++i) {
++ if (probe_rsa[i] == up->port.iobase &&
++ __enable_rsa(up)) {
++ up->port.type = PORT_RSA;
++ break;
++ }
++ }
++ }
++#endif
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++ /* if access method is AU, it is a 16550 with a quirk */
++ if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
++ up->bugs |= UART_BUG_NOMSR;
++#endif
++
++ serial_outp(up, UART_LCR, save_lcr);
++
++ if (up->capabilities != uart_config[up->port.type].flags) {
++ printk(KERN_WARNING
++ "ttyS%d: detected caps %08x should be %08x\n",
++ up->port.line, up->capabilities,
++ uart_config[up->port.type].flags);
++ }
++
++ up->port.fifosize = uart_config[up->port.type].fifo_size;
++ up->capabilities = uart_config[up->port.type].flags;
++ up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
++
++ if (up->port.type == PORT_UNKNOWN)
++ goto out;
++
++ /*
++ * Reset the UART.
++ */
++#ifdef CONFIG_SERIAL_8250_RSA
++ if (up->port.type == PORT_RSA)
++ serial_outp(up, UART_RSA_FRR, 0);
++#endif
++ serial_outp(up, UART_MCR, save_mcr);
++ serial8250_clear_fifos(up);
++ serial_in(up, UART_RX);
++ if (up->capabilities & UART_CAP_UUE)
++ serial_outp(up, UART_IER, UART_IER_UUE);
++ else
++ serial_outp(up, UART_IER, 0);
++
++ out:
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
++}
++
++static void autoconfig_irq(struct uart_8250_port *up)
++{
++ unsigned char save_mcr, save_ier;
++ unsigned char save_ICP = 0;
++ unsigned int ICP = 0;
++ unsigned long irqs;
++ int irq;
++
++ if (up->port.flags & UPF_FOURPORT) {
++ ICP = (up->port.iobase & 0xfe0) | 0x1f;
++ save_ICP = inb_p(ICP);
++ outb_p(0x80, ICP);
++ (void) inb_p(ICP);
++ }
++
++ /* forget possible initially masked and pending IRQ */
++ probe_irq_off(probe_irq_on());
++ save_mcr = serial_inp(up, UART_MCR);
++ save_ier = serial_inp(up, UART_IER);
++ serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
++
++ irqs = probe_irq_on();
++ serial_outp(up, UART_MCR, 0);
++ udelay(10);
++ if (up->port.flags & UPF_FOURPORT) {
++ serial_outp(up, UART_MCR,
++ UART_MCR_DTR | UART_MCR_RTS);
++ } else {
++ serial_outp(up, UART_MCR,
++ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
++ }
++ serial_outp(up, UART_IER, 0x0f); /* enable all intrs */
++ (void)serial_inp(up, UART_LSR);
++ (void)serial_inp(up, UART_RX);
++ (void)serial_inp(up, UART_IIR);
++ (void)serial_inp(up, UART_MSR);
++ serial_outp(up, UART_TX, 0xFF);
++ udelay(20);
++ irq = probe_irq_off(irqs);
++
++ serial_outp(up, UART_MCR, save_mcr);
++ serial_outp(up, UART_IER, save_ier);
++
++ if (up->port.flags & UPF_FOURPORT)
++ outb_p(save_ICP, ICP);
++
++ up->port.irq = (irq > 0) ? irq : 0;
++}
++
++static inline void __stop_tx(struct uart_8250_port *p)
++{
++ if (p->ier & UART_IER_THRI) {
++ p->ier &= ~UART_IER_THRI;
++ serial_out(p, UART_IER, p->ier);
++ }
++}
++
++static void serial8250_stop_tx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ __stop_tx(up);
++
++ /*
++ * We really want to stop the transmitter from sending.
++ */
++ if (up->port.type == PORT_16C950) {
++ up->acr |= UART_ACR_TXDIS;
++ serial_icr_write(up, UART_ACR, up->acr);
++ }
++}
++
++static void transmit_chars(struct uart_8250_port *up);
++
++static void serial8250_start_tx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ if (!(up->ier & UART_IER_THRI)) {
++ up->ier |= UART_IER_THRI;
++ serial_out(up, UART_IER, up->ier);
++
++ if (up->bugs & UART_BUG_TXEN) {
++ unsigned char lsr, iir;
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ iir = serial_in(up, UART_IIR) & 0x0f;
++ if ((up->port.type == PORT_RM9000) ?
++ (lsr & UART_LSR_THRE &&
++ (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
++ (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
++ transmit_chars(up);
++ }
++ }
++
++ /*
++ * Re-enable the transmitter if we disabled it.
++ */
++ if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
++ up->acr &= ~UART_ACR_TXDIS;
++ serial_icr_write(up, UART_ACR, up->acr);
++ }
++}
++
++static void serial8250_stop_rx(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ up->ier &= ~UART_IER_RLSI;
++ up->port.read_status_mask &= ~UART_LSR_DR;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void serial8250_enable_ms(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ /* no MSR capabilities */
++ if (up->bugs & UART_BUG_NOMSR)
++ return;
++
++ up->ier |= UART_IER_MSI;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void
++receive_chars(struct uart_8250_port *up, unsigned int *status)
++{
++ struct tty_struct *tty = up->port.info->tty;
++ unsigned char ch, lsr = *status;
++ int max_count = 256;
++ char flag;
++
++ do {
++ ch = serial_inp(up, UART_RX);
++ flag = TTY_NORMAL;
++ up->port.icount.rx++;
++
++ lsr |= up->lsr_saved_flags;
++ up->lsr_saved_flags = 0;
++
++ if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
++ /*
++ * For statistics only
++ */
++ if (lsr & UART_LSR_BI) {
++ lsr &= ~(UART_LSR_FE | UART_LSR_PE);
++ up->port.icount.brk++;
++ /*
++ * We do the SysRQ and SAK checking
++ * here because otherwise the break
++ * may get masked by ignore_status_mask
++ * or read_status_mask.
++ */
++ if (uart_handle_break(&up->port))
++ goto ignore_char;
++ } else if (lsr & UART_LSR_PE)
++ up->port.icount.parity++;
++ else if (lsr & UART_LSR_FE)
++ up->port.icount.frame++;
++ if (lsr & UART_LSR_OE)
++ up->port.icount.overrun++;
++
++ /*
++ * Mask off conditions which should be ignored.
++ */
++ lsr &= up->port.read_status_mask;
++
++ if (lsr & UART_LSR_BI) {
++ DEBUG_INTR("handling break....");
++ flag = TTY_BREAK;
++ } else if (lsr & UART_LSR_PE)
++ flag = TTY_PARITY;
++ else if (lsr & UART_LSR_FE)
++ flag = TTY_FRAME;
++ }
++ if (uart_handle_sysrq_char(&up->port, ch))
++ goto ignore_char;
++
++ uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
++
++ignore_char:
++ lsr = serial_inp(up, UART_LSR);
++ } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
++ spin_unlock(&up->port.lock);
++ tty_flip_buffer_push(tty);
++ spin_lock(&up->port.lock);
++ *status = lsr;
++}
++
++static void transmit_chars(struct uart_8250_port *up)
++{
++ struct circ_buf *xmit = &up->port.info->xmit;
++ int count;
++
++ if (up->port.x_char) {
++ serial_outp(up, UART_TX, up->port.x_char);
++ up->port.icount.tx++;
++ up->port.x_char = 0;
++ return;
++ }
++ if (uart_tx_stopped(&up->port)) {
++ serial8250_stop_tx(&up->port);
++ return;
++ }
++ if (uart_circ_empty(xmit)) {
++ __stop_tx(up);
++ return;
++ }
++
++ count = up->tx_loadsz;
++ do {
++ serial_out(up, UART_TX, xmit->buf[xmit->tail]);
++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++ up->port.icount.tx++;
++ if (uart_circ_empty(xmit))
++ break;
++ } while (--count > 0);
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&up->port);
++
++ DEBUG_INTR("THRE...");
++
++ if (uart_circ_empty(xmit))
++ __stop_tx(up);
++}
++
++static unsigned int check_modem_status(struct uart_8250_port *up)
++{
++ unsigned int status = serial_in(up, UART_MSR);
++
++ status |= up->msr_saved_flags;
++ up->msr_saved_flags = 0;
++ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
++ up->port.info != NULL) {
++ if (status & UART_MSR_TERI)
++ up->port.icount.rng++;
++ if (status & UART_MSR_DDSR)
++ up->port.icount.dsr++;
++ if (status & UART_MSR_DDCD)
++ uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
++ if (status & UART_MSR_DCTS)
++ uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
++
++ wake_up_interruptible(&up->port.info->delta_msr_wait);
++ }
++
++ return status;
++}
++
++/*
++ * This handles the interrupt from one port.
++ */
++static inline void
++serial8250_handle_port(struct uart_8250_port *up)
++{
++ unsigned int status;
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ status = serial_inp(up, UART_LSR);
++
++ DEBUG_INTR("status = %x...", status);
++
++ if (status & UART_LSR_DR)
++ receive_chars(up, &status);
++ check_modem_status(up);
++ if (status & UART_LSR_THRE)
++ transmit_chars(up);
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++/*
++ * This is the serial driver's interrupt routine.
++ *
++ * Arjan thinks the old way was overly complex, so it got simplified.
++ * Alan disagrees, saying that need the complexity to handle the weird
++ * nature of ISA shared interrupts. (This is a special exception.)
++ *
++ * In order to handle ISA shared interrupts properly, we need to check
++ * that all ports have been serviced, and therefore the ISA interrupt
++ * line has been de-asserted.
++ *
++ * This means we need to loop through all ports. checking that they
++ * don't have an interrupt pending.
++ */
++static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
++{
++ struct irq_info *i = dev_id;
++ struct list_head *l, *end = NULL;
++ int pass_counter = 0, handled = 0;
++
++ DEBUG_INTR("serial8250_interrupt(%d)...", irq);
++
++ spin_lock(&i->lock);
++
++ l = i->head;
++ do {
++ struct uart_8250_port *up;
++ unsigned int iir;
++
++ up = list_entry(l, struct uart_8250_port, list);
++
++ iir = serial_in(up, UART_IIR);
++ if (!(iir & UART_IIR_NO_INT)) {
++ serial8250_handle_port(up);
++
++ handled = 1;
++
++ end = NULL;
++ } else if (up->port.iotype == UPIO_DWAPB &&
++ (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
++ /* The DesignWare APB UART has an Busy Detect (0x07)
++ * interrupt meaning an LCR write attempt occured while the
++ * UART was busy. The interrupt must be cleared by reading
++ * the UART status register (USR) and the LCR re-written. */
++ unsigned int status;
++ status = *(volatile u32 *)up->port.private_data;
++ serial_out(up, UART_LCR, up->lcr);
++
++ handled = 1;
++
++ end = NULL;
++ } else if (end == NULL)
++ end = l;
++
++ l = l->next;
++
++ if (l == i->head && pass_counter++ > PASS_LIMIT) {
++ /* If we hit this, we're dead. */
++ printk(KERN_ERR "serial8250: too much work for "
++ "irq%d\n", irq);
++ break;
++ }
++ } while (l != end);
++
++ spin_unlock(&i->lock);
++
++ DEBUG_INTR("end.\n");
++
++ return IRQ_RETVAL(handled);
++}
++
++/*
++ * To support ISA shared interrupts, we need to have one interrupt
++ * handler that ensures that the IRQ line has been deasserted
++ * before returning. Failing to do this will result in the IRQ
++ * line being stuck active, and, since ISA irqs are edge triggered,
++ * no more IRQs will be seen.
++ */
++static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
++{
++ spin_lock_irq(&i->lock);
++
++ if (!list_empty(i->head)) {
++ if (i->head == &up->list)
++ i->head = i->head->next;
++ list_del(&up->list);
++ } else {
++ BUG_ON(i->head != &up->list);
++ i->head = NULL;
++ }
++
++ spin_unlock_irq(&i->lock);
++}
++
++static int serial_link_irq_chain(struct uart_8250_port *up)
++{
++ struct irq_info *i = irq_lists + up->port.irq;
++ int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
++
++ spin_lock_irq(&i->lock);
++
++ if (i->head) {
++ list_add(&up->list, i->head);
++ spin_unlock_irq(&i->lock);
++
++ ret = 0;
++ } else {
++ INIT_LIST_HEAD(&up->list);
++ i->head = &up->list;
++ spin_unlock_irq(&i->lock);
++
++ ret = request_irq(up->port.irq, serial8250_interrupt,
++ irq_flags, "serial", i);
++ if (ret < 0)
++ serial_do_unlink(i, up);
++ }
++
++ return ret;
++}
++
++static void serial_unlink_irq_chain(struct uart_8250_port *up)
++{
++ struct irq_info *i = irq_lists + up->port.irq;
++
++ BUG_ON(i->head == NULL);
++
++ if (list_empty(i->head))
++ free_irq(up->port.irq, i);
++
++ serial_do_unlink(i, up);
++}
++
++/* Base timer interval for polling */
++static inline int poll_timeout(int timeout)
++{
++ return timeout > 6 ? (timeout / 2 - 2) : 1;
++}
++
++/*
++ * This function is used to handle ports that do not have an
++ * interrupt. This doesn't work very well for 16450's, but gives
++ * barely passable results for a 16550A. (Although at the expense
++ * of much CPU overhead).
++ */
++static void serial8250_timeout(unsigned long data)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)data;
++ unsigned int iir;
++
++ iir = serial_in(up, UART_IIR);
++ if (!(iir & UART_IIR_NO_INT))
++ serial8250_handle_port(up);
++ mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++}
++
++static void serial8250_backup_timeout(unsigned long data)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)data;
++ unsigned int iir, ier = 0, lsr;
++ unsigned long flags;
++
++ /*
++ * Must disable interrupts or else we risk racing with the interrupt
++ * based handler.
++ */
++ if (is_real_interrupt(up->port.irq)) {
++ ier = serial_in(up, UART_IER);
++ serial_out(up, UART_IER, 0);
++ }
++
++ iir = serial_in(up, UART_IIR);
++
++ /*
++ * This should be a safe test for anyone who doesn't trust the
++ * IIR bits on their UART, but it's specifically designed for
++ * the "Diva" UART used on the management processor on many HP
++ * ia64 and parisc boxes.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
++ (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
++ (lsr & UART_LSR_THRE)) {
++ iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
++ iir |= UART_IIR_THRI;
++ }
++
++ if (!(iir & UART_IIR_NO_INT))
++ serial8250_handle_port(up);
++
++ if (is_real_interrupt(up->port.irq))
++ serial_out(up, UART_IER, ier);
++
++ /* Standard timer interval plus 0.2s to keep the port running */
++ mod_timer(&up->timer,
++ jiffies + poll_timeout(up->port.timeout) + HZ / 5);
++}
++
++static unsigned int serial8250_tx_empty(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ unsigned int lsr;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int serial8250_get_mctrl(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned int status;
++ unsigned int ret;
++
++ status = check_modem_status(up);
++
++ ret = 0;
++ if (status & UART_MSR_DCD)
++ ret |= TIOCM_CAR;
++ if (status & UART_MSR_RI)
++ ret |= TIOCM_RNG;
++ if (status & UART_MSR_DSR)
++ ret |= TIOCM_DSR;
++ if (status & UART_MSR_CTS)
++ ret |= TIOCM_CTS;
++ return ret;
++}
++
++static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned char mcr = 0;
++
++ if (mctrl & TIOCM_RTS)
++ mcr |= UART_MCR_RTS;
++ if (mctrl & TIOCM_DTR)
++ mcr |= UART_MCR_DTR;
++ if (mctrl & TIOCM_OUT1)
++ mcr |= UART_MCR_OUT1;
++ if (mctrl & TIOCM_OUT2)
++ mcr |= UART_MCR_OUT2;
++ if (mctrl & TIOCM_LOOP)
++ mcr |= UART_MCR_LOOP;
++
++ mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
++
++ serial_out(up, UART_MCR, mcr);
++}
++
++static void serial8250_break_ctl(struct uart_port *port, int break_state)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (break_state == -1)
++ up->lcr |= UART_LCR_SBC;
++ else
++ up->lcr &= ~UART_LCR_SBC;
++ serial_out(up, UART_LCR, up->lcr);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
++/*
++ * Wait for transmitter & holding register to empty
++ */
++static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
++{
++ unsigned int status, tmout = 10000;
++
++ /* Wait up to 10ms for the character(s) to be sent. */
++ do {
++ status = serial_in(up, UART_LSR);
++
++ up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
++
++ if (--tmout == 0)
++ break;
++ udelay(1);
++ } while ((status & bits) != bits);
++
++ /* Wait up to 1s for flow control if necessary */
++ if (up->port.flags & UPF_CONS_FLOW) {
++ unsigned int tmout;
++ for (tmout = 1000000; tmout; tmout--) {
++ unsigned int msr = serial_in(up, UART_MSR);
++ up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
++ if (msr & UART_MSR_CTS)
++ break;
++ udelay(1);
++ touch_nmi_watchdog();
++ }
++ }
++}
++
++static int serial8250_startup(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ unsigned char lsr, iir;
++ int retval;
++
++ up->capabilities = uart_config[up->port.type].flags;
++ up->mcr = 0;
++
++ if (up->port.type == PORT_16C950) {
++ /* Wake up and initialize UART */
++ up->acr = 0;
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, UART_EFR_ECB);
++ serial_outp(up, UART_IER, 0);
++ serial_outp(up, UART_LCR, 0);
++ serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, UART_EFR_ECB);
++ serial_outp(up, UART_LCR, 0);
++ }
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * If this is an RSA port, see if we can kick it up to the
++ * higher speed clock.
++ */
++ enable_rsa(up);
++#endif
++
++ /*
++ * Clear the FIFO buffers and disable them.
++ * (they will be reenabled in set_termios())
++ */
++ serial8250_clear_fifos(up);
++
++ /*
++ * Clear the interrupt registers.
++ */
++ (void) serial_inp(up, UART_LSR);
++ (void) serial_inp(up, UART_RX);
++ (void) serial_inp(up, UART_IIR);
++ (void) serial_inp(up, UART_MSR);
++
++ /*
++ * At this point, there's no way the LSR could still be 0xff;
++ * if it is, then bail out, because there's likely no UART
++ * here.
++ */
++ if (!(up->port.flags & UPF_BUGGY_UART) &&
++ (serial_inp(up, UART_LSR) == 0xff)) {
++ printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
++ return -ENODEV;
++ }
++
++ /*
++ * For a XR16C850, we need to set the trigger levels
++ */
++ if (up->port.type == PORT_16850) {
++ unsigned char fctr;
++
++ serial_outp(up, UART_LCR, 0xbf);
++
++ fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
++ serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
++ serial_outp(up, UART_TRG, UART_TRG_96);
++ serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX);
++ serial_outp(up, UART_TRG, UART_TRG_96);
++
++ serial_outp(up, UART_LCR, 0);
++ }
++
++ if (is_real_interrupt(up->port.irq)) {
++ /*
++ * Test for UARTs that do not reassert THRE when the
++ * transmitter is idle and the interrupt has already
++ * been cleared. Real 16550s should always reassert
++ * this interrupt whenever the transmitter is idle and
++ * the interrupt is enabled. Delays are necessary to
++ * allow register changes to become visible.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ wait_for_xmitr(up, UART_LSR_THRE);
++ serial_out_sync(up, UART_IER, UART_IER_THRI);
++ udelay(1); /* allow THRE to set */
++ serial_in(up, UART_IIR);
++ serial_out(up, UART_IER, 0);
++ serial_out_sync(up, UART_IER, UART_IER_THRI);
++ udelay(1); /* allow a working UART time to re-assert THRE */
++ iir = serial_in(up, UART_IIR);
++ serial_out(up, UART_IER, 0);
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * If the interrupt is not reasserted, setup a timer to
++ * kick the UART on a regular basis.
++ */
++ if (iir & UART_IIR_NO_INT) {
++ pr_debug("ttyS%d - using backup timer\n", port->line);
++ up->timer.function = serial8250_backup_timeout;
++ up->timer.data = (unsigned long)up;
++ mod_timer(&up->timer, jiffies +
++ poll_timeout(up->port.timeout) + HZ / 5);
++ }
++ }
++
++ /*
++ * If the "interrupt" for this port doesn't correspond with any
++ * hardware interrupt, we use a timer-based system. The original
++ * driver used to do this with IRQ0.
++ */
++ if (!is_real_interrupt(up->port.irq)) {
++ up->timer.data = (unsigned long)up;
++ mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++ } else {
++ retval = serial_link_irq_chain(up);
++ if (retval)
++ return retval;
++ }
++
++ /*
++ * Now, initialize the UART
++ */
++ serial_outp(up, UART_LCR, UART_LCR_WLEN8);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (up->port.flags & UPF_FOURPORT) {
++ if (!is_real_interrupt(up->port.irq))
++ up->port.mctrl |= TIOCM_OUT1;
++ } else
++ /*
++ * Most PC uarts need OUT2 raised to enable interrupts.
++ */
++ if (is_real_interrupt(up->port.irq))
++ up->port.mctrl |= TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++
++ /*
++ * Do a quick test to see if we receive an
++ * interrupt when we enable the TX irq.
++ */
++ serial_outp(up, UART_IER, UART_IER_THRI);
++ lsr = serial_in(up, UART_LSR);
++ iir = serial_in(up, UART_IIR);
++ serial_outp(up, UART_IER, 0);
++
++ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
++ if (!(up->bugs & UART_BUG_TXEN)) {
++ up->bugs |= UART_BUG_TXEN;
++ pr_debug("ttyS%d - enabling bad tx status workarounds\n",
++ port->line);
++ }
++ } else {
++ up->bugs &= ~UART_BUG_TXEN;
++ }
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Clear the interrupt registers again for luck, and clear the
++ * saved flags to avoid getting false values from polling
++ * routines or the previous session.
++ */
++ serial_inp(up, UART_LSR);
++ serial_inp(up, UART_RX);
++ serial_inp(up, UART_IIR);
++ serial_inp(up, UART_MSR);
++ up->lsr_saved_flags = 0;
++ up->msr_saved_flags = 0;
++
++ /*
++ * Finally, enable interrupts. Note: Modem status interrupts
++ * are set via set_termios(), which will be occurring imminently
++ * anyway, so we don't enable them here.
++ */
++ up->ier = UART_IER_RLSI | UART_IER_RDI;
++ serial_outp(up, UART_IER, up->ier);
++
++ if (up->port.flags & UPF_FOURPORT) {
++ unsigned int icp;
++ /*
++ * Enable interrupts on the AST Fourport board
++ */
++ icp = (up->port.iobase & 0xfe0) | 0x01f;
++ outb_p(0x80, icp);
++ (void) inb_p(icp);
++ }
++
++ return 0;
++}
++
++static void serial8250_shutdown(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++
++ /*
++ * Disable interrupts from this port
++ */
++ up->ier = 0;
++ serial_outp(up, UART_IER, 0);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (up->port.flags & UPF_FOURPORT) {
++ /* reset interrupts on the AST Fourport board */
++ inb((up->port.iobase & 0xfe0) | 0x1f);
++ up->port.mctrl |= TIOCM_OUT1;
++ } else
++ up->port.mctrl &= ~TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Disable break condition and FIFOs
++ */
++ serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
++ serial8250_clear_fifos(up);
++
++#ifdef CONFIG_SERIAL_8250_RSA
++ /*
++ * Reset the RSA board back to 115kbps compat mode.
++ */
++ disable_rsa(up);
++#endif
++
++ /*
++ * Read data port to reset things, and then unlink from
++ * the IRQ chain.
++ */
++ (void) serial_in(up, UART_RX);
++
++ del_timer_sync(&up->timer);
++ up->timer.function = serial8250_timeout;
++ if (is_real_interrupt(up->port.irq))
++ serial_unlink_irq_chain(up);
++}
++
++static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
++{
++ unsigned int quot;
++
++ /*
++ * Handle magic divisors for baud rates above baud_base on
++ * SMSC SuperIO chips.
++ */
++ if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++ baud == (port->uartclk/4))
++ quot = 0x8001;
++ else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++ baud == (port->uartclk/8))
++ quot = 0x8002;
++ else
++ quot = uart_get_divisor(port, baud);
++
++ return quot;
++}
++
++static void
++serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
++ struct ktermios *old)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned char cval, fcr = 0;
++ unsigned long flags;
++ unsigned int baud, quot;
++
++ switch (termios->c_cflag & CSIZE) {
++ case CS5:
++ cval = UART_LCR_WLEN5;
++ break;
++ case CS6:
++ cval = UART_LCR_WLEN6;
++ break;
++ case CS7:
++ cval = UART_LCR_WLEN7;
++ break;
++ default:
++ case CS8:
++ cval = UART_LCR_WLEN8;
++ break;
++ }
++
++ if (termios->c_cflag & CSTOPB)
++ cval |= UART_LCR_STOP;
++ if (termios->c_cflag & PARENB)
++ cval |= UART_LCR_PARITY;
++ if (!(termios->c_cflag & PARODD))
++ cval |= UART_LCR_EPAR;
++#ifdef CMSPAR
++ if (termios->c_cflag & CMSPAR)
++ cval |= UART_LCR_SPAR;
++#endif
++
++ /*
++ * Ask the core to calculate the divisor for us.
++ */
++ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
++ quot = serial8250_get_divisor(port, baud);
++
++ /*
++ * Oxford Semi 952 rev B workaround
++ */
++ if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
++ quot++;
++
++ if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
++ if (baud < 2400)
++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
++ else
++ fcr = uart_config[up->port.type].fcr;
++ }
++
++ /*
++ * MCR-based auto flow control. When AFE is enabled, RTS will be
++ * deasserted when the receive FIFO contains more characters than
++ * the trigger, or the MCR RTS bit is cleared. In the case where
++ * the remote UART is not using CTS auto flow control, we must
++ * have sufficient FIFO entries for the latency of the remote
++ * UART to respond. IOW, at least 32 bytes of FIFO.
++ */
++ if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {
++ up->mcr &= ~UART_MCR_AFE;
++ if (termios->c_cflag & CRTSCTS)
++ up->mcr |= UART_MCR_AFE;
++ }
++
++ /*
++ * Ok, we're now changing the port state. Do it with
++ * interrupts disabled.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ /*
++ * Update the per-port timeout.
++ */
++ uart_update_timeout(port, termios->c_cflag, baud);
++
++ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++ if (termios->c_iflag & INPCK)
++ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & (BRKINT | PARMRK))
++ up->port.read_status_mask |= UART_LSR_BI;
++
++ /*
++ * Characteres to ignore
++ */
++ up->port.ignore_status_mask = 0;
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++ if (termios->c_iflag & IGNBRK) {
++ up->port.ignore_status_mask |= UART_LSR_BI;
++ /*
++ * If we're ignoring parity and break indicators,
++ * ignore overruns too (for real raw support).
++ */
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_OE;
++ }
++
++ /*
++ * ignore all characters if CREAD is not set
++ */
++ if ((termios->c_cflag & CREAD) == 0)
++ up->port.ignore_status_mask |= UART_LSR_DR;
++
++ /*
++ * CTS flow control flag and modem status interrupts
++ */
++ up->ier &= ~UART_IER_MSI;
++ if (!(up->bugs & UART_BUG_NOMSR) &&
++ UART_ENABLE_MS(&up->port, termios->c_cflag))
++ up->ier |= UART_IER_MSI;
++ if (up->capabilities & UART_CAP_UUE)
++ up->ier |= UART_IER_UUE | UART_IER_RTOIE;
++
++ serial_out(up, UART_IER, up->ier);
++
++ if (up->capabilities & UART_CAP_EFR) {
++ unsigned char efr = 0;
++ /*
++ * TI16C752/Startech hardware flow control. FIXME:
++ * - TI16C752 requires control thresholds to be set.
++ * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
++ */
++ if (termios->c_cflag & CRTSCTS)
++ efr |= UART_EFR_CTS;
++
++ serial_outp(up, UART_LCR, 0xBF);
++ serial_outp(up, UART_EFR, efr);
++ }
++
++#ifdef CONFIG_ARCH_OMAP15XX
++ /* Workaround to enable 115200 baud on OMAP1510 internal ports */
++ if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
++ if (baud == 115200) {
++ quot = 1;
++ serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
++ } else
++ serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
++ }
++#endif
++
++ if (up->capabilities & UART_NATSEMI) {
++ /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
++ serial_outp(up, UART_LCR, 0xe0);
++ } else {
++ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
++ }
++
++ serial_dl_write(up, quot);
++
++ /*
++ * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
++ * is written without DLAB set, this mode will be disabled.
++ */
++ if (up->port.type == PORT_16750)
++ serial_outp(up, UART_FCR, fcr);
++
++ serial_outp(up, UART_LCR, cval); /* reset DLAB */
++ up->lcr = cval; /* Save LCR */
++ if (up->port.type != PORT_16750) {
++ if (fcr & UART_FCR_ENABLE_FIFO) {
++ /* emulated UARTs (Lucent Venus 167x) need two steps */
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ }
++ serial_outp(up, UART_FCR, fcr); /* set fcr */
++ }
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ tty_termios_encode_baud_rate(termios, baud, baud);
++}
++
++static void
++serial8250_pm(struct uart_port *port, unsigned int state,
++ unsigned int oldstate)
++{
++ struct uart_8250_port *p = (struct uart_8250_port *)port;
++
++ serial8250_set_sleep(p, state != 0);
++
++ if (p->pm)
++ p->pm(port, state, oldstate);
++}
++
++/*
++ * Resource handling.
++ */
++static int serial8250_request_std_resource(struct uart_8250_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++ int ret = 0;
++
++ switch (up->port.iotype) {
++ case UPIO_AU:
++ size = 0x100000;
++ /* fall thru */
++ case UPIO_TSI:
++ case UPIO_MEM32:
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ if (!up->port.mapbase)
++ break;
++
++ if (!request_mem_region(up->port.mapbase, size, "serial")) {
++ ret = -EBUSY;
++ break;
++ }
++
++ if (up->port.flags & UPF_IOREMAP) {
++ up->port.membase = ioremap(up->port.mapbase, size);
++ if (!up->port.membase) {
++ release_mem_region(up->port.mapbase, size);
++ ret = -ENOMEM;
++ }
++ }
++ break;
++
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ if (!request_region(up->port.iobase, size, "serial"))
++ ret = -EBUSY;
++ break;
++ }
++ return ret;
++}
++
++static void serial8250_release_std_resource(struct uart_8250_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_AU:
++ size = 0x100000;
++ /* fall thru */
++ case UPIO_TSI:
++ case UPIO_MEM32:
++ case UPIO_MEM:
++ case UPIO_DWAPB:
++ if (!up->port.mapbase)
++ break;
++
++ if (up->port.flags & UPF_IOREMAP) {
++ iounmap(up->port.membase);
++ up->port.membase = NULL;
++ }
++
++ release_mem_region(up->port.mapbase, size);
++ break;
++
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ release_region(up->port.iobase, size);
++ break;
++ }
++}
++
++static int serial8250_request_rsa_resource(struct uart_8250_port *up)
++{
++ unsigned long start = UART_RSA_BASE << up->port.regshift;
++ unsigned int size = 8 << up->port.regshift;
++ int ret = -EINVAL;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ start += up->port.iobase;
++ if (request_region(start, size, "serial-rsa"))
++ ret = 0;
++ else
++ ret = -EBUSY;
++ break;
++ }
++
++ return ret;
++}
++
++static void serial8250_release_rsa_resource(struct uart_8250_port *up)
++{
++ unsigned long offset = UART_RSA_BASE << up->port.regshift;
++ unsigned int size = 8 << up->port.regshift;
++
++ switch (up->port.iotype) {
++ case UPIO_HUB6:
++ case UPIO_PORT:
++ release_region(up->port.iobase + offset, size);
++ break;
++ }
++}
++
++static void serial8250_release_port(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ serial8250_release_std_resource(up);
++ if (up->port.type == PORT_RSA)
++ serial8250_release_rsa_resource(up);
++}
++
++static int serial8250_request_port(struct uart_port *port)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ int ret = 0;
++
++ ret = serial8250_request_std_resource(up);
++ if (ret == 0 && up->port.type == PORT_RSA) {
++ ret = serial8250_request_rsa_resource(up);
++ if (ret < 0)
++ serial8250_release_std_resource(up);
++ }
++
++ return ret;
++}
++
++static void serial8250_config_port(struct uart_port *port, int flags)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ int probeflags = PROBE_ANY;
++ int ret;
++
++ /*
++ * Find the region that we can probe for. This in turn
++ * tells us whether we can probe for the type of port.
++ */
++ ret = serial8250_request_std_resource(up);
++ if (ret < 0)
++ return;
++
++ ret = serial8250_request_rsa_resource(up);
++ if (ret < 0)
++ probeflags &= ~PROBE_RSA;
++
++ if (flags & UART_CONFIG_TYPE)
++ autoconfig(up, probeflags);
++ if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
++ autoconfig_irq(up);
++
++ if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
++ serial8250_release_rsa_resource(up);
++ if (up->port.type == PORT_UNKNOWN)
++ serial8250_release_std_resource(up);
++}
++
++static int
++serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++ if (ser->irq >= NR_IRQS || ser->irq < 0 ||
++ ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
++ ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
++ ser->type == PORT_STARTECH)
++ return -EINVAL;
++ return 0;
++}
++
++static const char *
++serial8250_type(struct uart_port *port)
++{
++ int type = port->type;
++
++ if (type >= ARRAY_SIZE(uart_config))
++ type = 0;
++ return uart_config[type].name;
++}
++
++static struct uart_ops serial8250_pops = {
++ .tx_empty = serial8250_tx_empty,
++ .set_mctrl = serial8250_set_mctrl,
++ .get_mctrl = serial8250_get_mctrl,
++ .stop_tx = serial8250_stop_tx,
++ .start_tx = serial8250_start_tx,
++ .stop_rx = serial8250_stop_rx,
++ .enable_ms = serial8250_enable_ms,
++ .break_ctl = serial8250_break_ctl,
++ .startup = serial8250_startup,
++ .shutdown = serial8250_shutdown,
++ .set_termios = serial8250_set_termios,
++ .pm = serial8250_pm,
++ .type = serial8250_type,
++ .release_port = serial8250_release_port,
++ .request_port = serial8250_request_port,
++ .config_port = serial8250_config_port,
++ .verify_port = serial8250_verify_port,
++};
++
++static struct uart_8250_port serial8250_ports[UART_NR];
++
++static void __init serial8250_isa_init_ports(void)
++{
++ struct uart_8250_port *up;
++ static int first = 1;
++ int i;
++
++ if (!first)
++ return;
++ first = 0;
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ up->port.line = i+3; // i; // Modified from i to i+4 for getting the /dev/ttyS3 to /dev/ttyS6 entries for the Quad uart ports
++ spin_lock_init(&up->port.lock);
++
++ init_timer(&up->timer);
++ up->timer.function = serial8250_timeout;
++
++ /*
++ * ALPHA_KLUDGE_MCR needs to be killed.
++ */
++ up->mcr_mask = ~ALPHA_KLUDGE_MCR;
++ up->mcr_force = ALPHA_KLUDGE_MCR;
++
++ up->port.ops = &serial8250_pops;
++ }
++
++ for (i = 0, up = serial8250_ports;
++ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
++ i++, up++) {
++ up->port.iobase = old_serial_port[i].port;
++ up->port.irq = irq_canonicalize(old_serial_port[i].irq);
++ up->port.uartclk = old_serial_port[i].baud_base * 16;
++ up->port.flags = old_serial_port[i].flags;
++ up->port.hub6 = old_serial_port[i].hub6;
++ up->port.membase = old_serial_port[i].iomem_base;
++ up->port.iotype = old_serial_port[i].io_type;
++ up->port.regshift = old_serial_port[i].iomem_reg_shift;
++ if (share_irqs)
++ up->port.flags |= UPF_SHARE_IRQ;
++ }
++}
++
++static void __init
++serial8250_register_ports(struct uart_driver *drv, struct device *dev)
++{
++#if 0
++ int i;
++#endif
++
++ serial8250_isa_init_ports();
++#if 0
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ up->port.dev = dev;
++ uart_add_one_port(drv, &up->port);
++ }
++#endif
++}
++
++#ifdef CONFIG_SERIAL_8250_CONSOLE
++
++static void serial8250_console_putchar(struct uart_port *port, int ch)
++{
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++ wait_for_xmitr(up, UART_LSR_THRE);
++ serial_out(up, UART_TX, ch);
++}
++
++/*
++ * Print a string to the serial port trying not to disturb
++ * any possible real use of the port...
++ *
++ * The console_lock must be held when we get here.
++ */
++static void
++serial8250_console_write(struct console *co, const char *s, unsigned int count)
++{
++ struct uart_8250_port *up = &serial8250_ports[co->index];
++ unsigned long flags;
++ unsigned int ier;
++ int locked = 1;
++
++ touch_nmi_watchdog();
++
++ local_irq_save(flags);
++ if (up->port.sysrq) {
++ /* serial8250_handle_port() already took the lock */
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&up->port.lock);
++ } else
++ spin_lock(&up->port.lock);
++
++ /*
++ * First save the IER then disable the interrupts
++ */
++ ier = serial_in(up, UART_IER);
++
++ if (up->capabilities & UART_CAP_UUE)
++ serial_out(up, UART_IER, UART_IER_UUE);
++ else
++ serial_out(up, UART_IER, 0);
++
++ uart_console_write(&up->port, s, count, serial8250_console_putchar);
++
++ /*
++ * Finally, wait for transmitter to become empty
++ * and restore the IER
++ */
++ wait_for_xmitr(up, BOTH_EMPTY);
++ serial_out(up, UART_IER, ier);
++
++ /*
++ * The receive handling will happen properly because the
++ * receive ready bit will still be set; it is not cleared
++ * on read. However, modem control will not, we must
++ * call it if we have saved something in the saved flags
++ * while processing with interrupts off.
++ */
++ if (up->msr_saved_flags)
++ check_modem_status(up);
++
++ if (locked)
++ spin_unlock(&up->port.lock);
++ local_irq_restore(flags);
++}
++
++static int __init serial8250_console_setup(struct console *co, char *options)
++{
++ struct uart_port *port;
++ int baud = 9600;
++ int bits = 8;
++ int parity = 'n';
++ int flow = 'n';
++
++ /*
++ * Check whether an invalid uart number has been specified, and
++ * if so, search for the first available port that does have
++ * console support.
++ */
++ if (co->index >= nr_uarts)
++ co->index = 0;
++ port = &serial8250_ports[co->index].port;
++ if (!port->iobase && !port->membase)
++ return -ENODEV;
++
++ if (options)
++ uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++ return uart_set_options(port, co, baud, parity, bits, flow);
++}
++
++static int serial8250_console_early_setup(void)
++{
++ return serial8250_find_port_for_earlycon();
++}
++
++static struct uart_driver serial8250_reg;
++static struct console serial8250_console = {
++ .name = "ttyS",
++ .write = serial8250_console_write,
++ .device = uart_console_device,
++ .setup = serial8250_console_setup,
++ .early_setup = serial8250_console_early_setup,
++ .flags = CON_PRINTBUFFER,
++ .index = -1,
++ .data = &serial8250_reg,
++};
++
++static int __init serial8250_console_init(void)
++{
++ serial8250_isa_init_ports();
++ register_console(&serial8250_console);
++ return 0;
++}
++console_initcall(serial8250_console_init);
++
++int serial8250_find_port(struct uart_port *p)
++{
++ int line;
++ struct uart_port *port;
++
++ for (line = 0; line < nr_uarts; line++) {
++ port = &serial8250_ports[line].port;
++ if (uart_match_port(p, port))
++ return line;
++ }
++ return -ENODEV;
++}
++
++#define SERIAL8250_CONSOLE &serial8250_console
++#else
++#define SERIAL8250_CONSOLE NULL
++#endif
++
++static struct uart_driver serial8250_reg = {
++ .owner = THIS_MODULE,
++ .driver_name = "serial",
++ .dev_name = "ttyS", //"ttyEQ",
++ .major = 4,
++ .minor = 68,
++ .nr = UART_NR,
++ .cons = SERIAL8250_CONSOLE,
++};
++
++/*
++ * early_serial_setup - early registration for 8250 ports
++ *
++ * Setup an 8250 port structure prior to console initialisation. Use
++ * after console initialisation will cause undefined behaviour.
++ */
++int __init early_serial_setup(struct uart_port *port)
++{
++ if (port->line >= ARRAY_SIZE(serial8250_ports))
++ return -ENODEV;
++
++ serial8250_isa_init_ports();
++ serial8250_ports[port->line].port = *port;
++ serial8250_ports[port->line].port.ops = &serial8250_pops;
++ return 0;
++}
++
++/**
++ * serial8250_suspend_port - suspend one serial port
++ * @line: serial line number
++ *
++ * Suspend one serial port.
++ */
++void serial8250_suspend_port(int line)
++{
++ uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
++}
++
++/**
++ * serial8250_resume_port - resume one serial port
++ * @line: serial line number
++ *
++ * Resume one serial port.
++ */
++void serial8250_resume_port(int line)
++{
++ struct uart_8250_port *up = &serial8250_ports[line];
++
++ if (up->capabilities & UART_NATSEMI) {
++ unsigned char tmp;
++
++ /* Ensure it's still in high speed mode */
++ serial_outp(up, UART_LCR, 0xE0);
++
++ tmp = serial_in(up, 0x04); /* EXCR2 */
++ tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++ tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
++ serial_outp(up, 0x04, tmp);
++
++ serial_outp(up, UART_LCR, 0);
++ }
++ uart_resume_port(&serial8250_reg, &up->port);
++}
++
++/*
++ * Register a set of serial devices attached to a platform device. The
++ * list is terminated with a zero flags entry, which means we expect
++ * all entries to have at least UPF_BOOT_AUTOCONF set.
++ */
++static int __devinit serial8250_probe(struct platform_device *dev)
++{
++ struct plat_serial8250_port *p = dev->dev.platform_data;
++ struct uart_port port;
++ int ret, i;
++
++ memset(&port, 0, sizeof(struct uart_port));
++
++ for (i = 0; p && p->flags != 0; p++, i++) {
++ port.iobase = p->iobase;
++ port.membase = p->membase;
++ port.irq = p->irq;
++ port.uartclk = p->uartclk;
++ port.regshift = p->regshift;
++ port.iotype = p->iotype;
++ port.flags = p->flags;
++ port.mapbase = p->mapbase;
++ port.hub6 = p->hub6;
++ port.private_data = p->private_data;
++ port.dev = &dev->dev;
++ if (share_irqs)
++ port.flags |= UPF_SHARE_IRQ;
++ //printk("FUNC %s() : LINE %d: i is %d. Calling serial8250_register_port() \n",__FUNCTION__,__LINE__,i);
++ ret = serial8250_register_port(&port);
++ if (ret < 0) {
++ dev_err(&dev->dev, "unable to register port at index %d "
++ "(IO%lx MEM%llx IRQ%d): %d\n", i,
++ p->iobase, (unsigned long long)p->mapbase,
++ p->irq, ret);
++ }
++ }
++ return 0;
++}
++
++/*
++ * Remove serial ports registered against a platform device.
++ */
++static int __devexit serial8250_remove(struct platform_device *dev)
++{
++ int i;
++
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.dev == &dev->dev)
++ serial8250_unregister_port(i);
++ }
++ return 0;
++}
++
++static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
++{
++ int i;
++
++ for (i = 0; i < UART_NR; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ uart_suspend_port(&serial8250_reg, &up->port);
++ }
++
++ return 0;
++}
++
++static int serial8250_resume(struct platform_device *dev)
++{
++ int i;
++
++ for (i = 0; i < UART_NR; i++) {
++ struct uart_8250_port *up = &serial8250_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ serial8250_resume_port(i);
++ }
++
++ return 0;
++}
++
++
++//Added for avoing the kernel warning while unloading this serial8250 driver
++static void serial8250_release_dev(struct device *_d)
++{
++ return ;
++}
++
++
++
++static struct platform_driver serial8250_isa_driver = {
++ .probe = serial8250_probe,
++ .remove = __devexit_p(serial8250_remove),
++ .suspend = serial8250_suspend,
++ .resume = serial8250_resume,
++ .driver = {
++ .name = "serial8250",
++ .owner = THIS_MODULE,
++ },
++};
++
++/*
++ * This "device" covers _all_ ISA 8250-compatible serial devices listed
++ * in the table in include/asm/serial.h
++ */
++//static struct platform_device *serial8250_isa_devs;
++ static struct platform_device serial8250_devs = {
++ .name = "serial8250",
++ .id = PLAT8250_DEV_PLATFORM,
++ .dev = {
++ .platform_data = serial_quad_ports,
++ .release = serial8250_release_dev, //Added for avoing the kernel warning while unloading this serial8250 driver
++ },
++ };
++static struct platform_device *serial8250_isa_devs=&serial8250_devs;
++
++/*
++ * serial8250_register_port and serial8250_unregister_port allows for
++ * 16x50 serial ports to be configured at run-time, to support PCMCIA
++ * modems and PCI multiport cards.
++ */
++static DEFINE_MUTEX(serial_mutex);
++
++static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
++{
++ int i;
++
++ /*
++ * First, find a port entry which matches.
++ */
++ //printk("FUNC %s(): LINE %d: First, find a port entry which matches. \n",__FUNCTION__,__LINE__);
++ for (i = 0; i < nr_uarts; i++)
++ if (uart_match_port(&serial8250_ports[i].port, port))
++ return &serial8250_ports[i];
++
++ /*
++ * We didn't find a matching entry, so look for the first
++ * free entry. We look for one which hasn't been previously
++ * used (indicated by zero iobase).
++ */
++ //printk("FUNC %s(): LINE %d:We didn't find a matching entry, so look for the first free entry \n",__FUNCTION__,__LINE__);
++ for (i = 0; i < nr_uarts; i++)
++ if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
++ serial8250_ports[i].port.iobase == 0)
++ return &serial8250_ports[i];
++
++ /*
++ * That also failed. Last resort is to find any entry which
++ * doesn't have a real port associated with it.
++ */
++ //printk("FUNC %s(): LINE %d: That also failed. Last resort is to find any entry which doesn't have a real port associated with it.\n",__FUNCTION__,__LINE__);
++ for (i = 0; i < nr_uarts; i++)
++ if (serial8250_ports[i].port.type == PORT_UNKNOWN)
++ return &serial8250_ports[i];
++
++
++ //printk("FUNC %s(): LINE %d: Returning NULL \n",__FUNCTION__,__LINE__);
++ return NULL;
++}
++
++/**
++ * serial8250_register_port - register a serial port
++ * @port: serial port template
++ *
++ * Configure the serial port specified by the request. If the
++ * port exists and is in use, it is hung up and unregistered
++ * first.
++ *
++ * The port is then probed and if necessary the IRQ is autodetected
++ * If this fails an error is returned.
++ *
++ * On success the port is ready to use and the line number is returned.
++ */
++int serial8250_register_port(struct uart_port *port)
++{
++ struct uart_8250_port *uart;
++ int ret = -ENOSPC;
++
++ if (port->uartclk == 0)
++ return -EINVAL;
++
++ mutex_lock(&serial_mutex);
++
++ //printk("FUNC %s() : LINE %d: Calling serial8250_find_match_or_unused. \n",__FUNCTION__,__LINE__);
++ uart = serial8250_find_match_or_unused(port);
++ if (uart) {
++ //uart_remove_one_port(&serial8250_reg, &uart->port); // Commented by econ on 23 jan 2009
++
++ uart->port.iobase = port->iobase;
++ uart->port.membase = port->membase;
++ uart->port.irq = port->irq;
++ uart->port.uartclk = port->uartclk;
++ uart->port.fifosize = port->fifosize;
++ uart->port.regshift = port->regshift;
++ uart->port.iotype = port->iotype;
++ uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
++ uart->port.mapbase = port->mapbase;
++ uart->port.private_data = port->private_data;
++ if (port->dev)
++ uart->port.dev = port->dev;
++
++
++ //printk("FUNC %s() : LINE %d: Calling uart_add_one_port() \n",__FUNCTION__,__LINE__);
++ ret = uart_add_one_port(&serial8250_reg, &uart->port);
++ if (ret == 0)
++ {
++ //printk("FUNC %s() : LINE %d: uart_add_one_port() returns ZERO uart->port.line is %d \n",__FUNCTION__,__LINE__,uart->port.line);
++ ret = uart->port.line;
++ }
++ }
++ mutex_unlock(&serial_mutex);
++
++ return ret;
++}
++EXPORT_SYMBOL(serial8250_register_port);
++
++/**
++ * serial8250_unregister_port - remove a 16x50 serial port at runtime
++ * @line: serial line number
++ *
++ * Remove one serial port. This may not be called from interrupt
++ * context. We hand the port back to the our control.
++ */
++void serial8250_unregister_port(int line)
++{
++ struct uart_8250_port *uart = &serial8250_ports[line];
++
++ mutex_lock(&serial_mutex);
++ uart_remove_one_port(&serial8250_reg, &uart->port);
++ if (serial8250_isa_devs) {
++ uart->port.flags &= ~UPF_BOOT_AUTOCONF;
++ uart->port.type = PORT_UNKNOWN;
++ uart->port.dev = &serial8250_isa_devs->dev;
++ uart_add_one_port(&serial8250_reg, &uart->port);
++ } else {
++ uart->port.dev = NULL;
++ }
++ mutex_unlock(&serial_mutex);
++}
++EXPORT_SYMBOL(serial8250_unregister_port);
++
++
++
++
++#define GPIO033_CHIP_SELECT_QUAD (33 | GPIO_DFLT_HIGH|GPIO_ALT_FN_2_OUT)
++
++#define GPIO022_EXTERNAL_BUS_INTERFACE 22
++#define EXTERNAL_BUS_INTERFACE_GPIO22_OUT (GPIO22_EXTERNAL_BUS_INTERFACE | GPIO_OUT|GPIO_DFLT_LOW)
++
++void config_quad_uart(void)
++{
++ pxa_gpio_mode(GPIO_FOR_QUAD_UART_A_IRQ_MD);
++ pxa_gpio_mode(GPIO_FOR_QUAD_UART_B_IRQ_MD);
++ pxa_gpio_mode(GPIO_FOR_QUAD_UART_C_IRQ_MD);
++ pxa_gpio_mode(GPIO_FOR_QUAD_UART_D_IRQ_MD);
++
++ pxa_gpio_mode(GPIO033_CHIP_SELECT_QUAD);
++ MSC2 &=(0x0000FFFF);
++ MSC2 |= 0x7FF90000;
++
++ set_irq_type(QUAD_UART_A_IRQ,IRQT_RISING);
++ set_irq_type(QUAD_UART_B_IRQ,IRQT_RISING);
++ set_irq_type(QUAD_UART_C_IRQ,IRQT_RISING);
++ set_irq_type(QUAD_UART_D_IRQ,IRQT_RISING);
++
++ return ;
++}
++
++
++
++
++static int __init serial8250_init(void)
++{
++ int ret, i;
++
++ if (nr_uarts > UART_NR)
++ nr_uarts = UART_NR;
++ config_quad_uart();
++
++ printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
++ "%d ports, IRQ sharing %sabled\n", nr_uarts,
++ share_irqs ? "en" : "dis");
++
++ for (i = 0; i < NR_IRQS; i++)
++ spin_lock_init(&irq_lists[i].lock);
++
++
++ //printk("FUNC %s(): LINE %d: Registering uart_driver \n",__FUNCTION__,__LINE__);
++ ret = uart_register_driver(&serial8250_reg);
++ if (ret)
++ {
++ printk("FUNC %s(): LINE %d: Failed in Registering uart_driver \n",__FUNCTION__,__LINE__);
++
++ goto out;
++ }
++
++#if 1
++ //printk("FUNC %s(): LINE %d: Registering platform device \n",__FUNCTION__,__LINE__);
++ platform_device_register(serial8250_isa_devs);
++#else
++ serial8250_isa_devs = platform_device_alloc("serial8250",PLAT8250_DEV_LEGACY);
++ if (!serial8250_isa_devs) {
++ printk("FUNC %s(): LINE %d: serial8250_isa_devs is NULL \n",__FUNCTION__,__LINE__);
++ ret = -ENOMEM;
++ goto unreg_uart_drv;
++ }
++
++ printk("FUNC %s(): LINE %d: Adding platform device \n",__FUNCTION__,__LINE__);
++ ret = platform_device_add(serial8250_isa_devs);
++ if (ret)
++ {
++ printk("FUNC %s(): LINE %d: Failed in Adding platform device \n",__FUNCTION__,__LINE__);
++ goto put_dev;
++ }
++#endif
++
++ //printk("FUNC %s(): LINE %d: Registeting serial8250 ports \n",__FUNCTION__,__LINE__);
++ serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
++
++ //printk("FUNC %s(): LINE %d: Registeting platform driver \n",__FUNCTION__,__LINE__);
++ ret = platform_driver_register(&serial8250_isa_driver);
++ if (ret == 0)
++ {
++ //printk("FUNC %s(): LINE %d: Success in Registeting platform driver \n",__FUNCTION__,__LINE__);
++ goto out;
++ }
++ else
++ {
++ printk("FUNC %s(): LINE %d: Failed in Registeting platform driver \n",__FUNCTION__,__LINE__);
++ }
++ platform_device_del(serial8250_isa_devs);
++#if 0
++ put_dev:
++#endif
++ platform_device_put(serial8250_isa_devs);
++#if 0
++ unreg_uart_drv:
++#endif
++ uart_unregister_driver(&serial8250_reg);
++ out:
++ return ret;
++}
++
++static void __exit serial8250_exit(void)
++{
++ struct platform_device *isa_dev = serial8250_isa_devs;
++
++ /*
++ * This tells serial8250_unregister_port() not to re-register
++ * the ports (thereby making serial8250_isa_driver permanently
++ * in use.)
++ */
++ serial8250_isa_devs = NULL;
++
++ platform_driver_unregister(&serial8250_isa_driver);
++ platform_device_unregister(isa_dev);
++
++ uart_unregister_driver(&serial8250_reg);
++}
++
++module_init(serial8250_init);
++module_exit(serial8250_exit);
++
++EXPORT_SYMBOL(serial8250_suspend_port);
++EXPORT_SYMBOL(serial8250_resume_port);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $");
++
++module_param(share_irqs, uint, 0644);
++MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
++ " (unsafe)");
++
++module_param(nr_uarts, uint, 0644);
++MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
++
++#ifdef CONFIG_SERIAL_8250_RSA
++module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
++MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
++#endif
++MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+diff -Naur linux-2.6.25_original/drivers/serial/Kconfig linux-2.6.25/drivers/serial/Kconfig
+--- linux-2.6.25_original/drivers/serial/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -9,9 +9,17 @@
+
+ #
+ # The new 8250/16550 serial drivers
++
++
++config E_CON_QUAD_UART_TI16C174B
++ tristate "sirius external quad uart (TI16C174B) 4 ports"
++ depends on (MACH_SIRIUS || MACH_REGULUS)
++ ---help---
++ .............need to write...............
++
+ config SERIAL_8250
+ tristate "8250/16550 and compatible serial support"
+- depends on (BROKEN || !SPARC)
++ depends on (BROKEN || !SPARC) &&(!E_CON_QUAD_UART_TI16C174B)
+ select SERIAL_CORE
+ ---help---
+ This selects whether you want to include the driver for the standard
+@@ -42,7 +50,7 @@
+
+ config SERIAL_8250_CONSOLE
+ bool "Console on 8250/16550 and compatible serial port"
+- depends on SERIAL_8250=y
++ depends on SERIAL_8250=y && (!E_CON_QUAD_UART_TI16C174B)
+ select SERIAL_CORE_CONSOLE
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+@@ -80,12 +88,12 @@
+
+ config SERIAL_8250_GSC
+ tristate
+- depends on SERIAL_8250 && GSC
++ depends on SERIAL_8250 && GSC &&(!E_CON_QUAD_UART_TI16C174B)
+ default SERIAL_8250
+
+ config SERIAL_8250_PCI
+ tristate "8250/16550 PCI device support" if EMBEDDED
+- depends on SERIAL_8250 && PCI
++ depends on SERIAL_8250 && PCI &&(!E_CON_QUAD_UART_TI16C174B)
+ default SERIAL_8250
+ help
+ This builds standard PCI serial support. You may be able to
+@@ -94,7 +102,7 @@
+
+ config SERIAL_8250_PNP
+ tristate "8250/16550 PNP device support" if EMBEDDED
+- depends on SERIAL_8250 && PNP
++ depends on SERIAL_8250 && PNP && (!E_CON_QUAD_UART_TI16C174B)
+ default SERIAL_8250
+ help
+ This builds standard PNP serial support. You may be able to
+@@ -102,12 +110,12 @@
+
+ config SERIAL_8250_HP300
+ tristate
+- depends on SERIAL_8250 && HP300
++ depends on SERIAL_8250 && HP300 && (!E_CON_QUAD_UART_TI16C174B)
+ default SERIAL_8250
+
+ config SERIAL_8250_CS
+ tristate "8250/16550 PCMCIA device support"
+- depends on PCMCIA && SERIAL_8250
++ depends on PCMCIA && SERIAL_8250 && (!E_CON_QUAD_UART_TI16C174B)
+ ---help---
+ Say Y here to enable support for 16-bit PCMCIA serial devices,
+ including serial port cards, modems, and the modem functions of
+@@ -121,7 +129,7 @@
+
+ config SERIAL_8250_NR_UARTS
+ int "Maximum number of 8250/16550 serial ports"
+- depends on SERIAL_8250
++ depends on SERIAL_8250 && (!E_CON_QUAD_UART_TI16C174B)
+ default "4"
+ help
+ Set this to the number of serial ports you want the driver
+@@ -131,7 +139,7 @@
+
+ config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+- depends on SERIAL_8250
++ depends on SERIAL_8250 && (!E_CON_QUAD_UART_TI16C174B)
+ range 0 SERIAL_8250_NR_UARTS
+ default "4"
+ help
+@@ -142,7 +150,7 @@
+
+ config SERIAL_8250_EXTENDED
+ bool "Extended 8250/16550 serial driver options"
+- depends on SERIAL_8250
++ depends on SERIAL_8250 && (!E_CON_QUAD_UART_TI16C174B)
+ help
+ If you wish to use any non-standard features of the standard "dumb"
+ driver, say Y here. This includes HUB6 support, shared serial
+diff -Naur linux-2.6.25_original/drivers/serial/Makefile linux-2.6.25/drivers/serial/Makefile
+--- linux-2.6.25_original/drivers/serial/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -6,6 +6,7 @@
+
+ obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+ obj-$(CONFIG_SERIAL_21285) += 21285.o
++obj-$(CONFIG_E_CON_QUAD_UART_TI16C174B) += e_conquad_8250_16c174b.o
+ obj-$(CONFIG_SERIAL_8250) += 8250.o
+ obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
+ obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
+diff -Naur linux-2.6.25_original/drivers/serial/pxa.c linux-2.6.25/drivers/serial/pxa.c
+--- linux-2.6.25_original/drivers/serial/pxa.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/pxa.c 2009-05-16 18:43:58.000000000 +0530
+@@ -785,8 +785,16 @@
+ sport->name = "FFUART";
+ else if (mmres->start == __PREG(BTUART))
+ sport->name = "BTUART";
++#ifdef CONFIG_KGDB // Added by e-con for KGDB Support
+ else if (mmres->start == __PREG(STUART))
++ {
+ sport->name = "STUART";
++ return 0;
++ }
++#else // Added by e-con for KGDB Support
++ else if (mmres->start == __PREG(STUART))
++ sport->name = "STUART";
++#endif
+ else if (mmres->start == __PREG(HWUART))
+ sport->name = "HWUART";
+ else
+diff -Naur linux-2.6.25_original/drivers/serial/serial_core.c linux-2.6.25/drivers/serial/serial_core.c
+--- linux-2.6.25_original/drivers/serial/serial_core.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/serial/serial_core.c 2009-05-16 18:43:58.000000000 +0530
+@@ -32,6 +32,7 @@
+ #include <linux/device.h>
+ #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
+ #include <linux/delay.h>
++#include <linux/kgdb.h>
+ #include <linux/mutex.h>
+
+ #include <asm/irq.h>
+@@ -1678,6 +1679,9 @@
+ mmio ? (unsigned long long)port->mapbase
+ : (unsigned long long) port->iobase,
+ port->irq);
++ if (port->iotype == UPIO_MEM)
++ ret += sprintf(buf+ret, " membase 0x%08lX",
++ (unsigned long) port->membase);
+
+ if (port->type == PORT_UNKNOWN) {
+ strcat(buf, "\n");
+@@ -2111,7 +2115,9 @@
+ case UPIO_TSI:
+ case UPIO_DWAPB:
+ snprintf(address, sizeof(address),
+- "MMIO 0x%llx", (unsigned long long)port->mapbase);
++ "MMIO map 0x%lx mem 0x%lx", port->mapbase,
++ (unsigned long) port->membase);
++
+ break;
+ default:
+ strlcpy(address, "*unknown*", sizeof(address));
+@@ -2172,7 +2178,13 @@
+ */
+ if (port->cons && !(port->cons->flags & CON_ENABLED))
+ register_console(port->cons);
+-
++#if 0
++#if defined(CONFIG_KGDB_8250)
++ /* Add any 8250-like ports we find later. */
++ if (port->type <= PORT_MAX_8250)
++ kgdb8250_add_port(port->line, port);
++#endif
++#endif
+ /*
+ * Power down all ports by default, except the
+ * console if we have one.
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/epautoconf.c linux-2.6.25/drivers/usb/gadget/epautoconf.c
+--- linux-2.6.25_original/drivers/usb/gadget/epautoconf.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/epautoconf.c 2009-05-16 18:43:58.000000000 +0530
+@@ -28,10 +28,15 @@
+ #include <linux/string.h>
+
+ #include <linux/usb/ch9.h>
+-#include <linux/usb/gadget.h>
++#include <linux/usb_gadget.h>
+
+ #include "gadget_chips.h"
+
++extern struct usb_ep* pxa27x_ep_config(
++ struct usb_gadget *gadget,
++ struct usb_endpoint_descriptor *desc,
++ int config, int interface, int alt);
++
+
+ /* we must assign addresses for configurable endpoints (like net2280) */
+ static __devinitdata unsigned epnum;
+@@ -71,7 +76,7 @@
+ u16 max;
+
+ /* endpoint already claimed? */
+- if (NULL != ep->driver_data)
++ if (0 != ep->driver_data)
+ return 0;
+
+ /* only support ep0 for portable CONTROL traffic */
+@@ -274,6 +279,16 @@
+ ep = find_ep (gadget, "ep1-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
++ }else if (gadget_is_pxa27x (gadget) ) {
++ ep = pxa27x_ep_config(gadget, desc,1,0,0);
++ if(!ep)
++ {
++ printk("pxa27x_ep_config returns NULL value \n");
++ }
++ if (ep && ep_matches (gadget, ep, desc))
++ /*if (ep )*/
++ return ep;
++
+ }
+
+ /* Second, look at endpoints until an unclaimed one looks usable */
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/ether.c linux-2.6.25/drivers/usb/gadget/ether.c
+--- linux-2.6.25_original/drivers/usb/gadget/ether.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/ether.c 2009-05-16 18:43:58.000000000 +0530
+@@ -1,7 +1,7 @@
+ /*
+ * ether.c -- Ethernet gadget driver, with CDC and non-CDC options
+ *
+- * Copyright (C) 2003-2005 David Brownell
++ * Copyright (C) 2003-2004 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -19,19 +19,44 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-/* #define VERBOSE_DEBUG */
+
++// #define DEBUG 1
++// #define VERBOSE
++
++#include <linux/autoconf.h>
++#include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/utsname.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/smp_lock.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/uts.h>
++#include <linux/version.h>
+ #include <linux/device.h>
++#include <linux/moduleparam.h>
+ #include <linux/ctype.h>
+-#include <linux/etherdevice.h>
+-#include <linux/ethtool.h>
+
+-#include <linux/usb/ch9.h>
+-#include <linux/usb/cdc.h>
+-#include <linux/usb/gadget.h>
++#include <asm/byteorder.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/unaligned.h>
+
++#include <linux/usb_ch9.h>
++#include <linux/usb_gadget.h>
++
++#include <linux/random.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/utsrelease.h>
+ #include "gadget_chips.h"
+
+ /*-------------------------------------------------------------------------*/
+@@ -48,18 +73,9 @@
+ *
+ * There's some hardware that can't talk CDC. We make that hardware
+ * implement a "minimalist" vendor-agnostic CDC core: same framing, but
+- * link-level setup only requires activating the configuration. Only the
+- * endpoint descriptors, and product/vendor IDs, are relevant; no control
+- * operations are available. Linux supports it, but other host operating
+- * systems may not. (This is a subset of CDC Ethernet.)
+- *
+- * It turns out that if you add a few descriptors to that "CDC Subset",
+- * (Windows) host side drivers from MCCI can treat it as one submode of
+- * a proprietary scheme called "SAFE" ... without needing to know about
+- * specific product/vendor IDs. So we do that, making it easier to use
+- * those MS-Windows drivers. Those added descriptors make it resemble a
+- * CDC MDLM device, but they don't change device behavior at all. (See
+- * MCCI Engineering report 950198 "SAFE Networking Functions".)
++ * link-level setup only requires activating the configuration.
++ * Linux supports it, but other host operating systems may not.
++ * (This is a subset of CDC Ethernet.)
+ *
+ * A third option is also in use. Rather than CDC Ethernet, or something
+ * simpler, Microsoft pushes their own approach: RNDIS. The published
+@@ -68,42 +84,31 @@
+ */
+
+ #define DRIVER_DESC "Ethernet Gadget"
+-#define DRIVER_VERSION "May Day 2005"
++#define DRIVER_VERSION "St Patrick's Day 2004"
+
+ static const char shortname [] = "ether";
+ static const char driver_desc [] = DRIVER_DESC;
+
+ #define RX_EXTRA 20 /* guard against rx overflows */
+
++#ifdef CONFIG_USB_ETH_RNDIS
+ #include "rndis.h"
+-
+-#ifndef CONFIG_USB_ETH_RNDIS
+-#define rndis_uninit(x) do{}while(0)
+-#define rndis_deregister(c) do{}while(0)
+-#define rndis_exit() do{}while(0)
++#else
++#define rndis_init() 0
++#define rndis_exit() do{}while(0)
+ #endif
+
+-/* CDC and RNDIS support the same host-chosen outgoing packet filters. */
+-#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
+- |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+- |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+- |USB_CDC_PACKET_TYPE_DIRECTED)
+-
+-
+ /*-------------------------------------------------------------------------*/
+
+ struct eth_dev {
+ spinlock_t lock;
+ struct usb_gadget *gadget;
+ struct usb_request *req; /* for control responses */
+- struct usb_request *stat_req; /* for cdc & rndis status */
+
+ u8 config;
+ struct usb_ep *in_ep, *out_ep, *status_ep;
+ const struct usb_endpoint_descriptor
+ *in, *out, *status;
+-
+- spinlock_t req_lock;
+ struct list_head tx_reqs, rx_reqs;
+
+ struct net_device *net;
+@@ -127,6 +132,9 @@
+ * It also ASSUMES a self-powered device, without remote wakeup,
+ * although remote wakeup support would make sense.
+ */
++static const char *EP_IN_NAME;
++static const char *EP_OUT_NAME;
++static const char *EP_STATUS_NAME;
+
+ /*-------------------------------------------------------------------------*/
+
+@@ -168,37 +176,33 @@
+ * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
+ */
+
+-static ushort idVendor;
++static ushort __initdata idVendor;
+ module_param(idVendor, ushort, S_IRUGO);
+ MODULE_PARM_DESC(idVendor, "USB Vendor ID");
+
+-static ushort idProduct;
++static ushort __initdata idProduct;
+ module_param(idProduct, ushort, S_IRUGO);
+ MODULE_PARM_DESC(idProduct, "USB Product ID");
+
+-static ushort bcdDevice;
++static ushort __initdata bcdDevice;
+ module_param(bcdDevice, ushort, S_IRUGO);
+ MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
+
+-static char *iManufacturer;
++static char *__initdata iManufacturer;
+ module_param(iManufacturer, charp, S_IRUGO);
+ MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
+
+-static char *iProduct;
++static char *__initdata iProduct;
+ module_param(iProduct, charp, S_IRUGO);
+ MODULE_PARM_DESC(iProduct, "USB Product string");
+
+-static char *iSerialNumber;
+-module_param(iSerialNumber, charp, S_IRUGO);
+-MODULE_PARM_DESC(iSerialNumber, "SerialNumber");
+-
+ /* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
+-static char *dev_addr;
++static char *__initdata dev_addr;
+ module_param(dev_addr, charp, S_IRUGO);
+-MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
++MODULE_PARM_DESC(iProduct, "Device Ethernet Address");
+
+ /* this address is invisible to ifconfig */
+-static char *host_addr;
++static char *__initdata host_addr;
+ module_param(host_addr, charp, S_IRUGO);
+ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
+
+@@ -219,10 +223,6 @@
+ #define DEV_CONFIG_CDC
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_LH7A40X
+-#define DEV_CONFIG_CDC
+-#endif
+-
+ #ifdef CONFIG_USB_GADGET_MQ11XX
+ #define DEV_CONFIG_CDC
+ #endif
+@@ -231,36 +231,8 @@
+ #define DEV_CONFIG_CDC
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_N9604
+-#define DEV_CONFIG_CDC
+-#endif
+-
+ #ifdef CONFIG_USB_GADGET_PXA27X
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_S3C2410
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_AT91
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_MUSBHSFC
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_ATMEL_USBA
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-#ifdef CONFIG_USB_GADGET_FSL_USB2
+-#define DEV_CONFIG_CDC
++//#define DEV_CONFIG_CDC
+ #endif
+
+ /* For CDC-incapable hardware, choose the simple cdc subset.
+@@ -269,62 +241,34 @@
+ #ifdef CONFIG_USB_GADGET_PXA2XX
+ #define DEV_CONFIG_SUBSET
+ #endif
+-
+-#ifdef CONFIG_USB_GADGET_SUPERH
+-#define DEV_CONFIG_SUBSET
++
++#ifdef CONFIG_USB_GADGET_PXA27X
++#define DEV_CONFIG_SUBSET
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_SA1100
+-/* use non-CDC for backwards compatibility */
++#ifdef CONFIG_USB_GADGET_SH
+ #define DEV_CONFIG_SUBSET
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_M66592
++#ifdef CONFIG_USB_GADGET_LH7A40X
+ #define DEV_CONFIG_CDC
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_AMD5536UDC
+-#define DEV_CONFIG_CDC
+-#endif
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* "main" config is either CDC, or its simple subset */
+-static inline int is_cdc(struct eth_dev *dev)
+-{
+-#if !defined(DEV_CONFIG_SUBSET)
+- return 1; /* only cdc possible */
+-#elif !defined (DEV_CONFIG_CDC)
+- return 0; /* only subset possible */
+-#else
+- return dev->cdc; /* depends on what hardware we found */
++#ifdef CONFIG_USB_GADGET_SA1100
++/* use non-CDC for backwards compatibility */
++#define DEV_CONFIG_SUBSET
+ #endif
+-}
+
+-/* "secondary" RNDIS config may sometimes be activated */
+-static inline int rndis_active(struct eth_dev *dev)
+-{
+-#ifdef CONFIG_USB_ETH_RNDIS
+- return dev->rndis;
+-#else
+- return 0;
++#ifdef CONFIG_USB_PXA27X
++extern struct usb_ep* pxa27x_ep_config(struct usb_gadget *gadget,
++ struct usb_endpoint_descriptor *desc,int config,int interface,int alt);
+ #endif
+-}
+-
+-#define subset_active(dev) (!is_cdc(dev) && !rndis_active(dev))
+-#define cdc_active(dev) ( is_cdc(dev) && !rndis_active(dev))
+-
+
++/*-------------------------------------------------------------------------*/
+
+ #define DEFAULT_QLEN 2 /* double buffering by default */
+
+-/* peak bulk transfer bits-per-second */
+-#define HS_BPS (13 * 512 * 8 * 1000 * 8)
+-#define FS_BPS (19 * 64 * 1 * 1000 * 8)
+-
+ #ifdef CONFIG_USB_GADGET_DUALSPEED
+-#define DEVSPEED USB_SPEED_HIGH
+
+ static unsigned qmult = 5;
+ module_param (qmult, uint, S_IRUGO|S_IWUSR);
+@@ -334,23 +278,15 @@
+ #define qlen(gadget) \
+ (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1))
+
+-static inline int BITRATE(struct usb_gadget *g)
+-{
+- return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS;
+-}
+-
+-#else /* full speed (low speed doesn't do bulk) */
+-
+-#define qmult 1
++/* also defer IRQs on highspeed TX */
++#define TX_DELAY qmult
+
+-#define DEVSPEED USB_SPEED_FULL
++#define BITRATE(g) ((g->speed == USB_SPEED_HIGH) ? 4800000 : 120000)
+
++#else /* full speed (low speed doesn't do bulk) */
+ #define qlen(gadget) DEFAULT_QLEN
+
+-static inline int BITRATE(struct usb_gadget *g)
+-{
+- return FS_BPS;
+-}
++#define BITRATE(g) (12000)
+ #endif
+
+
+@@ -368,7 +304,7 @@
+ do { } while (0)
+ #endif /* DEBUG */
+
+-#ifdef VERBOSE_DEBUG
++#ifdef VERBOSE
+ #define VDEBUG DEBUG
+ #else
+ #define VDEBUG(dev,fmt,args...) \
+@@ -409,10 +345,8 @@
+ #define STRING_CDC 7
+ #define STRING_SUBSET 8
+ #define STRING_RNDIS 9
+-#define STRING_SERIALNUMBER 10
+
+-/* holds our biggest descriptor (or RNDIS response) */
+-#define USB_BUFSIZ 256
++#define USB_BUFSIZ 256 /* holds our biggest descriptor */
+
+ /*
+ * This device advertises one configuration, eth_config, unless RNDIS
+@@ -464,11 +398,11 @@
+ .bConfigurationValue = DEV_CONFIG_VALUE,
+ .iConfiguration = STRING_CDC,
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+- .bMaxPower = 50,
++ .bMaxPower = 1,
+ };
+
+ #ifdef CONFIG_USB_ETH_RNDIS
+-static struct usb_config_descriptor
++static struct usb_config_descriptor
+ rndis_config = {
+ .bLength = sizeof rndis_config,
+ .bDescriptorType = USB_DT_CONFIG,
+@@ -478,7 +412,7 @@
+ .bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
+ .iConfiguration = STRING_RNDIS,
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+- .bMaxPower = 50,
++ .bMaxPower = 1,
+ };
+ #endif
+
+@@ -488,17 +422,8 @@
+ * endpoint. Both have a "data" interface and two bulk endpoints.
+ * There are also differences in how control requests are handled.
+ *
+- * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the
+- * CDC-ACM (modem) spec. Unfortunately MSFT's RNDIS driver is buggy; it
+- * may hang or oops. Since bugfixes (or accurate specs, letting Linux
+- * work around those bugs) are unlikely to ever come from MSFT, you may
+- * wish to avoid using RNDIS.
+- *
+- * MCCI offers an alternative to RNDIS if you need to connect to Windows
+- * but have hardware that can't support CDC Ethernet. We add descriptors
+- * to present the CDC Subset as a (nonconformant) CDC MDLM variant called
+- * "SAFE". That borrows from both CDC Ethernet and CDC MDLM. You can
+- * get those drivers from MCCI, or bundled with various products.
++ * RNDIS shares a lot with CDC-Ethernet, since it's a variant of
++ * the CDC-ACM (modem) spec.
+ */
+
+ #ifdef DEV_CONFIG_CDC
+@@ -511,8 +436,8 @@
+ /* status endpoint is optional; this may be patched later */
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_COMM,
+- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+- .bInterfaceProtocol = USB_CDC_PROTO_NONE,
++ .bInterfaceSubClass = 6, /* ethernet control model */
++ .bInterfaceProtocol = 0,
+ .iInterface = STRING_CONTROL,
+ };
+ #endif
+@@ -522,30 +447,50 @@
+ rndis_control_intf = {
+ .bLength = sizeof rndis_control_intf,
+ .bDescriptorType = USB_DT_INTERFACE,
+-
++
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_COMM,
+- .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
+- .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
++ .bInterfaceSubClass = 2, /* abstract control model */
++ .bInterfaceProtocol = 0xff, /* vendor specific */
+ .iInterface = STRING_RNDIS_CONTROL,
+ };
+ #endif
+
+-static const struct usb_cdc_header_desc header_desc = {
++#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
++
++/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */
++struct header_desc {
++ u8 bLength;
++ u8 bDescriptorType;
++ u8 bDescriptorSubType;
++
++ u16 bcdCDC;
++} __attribute__ ((packed));
++
++static const struct header_desc header_desc = {
+ .bLength = sizeof header_desc,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_HEADER_TYPE,
++ .bDescriptorSubType = 0,
+
+ .bcdCDC = __constant_cpu_to_le16 (0x0110),
+ };
+
+-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
++/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
++struct union_desc {
++ u8 bLength;
++ u8 bDescriptorType;
++ u8 bDescriptorSubType;
++
++ u8 bMasterInterface0;
++ u8 bSlaveInterface0;
++ /* ... and there could be other slave interfaces */
++} __attribute__ ((packed));
+
+-static const struct usb_cdc_union_desc union_desc = {
++static const struct union_desc union_desc = {
+ .bLength = sizeof union_desc,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_UNION_TYPE,
++ .bDescriptorSubType = 6,
+
+ .bMasterInterface0 = 0, /* index of control interface */
+ .bSlaveInterface0 = 1, /* index of DATA interface */
+@@ -555,64 +500,64 @@
+
+ #ifdef CONFIG_USB_ETH_RNDIS
+
+-static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
+- .bLength = sizeof call_mgmt_descriptor,
+- .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
++/* "Call Management Descriptor" from CDC spec 5.2.3.3 */
++struct call_mgmt_descriptor {
++ u8 bLength;
++ u8 bDescriptorType;
++ u8 bDescriptorSubType;
+
+- .bmCapabilities = 0x00,
+- .bDataInterface = 0x01,
+-};
++ u8 bmCapabilities;
++ u8 bDataInterface;
++} __attribute__ ((packed));
+
+-static const struct usb_cdc_acm_descriptor acm_descriptor = {
+- .bLength = sizeof acm_descriptor,
+- .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_ACM_TYPE,
++static const struct call_mgmt_descriptor call_mgmt_descriptor = {
++ .bLength = sizeof call_mgmt_descriptor,
++ .bDescriptorType = USB_DT_CS_INTERFACE,
++ .bDescriptorSubType = 0x01,
+
+- .bmCapabilities = 0x00,
++ .bmCapabilities = 0x00,
++ .bDataInterface = 0x01,
+ };
+
+-#endif
+
+-#ifndef DEV_CONFIG_CDC
++/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.4 */
++struct acm_descriptor {
++ u8 bLength;
++ u8 bDescriptorType;
++ u8 bDescriptorSubType;
+
+-/* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various
+- * ways: data endpoints live in the control interface, there's no data
+- * interface, and it's not used to talk to a cell phone radio.
+- */
++ u8 bmCapabilities;
++} __attribute__ ((packed));
+
+-static const struct usb_cdc_mdlm_desc mdlm_desc = {
+- .bLength = sizeof mdlm_desc,
+- .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_MDLM_TYPE,
++static struct acm_descriptor acm_descriptor = {
++ .bLength = sizeof acm_descriptor,
++ .bDescriptorType = USB_DT_CS_INTERFACE,
++ .bDescriptorSubType = 0x02,
+
+- .bcdVersion = __constant_cpu_to_le16(0x0100),
+- .bGUID = {
+- 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
+- 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
+- },
++ .bmCapabilities = 0X00,
+ };
+
+-/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we
+- * can't really use its struct. All we do here is say that we're using
+- * the submode of "SAFE" which directly matches the CDC Subset.
+- */
+-static const u8 mdlm_detail_desc[] = {
+- 6,
+- USB_DT_CS_INTERFACE,
+- USB_CDC_MDLM_DETAIL_TYPE,
++#endif
+
+- 0, /* "SAFE" */
+- 0, /* network control capabilities (none) */
+- 0, /* network data capabilities ("raw" encapsulation) */
+-};
++#ifdef DEV_CONFIG_CDC
+
+-#endif
++/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */
++struct ether_desc {
++ u8 bLength;
++ u8 bDescriptorType;
++ u8 bDescriptorSubType;
++
++ u8 iMACAddress;
++ u32 bmEthernetStatistics;
++ u16 wMaxSegmentSize;
++ u16 wNumberMCFilters;
++ u8 bNumberPowerFilters;
++} __attribute__ ((packed));
+
+-static const struct usb_cdc_ether_desc ether_desc = {
++static const struct ether_desc ether_desc = {
+ .bLength = sizeof ether_desc,
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
++ .bDescriptorSubType = 0x0f,
+
+ /* this descriptor actually adds value, surprise! */
+ .iMACAddress = STRING_ETHADDR,
+@@ -622,12 +567,14 @@
+ .bNumberPowerFilters = 0,
+ };
+
++#endif
+
+ #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+
+ /* include the status endpoint if we can, even where it's optional.
+- * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
+- * packet, to simplify cancellation; and a big transfer interval, to
++ * use small wMaxPacketSize, since many "interrupt" endpoints have
++ * very small fifos and it's no big deal if CDC_NOTIFY_SPEED_CHANGE
++ * takes two packets. also default to a big transfer interval, to
+ * waste less bandwidth.
+ *
+ * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
+@@ -638,9 +585,9 @@
+ * RNDIS requires the status endpoint, since it uses that encapsulation
+ * mechanism for its funky RPC scheme.
+ */
+-
++
+ #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
+-#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
++#define STATUS_BYTECOUNT 8 /* 8 byte header + data */
+
+ static struct usb_endpoint_descriptor
+ fs_status_desc = {
+@@ -714,9 +661,6 @@
+ /*
+ * "Simple" CDC-subset option is a simple vendor-neutral model that most
+ * full speed controllers can handle: one interface, two bulk endpoints.
+- *
+- * To assist host side drivers, we fancy it up a bit, and add descriptors
+- * so some host side drivers will understand it as a "SAFE" variant.
+ */
+
+ static const struct usb_interface_descriptor
+@@ -727,8 +671,8 @@
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 2,
+- .bInterfaceClass = USB_CLASS_COMM,
+- .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM,
++ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
++ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = STRING_DATA,
+ };
+@@ -776,15 +720,10 @@
+ static inline void __init fs_subset_descriptors(void)
+ {
+ #ifdef DEV_CONFIG_SUBSET
+- /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
+ fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
+- fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
+- fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;
+- fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;
+- fs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc;
+- fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc;
+- fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc;
+- fs_eth_function[8] = NULL;
++ fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;
++ fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;
++ fs_eth_function[4] = NULL;
+ #else
+ fs_eth_function[1] = NULL;
+ #endif
+@@ -808,6 +747,8 @@
+ };
+ #endif
+
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++
+ /*
+ * usb 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+@@ -876,15 +817,10 @@
+ static inline void __init hs_subset_descriptors(void)
+ {
+ #ifdef DEV_CONFIG_SUBSET
+- /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
+ hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
+- hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
+- hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;
+- hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;
+- hs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc;
+- hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc;
+- hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc;
+- hs_eth_function[8] = NULL;
++ hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;
++ hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;
++ hs_eth_function[4] = NULL;
+ #else
+ hs_eth_function[1] = NULL;
+ #endif
+@@ -910,36 +846,39 @@
+
+
+ /* maxpacket and other transfer characteristics vary by speed. */
+-static inline struct usb_endpoint_descriptor *
+-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
+- struct usb_endpoint_descriptor *fs)
+-{
+- if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+- return hs;
+- return fs;
++#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
++
++#else
++
++/* if there's no high speed support, maxpacket doesn't change. */
++#define ep_desc(g,hs,fs) fs
++
++static inline void __init hs_subset_descriptors(void)
++{
+ }
+
++#endif /* !CONFIG_USB_GADGET_DUALSPEED */
+
+ /*-------------------------------------------------------------------------*/
+
+ /* descriptors that are built on-demand */
+
+-static char manufacturer [50];
++static char manufacturer [40];
+ static char product_desc [40] = DRIVER_DESC;
+-static char serial_number [20];
+
++#ifdef DEV_CONFIG_CDC
+ /* address that the host will use ... usually assigned at random */
+ static char ethaddr [2 * ETH_ALEN + 1];
++#endif
+
+ /* static strings, in UTF-8 */
+ static struct usb_string strings [] = {
+ { STRING_MANUFACTURER, manufacturer, },
+ { STRING_PRODUCT, product_desc, },
+- { STRING_SERIALNUMBER, serial_number, },
+ { STRING_DATA, "Ethernet Data", },
+- { STRING_ETHADDR, ethaddr, },
+ #ifdef DEV_CONFIG_CDC
+ { STRING_CDC, "CDC Ethernet", },
++ { STRING_ETHADDR, ethaddr, },
+ { STRING_CONTROL, "CDC Communications Control", },
+ #endif
+ #ifdef DEV_CONFIG_SUBSET
+@@ -962,19 +901,22 @@
+ * complications: class descriptors, and an altsetting.
+ */
+ static int
+-config_buf(struct usb_gadget *g, u8 *buf, u8 type, unsigned index, int is_otg)
++config_buf (enum usb_device_speed speed,
++ u8 *buf, u8 type,
++ unsigned index, int is_otg)
+ {
+ int len;
+ const struct usb_config_descriptor *config;
+ const struct usb_descriptor_header **function;
+- int hs = 0;
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ int hs = (speed == USB_SPEED_HIGH);
+
+- if (gadget_is_dualspeed(g)) {
+- hs = (g->speed == USB_SPEED_HIGH);
+- if (type == USB_DT_OTHER_SPEED_CONFIG)
+- hs = !hs;
+- }
++ if (type == USB_DT_OTHER_SPEED_CONFIG)
++ hs = !hs;
+ #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function)
++#else
++#define which_fn(t) (fs_ ## t ## _function)
++#endif
+
+ if (index >= device_desc.bNumConfigurations)
+ return -EINVAL;
+@@ -1006,36 +948,13 @@
+
+ /*-------------------------------------------------------------------------*/
+
+-static void eth_start (struct eth_dev *dev, gfp_t gfp_flags);
+-static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags);
++static void eth_start (struct eth_dev *dev, int gfp_flags);
++static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags);
+
+-static int
+-set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
++#ifdef DEV_CONFIG_CDC
++static inline int ether_alt_ep_setup (struct eth_dev *dev, struct usb_ep *ep)
+ {
+- int result = 0;
+- struct usb_gadget *gadget = dev->gadget;
+-
+-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+- /* status endpoint used for RNDIS and (optionally) CDC */
+- if (!subset_active(dev) && dev->status_ep) {
+- dev->status = ep_desc (gadget, &hs_status_desc,
+- &fs_status_desc);
+- dev->status_ep->driver_data = dev;
+-
+- result = usb_ep_enable (dev->status_ep, dev->status);
+- if (result != 0) {
+- DEBUG (dev, "enable %s --> %d\n",
+- dev->status_ep->name, result);
+- goto done;
+- }
+- }
+-#endif
+-
+- dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
+- dev->in_ep->driver_data = dev;
+-
+- dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
+- dev->out_ep->driver_data = dev;
++ const struct usb_endpoint_descriptor *d;
+
+ /* With CDC, the host isn't allowed to use these two data
+ * endpoints in the default altsetting for the interface.
+@@ -1045,41 +964,153 @@
+ * a side effect of setting a packet filter. Deactivation is
+ * from REMOTE_NDIS_HALT_MSG, reset from REMOTE_NDIS_RESET_MSG.
+ */
+- if (!cdc_active(dev)) {
+- result = usb_ep_enable (dev->in_ep, dev->in);
+- if (result != 0) {
+- DEBUG(dev, "enable %s --> %d\n",
+- dev->in_ep->name, result);
+- goto done;
++
++ /* one endpoint writes data back IN to the host */
++ if (strcmp (ep->name, EP_IN_NAME) == 0) {
++ d = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
++ ep->driver_data = dev;
++ dev->in_ep = ep;
++ dev->in = d;
++
++ /* one endpoint just reads OUT packets */
++ } else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
++ d = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc);
++ ep->driver_data = dev;
++ dev->out_ep = ep;
++ dev->out = d;
++
++ /* optional status/notification endpoint */
++ } else if (EP_STATUS_NAME &&
++ strcmp (ep->name, EP_STATUS_NAME) == 0) {
++ int result;
++
++ d = ep_desc (dev->gadget, &hs_status_desc, &fs_status_desc);
++ result = usb_ep_enable (ep, d);
++ if (result < 0)
++ return result;
++
++ ep->driver_data = dev;
++ dev->status_ep = ep;
++ dev->status = d;
++ }
++ return 0;
++}
++#endif
++
++#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
++static inline int ether_ep_setup (struct eth_dev *dev, struct usb_ep *ep)
++{
++ int result;
++ const struct usb_endpoint_descriptor *d;
++
++ /* CDC subset is simpler: if the device is there,
++ * it's live with rx and tx endpoints.
++ *
++ * Do this as a shortcut for RNDIS too.
++ */
++
++ /* one endpoint writes data back IN to the host */
++ if (strcmp (ep->name, EP_IN_NAME) == 0) {
++ d = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
++ result = usb_ep_enable (ep, d);
++ if (result < 0)
++ return result;
++
++ ep->driver_data = dev;
++ dev->in_ep = ep;
++ dev->in = d;
++
++ /* one endpoint just reads OUT packets */
++ } else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
++ d = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc);
++ result = usb_ep_enable (ep, d);
++ if (result < 0)
++ return result;
++
++ ep->driver_data = dev;
++ dev->out_ep = ep;
++ dev->out = d;
++ }
++
++ return 0;
++}
++#endif
++
++static int
++set_ether_config (struct eth_dev *dev, int gfp_flags)
++{
++ int result = 0;
++ struct usb_ep *ep;
++ struct usb_gadget *gadget = dev->gadget;
++
++ gadget_for_each_ep (ep, gadget) {
++#ifdef DEV_CONFIG_CDC
++ if (!dev->rndis && dev->cdc) {
++ result = ether_alt_ep_setup (dev, ep);
++ if (result == 0)
++ continue;
+ }
++#endif
+
+- result = usb_ep_enable (dev->out_ep, dev->out);
+- if (result != 0) {
+- DEBUG (dev, "enable %s --> %d\n",
+- dev->out_ep->name, result);
+- goto done;
++#ifdef CONFIG_USB_ETH_RNDIS
++ if (dev->rndis && strcmp (ep->name, EP_STATUS_NAME) == 0) {
++ const struct usb_endpoint_descriptor *d;
++ d = ep_desc (gadget, &hs_status_desc, &fs_status_desc);
++ result = usb_ep_enable (ep, d);
++ if (result == 0) {
++ ep->driver_data = dev;
++ dev->status_ep = ep;
++ dev->status = d;
++ continue;
++ }
++ } else
++#endif
++
++ {
++#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
++ result = ether_ep_setup (dev, ep);
++ if (result == 0)
++ continue;
++#endif
+ }
++
++ /* stop on error */
++ ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
++ break;
+ }
++ if (!result && (!dev->in_ep || !dev->out_ep))
++ result = -ENODEV;
+
+-done:
+ if (result == 0)
+ result = alloc_requests (dev, qlen (gadget), gfp_flags);
+
+ /* on error, disable any endpoints */
+ if (result < 0) {
+- if (!subset_active(dev) && dev->status_ep)
++#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
++ if (dev->status_ep)
+ (void) usb_ep_disable (dev->status_ep);
++#endif
++ dev->status_ep = NULL;
+ dev->status = NULL;
+- (void) usb_ep_disable (dev->in_ep);
+- (void) usb_ep_disable (dev->out_ep);
++#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
++ if (dev->rndis || !dev->cdc) {
++ if (dev->in_ep)
++ (void) usb_ep_disable (dev->in_ep);
++ if (dev->out_ep)
++ (void) usb_ep_disable (dev->out_ep);
++ }
++#endif
++ dev->in_ep = NULL;
+ dev->in = NULL;
++ dev->out_ep = NULL;
+ dev->out = NULL;
+- }
++ } else
+
+ /* activate non-CDC configs right away
+ * this isn't strictly according to the RNDIS spec
+ */
+- else if (!cdc_active (dev)) {
++#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
++ if (dev->rndis || !dev->cdc) {
+ netif_carrier_on (dev->net);
+ if (netif_running (dev->net)) {
+ spin_unlock (&dev->lock);
+@@ -1087,6 +1118,7 @@
+ spin_lock (&dev->lock);
+ }
+ }
++#endif
+
+ if (result == 0)
+ DEBUG (dev, "qlen %d\n", qlen (gadget));
+@@ -1106,45 +1138,35 @@
+
+ netif_stop_queue (dev->net);
+ netif_carrier_off (dev->net);
+- rndis_uninit(dev->rndis_config);
+
+ /* disable endpoints, forcing (synchronous) completion of
+ * pending i/o. then free the requests.
+ */
+- if (dev->in) {
++ if (dev->in_ep) {
+ usb_ep_disable (dev->in_ep);
+- spin_lock(&dev->req_lock);
+ while (likely (!list_empty (&dev->tx_reqs))) {
+ req = container_of (dev->tx_reqs.next,
+ struct usb_request, list);
+ list_del (&req->list);
+-
+- spin_unlock(&dev->req_lock);
+ usb_ep_free_request (dev->in_ep, req);
+- spin_lock(&dev->req_lock);
+ }
+- spin_unlock(&dev->req_lock);
++ dev->in_ep = NULL;
+ }
+- if (dev->out) {
++ if (dev->out_ep) {
+ usb_ep_disable (dev->out_ep);
+- spin_lock(&dev->req_lock);
+ while (likely (!list_empty (&dev->rx_reqs))) {
+ req = container_of (dev->rx_reqs.next,
+ struct usb_request, list);
+ list_del (&req->list);
+-
+- spin_unlock(&dev->req_lock);
+ usb_ep_free_request (dev->out_ep, req);
+- spin_lock(&dev->req_lock);
+ }
+- spin_unlock(&dev->req_lock);
++ dev->out_ep = NULL;
+ }
+
+- if (dev->status) {
++ if (dev->status_ep) {
+ usb_ep_disable (dev->status_ep);
++ dev->status_ep = NULL;
+ }
+- dev->rndis = 0;
+- dev->cdc_filter = 0;
+ dev->config = 0;
+ }
+
+@@ -1152,11 +1174,14 @@
+ * that returns config descriptors, and altsetting code.
+ */
+ static int
+-eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
++eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
+ {
+ int result = 0;
+ struct usb_gadget *gadget = dev->gadget;
+
++ if (number == dev->config)
++ return 0;
++
+ if (gadget_is_sa1100 (gadget)
+ && dev->config
+ && atomic_read (&dev->tx_qlen) != 0) {
+@@ -1166,8 +1191,12 @@
+ }
+ eth_reset_config (dev);
+
++ /* default: pass all packets, no multicast filtering */
++ dev->cdc_filter = 0x000f;
++
+ switch (number) {
+ case DEV_CONFIG_VALUE:
++ dev->rndis = 0;
+ result = set_ether_config (dev, gfp_flags);
+ break;
+ #ifdef CONFIG_USB_ETH_RNDIS
+@@ -1180,35 +1209,28 @@
+ result = -EINVAL;
+ /* FALL THROUGH */
+ case 0:
+- break;
++ return result;
+ }
+
+- if (result) {
+- if (number)
+- eth_reset_config (dev);
+- usb_gadget_vbus_draw(dev->gadget,
+- gadget_is_otg(dev->gadget) ? 8 : 100);
+- } else {
++ if (result)
++ eth_reset_config (dev);
++ else {
+ char *speed;
+- unsigned power;
+-
+- power = 2 * eth_config.bMaxPower;
+- usb_gadget_vbus_draw(dev->gadget, power);
+
+ switch (gadget->speed) {
+ case USB_SPEED_FULL: speed = "full"; break;
+ #ifdef CONFIG_USB_GADGET_DUALSPEED
+ case USB_SPEED_HIGH: speed = "high"; break;
+ #endif
+- default: speed = "?"; break;
++ default: speed = "?"; break;
+ }
+
+ dev->config = number;
+- INFO (dev, "%s speed config #%d: %d mA, %s, using %s\n",
+- speed, number, power, driver_desc,
+- rndis_active(dev)
++ INFO (dev, "%s speed config #%d: %s, using %s\n",
++ speed, number, driver_desc,
++ dev->rndis
+ ? "RNDIS"
+- : (cdc_active(dev)
++ : (dev->cdc
+ ? "CDC Ethernet"
+ : "CDC Ethernet Subset"));
+ }
+@@ -1217,52 +1239,68 @@
+
+ /*-------------------------------------------------------------------------*/
+
++/* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications
++ * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS
++ * and RNDIS also defines its own bit-incompatible notifications
++ */
++#define CDC_NOTIFY_NETWORK_CONNECTION 0x00 /* required; 6.3.1 */
++#define CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 /* optional; 6.3.2 */
++#define CDC_NOTIFY_SPEED_CHANGE 0x2a /* required; 6.3.8 */
++
+ #ifdef DEV_CONFIG_CDC
+
+-/* The interrupt endpoint is used in CDC networking models (Ethernet, ATM)
+- * only to notify the host about link status changes (which we support) or
+- * report completion of some encapsulated command (as used in RNDIS). Since
+- * we want this CDC Ethernet code to be vendor-neutral, we don't use that
+- * command mechanism; and only one status request is ever queued.
+- */
++struct cdc_notification {
++ u8 bmRequestType;
++ u8 bNotificationType;
++ u16 wValue;
++ u16 wIndex;
++ u16 wLength;
++
++ /* SPEED_CHANGE data looks like this */
++ u32 data [2];
++};
+
+ static void eth_status_complete (struct usb_ep *ep, struct usb_request *req)
+ {
+- struct usb_cdc_notification *event = req->buf;
+- int value = req->status;
+- struct eth_dev *dev = ep->driver_data;
++ struct cdc_notification *event = req->buf;
++ int value = req->status;
++ struct eth_dev *dev = ep->driver_data;
+
+ /* issue the second notification if host reads the first */
+- if (event->bNotificationType == USB_CDC_NOTIFY_NETWORK_CONNECTION
++ if (event->bNotificationType == CDC_NOTIFY_NETWORK_CONNECTION
+ && value == 0) {
+- __le32 *data = req->buf + sizeof *event;
+-
+ event->bmRequestType = 0xA1;
+- event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
++ event->bNotificationType = CDC_NOTIFY_SPEED_CHANGE;
+ event->wValue = __constant_cpu_to_le16 (0);
+ event->wIndex = __constant_cpu_to_le16 (1);
+ event->wLength = __constant_cpu_to_le16 (8);
+
+ /* SPEED_CHANGE data is up/down speeds in bits/sec */
+- data [0] = data [1] = cpu_to_le32 (BITRATE (dev->gadget));
++ event->data [0] = event->data [1] =
++ (dev->gadget->speed == USB_SPEED_HIGH)
++ ? (13 * 512 * 8 * 1000 * 8)
++ : (19 * 64 * 1 * 1000 * 8);
+
+- req->length = STATUS_BYTECOUNT;
++ req->length = 16;
+ value = usb_ep_queue (ep, req, GFP_ATOMIC);
+ DEBUG (dev, "send SPEED_CHANGE --> %d\n", value);
+ if (value == 0)
+ return;
+- } else if (value != -ECONNRESET)
++ } else
+ DEBUG (dev, "event %02x --> %d\n",
+ event->bNotificationType, value);
+- req->context = NULL;
++
++ /* free when done */
++ usb_ep_free_buffer (ep, req->buf, req->dma, 16);
++ usb_ep_free_request (ep, req);
+ }
+
+ static void issue_start_status (struct eth_dev *dev)
+ {
+- struct usb_request *req = dev->stat_req;
+- struct usb_cdc_notification *event;
+- int value;
+-
++ struct usb_request *req;
++ struct cdc_notification *event;
++ int value;
++
+ DEBUG (dev, "%s, flush old status first\n", __FUNCTION__);
+
+ /* flush old status
+@@ -1271,29 +1309,44 @@
+ * a "cancel the whole queue" primitive since any
+ * unlink-one primitive has way too many error modes.
+ * here, we "know" toggle is already clear...
+- *
+- * FIXME iff req->context != null just dequeue it
+ */
+ usb_ep_disable (dev->status_ep);
+ usb_ep_enable (dev->status_ep, dev->status);
+
++ /* FIXME make these allocations static like dev->req */
++ req = usb_ep_alloc_request (dev->status_ep, GFP_ATOMIC);
++ if (req == 0) {
++ DEBUG (dev, "status ENOMEM\n");
++ return;
++ }
++ req->buf = usb_ep_alloc_buffer (dev->status_ep, 16,
++ &dev->req->dma, GFP_ATOMIC);
++ if (req->buf == 0) {
++ DEBUG (dev, "status buf ENOMEM\n");
++free_req:
++ usb_ep_free_request (dev->status_ep, req);
++ return;
++ }
++
+ /* 3.8.1 says to issue first NETWORK_CONNECTION, then
+ * a SPEED_CHANGE. could be useful in some configs.
+ */
+ event = req->buf;
+ event->bmRequestType = 0xA1;
+- event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
++ event->bNotificationType = CDC_NOTIFY_NETWORK_CONNECTION;
+ event->wValue = __constant_cpu_to_le16 (1); /* connected */
+ event->wIndex = __constant_cpu_to_le16 (1);
+ event->wLength = 0;
+
+- req->length = sizeof *event;
++ req->length = 8;
+ req->complete = eth_status_complete;
+- req->context = dev;
+-
+ value = usb_ep_queue (dev->status_ep, req, GFP_ATOMIC);
+- if (value < 0)
++ if (value < 0) {
+ DEBUG (dev, "status buf queue --> %d\n", value);
++ usb_ep_free_buffer (dev->status_ep,
++ req->buf, dev->req->dma, 16);
++ goto free_req;
++ }
+ }
+
+ #endif
+@@ -1308,24 +1361,43 @@
+ req->status, req->actual, req->length);
+ }
+
++/* see section 3.8.2 table 10 of the CDC spec for more ethernet
++ * requests, mostly for filters (multicast, pm) and statistics
++ * section 3.6.2.1 table 4 has ACM requests; RNDIS requires the
++ * encapsulated command mechanism.
++ */
++#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 /* optional */
++#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 /* optional */
++#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 /* optional */
++#define CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 /* optional */
++#define CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 /* optional */
++#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 /* required */
++#define CDC_GET_ETHERNET_STATISTIC 0x44 /* optional */
++
++/* table 62; bits in cdc_filter */
++#define CDC_PACKET_TYPE_PROMISCUOUS (1 << 0)
++#define CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */
++#define CDC_PACKET_TYPE_DIRECTED (1 << 2)
++#define CDC_PACKET_TYPE_BROADCAST (1 << 3)
++#define CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */
++
+ #ifdef CONFIG_USB_ETH_RNDIS
+
+ static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
+ {
+ if (req->status || req->actual != req->length)
+- DEBUG ((struct eth_dev *) ep->driver_data,
+- "rndis response complete --> %d, %d/%d\n",
+- req->status, req->actual, req->length);
++ DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
++ req->status, req->actual, req->length);
+
+- /* done sending after USB_CDC_GET_ENCAPSULATED_RESPONSE */
++ /* done sending after CDC_GET_ENCAPSULATED_RESPONSE */
+ }
+
+ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
+ {
+ struct eth_dev *dev = ep->driver_data;
+ int status;
+-
+- /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
++
++ /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
+ spin_lock(&dev->lock);
+ status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
+ if (status < 0)
+@@ -1350,9 +1422,6 @@
+ struct eth_dev *dev = get_gadget_data (gadget);
+ struct usb_request *req = dev->req;
+ int value = -EOPNOTSUPP;
+- u16 wIndex = le16_to_cpu(ctrl->wIndex);
+- u16 wValue = le16_to_cpu(ctrl->wValue);
+- u16 wLength = le16_to_cpu(ctrl->wLength);
+
+ /* descriptors just go into the pre-allocated ep0 buffer,
+ * while config change events may enable network traffic.
+@@ -1363,37 +1432,39 @@
+ case USB_REQ_GET_DESCRIPTOR:
+ if (ctrl->bRequestType != USB_DIR_IN)
+ break;
+- switch (wValue >> 8) {
++ switch (ctrl->wValue >> 8) {
+
+ case USB_DT_DEVICE:
+- value = min (wLength, (u16) sizeof device_desc);
++ value = min (ctrl->wLength, (u16) sizeof device_desc);
+ memcpy (req->buf, &device_desc, value);
+ break;
++#ifdef CONFIG_USB_GADGET_DUALSPEED
+ case USB_DT_DEVICE_QUALIFIER:
+- if (!gadget_is_dualspeed(gadget))
++ if (!gadget->is_dualspeed)
+ break;
+- value = min (wLength, (u16) sizeof dev_qualifier);
++ value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
+ memcpy (req->buf, &dev_qualifier, value);
+ break;
+
+ case USB_DT_OTHER_SPEED_CONFIG:
+- if (!gadget_is_dualspeed(gadget))
++ if (!gadget->is_dualspeed)
+ break;
+ // FALLTHROUGH
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
+ case USB_DT_CONFIG:
+- value = config_buf(gadget, req->buf,
+- wValue >> 8,
+- wValue & 0xff,
+- gadget_is_otg(gadget));
++ value = config_buf (gadget->speed, req->buf,
++ ctrl->wValue >> 8,
++ ctrl->wValue & 0xff,
++ gadget->is_otg);
+ if (value >= 0)
+- value = min (wLength, (u16) value);
++ value = min (ctrl->wLength, (u16) value);
+ break;
+
+ case USB_DT_STRING:
+ value = usb_gadget_get_string (&stringtab,
+- wValue & 0xff, req->buf);
++ ctrl->wValue & 0xff, req->buf);
+ if (value >= 0)
+- value = min (wLength, (u16) value);
++ value = min (ctrl->wLength, (u16) value);
+ break;
+ }
+ break;
+@@ -1406,22 +1477,22 @@
+ else if (gadget->a_alt_hnp_support)
+ DEBUG (dev, "HNP needs a different root port\n");
+ spin_lock (&dev->lock);
+- value = eth_set_config (dev, wValue, GFP_ATOMIC);
++ value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
+ spin_unlock (&dev->lock);
+ break;
+ case USB_REQ_GET_CONFIGURATION:
+ if (ctrl->bRequestType != USB_DIR_IN)
+ break;
+ *(u8 *)req->buf = dev->config;
+- value = min (wLength, (u16) 1);
++ value = min (ctrl->wLength, (u16) 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (ctrl->bRequestType != USB_RECIP_INTERFACE
+ || !dev->config
+- || wIndex > 1)
++ || ctrl->wIndex > 1)
+ break;
+- if (!cdc_active(dev) && wIndex != 0)
++ if (!dev->cdc && ctrl->wIndex != 0)
+ break;
+ spin_lock (&dev->lock);
+
+@@ -1435,34 +1506,31 @@
+ }
+
+ #ifdef DEV_CONFIG_CDC
+- switch (wIndex) {
++ switch (ctrl->wIndex) {
+ case 0: /* control/master intf */
+- if (wValue != 0)
++ if (ctrl->wValue != 0)
+ break;
+- if (dev->status) {
++ if (dev->status_ep) {
+ usb_ep_disable (dev->status_ep);
+ usb_ep_enable (dev->status_ep, dev->status);
+ }
+ value = 0;
+ break;
+ case 1: /* data intf */
+- if (wValue > 1)
++ if (ctrl->wValue > 1)
+ break;
+ usb_ep_disable (dev->in_ep);
+ usb_ep_disable (dev->out_ep);
+
+ /* CDC requires the data transfers not be done from
+ * the default interface setting ... also, setting
+- * the non-default interface resets filters etc.
++ * the non-default interface clears filters etc.
+ */
+- if (wValue == 1) {
+- if (!cdc_active (dev))
+- break;
++ if (ctrl->wValue == 1) {
+ usb_ep_enable (dev->in_ep, dev->in);
+ usb_ep_enable (dev->out_ep, dev->out);
+- dev->cdc_filter = DEFAULT_FILTER;
+ netif_carrier_on (dev->net);
+- if (dev->status)
++ if (dev->status_ep)
+ issue_start_status (dev);
+ if (netif_running (dev->net)) {
+ spin_unlock (&dev->lock);
+@@ -1489,79 +1557,75 @@
+ case USB_REQ_GET_INTERFACE:
+ if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)
+ || !dev->config
+- || wIndex > 1)
++ || ctrl->wIndex > 1)
+ break;
+- if (!(cdc_active(dev) || rndis_active(dev)) && wIndex != 0)
++ if (!(dev->cdc || dev->rndis) && ctrl->wIndex != 0)
+ break;
+
+ /* for CDC, iff carrier is on, data interface is active. */
+- if (rndis_active(dev) || wIndex != 1)
++ if (dev->rndis || ctrl->wIndex != 1)
+ *(u8 *)req->buf = 0;
+ else
+ *(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;
+- value = min (wLength, (u16) 1);
++ value = min (ctrl->wLength, (u16) 1);
+ break;
+
+ #ifdef DEV_CONFIG_CDC
+- case USB_CDC_SET_ETHERNET_PACKET_FILTER:
++ case CDC_SET_ETHERNET_PACKET_FILTER:
+ /* see 6.2.30: no data, wIndex = interface,
+ * wValue = packet filter bitmap
+ */
+ if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
+- || !cdc_active(dev)
+- || wLength != 0
+- || wIndex > 1)
++ || !dev->cdc
++ || dev->rndis
++ || ctrl->wLength != 0
++ || ctrl->wIndex > 1)
+ break;
+- DEBUG (dev, "packet filter %02x\n", wValue);
+- dev->cdc_filter = wValue;
++ DEBUG (dev, "NOP packet filter %04x\n", ctrl->wValue);
++ /* NOTE: table 62 has 5 filter bits to reduce traffic,
++ * and we "must" support multicast and promiscuous.
++ * this NOP implements a bad filter (always promisc)
++ */
++ dev->cdc_filter = ctrl->wValue;
+ value = 0;
+ break;
+-
+- /* and potentially:
+- * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS:
+- * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER:
+- * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER:
+- * case USB_CDC_GET_ETHERNET_STATISTIC:
+- */
+-
+ #endif /* DEV_CONFIG_CDC */
+
+-#ifdef CONFIG_USB_ETH_RNDIS
++#ifdef CONFIG_USB_ETH_RNDIS
+ /* RNDIS uses the CDC command encapsulation mechanism to implement
+ * an RPC scheme, with much getting/setting of attributes by OID.
+ */
+- case USB_CDC_SEND_ENCAPSULATED_COMMAND:
++ case CDC_SEND_ENCAPSULATED_COMMAND:
+ if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
+- || !rndis_active(dev)
+- || wLength > USB_BUFSIZ
+- || wValue
++ || !dev->rndis
++ || ctrl->wLength > USB_BUFSIZ
++ || ctrl->wValue
+ || rndis_control_intf.bInterfaceNumber
+- != wIndex)
++ != ctrl->wIndex)
+ break;
+ /* read the request, then process it */
+- value = wLength;
++ value = ctrl->wLength;
+ req->complete = rndis_command_complete;
+ /* later, rndis_control_ack () sends a notification */
+ break;
+-
+- case USB_CDC_GET_ENCAPSULATED_RESPONSE:
++
++ case CDC_GET_ENCAPSULATED_RESPONSE:
+ if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
+ == ctrl->bRequestType
+- && rndis_active(dev)
+- // && wLength >= 0x0400
+- && !wValue
++ && dev->rndis
++ // && ctrl->wLength >= 0x0400
++ && !ctrl->wValue
+ && rndis_control_intf.bInterfaceNumber
+- == wIndex) {
++ == ctrl->wIndex) {
+ u8 *buf;
+- u32 n;
+
+ /* return the result */
+- buf = rndis_get_next_response(dev->rndis_config, &n);
++ buf = rndis_get_next_response (dev->rndis_config,
++ &value);
+ if (buf) {
+- memcpy(req->buf, buf, n);
++ memcpy (req->buf, buf, value);
+ req->complete = rndis_response_complete;
+ rndis_free_response(dev->rndis_config, buf);
+- value = n;
+ }
+ /* else stalls ... spec says to avoid that */
+ }
+@@ -1572,13 +1636,13 @@
+ VDEBUG (dev,
+ "unknown control req%02x.%02x v%04x i%04x l%d\n",
+ ctrl->bRequestType, ctrl->bRequest,
+- wValue, wIndex, wLength);
++ ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+ }
+
+ /* respond with data transfer before status phase? */
+ if (value >= 0) {
+ req->length = value;
+- req->zero = value < wLength
++ req->zero = value < ctrl->wLength
+ && (value % gadget->ep0->maxpacket) == 0;
+ value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
+ if (value < 0) {
+@@ -1617,10 +1681,9 @@
+
+ static int eth_change_mtu (struct net_device *net, int new_mtu)
+ {
+- struct eth_dev *dev = netdev_priv(net);
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
+
+- if (dev->rndis)
+- return -EBUSY;
++ // FIXME if rndis, don't change while link's live
+
+ if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
+ return -ERANGE;
+@@ -1633,29 +1696,58 @@
+
+ static struct net_device_stats *eth_get_stats (struct net_device *net)
+ {
+- return &((struct eth_dev *)netdev_priv(net))->stats;
++ return &((struct eth_dev *) net->priv)->stats;
+ }
+
+-static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
++static int eth_ethtool_ioctl (struct net_device *net, void __user *useraddr)
+ {
+- struct eth_dev *dev = netdev_priv(net);
+- strlcpy(p->driver, shortname, sizeof p->driver);
+- strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
+- strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
+- strlcpy (p->bus_info, dev->gadget->dev.bus_id, sizeof p->bus_info);
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
++ u32 cmd;
++
++ if (get_user (cmd, (u32 __user *)useraddr))
++ return -EFAULT;
++ switch (cmd) {
++
++ case ETHTOOL_GDRVINFO: { /* get driver info */
++ struct ethtool_drvinfo info;
++
++ memset (&info, 0, sizeof info);
++ info.cmd = ETHTOOL_GDRVINFO;
++ strlcpy (info.driver, shortname, sizeof info.driver);
++ strlcpy (info.version, DRIVER_VERSION, sizeof info.version);
++ strlcpy (info.fw_version, dev->gadget->name,
++ sizeof info.fw_version);
++ strlcpy (info.bus_info, dev->gadget->dev.bus_id,
++ sizeof info.bus_info);
++ if (copy_to_user (useraddr, &info, sizeof (info)))
++ return -EFAULT;
++ return 0;
++ }
++
++ case ETHTOOL_GLINK: { /* get link status */
++ struct ethtool_value edata = { ETHTOOL_GLINK };
++
++ edata.data = (dev->gadget->speed != USB_SPEED_UNKNOWN);
++ if (copy_to_user (useraddr, &edata, sizeof (edata)))
++ return -EFAULT;
++ return 0;
++ }
++
++ }
++ /* Note that the ethtool user space code requires EOPNOTSUPP */
++ return -EOPNOTSUPP;
+ }
+
+-static u32 eth_get_link(struct net_device *net)
++static int eth_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+ {
+- struct eth_dev *dev = netdev_priv(net);
+- return dev->gadget->speed != USB_SPEED_UNKNOWN;
++ switch (cmd) {
++ case SIOCETHTOOL:
++ return eth_ethtool_ioctl(net, rq->ifr_data);
++ default:
++ return -EOPNOTSUPP;
++ }
+ }
+
+-static struct ethtool_ops ops = {
+- .get_drvinfo = eth_get_drvinfo,
+- .get_link = eth_get_link
+-};
+-
+ static void defer_kevent (struct eth_dev *dev, int flag)
+ {
+ if (test_and_set_bit (flag, &dev->todo))
+@@ -1669,7 +1761,7 @@
+ static void rx_complete (struct usb_ep *ep, struct usb_request *req);
+
+ static int
+-rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
++rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
+ {
+ struct sk_buff *skb;
+ int retval = -ENOMEM;
+@@ -1688,22 +1780,17 @@
+ */
+ size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
+ size += dev->out_ep->maxpacket - 1;
+- if (rndis_active(dev))
++#ifdef CONFIG_USB_ETH_RNDIS
++ if (dev->rndis)
+ size += sizeof (struct rndis_packet_msg_type);
++#endif
+ size -= size % dev->out_ep->maxpacket;
+
+- skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
+- if (skb == NULL) {
++ if ((skb = alloc_skb (size, gfp_flags)) == 0) {
+ DEBUG (dev, "no rx skb\n");
+ goto enomem;
+ }
+
+- /* Some platforms perform better when IP packets are aligned,
+- * but on at least one, checksumming fails otherwise. Note:
+- * RNDIS headers involve variable numbers of LE32 values.
+- */
+- skb_reserve(skb, NET_IP_ALIGN);
+-
+ req->buf = skb->data;
+ req->length = size;
+ req->complete = rx_complete;
+@@ -1715,11 +1802,10 @@
+ defer_kevent (dev, WORK_RX_MEMORY);
+ if (retval) {
+ DEBUG (dev, "rx submit --> %d\n", retval);
+- if (skb)
+- dev_kfree_skb_any(skb);
+- spin_lock(&dev->req_lock);
++ dev_kfree_skb_any (skb);
++ spin_lock (&dev->lock);
+ list_add (&req->list, &dev->rx_reqs);
+- spin_unlock(&dev->req_lock);
++ spin_unlock (&dev->lock);
+ }
+ return retval;
+ }
+@@ -1735,18 +1821,19 @@
+ /* normal completion */
+ case 0:
+ skb_put (skb, req->actual);
++#ifdef CONFIG_USB_ETH_RNDIS
+ /* we know MaxPacketsPerTransfer == 1 here */
+- if (rndis_active(dev))
+- status = rndis_rm_hdr (skb);
+- if (status < 0
+- || ETH_HLEN > skb->len
+- || skb->len > ETH_FRAME_LEN) {
++ if (dev->rndis)
++ rndis_rm_hdr (req->buf, &(skb->len));
++#endif
++ if (ETH_HLEN > skb->len || skb->len > ETH_FRAME_LEN) {
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
+ DEBUG (dev, "rx length %d\n", skb->len);
+ break;
+ }
+
++ skb->dev = dev->net;
+ skb->protocol = eth_type_trans (skb, dev->net);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+@@ -1776,7 +1863,7 @@
+ case -EOVERFLOW:
+ dev->stats.rx_over_errors++;
+ // FALLTHROUGH
+-
++
+ default:
+ dev->stats.rx_errors++;
+ DEBUG (dev, "rx status %d\n", status);
+@@ -1787,9 +1874,8 @@
+ dev_kfree_skb_any (skb);
+ if (!netif_running (dev->net)) {
+ clean:
+- spin_lock(&dev->req_lock);
++ /* nobody reading rx_reqs, so no dev->lock */
+ list_add (&req->list, &dev->rx_reqs);
+- spin_unlock(&dev->req_lock);
+ req = NULL;
+ }
+ if (req)
+@@ -1797,7 +1883,7 @@
+ }
+
+ static int prealloc (struct list_head *list, struct usb_ep *ep,
+- unsigned n, gfp_t gfp_flags)
++ unsigned n, int gfp_flags)
+ {
+ unsigned i;
+ struct usb_request *req;
+@@ -1836,55 +1922,56 @@
+ return 0;
+ }
+
+-static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
++static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags)
+ {
+ int status;
+
+- spin_lock(&dev->req_lock);
+ status = prealloc (&dev->tx_reqs, dev->in_ep, n, gfp_flags);
+ if (status < 0)
+ goto fail;
+ status = prealloc (&dev->rx_reqs, dev->out_ep, n, gfp_flags);
+ if (status < 0)
+ goto fail;
+- goto done;
++ return 0;
+ fail:
+ DEBUG (dev, "can't alloc requests\n");
+-done:
+- spin_unlock(&dev->req_lock);
+ return status;
+ }
+
+-static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
++static void rx_fill (struct eth_dev *dev, int gfp_flags)
+ {
+ struct usb_request *req;
+ unsigned long flags;
+
++ clear_bit (WORK_RX_MEMORY, &dev->todo);
++
+ /* fill unused rxq slots with some skb */
+- spin_lock_irqsave(&dev->req_lock, flags);
++ spin_lock_irqsave (&dev->lock, flags);
+ while (!list_empty (&dev->rx_reqs)) {
+ req = container_of (dev->rx_reqs.next,
+ struct usb_request, list);
+ list_del_init (&req->list);
+- spin_unlock_irqrestore(&dev->req_lock, flags);
++ spin_unlock_irqrestore (&dev->lock, flags);
+
+ if (rx_submit (dev, req, gfp_flags) < 0) {
+ defer_kevent (dev, WORK_RX_MEMORY);
+ return;
+ }
+
+- spin_lock_irqsave(&dev->req_lock, flags);
++ spin_lock_irqsave (&dev->lock, flags);
+ }
+- spin_unlock_irqrestore(&dev->req_lock, flags);
++ spin_unlock_irqrestore (&dev->lock, flags);
+ }
+
+-static void eth_work (struct work_struct *work)
++static void eth_work (void *_dev)
+ {
+- struct eth_dev *dev = container_of(work, struct eth_dev, work);
++ struct eth_dev *dev = _dev;
+
+- if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) {
++ if (test_bit (WORK_RX_MEMORY, &dev->todo)) {
+ if (netif_running (dev->net))
+ rx_fill (dev, GFP_KERNEL);
++ else
++ clear_bit (WORK_RX_MEMORY, &dev->todo);
+ }
+
+ if (dev->todo)
+@@ -1909,9 +1996,9 @@
+ }
+ dev->stats.tx_packets++;
+
+- spin_lock(&dev->req_lock);
++ spin_lock (&dev->lock);
+ list_add (&req->list, &dev->tx_reqs);
+- spin_unlock(&dev->req_lock);
++ spin_unlock (&dev->lock);
+ dev_kfree_skb_any (skb);
+
+ atomic_dec (&dev->tx_qlen);
+@@ -1919,80 +2006,45 @@
+ netif_wake_queue (dev->net);
+ }
+
+-static inline int eth_is_promisc (struct eth_dev *dev)
+-{
+- /* no filters for the CDC subset; always promisc */
+- if (subset_active (dev))
+- return 1;
+- return dev->cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;
+-}
+-
+ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
+ {
+- struct eth_dev *dev = netdev_priv(net);
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
+ int length = skb->len;
+ int retval;
+ struct usb_request *req = NULL;
+ unsigned long flags;
+
+- /* apply outgoing CDC or RNDIS filters */
+- if (!eth_is_promisc (dev)) {
+- u8 *dest = skb->data;
+-
+- if (is_multicast_ether_addr(dest)) {
+- u16 type;
+-
+- /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
+- * SET_ETHERNET_MULTICAST_FILTERS requests
+- */
+- if (is_broadcast_ether_addr(dest))
+- type = USB_CDC_PACKET_TYPE_BROADCAST;
+- else
+- type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
+- if (!(dev->cdc_filter & type)) {
+- dev_kfree_skb_any (skb);
+- return 0;
+- }
+- }
+- /* ignores USB_CDC_PACKET_TYPE_DIRECTED */
+- }
+-
+- spin_lock_irqsave(&dev->req_lock, flags);
+- /*
+- * this freelist can be empty if an interrupt triggered disconnect()
+- * and reconfigured the gadget (shutting down this queue) after the
+- * network stack decided to xmit but before we got the spinlock.
+- */
+- if (list_empty(&dev->tx_reqs)) {
+- spin_unlock_irqrestore(&dev->req_lock, flags);
+- return 1;
+- }
++ /* FIXME check dev->cdc_filter to decide whether to send this,
++ * instead of acting as if CDC_PACKET_TYPE_PROMISCUOUS were
++ * always set. RNDIS has the same kind of outgoing filter.
++ */
+
++ spin_lock_irqsave (&dev->lock, flags);
+ req = container_of (dev->tx_reqs.next, struct usb_request, list);
+ list_del (&req->list);
+-
+- /* temporarily stop TX queue when the freelist empties */
+ if (list_empty (&dev->tx_reqs))
+ netif_stop_queue (net);
+- spin_unlock_irqrestore(&dev->req_lock, flags);
++ spin_unlock_irqrestore (&dev->lock, flags);
+
+ /* no buffer copies needed, unless the network stack did it
+ * or the hardware can't use skb buffers.
+ * or there's not enough space for any RNDIS headers we need
+ */
+- if (rndis_active(dev)) {
++#ifdef CONFIG_USB_ETH_RNDIS
++ if (dev->rndis) {
+ struct sk_buff *skb_rndis;
+
+ skb_rndis = skb_realloc_headroom (skb,
+ sizeof (struct rndis_packet_msg_type));
+ if (!skb_rndis)
+ goto drop;
+-
++
+ dev_kfree_skb_any (skb);
+ skb = skb_rndis;
+ rndis_add_hdr (skb);
+ length = skb->len;
+ }
++#endif
+ req->buf = skb->data;
+ req->context = skb;
+ req->complete = tx_complete;
+@@ -2007,11 +2059,12 @@
+
+ req->length = length;
+
++#ifdef CONFIG_USB_GADGET_DUALSPEED
+ /* throttle highspeed IRQ rate back slightly */
+- if (gadget_is_dualspeed(dev->gadget))
+- req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
+- ? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
+- : 0;
++ req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
++ ? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0)
++ : 0;
++#endif
+
+ retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC);
+ switch (retval) {
+@@ -2024,14 +2077,16 @@
+ }
+
+ if (retval) {
++#ifdef CONFIG_USB_ETH_RNDIS
+ drop:
++#endif
+ dev->stats.tx_dropped++;
+ dev_kfree_skb_any (skb);
+- spin_lock_irqsave(&dev->req_lock, flags);
++ spin_lock_irqsave (&dev->lock, flags);
+ if (list_empty (&dev->tx_reqs))
+ netif_start_queue (net);
+ list_add (&req->list, &dev->tx_reqs);
+- spin_unlock_irqrestore(&dev->req_lock, flags);
++ spin_unlock_irqrestore (&dev->lock, flags);
+ }
+ return 0;
+ }
+@@ -2040,98 +2095,100 @@
+
+ #ifdef CONFIG_USB_ETH_RNDIS
+
+-/* The interrupt endpoint is used in RNDIS to notify the host when messages
+- * other than data packets are available ... notably the REMOTE_NDIS_*_CMPLT
+- * messages, but also REMOTE_NDIS_INDICATE_STATUS_MSG and potentially even
+- * REMOTE_NDIS_KEEPALIVE_MSG.
+- *
+- * The RNDIS control queue is processed by GET_ENCAPSULATED_RESPONSE, and
+- * normally just one notification will be queued.
+- */
+-
+-static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, gfp_t);
+-static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
+-
+-static void
+-rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
++static void rndis_send_media_state (struct eth_dev *dev, int connect)
+ {
+- struct eth_dev *dev = ep->driver_data;
++ if (!dev)
++ return;
++
++ if (connect) {
++ if (rndis_signal_connect (dev->rndis_config))
++ return;
++ } else {
++ if (rndis_signal_disconnect (dev->rndis_config))
++ return;
++ }
++}
+
++static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
++{
+ if (req->status || req->actual != req->length)
+- DEBUG (dev,
+- "rndis control ack complete --> %d, %d/%d\n",
+- req->status, req->actual, req->length);
+- req->context = NULL;
++ DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n",
++ req->status, req->actual, req->length);
+
+- if (req != dev->stat_req)
+- eth_req_free(ep, req);
++ usb_ep_free_buffer(ep, req->buf, req->dma, 8);
++ usb_ep_free_request(ep, req);
+ }
+
+ static int rndis_control_ack (struct net_device *net)
+ {
+- struct eth_dev *dev = netdev_priv(net);
+- int length;
+- struct usb_request *resp = dev->stat_req;
+-
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
++ u32 length;
++ struct usb_request *resp;
++
+ /* in case RNDIS calls this after disconnect */
+- if (!dev->status) {
++ if (!dev->status_ep) {
+ DEBUG (dev, "status ENODEV\n");
+ return -ENODEV;
+ }
+
+- /* in case queue length > 1 */
+- if (resp->context) {
+- resp = eth_req_alloc (dev->status_ep, 8, GFP_ATOMIC);
+- if (!resp)
+- return -ENOMEM;
++ /* Allocate memory for notification ie. ACK */
++ resp = usb_ep_alloc_request (dev->status_ep, GFP_ATOMIC);
++ if (!resp) {
++ DEBUG (dev, "status ENOMEM\n");
++ return -ENOMEM;
+ }
+-
++
++ resp->buf = usb_ep_alloc_buffer (dev->status_ep, 8,
++ &resp->dma, GFP_ATOMIC);
++ if (!resp->buf) {
++ DEBUG (dev, "status buf ENOMEM\n");
++ usb_ep_free_request (dev->status_ep, resp);
++ return -ENOMEM;
++ }
++
+ /* Send RNDIS RESPONSE_AVAILABLE notification;
+- * USB_CDC_NOTIFY_RESPONSE_AVAILABLE should work too
++ * CDC_NOTIFY_RESPONSE_AVAILABLE should work too
+ */
+ resp->length = 8;
+ resp->complete = rndis_control_ack_complete;
+- resp->context = dev;
+-
+- *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
+- *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
+-
++
++ *((u32 *) resp->buf) = __constant_cpu_to_le32 (1);
++ *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
++
+ length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
+ if (length < 0) {
+ resp->status = 0;
+ rndis_control_ack_complete (dev->status_ep, resp);
+ }
+-
++
+ return 0;
+ }
+
+-#else
+-
+-#define rndis_control_ack NULL
+-
+ #endif /* RNDIS */
+
+-static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
++static void eth_start (struct eth_dev *dev, int gfp_flags)
+ {
+ DEBUG (dev, "%s\n", __FUNCTION__);
+
+ /* fill the rx queue */
+ rx_fill (dev, gfp_flags);
+
+- /* and open the tx floodgates */
++ /* and open the tx floodgates */
+ atomic_set (&dev->tx_qlen, 0);
+ netif_wake_queue (dev->net);
+- if (rndis_active(dev)) {
++#ifdef CONFIG_USB_ETH_RNDIS
++ if (dev->rndis) {
+ rndis_set_param_medium (dev->rndis_config,
+ NDIS_MEDIUM_802_3,
+- BITRATE(dev->gadget)/100);
+- (void) rndis_signal_connect (dev->rndis_config);
++ BITRATE(dev->gadget));
++ rndis_send_media_state (dev, 1);
+ }
++#endif
+ }
+
+ static int eth_open (struct net_device *net)
+ {
+- struct eth_dev *dev = netdev_priv(net);
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
+
+ DEBUG (dev, "%s\n", __FUNCTION__);
+ if (netif_carrier_ok (dev->net))
+@@ -2141,18 +2198,18 @@
+
+ static int eth_stop (struct net_device *net)
+ {
+- struct eth_dev *dev = netdev_priv(net);
++ struct eth_dev *dev = (struct eth_dev *) net->priv;
+
+ VDEBUG (dev, "%s\n", __FUNCTION__);
+ netif_stop_queue (net);
+
+ DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
+- dev->stats.rx_packets, dev->stats.tx_packets,
++ dev->stats.rx_packets, dev->stats.tx_packets,
+ dev->stats.rx_errors, dev->stats.tx_errors
+ );
+
+ /* ensure there are no more active requests */
+- if (dev->config) {
++ if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
+ usb_ep_disable (dev->in_ep);
+ usb_ep_disable (dev->out_ep);
+ if (netif_carrier_ok (dev->net)) {
+@@ -2166,60 +2223,39 @@
+ usb_ep_enable (dev->status_ep, dev->status);
+ }
+ }
+-
+- if (rndis_active(dev)) {
+- rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0);
+- (void) rndis_signal_disconnect (dev->rndis_config);
++
++#ifdef CONFIG_USB_ETH_RNDIS
++ if (dev->rndis) {
++ rndis_set_param_medium (dev->rndis_config,
++ NDIS_MEDIUM_802_3, 0);
++ rndis_send_media_state (dev, 0);
+ }
++#endif
+
+ return 0;
+ }
+
+ /*-------------------------------------------------------------------------*/
+
+-static struct usb_request *
+-eth_req_alloc (struct usb_ep *ep, unsigned size, gfp_t gfp_flags)
+-{
+- struct usb_request *req;
+-
+- req = usb_ep_alloc_request (ep, gfp_flags);
+- if (!req)
+- return NULL;
+-
+- req->buf = kmalloc (size, gfp_flags);
+- if (!req->buf) {
+- usb_ep_free_request (ep, req);
+- req = NULL;
+- }
+- return req;
+-}
+-
+ static void
+-eth_req_free (struct usb_ep *ep, struct usb_request *req)
+-{
+- kfree (req->buf);
+- usb_ep_free_request (ep, req);
+-}
+-
+-
+-static void /* __init_or_exit */
+ eth_unbind (struct usb_gadget *gadget)
+ {
+ struct eth_dev *dev = get_gadget_data (gadget);
+
+ DEBUG (dev, "unbind\n");
++#ifdef CONFIG_USB_ETH_RNDIS
+ rndis_deregister (dev->rndis_config);
+ rndis_exit ();
++#endif
+
+ /* we've already been disconnected ... no i/o is active */
+ if (dev->req) {
+- eth_req_free (gadget->ep0, dev->req);
++ usb_ep_free_buffer (gadget->ep0,
++ dev->req->buf, dev->req->dma,
++ USB_BUFSIZ);
++ usb_ep_free_request (gadget->ep0, dev->req);
+ dev->req = NULL;
+ }
+- if (dev->stat_req) {
+- eth_req_free (dev->status_ep, dev->stat_req);
+- dev->stat_req = NULL;
+- }
+
+ unregister_netdev (dev->net);
+ free_netdev(dev->net);
+@@ -2229,7 +2265,7 @@
+ set_gadget_data (gadget, NULL);
+ }
+
+-static u8 __devinit nibble (unsigned char c)
++static u8 __init nibble (unsigned char c)
+ {
+ if (likely (isdigit (c)))
+ return c - '0';
+@@ -2239,7 +2275,7 @@
+ return 0;
+ }
+
+-static int __devinit get_ether_addr(const char *str, u8 *dev_addr)
++static void __init get_ether_addr (const char *str, u8 *dev_addr)
+ {
+ if (str) {
+ unsigned i;
+@@ -2254,21 +2290,19 @@
+ dev_addr [i] = num;
+ }
+ if (is_valid_ether_addr (dev_addr))
+- return 0;
++ return;
+ }
+ random_ether_addr(dev_addr);
+- return 1;
+ }
+
+-static int __devinit
++static int __init
+ eth_bind (struct usb_gadget *gadget)
+ {
+ struct eth_dev *dev;
+ struct net_device *net;
+ u8 cdc = 1, zlp = 1, rndis = 1;
+- struct usb_ep *in_ep, *out_ep, *status_ep = NULL;
++ struct usb_ep *ep;
+ int status = -ENOMEM;
+- int gcnum;
+
+ /* these flags are only ever cleared; compiler take note */
+ #ifndef DEV_CONFIG_CDC
+@@ -2282,29 +2316,39 @@
+ * standard protocol is _strongly_ preferred for interop purposes.
+ * (By everyone except Microsoft.)
+ */
+- if (gadget_is_pxa (gadget)) {
++ if (gadget_is_net2280 (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
++ } else if (gadget_is_dummy (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0202);
++ } else if (gadget_is_pxa (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
+ /* pxa doesn't support altsettings */
+ cdc = 0;
+- } else if (gadget_is_musbhdrc(gadget)) {
+- /* reduce tx dma overhead by avoiding special cases */
+- zlp = 0;
+ } else if (gadget_is_sh(gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
+ /* sh doesn't support multiple interfaces or configs */
+ cdc = 0;
+ rndis = 0;
+ } else if (gadget_is_sa1100 (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
+ /* hardware can't write zlps */
+ zlp = 0;
+ /* sa1100 CAN do CDC, without status endpoint ... we use
+ * non-CDC to be compatible with ARM Linux-2.4 "usb-eth".
+ */
+ cdc = 0;
+- }
+-
+- gcnum = usb_gadget_controller_number (gadget);
+- if (gcnum >= 0)
+- device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+- else {
++ } else if (gadget_is_goku (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
++ } else if (gadget_is_mq11xx (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
++ } else if (gadget_is_omap (gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
++ } else if (gadget_is_lh7a40x(gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
++ } else if (gadget_is_pxa27x(gadget)) {
++ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0110);
++ zlp = 0;
++ } else {
+ /* can't assume CDC works. don't want to default to
+ * anything less functional on CDC-capable hardware,
+ * so we fail in this case.
+@@ -2314,9 +2358,7 @@
+ gadget->name);
+ return -ENODEV;
+ }
+- snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
+- init_utsname()->sysname, init_utsname()->release,
+- gadget->name);
++ snprintf (manufacturer, sizeof manufacturer,UTS_SYSNAME UTS_RELEASE " " "/%s",gadget->name);
+
+ /* If there's an RNDIS configuration, that's what Windows wants to
+ * be using ... so use these product IDs here and in the "linux.inf"
+@@ -2333,10 +2375,10 @@
+ "RNDIS/%s", driver_desc);
+
+ /* CDC subset ... recognized by Linux since 2.4.10, but Windows
+- * drivers aren't widely available. (That may be improved by
+- * supporting one submode of the "SAFE" variant of MDLM.)
++ * drivers aren't widely available.
+ */
+ } else if (!cdc) {
++ device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+ device_desc.idVendor =
+ __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
+ device_desc.idProduct =
+@@ -2358,48 +2400,100 @@
+ strlcpy (manufacturer, iManufacturer, sizeof manufacturer);
+ if (iProduct)
+ strlcpy (product_desc, iProduct, sizeof product_desc);
+- if (iSerialNumber) {
+- device_desc.iSerialNumber = STRING_SERIALNUMBER,
+- strlcpy(serial_number, iSerialNumber, sizeof serial_number);
+- }
+
+ /* all we really need is bulk IN/OUT */
+ usb_ep_autoconfig_reset (gadget);
+- in_ep = usb_ep_autoconfig (gadget, &fs_source_desc);
+- if (!in_ep) {
++#ifdef CONFIG_USB_PXA27X
++#ifdef CONFIG_USB_ETH_RNDIS
++ ep = pxa27x_ep_config (gadget, &fs_source_desc,
++ DEV_RNDIS_CONFIG_VALUE,
++ (int)rndis_data_intf.bInterfaceNumber,
++ (int)rndis_data_intf.bAlternateSetting);
++#elif defined(DEV_CONFIG_CDC)
++ ep = pxa27x_ep_config (gadget, &fs_source_desc,
++ DEV_CONFIG_VALUE,
++ (int)data_intf.bInterfaceNumber,
++ (int)data_intf.bAlternateSetting);
++#elif defined(DEV_CONFIG_SUBSET)
++ ep = pxa27x_ep_config (gadget, &fs_source_desc,
++ DEV_CONFIG_VALUE,
++ (int)subset_data_intf.bInterfaceNumber,
++ (int)subset_data_intf.bAlternateSetting);
++
++#endif //CONFIG_USB_ETH_RNDIS
++#else
++ ep = usb_ep_autoconfig (gadget, &fs_source_desc);
++#endif //CONFIG_USB_PXA27X
++ if (!ep) {
+ autoconf_fail:
+ dev_err (&gadget->dev,
+ "can't autoconfigure on %s\n",
+ gadget->name);
+ return -ENODEV;
+ }
+- in_ep->driver_data = in_ep; /* claim */
+-
+- out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
+- if (!out_ep)
++ EP_IN_NAME = ep->name;
++ ep->driver_data = ep; /* claim */
++#ifdef CONFIG_USB_PXA27X
++#ifdef CONFIG_USB_ETH_RNDIS
++ ep = pxa27x_ep_config (gadget, &fs_sink_desc,
++ DEV_RNDIS_CONFIG_VALUE,
++ (int)rndis_data_intf.bInterfaceNumber,
++ (int)rndis_data_intf.bAlternateSetting);
++#elif defined(DEV_CONFIG_CDC)
++ ep = pxa27x_ep_config (gadget, &fs_sink_desc,
++ DEV_CONFIG_VALUE,
++ (int)data_intf.bInterfaceNumber,
++ (int)data_intf.bAlternateSetting);
++#elif defined(DEV_CONFIG_SUBSET)
++ ep = pxa27x_ep_config (gadget, &fs_sink_desc,
++ DEV_CONFIG_VALUE,
++ (int)subset_data_intf.bInterfaceNumber,
++ (int)subset_data_intf.bAlternateSetting);
++#endif //CONFIG_USB_ETH_RNDIS
++#else
++ ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
++#endif //CONFIG_USB_PXA27X
++ if (!ep)
+ goto autoconf_fail;
+- out_ep->driver_data = out_ep; /* claim */
++ EP_OUT_NAME = ep->name;
++ ep->driver_data = ep; /* claim */
+
+ #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+ /* CDC Ethernet control interface doesn't require a status endpoint.
+ * Since some hosts expect one, try to allocate one anyway.
+ */
+ if (cdc || rndis) {
+- status_ep = usb_ep_autoconfig (gadget, &fs_status_desc);
+- if (status_ep) {
+- status_ep->driver_data = status_ep; /* claim */
++#ifdef CONFIG_USB_PXA27X
++#ifdef CONFIG_USB_ETH_RNDIS
++ ep = pxa27x_ep_config (gadget, &fs_status_desc,
++ DEV_RNDIS_CONFIG_VALUE,
++ (int)rndis_control_intf.bInterfaceNumber,
++ (int)rndis_control_intf.bAlternateSetting);
++#elif defined(DEV_CONFIG_CDC)
++ ep = pxa27x_ep_config (gadget, &fs_status_desc,
++ DEV_CONFIG_VALUE,
++ (int)control_intf.bInterfaceNumber,
++ (int)control_intf.bAlternateSetting);
++
++#endif //CONFIG_USB_ETH_RNDIS
++#else
++ ep = usb_ep_autoconfig (gadget, &fs_status_desc);
++#endif //CONFIG_USB_PXA27X
++ if (ep) {
++ EP_STATUS_NAME = ep->name;
++ ep->driver_data = ep; /* claim */
+ } else if (rndis) {
+ dev_err (&gadget->dev,
+ "can't run RNDIS on %s\n",
+ gadget->name);
+ return -ENODEV;
+-#ifdef DEV_CONFIG_CDC
+- /* pxa25x only does CDC subset; often used with RNDIS */
+- } else if (cdc) {
++ }
++#ifndef CONFIG_USB_PXA27X
++ else if (cdc) {
+ control_intf.bNumEndpoints = 0;
+ /* FIXME remove endpoint from descriptor list */
+-#endif
+ }
++#endif //CONFIG_USB_PXA27X
+ }
+ #endif
+
+@@ -2407,88 +2501,75 @@
+ if (!cdc) {
+ eth_config.bNumInterfaces = 1;
+ eth_config.iConfiguration = STRING_SUBSET;
+-
+- /* use functions to set these up, in case we're built to work
+- * with multiple controllers and must override CDC Ethernet.
+- */
+ fs_subset_descriptors();
+ hs_subset_descriptors();
+ }
+
+- device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+- usb_gadget_set_selfpowered (gadget);
+-
+ /* For now RNDIS is always a second config */
+ if (rndis)
+ device_desc.bNumConfigurations = 2;
+
+- if (gadget_is_dualspeed(gadget)) {
+- if (rndis)
+- dev_qualifier.bNumConfigurations = 2;
+- else if (!cdc)
+- dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+-
+- /* assumes ep0 uses the same value for both speeds ... */
+- dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
+-
+- /* and that all endpoints are dual-speed */
+- hs_source_desc.bEndpointAddress =
+- fs_source_desc.bEndpointAddress;
+- hs_sink_desc.bEndpointAddress =
+- fs_sink_desc.bEndpointAddress;
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ if (rndis)
++ dev_qualifier.bNumConfigurations = 2;
++ else if (!cdc)
++ dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC;
++
++ /* assumes ep0 uses the same value for both speeds ... */
++ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
++
++ /* and that all endpoints are dual-speed */
++ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
++ hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
+ #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+- if (status_ep)
+- hs_status_desc.bEndpointAddress =
+- fs_status_desc.bEndpointAddress;
++ if (EP_STATUS_NAME)
++ hs_status_desc.bEndpointAddress =
++ fs_status_desc.bEndpointAddress;
+ #endif
+- }
++#endif /* DUALSPEED */
+
+- if (gadget_is_otg(gadget)) {
++ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
++ usb_gadget_set_selfpowered (gadget);
++
++ if (gadget->is_otg) {
+ otg_descriptor.bmAttributes |= USB_OTG_HNP,
+ eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+- eth_config.bMaxPower = 4;
+ #ifdef CONFIG_USB_ETH_RNDIS
+ rndis_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+- rndis_config.bMaxPower = 4;
+ #endif
+ }
+
+- net = alloc_etherdev (sizeof *dev);
+- if (!net)
++ net = alloc_etherdev (sizeof *dev);
++ if (!net)
+ return status;
+- dev = netdev_priv(net);
++ dev = net->priv;
+ spin_lock_init (&dev->lock);
+- spin_lock_init (&dev->req_lock);
++ //INIT_WORK (&dev->work, eth_work, dev);
+ INIT_WORK (&dev->work, eth_work);
+ INIT_LIST_HEAD (&dev->tx_reqs);
+ INIT_LIST_HEAD (&dev->rx_reqs);
+
+ /* network device setup */
+ dev->net = net;
++ //SET_MODULE_OWNER (net);
+ strcpy (net->name, "usb%d");
+ dev->cdc = cdc;
+ dev->zlp = zlp;
+
+- dev->in_ep = in_ep;
+- dev->out_ep = out_ep;
+- dev->status_ep = status_ep;
+-
+ /* Module params for these addresses should come from ID proms.
+ * The host side address is used with CDC and RNDIS, and commonly
+- * ends up in a persistent config database. It's not clear if
+- * host side code for the SAFE thing cares -- its original BLAN
+- * thing didn't, Sharp never assigned those addresses on Zaurii.
+- */
+- if (get_ether_addr(dev_addr, net->dev_addr))
+- dev_warn(&gadget->dev,
+- "using random %s ethernet address\n", "self");
+- if (get_ether_addr(host_addr, dev->host_mac))
+- dev_warn(&gadget->dev,
+- "using random %s ethernet address\n", "host");
+- snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
+- dev->host_mac [0], dev->host_mac [1],
+- dev->host_mac [2], dev->host_mac [3],
+- dev->host_mac [4], dev->host_mac [5]);
++ * ends up in a persistent config database.
++ */
++ get_ether_addr(dev_addr, net->dev_addr);
++ if (cdc || rndis) {
++ get_ether_addr(host_addr, dev->host_mac);
++#ifdef DEV_CONFIG_CDC
++ snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
++ dev->host_mac [0], dev->host_mac [1],
++ dev->host_mac [2], dev->host_mac [3],
++ dev->host_mac [4], dev->host_mac [5]);
++#endif
++ }
+
+ if (rndis) {
+ status = rndis_init();
+@@ -2506,32 +2587,25 @@
+ net->stop = eth_stop;
+ // watchdog_timeo, tx_timeout ...
+ // set_multicast_list
+- SET_ETHTOOL_OPS(net, &ops);
++ net->do_ioctl = eth_ioctl;
+
+- /* preallocate control message data and buffer */
+- dev->req = eth_req_alloc (gadget->ep0, USB_BUFSIZ, GFP_KERNEL);
++ /* preallocate control response and buffer */
++ dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
+ if (!dev->req)
+ goto fail;
+ dev->req->complete = eth_setup_complete;
+-
+- /* ... and maybe likewise for status transfer */
+-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+- if (dev->status_ep) {
+- dev->stat_req = eth_req_alloc (dev->status_ep,
+- STATUS_BYTECOUNT, GFP_KERNEL);
+- if (!dev->stat_req) {
+- eth_req_free (gadget->ep0, dev->req);
+- goto fail;
+- }
+- dev->stat_req->context = NULL;
++ dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
++ &dev->req->dma, GFP_KERNEL);
++ if (!dev->req->buf) {
++ usb_ep_free_request (gadget->ep0, dev->req);
++ goto fail;
+ }
+-#endif
+
+ /* finish hookup to lower layer ... */
+ dev->gadget = gadget;
+ set_gadget_data (gadget, dev);
+ gadget->ep0->driver_data = dev;
+-
++
+ /* two kinds of host-initiated state changes:
+ * - iff DATA transfer is active, carrier is "on"
+ * - tx queueing enabled if open *and* carrier is "on"
+@@ -2539,16 +2613,16 @@
+ netif_stop_queue (dev->net);
+ netif_carrier_off (dev->net);
+
+- SET_NETDEV_DEV (dev->net, &gadget->dev);
+- status = register_netdev (dev->net);
++ // SET_NETDEV_DEV (dev->net, &gadget->dev);
++ status = register_netdev (dev->net);
+ if (status < 0)
+ goto fail1;
+
+ INFO (dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
+ INFO (dev, "using %s, OUT %s IN %s%s%s\n", gadget->name,
+- out_ep->name, in_ep->name,
+- status_ep ? " STATUS " : "",
+- status_ep ? status_ep->name : ""
++ EP_OUT_NAME, EP_IN_NAME,
++ EP_STATUS_NAME ? " STATUS " : "",
++ EP_STATUS_NAME ? EP_STATUS_NAME : ""
+ );
+ INFO (dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ net->dev_addr [0], net->dev_addr [1],
+@@ -2561,11 +2635,12 @@
+ dev->host_mac [2], dev->host_mac [3],
+ dev->host_mac [4], dev->host_mac [5]);
+
++#ifdef CONFIG_USB_ETH_RNDIS
+ if (rndis) {
+ u32 vendorID = 0;
+
+ /* FIXME RNDIS vendor id == "vendor NIC code" == ? */
+-
++
+ dev->rndis_config = rndis_register (rndis_control_ack);
+ if (dev->rndis_config < 0) {
+ fail0:
+@@ -2573,20 +2648,22 @@
+ status = -ENODEV;
+ goto fail;
+ }
+-
++
+ /* these set up a lot of the OIDs that RNDIS needs */
+ rndis_set_host_mac (dev->rndis_config, dev->host_mac);
+ if (rndis_set_param_dev (dev->rndis_config, dev->net,
+- &dev->stats, &dev->cdc_filter))
++ &dev->stats))
+ goto fail0;
+- if (rndis_set_param_vendor(dev->rndis_config, vendorID,
+- manufacturer))
++ if (rndis_set_param_vendor (dev->rndis_config, vendorID,
++ manufacturer))
+ goto fail0;
+- if (rndis_set_param_medium(dev->rndis_config,
+- NDIS_MEDIUM_802_3, 0))
++ if (rndis_set_param_medium (dev->rndis_config,
++ NDIS_MEDIUM_802_3,
++ 0))
+ goto fail0;
+ INFO (dev, "RNDIS ready\n");
+ }
++#endif
+
+ return status;
+
+@@ -2620,8 +2697,11 @@
+ /*-------------------------------------------------------------------------*/
+
+ static struct usb_gadget_driver eth_driver = {
+- .speed = DEVSPEED,
+-
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ .speed = USB_SPEED_HIGH,
++#else
++ .speed = USB_SPEED_FULL,
++#endif
+ .function = (char *) driver_desc,
+ .bind = eth_bind,
+ .unbind = eth_unbind,
+@@ -2632,9 +2712,11 @@
+ .suspend = eth_suspend,
+ .resume = eth_resume,
+
+- .driver = {
++ .driver = {
+ .name = (char *) shortname,
+- .owner = THIS_MODULE,
++ // .shutdown = ...
++ // .suspend = ...
++ // .resume = ...
+ },
+ };
+
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/file_storage.c linux-2.6.25/drivers/usb/gadget/file_storage.c
+--- linux-2.6.25_original/drivers/usb/gadget/file_storage.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/file_storage.c 2009-06-23 11:46:22.000000000 +0530
+@@ -1,7 +1,7 @@
+ /*
+ * file_storage.c -- File-backed USB Storage Gadget, for USB development
+ *
+- * Copyright (C) 2003-2007 Alan Stern
++ * Copyright (C) 2003, 2004 Alan Stern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+@@ -71,12 +71,6 @@
+ * requirement amounts to two 16K buffers, size configurable by a parameter.
+ * Support is included for both full-speed and high-speed operation.
+ *
+- * Note that the driver is slightly non-portable in that it assumes a
+- * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
+- * interrupt-in endpoints. With most device controllers this isn't an
+- * issue, but there may be some with hardware restrictions that prevent
+- * a buffer from being used by more than one endpoint.
+- *
+ * Module options:
+ *
+ * file=filename[,filename...]
+@@ -87,10 +81,6 @@
+ * removable Default false, boolean for removable media
+ * luns=N Default N = number of filenames, number of
+ * LUNs to support
+- * stall Default determined according to the type of
+- * USB device controller (usually true),
+- * boolean to permit the driver to halt
+- * bulk endpoints
+ * transport=XXX Default BBB, transport name (CB, CBI, or BBB)
+ * protocol=YYY Default SCSI, protocol name (RBC, 8020 or
+ * ATAPI, QIC, UFI, 8070, or SCSI;
+@@ -101,10 +91,14 @@
+ * buflen=N Default N=16384, buffer size used (will be
+ * rounded down to a multiple of
+ * PAGE_CACHE_SIZE)
++ * stall Default determined according to the type of
++ * USB device controller (usually true),
++ * boolean to permit the driver to halt
++ * bulk endpoints
+ *
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
+- * "removable", "luns", and "stall" options are available; default values
+- * are used for everything else.
++ * "removable", and "luns" options are available; default values are used
++ * for everything else.
+ *
+ * The pathnames of the backing files and the ro settings are available in
+ * the attribute files "file" and "ro" in the lun<n> subdirectory of the
+@@ -114,14 +108,6 @@
+ * setting are not allowed when the medium is loaded.
+ *
+ * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
+- * The driver's SCSI command interface was based on the "Information
+- * technology - Small Computer System Interface - 2" document from
+- * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at
+- * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception
+- * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the
+- * "Universal Serial Bus Mass Storage Class UFI Command Specification"
+- * document, Revision 1.0, December 14, 1998, available at
+- * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
+ */
+
+
+@@ -217,30 +203,67 @@
+ */
+
+
+-/* #define VERBOSE_DEBUG */
+-/* #define DUMP_MSGS */
++//#undef DEBUG
++//#undef VERBOSE
++//#undef DUMP_MSGS
++
++#define DEBUG
++#define VERBOSE
++#define DUMP_MSGS
++
++#include <linux/config.h>
++
++#include <asm/system.h>
++#include <asm/uaccess.h>
++
++#include <linux/bitops.h>
++#include <linux/blkdev.h>
++#include <linux/compiler.h>
++#include <linux/completion.h>
++#include <linux/dcache.h>
++#include <linux/device.h>
++#include <linux/fcntl.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/limits.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/config.h>
+
++#include <asm/system.h>
++#include <asm/uaccess.h>
+
++#include <linux/bitops.h>
+ #include <linux/blkdev.h>
++#include <linux/compiler.h>
+ #include <linux/completion.h>
+ #include <linux/dcache.h>
+-#include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/fcntl.h>
+ #include <linux/file.h>
+ #include <linux/fs.h>
+-#include <linux/kref.h>
+-#include <linux/kthread.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
+ #include <linux/limits.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pagemap.h>
+ #include <linux/rwsem.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
+ #include <linux/string.h>
+-#include <linux/freezer.h>
+-#include <linux/utsname.h>
++#include <linux/uts.h>
++#include <linux/version.h>
++#include <linux/wait.h>
+
+-#include <linux/usb/ch9.h>
+-#include <linux/usb/gadget.h>
++#include <linux/usb_ch9.h>
++#include <linux/usb_gadget.h>
+
+ #include "gadget_chips.h"
+
+@@ -249,7 +272,7 @@
+
+ #define DRIVER_DESC "File-backed Storage Gadget"
+ #define DRIVER_NAME "g_file_storage"
+-#define DRIVER_VERSION "7 August 2007"
++#define DRIVER_VERSION "28 July 2004"
+
+ static const char longname[] = DRIVER_DESC;
+ static const char shortname[] = DRIVER_NAME;
+@@ -275,43 +298,56 @@
+
+ /*-------------------------------------------------------------------------*/
+
++#define xprintk(f,level,fmt,args...) \
++ dev_printk(level , &(f)->gadget->dev , fmt , ## args)
++#define yprintk(l,level,fmt,args...) \
++ dev_printk(level , &(l)->dev , fmt , ## args)
++
++#ifdef DEBUG
++#define DBG(fsg,fmt,args...) \
++ xprintk(fsg , KERN_DEBUG , fmt , ## args)
+ #define LDBG(lun,fmt,args...) \
+- dev_dbg(&(lun)->dev , fmt , ## args)
++ yprintk(lun , KERN_DEBUG , fmt , ## args)
+ #define MDBG(fmt,args...) \
+- pr_debug(DRIVER_NAME ": " fmt , ## args)
+-
+-#ifndef DEBUG
+-#undef VERBOSE_DEBUG
++ printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args)
++#else
++#define DBG(fsg,fmt,args...) \
++ do { } while (0)
++#define LDBG(lun,fmt,args...) \
++ do { } while (0)
++#define MDBG(fmt,args...) \
++ do { } while (0)
++#undef VERBOSE
+ #undef DUMP_MSGS
+-#endif /* !DEBUG */
++#endif /* DEBUG */
+
+-#ifdef VERBOSE_DEBUG
++#ifdef VERBOSE
++#define VDBG DBG
+ #define VLDBG LDBG
+ #else
++#define VDBG(fsg,fmt,args...) \
++ do { } while (0)
+ #define VLDBG(lun,fmt,args...) \
+ do { } while (0)
+-#endif /* VERBOSE_DEBUG */
++#endif /* VERBOSE */
+
++#define ERROR(fsg,fmt,args...) \
++ xprintk(fsg , KERN_ERR , fmt , ## args)
+ #define LERROR(lun,fmt,args...) \
+- dev_err(&(lun)->dev , fmt , ## args)
++ yprintk(lun , KERN_ERR , fmt , ## args)
++
++#define WARN(fsg,fmt,args...) \
++ xprintk(fsg , KERN_WARNING , fmt , ## args)
+ #define LWARN(lun,fmt,args...) \
+- dev_warn(&(lun)->dev , fmt , ## args)
++ yprintk(lun , KERN_WARNING , fmt , ## args)
++
++#define INFO(fsg,fmt,args...) \
++ xprintk(fsg , KERN_INFO , fmt , ## args)
+ #define LINFO(lun,fmt,args...) \
+- dev_info(&(lun)->dev , fmt , ## args)
++ yprintk(lun , KERN_INFO , fmt , ## args)
+
+ #define MINFO(fmt,args...) \
+- pr_info(DRIVER_NAME ": " fmt , ## args)
+-
+-#define DBG(d, fmt, args...) \
+- dev_dbg(&(d)->gadget->dev , fmt , ## args)
+-#define VDBG(d, fmt, args...) \
+- dev_vdbg(&(d)->gadget->dev , fmt , ## args)
+-#define ERROR(d, fmt, args...) \
+- dev_err(&(d)->gadget->dev , fmt , ## args)
+-#define WARN(d, fmt, args...) \
+- dev_warn(&(d)->gadget->dev , fmt , ## args)
+-#define INFO(d, fmt, args...) \
+- dev_info(&(d)->gadget->dev , fmt , ## args)
++ printk(KERN_INFO DRIVER_NAME ": " fmt , ## args)
+
+
+ /*-------------------------------------------------------------------------*/
+@@ -320,22 +356,23 @@
+
+ #define MAX_LUNS 8
+
++ /* Arggh! There should be a module_param_array_named macro! */
++static char *file[MAX_LUNS] = {NULL, };
++static int ro[MAX_LUNS] = {0, };
++
+ static struct {
+- char *file[MAX_LUNS];
+- int ro[MAX_LUNS];
+- unsigned int num_filenames;
+- unsigned int num_ros;
++ int num_filenames;
++ int num_ros;
+ unsigned int nluns;
+
+- int removable;
+- int can_stall;
+-
+ char *transport_parm;
+ char *protocol_parm;
++ int removable;
+ unsigned short vendor;
+ unsigned short product;
+ unsigned short release;
+ unsigned int buflen;
++ int can_stall;
+
+ int transport_type;
+ char *transport_name;
+@@ -346,19 +383,18 @@
+ .transport_parm = "BBB",
+ .protocol_parm = "SCSI",
+ .removable = 0,
+- .can_stall = 1,
+ .vendor = DRIVER_VENDOR_ID,
+ .product = DRIVER_PRODUCT_ID,
+ .release = 0xffff, // Use controller chip type
+ .buflen = 16384,
++ .can_stall = 1,
+ };
+
+
+-module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
+- S_IRUGO);
++module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO);
+ MODULE_PARM_DESC(file, "names of backing files or devices");
+
+-module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
++module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO);
+ MODULE_PARM_DESC(ro, "true to force read-only");
+
+ module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
+@@ -367,9 +403,6 @@
+ module_param_named(removable, mod_data.removable, bool, S_IRUGO);
+ MODULE_PARM_DESC(removable, "true to simulate removable media");
+
+-module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
+-MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
+-
+
+ /* In the non-TEST version, only the module parameters listed above
+ * are available. */
+@@ -394,6 +427,9 @@
+ module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
+ MODULE_PARM_DESC(buflen, "I/O buffer size");
+
++module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
++MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
++
+ #endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
+
+@@ -416,9 +452,9 @@
+
+ /* Command Block Wrapper */
+ struct bulk_cb_wrap {
+- __le32 Signature; // Contains 'USBC'
++ u32 Signature; // Contains 'USBC'
+ u32 Tag; // Unique per command id
+- __le32 DataTransferLength; // Size of the data
++ u32 DataTransferLength; // Size of the data
+ u8 Flags; // Direction in bit 7
+ u8 Lun; // LUN (normally 0)
+ u8 Length; // Of the CDB, <= MAX_COMMAND_SIZE
+@@ -431,9 +467,9 @@
+
+ /* Command Status Wrapper */
+ struct bulk_cs_wrap {
+- __le32 Signature; // Should = 'USBS'
++ u32 Signature; // Should = 'USBS'
+ u32 Tag; // Same as original command
+- __le32 Residue; // Amount not transferred
++ u32 Residue; // Amount not transferred
+ u8 Status; // See below
+ };
+
+@@ -540,7 +576,6 @@
+ unsigned int ro : 1;
+ unsigned int prevent_medium_removal : 1;
+ unsigned int registered : 1;
+- unsigned int info_valid : 1;
+
+ u32 sense_data;
+ u32 sense_data_info;
+@@ -551,7 +586,7 @@
+
+ #define backing_file_is_open(curlun) ((curlun)->filp != NULL)
+
+-static struct lun *dev_to_lun(struct device *dev)
++static inline struct lun *dev_to_lun(struct device *dev)
+ {
+ return container_of(dev, struct lun, dev);
+ }
+@@ -572,7 +607,8 @@
+
+ struct fsg_buffhd {
+ void *buf;
+- enum fsg_buffer_state state;
++ dma_addr_t dma;
++ volatile enum fsg_buffer_state state;
+ struct fsg_buffhd *next;
+
+ /* The NetChip 2280 is faster, and handles some protocol faults
+@@ -581,9 +617,9 @@
+ unsigned int bulk_out_intended_length;
+
+ struct usb_request *inreq;
+- int inreq_busy;
++ volatile int inreq_busy;
+ struct usb_request *outreq;
+- int outreq_busy;
++ volatile int outreq_busy;
+ };
+
+ enum fsg_state {
+@@ -616,16 +652,13 @@
+ /* filesem protects: backing files in use */
+ struct rw_semaphore filesem;
+
+- /* reference counting: wait until all LUNs are released */
+- struct kref ref;
+-
+ struct usb_ep *ep0; // Handy copy of gadget->ep0
+ struct usb_request *ep0req; // For control responses
+- unsigned int ep0_req_tag;
++ volatile unsigned int ep0_req_tag;
+ const char *ep0req_name;
+
+ struct usb_request *intreq; // For interrupt responses
+- int intreq_busy;
++ volatile int intreq_busy;
+ struct fsg_buffhd *intr_buffhd;
+
+ unsigned int bulk_out_maxpacket;
+@@ -655,9 +688,12 @@
+ struct fsg_buffhd *next_buffhd_to_drain;
+ struct fsg_buffhd buffhds[NUM_BUFFERS];
+
++ wait_queue_head_t thread_wqh;
+ int thread_wakeup_needed;
+ struct completion thread_notifier;
++ int thread_pid;
+ struct task_struct *thread_task;
++ sigset_t thread_signal_mask;
+
+ int cmnd_size;
+ u8 cmnd[MAX_COMMAND_SIZE];
+@@ -680,17 +716,18 @@
+ unsigned int nluns;
+ struct lun *luns;
+ struct lun *curlun;
++ struct completion lun_released;
+ };
+
+ typedef void (*fsg_routine_t)(struct fsg_dev *);
+
+-static int exception_in_progress(struct fsg_dev *fsg)
++static int inline exception_in_progress(struct fsg_dev *fsg)
+ {
+ return (fsg->state > FSG_STATE_IDLE);
+ }
+
+ /* Make bulk-out requests be divisible by the maxpacket size */
+-static void set_bulk_out_req_length(struct fsg_dev *fsg,
++static void inline set_bulk_out_req_length(struct fsg_dev *fsg,
+ struct fsg_buffhd *bh, unsigned int length)
+ {
+ unsigned int rem;
+@@ -716,36 +753,50 @@
+ static void dump_msg(struct fsg_dev *fsg, const char *label,
+ const u8 *buf, unsigned int length)
+ {
+- if (length < 512) {
+- DBG(fsg, "%s, length %u:\n", label, length);
+- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
+- 16, 1, buf, length, 0);
++ unsigned int start, num, i;
++ char line[52], *p;
++
++ if (length >= 512)
++ return;
++ DBG(fsg, "%s, length %u:\n", label, length);
++
++ start = 0;
++ while (length > 0) {
++ num = min(length, 16u);
++ p = line;
++ for (i = 0; i < num; ++i) {
++ if (i == 8)
++ *p++ = ' ';
++ sprintf(p, " %02x", buf[i]);
++ p += 3;
++ }
++ *p = 0;
++ printk(KERN_DEBUG "%6x: %s\n", start, line);
++ buf += num;
++ start += num;
++ length -= num;
+ }
+ }
+
+-static void dump_cdb(struct fsg_dev *fsg)
++static void inline dump_cdb(struct fsg_dev *fsg)
+ {}
+
+ #else
+
+-static void dump_msg(struct fsg_dev *fsg, const char *label,
++static void inline dump_msg(struct fsg_dev *fsg, const char *label,
+ const u8 *buf, unsigned int length)
+ {}
+
+-#ifdef VERBOSE_DEBUG
+-
+-static void dump_cdb(struct fsg_dev *fsg)
++static void inline dump_cdb(struct fsg_dev *fsg)
+ {
+- print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,
+- 16, 1, fsg->cmnd, fsg->cmnd_size, 0);
+-}
+-
+-#else
++ int i;
++ char cmdbuf[3*MAX_COMMAND_SIZE + 1];
+
+-static void dump_cdb(struct fsg_dev *fsg)
+-{}
++ for (i = 0; i < fsg->cmnd_size; ++i)
++ sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]);
++ VDBG(fsg, "SCSI CDB: %s\n", cmdbuf);
++}
+
+-#endif /* VERBOSE_DEBUG */
+ #endif /* DUMP_MSGS */
+
+
+@@ -768,29 +819,29 @@
+
+ /* Routines for unaligned data access */
+
+-static u16 get_be16(u8 *buf)
++static u16 inline get_be16(u8 *buf)
+ {
+ return ((u16) buf[0] << 8) | ((u16) buf[1]);
+ }
+
+-static u32 get_be32(u8 *buf)
++static u32 inline get_be32(u8 *buf)
+ {
+ return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) |
+ ((u32) buf[2] << 8) | ((u32) buf[3]);
+ }
+
+-static void put_be16(u8 *buf, u16 val)
++static void inline put_be16(u8 *buf, u16 val)
+ {
+ buf[0] = val >> 8;
+ buf[1] = val;
+ }
+
+-static void put_be32(u8 *buf, u32 val)
++static void inline put_be32(u8 *buf, u32 val)
+ {
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+- buf[3] = val & 0xff;
++ buf[3] = val;
+ }
+
+
+@@ -804,8 +855,6 @@
+ #define STRING_MANUFACTURER 1
+ #define STRING_PRODUCT 2
+ #define STRING_SERIAL 3
+-#define STRING_CONFIG 4
+-#define STRING_INTERFACE 5
+
+ /* There is only one configuration. */
+ #define CONFIG_VALUE 1
+@@ -837,19 +886,10 @@
+ /* wTotalLength computed by usb_gadget_config_buf() */
+ .bNumInterfaces = 1,
+ .bConfigurationValue = CONFIG_VALUE,
+- .iConfiguration = STRING_CONFIG,
+ .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+ .bMaxPower = 1, // self-powered
+ };
+
+-static struct usb_otg_descriptor
+-otg_desc = {
+- .bLength = sizeof(otg_desc),
+- .bDescriptorType = USB_DT_OTG,
+-
+- .bmAttributes = USB_OTG_SRP,
+-};
+-
+ /* There is only one interface. */
+
+ static struct usb_interface_descriptor
+@@ -861,7 +901,6 @@
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE,
+ .bInterfaceSubClass = USB_SC_SCSI, // Adjusted during fsg_bind()
+ .bInterfaceProtocol = USB_PR_BULK, // Adjusted during fsg_bind()
+- .iInterface = STRING_INTERFACE,
+ };
+
+ /* Three full-speed endpoint descriptors: bulk-in, bulk-out,
+@@ -899,16 +938,16 @@
+ };
+
+ static const struct usb_descriptor_header *fs_function[] = {
+- (struct usb_descriptor_header *) &otg_desc,
+ (struct usb_descriptor_header *) &intf_desc,
+ (struct usb_descriptor_header *) &fs_bulk_in_desc,
+ (struct usb_descriptor_header *) &fs_bulk_out_desc,
+ (struct usb_descriptor_header *) &fs_intr_in_desc,
+ NULL,
+ };
+-#define FS_FUNCTION_PRE_EP_ENTRIES 2
+
+
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++
+ /*
+ * USB 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+@@ -961,29 +1000,27 @@
+ };
+
+ static const struct usb_descriptor_header *hs_function[] = {
+- (struct usb_descriptor_header *) &otg_desc,
+ (struct usb_descriptor_header *) &intf_desc,
+ (struct usb_descriptor_header *) &hs_bulk_in_desc,
+ (struct usb_descriptor_header *) &hs_bulk_out_desc,
+ (struct usb_descriptor_header *) &hs_intr_in_desc,
+ NULL,
+ };
+-#define HS_FUNCTION_PRE_EP_ENTRIES 2
+
+ /* Maxpacket and other transfer characteristics vary by speed. */
+-static struct usb_endpoint_descriptor *
+-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
+- struct usb_endpoint_descriptor *hs)
+-{
+- if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+- return hs;
+- return fs;
+-}
++#define ep_desc(g,fs,hs) (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs))
++
++#else
++
++/* If there's no high speed support, always use the full-speed descriptor. */
++#define ep_desc(g,fs,hs) fs
++
++#endif /* !CONFIG_USB_GADGET_DUALSPEED */
+
+
+ /* The CBI specification limits the serial string to 12 uppercase hexadecimal
+ * characters. */
+-static char manufacturer[64];
++static char manufacturer[40];
+ static char serial[13];
+
+ /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+@@ -991,8 +1028,6 @@
+ {STRING_MANUFACTURER, manufacturer},
+ {STRING_PRODUCT, longname},
+ {STRING_SERIAL, serial},
+- {STRING_CONFIG, "Self-powered"},
+- {STRING_INTERFACE, "Mass Storage"},
+ {}
+ };
+
+@@ -1007,27 +1042,24 @@
+ * and with code managing interfaces and their altsettings. They must
+ * also handle different speeds and other-speed requests.
+ */
+-static int populate_config_buf(struct usb_gadget *gadget,
++static int populate_config_buf(enum usb_device_speed speed,
+ u8 *buf, u8 type, unsigned index)
+ {
+- enum usb_device_speed speed = gadget->speed;
+ int len;
+ const struct usb_descriptor_header **function;
+
+ if (index > 0)
+ return -EINVAL;
+
+- if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ if (type == USB_DT_OTHER_SPEED_CONFIG)
+ speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
+- if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH)
++ if (speed == USB_SPEED_HIGH)
+ function = hs_function;
+ else
++#endif
+ function = fs_function;
+
+- /* for now, don't advertise srp-only devices */
+- if (!gadget_is_otg(gadget))
+- function++;
+-
+ len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
+ ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
+ return len;
+@@ -1038,19 +1070,18 @@
+
+ /* These routines may be called in process context or in_irq */
+
+-/* Caller must hold fsg->lock */
+ static void wakeup_thread(struct fsg_dev *fsg)
+ {
+ /* Tell the main thread that something has happened */
+ fsg->thread_wakeup_needed = 1;
+- if (fsg->thread_task)
+- wake_up_process(fsg->thread_task);
++ wake_up_all(&fsg->thread_wqh);
+ }
+
+
+ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
+ {
+ unsigned long flags;
++ struct task_struct *thread_task;
+
+ /* Do nothing if a higher-priority exception is already in progress.
+ * If a lower-or-equal priority exception is in progress, preempt it
+@@ -1059,9 +1090,9 @@
+ if (fsg->state <= new_state) {
+ fsg->exception_req_tag = fsg->ep0_req_tag;
+ fsg->state = new_state;
+- if (fsg->thread_task)
+- send_sig_info(SIGUSR1, SEND_SIG_FORCED,
+- fsg->thread_task);
++ thread_task = fsg->thread_task;
++ if (thread_task)
++ send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
+ }
+ spin_unlock_irqrestore(&fsg->lock, flags);
+ }
+@@ -1099,7 +1130,7 @@
+
+ static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+- struct fsg_dev *fsg = ep->driver_data;
++ struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data;
+
+ if (req->actual > 0)
+ dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
+@@ -1121,8 +1152,8 @@
+
+ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+- struct fsg_dev *fsg = ep->driver_data;
+- struct fsg_buffhd *bh = req->context;
++ struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data;
++ struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context;
+
+ if (req->status || req->actual != req->length)
+ DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+@@ -1131,18 +1162,17 @@
+ usb_ep_fifo_flush(ep);
+
+ /* Hold the lock while we update the request and buffer states */
+- smp_wmb();
+ spin_lock(&fsg->lock);
+ bh->inreq_busy = 0;
+ bh->state = BUF_STATE_EMPTY;
+- wakeup_thread(fsg);
+ spin_unlock(&fsg->lock);
++ wakeup_thread(fsg);
+ }
+
+ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+- struct fsg_dev *fsg = ep->driver_data;
+- struct fsg_buffhd *bh = req->context;
++ struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data;
++ struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context;
+
+ dump_msg(fsg, "bulk-out", req->buf, req->actual);
+ if (req->status || req->actual != bh->bulk_out_intended_length)
+@@ -1153,20 +1183,19 @@
+ usb_ep_fifo_flush(ep);
+
+ /* Hold the lock while we update the request and buffer states */
+- smp_wmb();
+ spin_lock(&fsg->lock);
+ bh->outreq_busy = 0;
+ bh->state = BUF_STATE_FULL;
+- wakeup_thread(fsg);
+ spin_unlock(&fsg->lock);
++ wakeup_thread(fsg);
+ }
+
+
+ #ifdef CONFIG_USB_FILE_STORAGE_TEST
+ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+- struct fsg_dev *fsg = ep->driver_data;
+- struct fsg_buffhd *bh = req->context;
++ struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data;
++ struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context;
+
+ if (req->status || req->actual != req->length)
+ DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+@@ -1175,12 +1204,11 @@
+ usb_ep_fifo_flush(ep);
+
+ /* Hold the lock while we update the request and buffer states */
+- smp_wmb();
+ spin_lock(&fsg->lock);
+ fsg->intreq_busy = 0;
+ bh->state = BUF_STATE_EMPTY;
+- wakeup_thread(fsg);
+ spin_unlock(&fsg->lock);
++ wakeup_thread(fsg);
+ }
+
+ #else
+@@ -1231,8 +1259,8 @@
+ fsg->cbbuf_cmnd_size = req->actual;
+ memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
+
+- wakeup_thread(fsg);
+ spin_unlock(&fsg->lock);
++ wakeup_thread(fsg);
+ }
+
+ #else
+@@ -1246,9 +1274,6 @@
+ {
+ struct usb_request *req = fsg->ep0req;
+ int value = -EOPNOTSUPP;
+- u16 w_index = le16_to_cpu(ctrl->wIndex);
+- u16 w_value = le16_to_cpu(ctrl->wValue);
+- u16 w_length = le16_to_cpu(ctrl->wLength);
+
+ if (!fsg->config)
+ return value;
+@@ -1261,7 +1286,7 @@
+ if (ctrl->bRequestType != (USB_DIR_OUT |
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+ break;
+- if (w_index != 0 || w_value != 0) {
++ if (ctrl->wIndex != 0) {
+ value = -EDOM;
+ break;
+ }
+@@ -1277,13 +1302,13 @@
+ if (ctrl->bRequestType != (USB_DIR_IN |
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+ break;
+- if (w_index != 0 || w_value != 0) {
++ if (ctrl->wIndex != 0) {
+ value = -EDOM;
+ break;
+ }
+ VDBG(fsg, "get max LUN\n");
+ *(u8 *) req->buf = fsg->nluns - 1;
+- value = 1;
++ value = min(ctrl->wLength, (u16) 1);
+ break;
+ }
+ }
+@@ -1296,15 +1321,15 @@
+ if (ctrl->bRequestType != (USB_DIR_OUT |
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+ break;
+- if (w_index != 0 || w_value != 0) {
++ if (ctrl->wIndex != 0) {
+ value = -EDOM;
+ break;
+ }
+- if (w_length > MAX_COMMAND_SIZE) {
++ if (ctrl->wLength > MAX_COMMAND_SIZE) {
+ value = -EOVERFLOW;
+ break;
+ }
+- value = w_length;
++ value = ctrl->wLength;
+ fsg->ep0req->context = received_cbi_adsc;
+ break;
+ }
+@@ -1315,7 +1340,7 @@
+ "unknown class-specific control req "
+ "%02x.%02x v%04x i%04x l%u\n",
+ ctrl->bRequestType, ctrl->bRequest,
+- le16_to_cpu(ctrl->wValue), w_index, w_length);
++ ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+ return value;
+ }
+
+@@ -1329,8 +1354,6 @@
+ {
+ struct usb_request *req = fsg->ep0req;
+ int value = -EOPNOTSUPP;
+- u16 w_index = le16_to_cpu(ctrl->wIndex);
+- u16 w_value = le16_to_cpu(ctrl->wValue);
+
+ /* Usually this just stores reply data in the pre-allocated ep0 buffer,
+ * but config change events will also reconfigure hardware. */
+@@ -1340,33 +1363,39 @@
+ if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
+ USB_RECIP_DEVICE))
+ break;
+- switch (w_value >> 8) {
++ switch (ctrl->wValue >> 8) {
+
+ case USB_DT_DEVICE:
+ VDBG(fsg, "get device descriptor\n");
+- value = sizeof device_desc;
++ value = min(ctrl->wLength, (u16) sizeof device_desc);
+ memcpy(req->buf, &device_desc, value);
+ break;
++#ifdef CONFIG_USB_GADGET_DUALSPEED
+ case USB_DT_DEVICE_QUALIFIER:
+ VDBG(fsg, "get device qualifier\n");
+- if (!gadget_is_dualspeed(fsg->gadget))
++ if (!fsg->gadget->is_dualspeed)
+ break;
+- value = sizeof dev_qualifier;
++ value = min(ctrl->wLength, (u16) sizeof dev_qualifier);
+ memcpy(req->buf, &dev_qualifier, value);
+ break;
+
+ case USB_DT_OTHER_SPEED_CONFIG:
+ VDBG(fsg, "get other-speed config descriptor\n");
+- if (!gadget_is_dualspeed(fsg->gadget))
++ if (!fsg->gadget->is_dualspeed)
+ break;
+ goto get_config;
++#endif
+ case USB_DT_CONFIG:
+ VDBG(fsg, "get configuration descriptor\n");
+-get_config:
+- value = populate_config_buf(fsg->gadget,
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ get_config:
++#endif
++ value = populate_config_buf(fsg->gadget->speed,
+ req->buf,
+- w_value >> 8,
+- w_value & 0xff);
++ ctrl->wValue >> 8,
++ ctrl->wValue & 0xff);
++ if (value >= 0)
++ value = min(ctrl->wLength, (u16) value);
+ break;
+
+ case USB_DT_STRING:
+@@ -1374,7 +1403,9 @@
+
+ /* wIndex == language code */
+ value = usb_gadget_get_string(&stringtab,
+- w_value & 0xff, req->buf);
++ ctrl->wValue & 0xff, req->buf);
++ if (value >= 0)
++ value = min(ctrl->wLength, (u16) value);
+ break;
+ }
+ break;
+@@ -1385,8 +1416,8 @@
+ USB_RECIP_DEVICE))
+ break;
+ VDBG(fsg, "set configuration\n");
+- if (w_value == CONFIG_VALUE || w_value == 0) {
+- fsg->new_config = w_value;
++ if (ctrl->wValue == CONFIG_VALUE || ctrl->wValue == 0) {
++ fsg->new_config = ctrl->wValue;
+
+ /* Raise an exception to wipe out previous transaction
+ * state (queued bufs, etc) and set the new config. */
+@@ -1400,14 +1431,14 @@
+ break;
+ VDBG(fsg, "get configuration\n");
+ *(u8 *) req->buf = fsg->config;
+- value = 1;
++ value = min(ctrl->wLength, (u16) 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
+ USB_RECIP_INTERFACE))
+ break;
+- if (fsg->config && w_index == 0) {
++ if (fsg->config && ctrl->wIndex == 0) {
+
+ /* Raise an exception to wipe out previous transaction
+ * state (queued bufs, etc) and install the new
+@@ -1422,20 +1453,20 @@
+ break;
+ if (!fsg->config)
+ break;
+- if (w_index != 0) {
++ if (ctrl->wIndex != 0) {
+ value = -EDOM;
+ break;
+ }
+ VDBG(fsg, "get interface\n");
+ *(u8 *) req->buf = 0;
+- value = 1;
++ value = min(ctrl->wLength, (u16) 1);
+ break;
+
+ default:
+ VDBG(fsg,
+ "unknown control req %02x.%02x v%04x i%04x l%u\n",
+ ctrl->bRequestType, ctrl->bRequest,
+- w_value, w_index, le16_to_cpu(ctrl->wLength));
++ ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+ }
+
+ return value;
+@@ -1447,7 +1478,6 @@
+ {
+ struct fsg_dev *fsg = get_gadget_data(gadget);
+ int rc;
+- int w_length = le16_to_cpu(ctrl->wLength);
+
+ ++fsg->ep0_req_tag; // Record arrival of a new request
+ fsg->ep0req->context = NULL;
+@@ -1461,9 +1491,9 @@
+
+ /* Respond with data/status or defer until later? */
+ if (rc >= 0 && rc != DELAYED_STATUS) {
+- rc = min(rc, w_length);
+ fsg->ep0req->length = rc;
+- fsg->ep0req->zero = rc < w_length;
++ fsg->ep0req->zero = (rc < ctrl->wLength &&
++ (rc % gadget->ep0->maxpacket) == 0);
+ fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
+ "ep0-in" : "ep0-out");
+ rc = ep0_queue(fsg);
+@@ -1481,8 +1511,8 @@
+
+ /* Use this for bulk or interrupt transfers, not ep0 */
+ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
+- struct usb_request *req, int *pbusy,
+- enum fsg_buffer_state *state)
++ struct usb_request *req, volatile int *pbusy,
++ volatile enum fsg_buffer_state *state)
+ {
+ int rc;
+
+@@ -1490,11 +1520,8 @@
+ dump_msg(fsg, "bulk-in", req->buf, req->length);
+ else if (ep == fsg->intr_in)
+ dump_msg(fsg, "intr-in", req->buf, req->length);
+-
+- spin_lock_irq(&fsg->lock);
+ *pbusy = 1;
+ *state = BUF_STATE_BUSY;
+- spin_unlock_irq(&fsg->lock);
+ rc = usb_ep_queue(ep, req, GFP_KERNEL);
+ if (rc != 0) {
+ *pbusy = 0;
+@@ -1514,23 +1541,13 @@
+
+ static int sleep_thread(struct fsg_dev *fsg)
+ {
+- int rc = 0;
++ int rc;
+
+ /* Wait until a signal arrives or we are woken up */
+- for (;;) {
+- try_to_freeze();
+- set_current_state(TASK_INTERRUPTIBLE);
+- if (signal_pending(current)) {
+- rc = -EINTR;
+- break;
+- }
+- if (fsg->thread_wakeup_needed)
+- break;
+- schedule();
+- }
+- __set_current_state(TASK_RUNNING);
++ rc = wait_event_interruptible(fsg->thread_wqh,
++ fsg->thread_wakeup_needed);
+ fsg->thread_wakeup_needed = 0;
+- return rc;
++ return (rc ? -EINTR : 0);
+ }
+
+
+@@ -1595,8 +1612,7 @@
+ /* Wait for the next buffer to become available */
+ bh = fsg->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+ }
+
+@@ -1606,7 +1622,6 @@
+ curlun->sense_data =
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ bh->inreq->length = 0;
+ bh->state = BUF_STATE_FULL;
+ break;
+@@ -1642,7 +1657,6 @@
+ if (nread < amount) {
+ curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ break;
+ }
+
+@@ -1737,7 +1751,6 @@
+ curlun->sense_data =
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ curlun->sense_data_info = usb_offset >> 9;
+- curlun->info_valid = 1;
+ continue;
+ }
+ amount -= (amount & 511);
+@@ -1760,7 +1773,6 @@
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
+- bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+ fsg->next_buffhd_to_fill = bh->next;
+@@ -1772,7 +1784,6 @@
+ if (bh->state == BUF_STATE_EMPTY && !get_some_more)
+ break; // We stopped early
+ if (bh->state == BUF_STATE_FULL) {
+- smp_rmb();
+ fsg->next_buffhd_to_drain = bh->next;
+ bh->state = BUF_STATE_EMPTY;
+
+@@ -1780,7 +1791,6 @@
+ if (bh->outreq->status != 0) {
+ curlun->sense_data = SS_COMMUNICATION_FAILURE;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ break;
+ }
+
+@@ -1822,7 +1832,6 @@
+ if (nwritten < amount) {
+ curlun->sense_data = SS_WRITE_ERROR;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ break;
+ }
+
+@@ -1835,8 +1844,7 @@
+ }
+
+ /* Wait for something to happen */
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+ }
+
+@@ -1859,16 +1867,21 @@
+ if (!filp->f_op->fsync)
+ return -EINVAL;
+
+- inode = filp->f_path.dentry->d_inode;
++ inode = filp->f_dentry->d_inode;
+ mutex_lock(&inode->i_mutex);
++// down(&inode->i_sem);
++// current->flags |= PF_SYNCWRITE;
+ rc = filemap_fdatawrite(inode->i_mapping);
+- err = filp->f_op->fsync(filp, filp->f_path.dentry, 1);
++ err = filp->f_op->fsync(filp, filp->f_dentry, 1);
+ if (!rc)
+ rc = err;
+ err = filemap_fdatawait(inode->i_mapping);
+ if (!rc)
+ rc = err;
+ mutex_unlock(&inode->i_mutex);
++
++// current->flags &= ~PF_SYNCWRITE;
++// up(&inode->i_sem);
+ VLDBG(curlun, "fdatasync -> %d\n", rc);
+ return rc;
+ }
+@@ -1900,10 +1913,10 @@
+ static void invalidate_sub(struct lun *curlun)
+ {
+ struct file *filp = curlun->filp;
+- struct inode *inode = filp->f_path.dentry->d_inode;
++ struct inode *inode = filp->f_dentry->d_inode;
+ unsigned long rc;
+
+- rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
++ rc = invalidate_inode_pages(inode->i_mapping);
+ VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+ }
+
+@@ -1966,7 +1979,6 @@
+ curlun->sense_data =
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ break;
+ }
+
+@@ -1993,7 +2005,6 @@
+ if (nread == 0) {
+ curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+ curlun->sense_data_info = file_offset >> 9;
+- curlun->info_valid = 1;
+ break;
+ }
+ file_offset += nread;
+@@ -2037,7 +2048,6 @@
+ struct lun *curlun = fsg->curlun;
+ u8 *buf = (u8 *) bh->buf;
+ u32 sd, sdinfo;
+- int valid;
+
+ /*
+ * From the SCSI-2 spec., section 7.9 (Unit attention condition):
+@@ -2065,18 +2075,15 @@
+ fsg->bad_lun_okay = 1;
+ sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+ sdinfo = 0;
+- valid = 0;
+ } else {
+ sd = curlun->sense_data;
+ sdinfo = curlun->sense_data_info;
+- valid = curlun->info_valid << 7;
+ curlun->sense_data = SS_NO_SENSE;
+ curlun->sense_data_info = 0;
+- curlun->info_valid = 0;
+ }
+
+ memset(buf, 0, 18);
+- buf[0] = valid | 0x70; // Valid, current error
++ buf[0] = 0x80 | 0x70; // Valid, current error
+ buf[2] = SK(sd);
+ put_be32(&buf[3], sdinfo); // Sense information
+ buf[7] = 18 - 8; // Additional sense length
+@@ -2300,7 +2307,8 @@
+ }
+
+ /* Wait for a short time and then try again */
+- if (msleep_interruptible(100) != 0)
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (schedule_timeout(HZ / 10) != 0)
+ return -EINTR;
+ rc = usb_ep_set_halt(fsg->bulk_in);
+ }
+@@ -2320,8 +2328,7 @@
+
+ /* Wait for the next buffer to be free */
+ while (bh->state != BUF_STATE_EMPTY) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+ }
+
+@@ -2349,7 +2356,6 @@
+
+ /* Throw away the data in a filled buffer */
+ if (bh->state == BUF_STATE_FULL) {
+- smp_rmb();
+ bh->state = BUF_STATE_EMPTY;
+ fsg->next_buffhd_to_drain = bh->next;
+
+@@ -2372,7 +2378,6 @@
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
+- bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+ fsg->next_buffhd_to_fill = bh->next;
+@@ -2381,8 +2386,7 @@
+ }
+
+ /* Otherwise wait for something to happen */
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+ }
+ return 0;
+@@ -2504,8 +2508,7 @@
+ /* Wait for the next buffer to become available */
+ bh = fsg->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+ }
+
+@@ -2530,7 +2533,7 @@
+ }
+
+ if (transport_is_bbb()) {
+- struct bulk_cs_wrap *csw = bh->buf;
++ struct bulk_cs_wrap *csw = (struct bulk_cs_wrap *) bh->buf;
+
+ /* Store and send the Bulk-only CSW */
+ csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+@@ -2549,7 +2552,8 @@
+ return 0;
+
+ } else { // USB_PR_CBI
+- struct interrupt_data *buf = bh->buf;
++ struct interrupt_data *buf = (struct interrupt_data *)
++ bh->buf;
+
+ /* Store and send the Interrupt data. UFI sends the ASC
+ * and ASCQ bytes. Everything else sends a Type (which
+@@ -2565,6 +2569,7 @@
+
+ fsg->intr_buffhd = bh; // Point to the right buffhd
+ fsg->intreq->buf = bh->inreq->buf;
++ fsg->intreq->dma = bh->inreq->dma;
+ fsg->intreq->context = bh;
+ start_transfer(fsg, fsg->intr_in, fsg->intreq,
+ &fsg->intreq_busy, &bh->state);
+@@ -2651,7 +2656,7 @@
+ }
+ }
+
+- /* Check that the LUN values are consistent */
++ /* Check that the LUN values are oonsistent */
+ if (transport_is_bbb()) {
+ if (fsg->lun != lun)
+ DBG(fsg, "using LUN %d from CBW, "
+@@ -2666,7 +2671,6 @@
+ if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
+ curlun->sense_data = SS_NO_SENSE;
+ curlun->sense_data_info = 0;
+- curlun->info_valid = 0;
+ }
+ } else {
+ fsg->curlun = curlun = NULL;
+@@ -2725,10 +2729,9 @@
+ /* Wait for the next buffer to become available for data or status */
+ bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+- }
++ }
+ fsg->phase_error = 0;
+ fsg->short_packet_received = 0;
+
+@@ -2934,7 +2937,7 @@
+ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+ {
+ struct usb_request *req = bh->outreq;
+- struct bulk_cb_wrap *cbw = req->buf;
++ struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *) req->buf;
+
+ /* Was this a real packet? */
+ if (req->status)
+@@ -2960,7 +2963,7 @@
+
+ /* Is the CBW meaningful? */
+ if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+- cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
++ cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) {
+ DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
+ "cmdlen %u\n",
+ cbw->Lun, cbw->Flags, cbw->Length);
+@@ -3000,14 +3003,12 @@
+ /* Wait for the next buffer to become available */
+ bh = fsg->next_buffhd_to_fill;
+ while (bh->state != BUF_STATE_EMPTY) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+- }
++ }
+
+ /* Queue a request to read a Bulk-only CBW */
+ set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+- bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+
+@@ -3017,11 +3018,9 @@
+
+ /* Wait for the CBW to arrive */
+ while (bh->state != BUF_STATE_FULL) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+- }
+- smp_rmb();
++ }
+ rc = received_cbw(fsg, bh);
+ bh->state = BUF_STATE_EMPTY;
+
+@@ -3029,10 +3028,9 @@
+
+ /* Wait for the next command to arrive */
+ while (fsg->cbbuf_cmnd_size == 0) {
+- rc = sleep_thread(fsg);
+- if (rc)
++ if ((rc = sleep_thread(fsg)) != 0)
+ return rc;
+- }
++ }
+
+ /* Is the previous status interrupt request still busy?
+ * The host is allowed to skip reading the status,
+@@ -3139,7 +3137,7 @@
+ if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
+ goto reset;
+ fsg->bulk_out_enabled = 1;
+- fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
++ fsg->bulk_out_maxpacket = d->wMaxPacketSize;
+
+ if (transport_is_cbi()) {
+ d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
+@@ -3157,6 +3155,7 @@
+ if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
+ goto reset;
+ bh->inreq->buf = bh->outreq->buf = bh->buf;
++ bh->inreq->dma = bh->outreq->dma = bh->dma;
+ bh->inreq->context = bh->outreq->context = bh;
+ bh->inreq->complete = bulk_in_complete;
+ bh->outreq->complete = bulk_out_complete;
+@@ -3232,7 +3231,8 @@
+ /* Clear the existing signals. Anything but SIGUSR1 is converted
+ * into a high-priority EXIT exception. */
+ for (;;) {
+- sig = dequeue_signal_lock(current, ¤t->blocked, &info);
++ sig = dequeue_signal_lock(current, &fsg->thread_signal_mask,
++ &info);
+ if (!sig)
+ break;
+ if (sig != SIGUSR1) {
+@@ -3298,7 +3298,6 @@
+ curlun->sense_data = curlun->unit_attention_data =
+ SS_NO_SENSE;
+ curlun->sense_data_info = 0;
+- curlun->info_valid = 0;
+ }
+ fsg->state = FSG_STATE_IDLE;
+ }
+@@ -3381,23 +3380,28 @@
+
+ static int fsg_main_thread(void *fsg_)
+ {
+- struct fsg_dev *fsg = fsg_;
++ struct fsg_dev *fsg = (struct fsg_dev *) fsg_;
++
++ fsg->thread_task = current;
++
++ /* Release all our userspace resources */
++ daemonize("file-storage-gadget");
+
+ /* Allow the thread to be killed by a signal, but set the signal mask
+ * to block everything but INT, TERM, KILL, and USR1. */
+- allow_signal(SIGINT);
+- allow_signal(SIGTERM);
+- allow_signal(SIGKILL);
+- allow_signal(SIGUSR1);
+-
+- /* Allow the thread to be frozen */
+- set_freezable();
++ siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
++ sigmask(SIGTERM) | sigmask(SIGKILL) |
++ sigmask(SIGUSR1));
++ sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL);
+
+ /* Arrange for userspace references to be interpreted as kernel
+ * pointers. That way we can pass a kernel pointer to a routine
+ * that expects a __user pointer and it will work okay. */
+ set_fs(get_ds());
+
++ /* Wait for the gadget registration to finish up */
++ wait_for_completion(&fsg->thread_notifier);
++
+ /* The main loop */
+ while (fsg->state != FSG_STATE_TERMINATED) {
+ if (exception_in_progress(fsg) || signal_pending(current)) {
+@@ -3435,9 +3439,8 @@
+ spin_unlock_irq(&fsg->lock);
+ }
+
+- spin_lock_irq(&fsg->lock);
+ fsg->thread_task = NULL;
+- spin_unlock_irq(&fsg->lock);
++ flush_signals(current);
+
+ /* In case we are exiting because of a signal, unregister the
+ * gadget driver and close the backing file. */
+@@ -3482,8 +3485,8 @@
+ if (!(filp->f_mode & FMODE_WRITE))
+ ro = 1;
+
+- if (filp->f_path.dentry)
+- inode = filp->f_path.dentry->d_inode;
++ if (filp->f_dentry)
++ inode = filp->f_dentry->d_inode;
+ if (inode && S_ISBLK(inode->i_mode)) {
+ if (bdev_read_only(inode->i_bdev))
+ ro = 1;
+@@ -3546,24 +3549,26 @@
+ }
+
+
+-static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
++static ssize_t show_ro(struct device *dev, char *buf)
+ {
+ struct lun *curlun = dev_to_lun(dev);
+
+ return sprintf(buf, "%d\n", curlun->ro);
+ }
+
+-static ssize_t show_file(struct device *dev, struct device_attribute *attr,
+- char *buf)
++static ssize_t show_file(struct device *dev, char *buf)
+ {
+ struct lun *curlun = dev_to_lun(dev);
+- struct fsg_dev *fsg = dev_get_drvdata(dev);
++ struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+ char *p;
+ ssize_t rc;
+
+ down_read(&fsg->filesem);
+ if (backing_file_is_open(curlun)) { // Get the complete pathname
+ p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
++//
++// p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt,
++// buf, PAGE_SIZE - 1);
+ if (IS_ERR(p))
+ rc = PTR_ERR(p);
+ else {
+@@ -3581,12 +3586,11 @@
+ }
+
+
+-static ssize_t store_ro(struct device *dev, struct device_attribute *attr,
+- const char *buf, size_t count)
++ssize_t store_ro(struct device *dev, const char *buf, size_t count)
+ {
+ ssize_t rc = count;
+ struct lun *curlun = dev_to_lun(dev);
+- struct fsg_dev *fsg = dev_get_drvdata(dev);
++ struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+ int i;
+
+ if (sscanf(buf, "%d", &i) != 1)
+@@ -3606,11 +3610,10 @@
+ return rc;
+ }
+
+-static ssize_t store_file(struct device *dev, struct device_attribute *attr,
+- const char *buf, size_t count)
++ssize_t store_file(struct device *dev, const char *buf, size_t count)
+ {
+ struct lun *curlun = dev_to_lun(dev);
+- struct fsg_dev *fsg = dev_get_drvdata(dev);
++ struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+ int rc = 0;
+
+ if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
+@@ -3648,22 +3651,14 @@
+
+ /*-------------------------------------------------------------------------*/
+
+-static void fsg_release(struct kref *ref)
+-{
+- struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref);
+-
+- kfree(fsg->luns);
+- kfree(fsg);
+-}
+-
+ static void lun_release(struct device *dev)
+ {
+- struct fsg_dev *fsg = dev_get_drvdata(dev);
++ struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+
+- kref_put(&fsg->ref, fsg_release);
++ complete(&fsg->lun_released);
+ }
+
+-static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
++static void fsg_unbind(struct usb_gadget *gadget)
+ {
+ struct fsg_dev *fsg = get_gadget_data(gadget);
+ int i;
+@@ -3674,12 +3669,14 @@
+ clear_bit(REGISTERED, &fsg->atomic_bitflags);
+
+ /* Unregister the sysfs attribute files and the LUNs */
++ init_completion(&fsg->lun_released);
+ for (i = 0; i < fsg->nluns; ++i) {
+ curlun = &fsg->luns[i];
+ if (curlun->registered) {
+ device_remove_file(&curlun->dev, &dev_attr_ro);
+ device_remove_file(&curlun->dev, &dev_attr_file);
+ device_unregister(&curlun->dev);
++ wait_for_completion(&fsg->lun_released);
+ curlun->registered = 0;
+ }
+ }
+@@ -3694,12 +3691,19 @@
+ }
+
+ /* Free the data buffers */
+- for (i = 0; i < NUM_BUFFERS; ++i)
+- kfree(fsg->buffhds[i].buf);
++ for (i = 0; i < NUM_BUFFERS; ++i) {
++ struct fsg_buffhd *bh = &fsg->buffhds[i];
++
++ if (bh->buf)
++ usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma,
++ mod_data.buflen);
++ }
+
+ /* Free the request and buffer for endpoint 0 */
+ if (req) {
+- kfree(req->buf);
++ if (req->buf)
++ usb_ep_free_buffer(fsg->ep0, req->buf,
++ req->dma, EP0_BUFSIZE);
+ usb_ep_free_request(fsg->ep0, req);
+ }
+
+@@ -3710,29 +3714,44 @@
+ static int __init check_parameters(struct fsg_dev *fsg)
+ {
+ int prot;
+- int gcnum;
+
+ /* Store the default values */
+ mod_data.transport_type = USB_PR_BULK;
+ mod_data.transport_name = "Bulk-only";
+ mod_data.protocol_type = USB_SC_SCSI;
+ mod_data.protocol_name = "Transparent SCSI";
++
++#ifdef DEBUG
++ printk(" fsg->gadget->name = %s \n",fsg->gadget->name);
++#endif
+
+ if (gadget_is_sh(fsg->gadget))
+ mod_data.can_stall = 0;
+
+ if (mod_data.release == 0xffff) { // Parameter wasn't set
++ if (gadget_is_net2280(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0301);
++ else if (gadget_is_dummy(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0302);
++ else if (gadget_is_pxa27x(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0303);
++ else if (gadget_is_sh(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0304);
++
+ /* The sa1100 controller is not supported */
+- if (gadget_is_sa1100(fsg->gadget))
+- gcnum = -1;
+- else
+- gcnum = usb_gadget_controller_number(fsg->gadget);
+- if (gcnum >= 0)
+- mod_data.release = 0x0300 + gcnum;
++
++ else if (gadget_is_goku(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0306);
++ else if (gadget_is_mq11xx(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0307);
++ else if (gadget_is_omap(fsg->gadget))
++ mod_data.release = __constant_cpu_to_le16(0x0308);
++ else if (gadget_is_lh7a40x(gadget))
++ mod_data.release = __constant_cpu_to_le16 (0x0309);
+ else {
+ WARN(fsg, "controller '%s' not recognized\n",
+ fsg->gadget->name);
+- mod_data.release = 0x0399;
++ mod_data.release = __constant_cpu_to_le16(0x0399);
+ }
+ }
+
+@@ -3819,7 +3838,7 @@
+ /* Find out how many LUNs there should be */
+ i = mod_data.nluns;
+ if (i == 0)
+- i = max(mod_data.num_filenames, 1u);
++ i = max(mod_data.num_filenames, 1);
+ if (i > MAX_LUNS) {
+ ERROR(fsg, "invalid number of LUNs: %d\n", i);
+ rc = -EINVAL;
+@@ -3828,40 +3847,34 @@
+
+ /* Create the LUNs, open their backing files, and register the
+ * LUN devices in sysfs. */
+- fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
++ fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
+ if (!fsg->luns) {
+ rc = -ENOMEM;
+ goto out;
+ }
++ memset(fsg->luns, 0, i * sizeof(struct lun));
+ fsg->nluns = i;
+
+ for (i = 0; i < fsg->nluns; ++i) {
+ curlun = &fsg->luns[i];
+- curlun->ro = mod_data.ro[i];
+- curlun->dev.release = lun_release;
++ curlun->ro = ro[i];
+ curlun->dev.parent = &gadget->dev;
+ curlun->dev.driver = &fsg_driver.driver;
+ dev_set_drvdata(&curlun->dev, fsg);
+ snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
+ "%s-lun%d", gadget->dev.bus_id, i);
+
+- if ((rc = device_register(&curlun->dev)) != 0) {
++ if ((rc = device_register(&curlun->dev)) != 0)
+ INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
+- goto out;
+- }
+- if ((rc = device_create_file(&curlun->dev,
+- &dev_attr_ro)) != 0 ||
+- (rc = device_create_file(&curlun->dev,
+- &dev_attr_file)) != 0) {
+- device_unregister(&curlun->dev);
+- goto out;
++ else {
++ curlun->registered = 1;
++ curlun->dev.release = lun_release;
++ device_create_file(&curlun->dev, &dev_attr_ro);
++ device_create_file(&curlun->dev, &dev_attr_file);
+ }
+- curlun->registered = 1;
+- kref_get(&fsg->ref);
+
+- if (mod_data.file[i] && *mod_data.file[i]) {
+- if ((rc = open_backing_file(curlun,
+- mod_data.file[i])) != 0)
++ if (file[i] && *file[i]) {
++ if ((rc = open_backing_file(curlun, file[i])) != 0)
+ goto out;
+ } else if (!mod_data.removable) {
+ ERROR(fsg, "no file given for LUN%d\n", i);
+@@ -3874,20 +3887,35 @@
+ usb_ep_autoconfig_reset(gadget);
+ ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
+ if (!ep)
++ {
++#ifdef DEBUG
++ printk(" Error %d at %s() \n",__LINE__,__FUNCTION__);
++#endif
+ goto autoconf_fail;
++ }
+ ep->driver_data = fsg; // claim the endpoint
+ fsg->bulk_in = ep;
+
+ ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc);
+ if (!ep)
++ {
++#ifdef DEBUG
++ printk(" Error %d at %s() \n",__LINE__,__FUNCTION__);
++#endif
+ goto autoconf_fail;
++ }
+ ep->driver_data = fsg; // claim the endpoint
+ fsg->bulk_out = ep;
+
+ if (transport_is_cbi()) {
+ ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc);
+ if (!ep)
++ {
++#ifdef DEBUG
++ printk(" Error %d %st s() \n",__LINE__,__FUNCTION__);
++#endif
+ goto autoconf_fail;
++ }
+ ep->driver_data = fsg; // claim the endpoint
+ fsg->intr_in = ep;
+ }
+@@ -3902,25 +3930,19 @@
+ intf_desc.bNumEndpoints = i;
+ intf_desc.bInterfaceSubClass = mod_data.protocol_type;
+ intf_desc.bInterfaceProtocol = mod_data.transport_type;
+- fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+-
+- if (gadget_is_dualspeed(gadget)) {
+- hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
++ fs_function[i+1] = NULL;
+
+- /* Assume ep0 uses the same maxpacket value for both speeds */
+- dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ hs_function[i+1] = NULL;
+
+- /* Assume endpoint addresses are the same for both speeds */
+- hs_bulk_in_desc.bEndpointAddress =
+- fs_bulk_in_desc.bEndpointAddress;
+- hs_bulk_out_desc.bEndpointAddress =
+- fs_bulk_out_desc.bEndpointAddress;
+- hs_intr_in_desc.bEndpointAddress =
+- fs_intr_in_desc.bEndpointAddress;
+- }
++ /* Assume ep0 uses the same maxpacket value for both speeds */
++ dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
+
+- if (gadget_is_otg(gadget))
+- otg_desc.bmAttributes |= USB_OTG_HNP;
++ /* Assume that all endpoint addresses are the same for both speeds */
++ hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress;
++ hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress;
++ hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress;
++#endif
+
+ rc = -ENOMEM;
+
+@@ -3928,7 +3950,8 @@
+ fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
+ if (!req)
+ goto out;
+- req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
++ req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE,
++ &req->dma, GFP_KERNEL);
+ if (!req->buf)
+ goto out;
+ req->complete = ep0_complete;
+@@ -3937,10 +3960,8 @@
+ for (i = 0; i < NUM_BUFFERS; ++i) {
+ struct fsg_buffhd *bh = &fsg->buffhds[i];
+
+- /* Allocate for the bulk-in endpoint. We assume that
+- * the buffer will also work with the bulk-out (and
+- * interrupt-in) endpoint. */
+- bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
++ bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
++ &bh->dma, GFP_KERNEL);
+ if (!bh->buf)
+ goto out;
+ bh->next = bh + 1;
+@@ -3950,9 +3971,13 @@
+ /* This should reflect the actual gadget power source */
+ usb_gadget_set_selfpowered(gadget);
+
+- snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+- init_utsname()->sysname, init_utsname()->release,
+- gadget->name);
++// snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
++// init_utsname()->sysname, init_utsname()->release,
++// gadget->name);
++//
++// snprintf(manufacturer, sizeof manufacturer,
++// UTS_SYSNAME " " UTS_RELEASE " with %s",
++// gadget->name);
+
+ /* On a real device, serial[] would be loaded from permanent
+ * storage. We just encode it from the driver version string. */
+@@ -3964,12 +3989,10 @@
+ sprintf(&serial[i], "%02X", c);
+ }
+
+- fsg->thread_task = kthread_create(fsg_main_thread, fsg,
+- "file-storage-gadget");
+- if (IS_ERR(fsg->thread_task)) {
+- rc = PTR_ERR(fsg->thread_task);
++ if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
++ CLONE_FILES))) < 0)
+ goto out;
+- }
++ fsg->thread_pid = rc;
+
+ INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+ INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
+@@ -3982,6 +4005,10 @@
+ if (pathbuf) {
+ p = d_path(&curlun->filp->f_path,
+ pathbuf, PATH_MAX);
++//
++// p = d_path(curlun->filp->f_dentry,
++// curlun->filp->f_vfsmnt,
++// pathbuf, PATH_MAX);
+ if (IS_ERR(p))
+ p = NULL;
+ }
+@@ -4000,12 +4027,7 @@
+ DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
+ mod_data.removable, mod_data.can_stall,
+ mod_data.buflen);
+- DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
+-
+- set_bit(REGISTERED, &fsg->atomic_bitflags);
+-
+- /* Tell the thread to start working */
+- wake_up_process(fsg->thread_task);
++ DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
+ return 0;
+
+ autoconf_fail:
+@@ -4057,7 +4079,6 @@
+
+ .driver = {
+ .name = (char *) shortname,
+- .owner = THIS_MODULE,
+ // .release = ...
+ // .suspend = ...
+ // .resume = ...
+@@ -4069,12 +4090,13 @@
+ {
+ struct fsg_dev *fsg;
+
+- fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
++ fsg = kmalloc(sizeof *fsg, GFP_KERNEL);
+ if (!fsg)
+ return -ENOMEM;
++ memset(fsg, 0, sizeof *fsg);
+ spin_lock_init(&fsg->lock);
+ init_rwsem(&fsg->filesem);
+- kref_init(&fsg->ref);
++ init_waitqueue_head(&fsg->thread_wqh);
+ init_completion(&fsg->thread_notifier);
+
+ the_fsg = fsg;
+@@ -4082,17 +4104,36 @@
+ }
+
+
++static void fsg_free(struct fsg_dev *fsg)
++{
++ kfree(fsg->luns);
++ kfree(fsg);
++}
++
++
+ static int __init fsg_init(void)
+ {
+ int rc;
+ struct fsg_dev *fsg;
+-
++#ifdef DEBUG
++ printk("Entering fsg_init\n");
++#endif
+ if ((rc = fsg_alloc()) != 0)
+ return rc;
+ fsg = the_fsg;
+- if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
+- kref_put(&fsg->ref, fsg_release);
+- return rc;
++
++ if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) {
++#ifdef DEBUG
++ printk("%s,%d",__FUNCTION__,__LINE__);
++#endif
++ fsg_free(fsg);
++ return rc;
++ }
++ set_bit(REGISTERED, &fsg->atomic_bitflags);
++
++ /* Tell the thread to start working */
++ complete(&fsg->thread_notifier);
++ return 0;
+ }
+ module_init(fsg_init);
+
+@@ -4109,6 +4150,6 @@
+ wait_for_completion(&fsg->thread_notifier);
+
+ close_all_backing_files(fsg);
+- kref_put(&fsg->ref, fsg_release);
++ fsg_free(fsg);
+ }
+ module_exit(fsg_cleanup);
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/Kconfig linux-2.6.25/drivers/usb/gadget/Kconfig
+--- linux-2.6.25_original/drivers/usb/gadget/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -203,6 +203,21 @@
+ default y if USB_ETH
+ default y if USB_G_SERIAL
+
++config USB_GADGET_PXA27X
++ depends on ARCH_PXA && PXA27x
++ select USB_GADGET_SELECTED
++
++ bool "PXA27x"
++ help
++ Intel's USB Client support for PXA27x ARM processor.
++ For Mainstone and Glencoe, use this one for now.
++
++config USB_PXA27X
++ bool
++ depends on USB_GADGET_PXA27X
++ default USB_GADGET
++
++
+ config USB_GADGET_M66592
+ boolean "Renesas M66592 USB Peripheral Controller"
+ select USB_GADGET_DUALSPEED
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/Makefile linux-2.6.25/drivers/usb/gadget/Makefile
+--- linux-2.6.25_original/drivers/usb/gadget/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -16,6 +16,7 @@
+ obj-$(CONFIG_USB_AT91) += at91_udc.o
+ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
+ obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
++obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o
+ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+
+ #
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/pxa27x_udc.c linux-2.6.25/drivers/usb/gadget/pxa27x_udc.c
+--- linux-2.6.25_original/drivers/usb/gadget/pxa27x_udc.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/pxa27x_udc.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,2407 @@
++/*
++ * linux/drivers/usb/gadget/pxa27x_udc.c
++ * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers
++ *
++ * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker)
++ * Copyright (C) 2003 Robert Schwebel, Pengutronix
++ * Copyright (C) 2003 Benedikt Spranger, Pengutronix
++ * Copyright (C) 2003 David Brownell
++ * Copyright (C) 2003 Joshua Wise
++ * Copyright (C) 2004 Intel Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#undef DEBUG
++#undef VERBOSE
++//#define DEBUG
++//#define VERBOSE DBG_VERBOSE
++
++#include <linux/autoconf.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/proc_fs.h>
++#include <linux/mm.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h> //Added on July 1 2007 for usb device in regulus
++#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */
++ //Added on aug 16 2007 for usb device in regulus
++
++#define SA_INTERRUPT IRQF_DISABLED
++
++#include <asm/byteorder.h>
++#include <asm/dma.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++#include <asm/unaligned.h>
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++#ifdef CONFIG_MACH_MAINSTONE
++ #include <asm/arch/mainstone.h>
++#elif CONFIG_MACH_REGULUS
++ #include <asm/arch/regulus.h>
++#endif
++
++#include <linux/usb_ch9.h>
++#include <linux/usb_gadget.h>
++
++#include <asm/arch/udc.h>
++extern void SPITransaction(unsigned short *pWords,unsigned short iNbWords);
++#define TSC2301_READ 0x8000
++#define TSC2301_WRITE 0x0000
++
++
++
++
++/*
++ * This driver handles the USB Device Controller (UDC) in Intel's PXA 27777777x
++ * series processors.
++ * Such controller drivers work with a gadget driver. The gadget driver
++ * returns descriptors, implements configuration and data protocols used
++ * by the host to interact with this device, and allocates endpoints to
++ * the different protocol interfaces. The controller driver virtualizes
++ * usb hardware so that the gadget drivers will be more portable.
++ *
++ * This UDC hardware wants to implement a bit too much USB protocol, so
++ * it constrains the sorts of USB configuration change events that work.
++ * The errata for these chips are misleading; some "fixed" bugs from
++ * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
++ */
++
++#define DRIVER_VERSION "28-Jun-2007" // Added
++#define DRIVER_DESC "PXA 27x USB Device Controller driver"
++
++
++static const char driver_name [] = "pxa27x_udc";
++
++static const char ep0name [] = "ep0";
++
++
++//#define USE_DMA
++#undef USE_DMA
++//#define DISABLE_TEST_MODE
++#undef DISABLE_TEST_MODE
++
++#ifdef CONFIG_PROC_FS
++#define UDC_PROC_FILE
++#endif
++
++#include "pxa27x_udc.h"
++
++#ifdef CONFIG_EMBEDDED
++/* few strings, and little code to use them */
++#undef DEBUG
++#undef UDC_PROC_FILE
++#endif
++
++#ifdef USE_DMA
++static int use_dma = 1;
++module_param(use_dma, bool, 0);
++MODULE_PARM_DESC (use_dma, "true to use dma");
++
++static void dma_nodesc_handler (int dmach, void *_ep, struct pt_regs *r);
++static void kick_dma(struct pxa27x_ep *ep, struct pxa27x_request *req);
++
++#define DMASTR " (dma support)"
++
++#else /* !USE_DMA */
++#define DMASTR " (pio only)"
++#endif
++
++#ifdef CONFIG_USB_PXA27X_SMALL
++#define SIZE_STR " (small)"
++#else
++#define SIZE_STR ""
++#endif
++
++#ifdef DISABLE_TEST_MODE
++/* (mode == 0) == no undocumented chip tweaks
++ * (mode & 1) == double buffer bulk IN
++ * (mode & 2) == double buffer bulk OUT
++ * ... so mode = 3 (or 7, 15, etc) does it for both
++ */
++static ushort fifo_mode = 0;
++//static unsigned short fifo_mode = 0;
++module_param(fifo_mode, ushort, 0);
++//module_param(fifo_mode, unsigned short, 0);
++MODULE_PARM_DESC (fifo_mode, "pxa27x udc fifo mode");
++#endif
++
++#define UDCISR0_IR0 0x3
++#define UDCISR_INT_MASK (UDC_INT_FIFOERROR | UDC_INT_PACKETCMP)
++#define UDCICR_INT_MASK UDCISR_INT_MASK
++
++#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME)
++/* ---------------------------------------------------------------------------
++ * endpoint related parts of the api to the usb controller hardware,
++ * used by gadget driver; and the inner talker-to-hardware core.
++ * ---------------------------------------------------------------------------
++ */
++
++static void pxa27x_ep_fifo_flush (struct usb_ep *ep);
++static void nuke (struct pxa27x_ep *, int status);
++
++static void pio_irq_enable(int ep_num)
++{
++ if (ep_num < 16)
++ UDCICR0 |= 3 << (ep_num * 2);
++ else {
++ ep_num -= 16;
++ UDCICR1 |= 3 << (ep_num * 2);
++ }
++}
++
++static void pio_irq_disable(int ep_num)
++{
++ ep_num &= 0xf;
++ if (ep_num < 16)
++ UDCICR0 &= ~(3 << (ep_num * 2));
++ else {
++ ep_num -= 16;
++ UDCICR1 &= ~(3 << (ep_num * 2));
++ }
++}
++
++/* The UDCCR reg contains mask and interrupt status bits,
++ * so using '|=' isn't safe as it may ack an interrupt.
++ */
++#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_UDE)
++
++static inline void udc_set_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
++}
++
++static inline void udc_clear_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
++}
++
++static inline void udc_ack_int_UDCCR(int mask)
++{
++ /* udccr contains the bits we dont want to change */
++ __u32 udccr = UDCCR & UDCCR_MASK_BITS;
++
++ UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);
++}
++
++/*
++ * endpoint enable/disable
++ *
++ * we need to verify the descriptors used to enable endpoints. since pxa27x
++ * endpoint configurations are fixed, and are pretty much always enabled,
++ * there's not a lot to manage here.
++ *
++ * because pxa27x can't selectively initialize bulk (or interrupt) endpoints,
++ * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except
++ * for a single interface (with only the default altsetting) and for gadget
++ * drivers that don't halt endpoints (not reset by set_interface). that also
++ * means that if you use ISO, you must violate the USB spec rule that all
++ * iso endpoints must be in non-default altsettings.
++ */
++static int pxa27x_ep_enable (struct usb_ep *_ep,
++ const struct usb_endpoint_descriptor *desc)
++{
++ struct pxa27x_ep *ep;
++ struct pxa27x_udc *dev;
++
++ ep = container_of (_ep, struct pxa27x_ep, ep);
++ if (!_ep || !desc || _ep->name == ep0name
++ || desc->bDescriptorType != USB_DT_ENDPOINT
++ || ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) {
++ DMSG("%s, bad ep or descriptor\n", __FUNCTION__);
++ return -EINVAL;
++ }
++
++ /* xfer types must match, except that interrupt ~= bulk */
++ if( ep->ep_type != USB_ENDPOINT_XFER_BULK
++ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
++ DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
++ return -EINVAL;
++ }
++
++ /* hardware _could_ do smaller, but driver doesn't */
++ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
++ && le16_to_cpu (desc->wMaxPacketSize)
++ != BULK_FIFO_SIZE)
++ || !desc->wMaxPacketSize) {
++ DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
++ return -ERANGE;
++ }
++
++ dev = ep->dev;
++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
++ DMSG("%s, bogus device state\n", __FUNCTION__);
++ return -ESHUTDOWN;
++ }
++
++ ep->desc = desc;
++ ep->dma = -1;
++ ep->stopped = 0;
++ ep->pio_irqs = ep->dma_irqs = 0;
++ ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);
++
++ /* flush fifo (mostly for OUT buffers) */
++ pxa27x_ep_fifo_flush (_ep);
++
++ /* ... reset halt state too, if we could ... */
++
++#ifdef USE_DMA
++ /* for (some) bulk and ISO endpoints, try to get a DMA channel and
++ * bind it to the endpoint. otherwise use PIO.
++ */
++ DMSG("%s: called attributes=%d\n", __FUNCTION__, ep->ep_type);
++ switch (ep->ep_type) {
++ case USB_ENDPOINT_XFER_ISOC:
++ if (le16_to_cpu(desc->wMaxPacketSize) % 32)
++ break;
++ // fall through
++ case USB_ENDPOINT_XFER_BULK:
++ if (!use_dma || !ep->reg_drcmr)
++ break;
++ ep->dma = pxa_request_dma ((char *)_ep->name,
++ (le16_to_cpu (desc->wMaxPacketSize) > 64)
++ ? DMA_PRIO_MEDIUM /* some iso */
++ : DMA_PRIO_LOW,
++ dma_nodesc_handler, ep);
++ if (ep->dma >= 0) {
++ *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;
++ DMSG("%s using dma%d\n", _ep->name, ep->dma);
++ }
++ default:
++ break;
++ }
++#endif
++ DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);
++ return 0;
++}
++
++static int pxa27x_ep_disable (struct usb_ep *_ep)
++{
++ struct pxa27x_ep *ep;
++
++ ep = container_of (_ep, struct pxa27x_ep, ep);
++ if (!_ep || !ep->desc) {
++ DMSG("%s, %s not enabled\n", __FUNCTION__,
++ _ep ? ep->ep.name : NULL);
++ return -EINVAL;
++ }
++ nuke (ep, -ESHUTDOWN);
++
++#ifdef USE_DMA
++ if (ep->dma >= 0) {
++ *ep->reg_drcmr = 0;
++ pxa_free_dma (ep->dma);
++ ep->dma = -1;
++ }
++#endif
++
++ /* flush fifo (mostly for IN buffers) */
++ pxa27x_ep_fifo_flush (_ep);
++
++ ep->desc = 0;
++ ep->stopped = 1;
++
++ DBG(DBG_VERBOSE, "%s disabled\n", _ep->name);
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* for the pxa27x, these can just wrap kmalloc/kfree. gadget drivers
++ * must still pass correctly initialized endpoints, since other controller
++ * drivers may care about how it's currently set up (dma issues etc).
++ */
++
++/*
++ * pxa27x_ep_alloc_request - allocate a request data structure
++ */
++static struct usb_request * pxa27x_ep_alloc_request (struct usb_ep *_ep, int gfp_flags)
++{
++ struct pxa27x_request *req;
++
++ req = kmalloc (sizeof *req, gfp_flags);
++ if (!req)
++ return 0;
++
++ memset (req, 0, sizeof *req);
++ INIT_LIST_HEAD (&req->queue);
++ return &req->req;
++}
++
++
++/*
++ * pxa27x_ep_free_request - deallocate a request data structure
++ */
++static void pxa27x_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct pxa27x_request *req;
++
++ req = container_of(_req, struct pxa27x_request, req);
++ WARN_ON (!list_empty (&req->queue));
++ kfree(req);
++}
++
++
++/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's
++ * no device-affinity and the heap works perfectly well for i/o buffers.
++ * It wastes much less memory than dma_alloc_coherent() would, and even
++ * prevents cacheline (32 bytes wide) sharing problems.
++ */
++static void * pxa27x_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
++ dma_addr_t *dma, int gfp_flags)
++{
++ char *retval;
++
++ retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
++ if (retval)
++ *dma = virt_to_bus (retval);
++ return retval;
++}
++
++static void pxa27x_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma,
++ unsigned bytes)
++{
++ kfree (buf);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * done - retire a request; caller blocked irqs
++ */
++static void done(struct pxa27x_ep *ep, struct pxa27x_request *req, int status)
++{
++ list_del_init(&req->queue);
++ if (likely (req->req.status == -EINPROGRESS))
++ req->req.status = status;
++ else
++ status = req->req.status;
++
++ if (status && status != -ESHUTDOWN)
++ DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n",
++ ep->ep.name, &req->req, status,
++ req->req.actual, req->req.length);
++
++ /* don't modify queue heads during completion callback */
++ req->req.complete(&ep->ep, &req->req);
++}
++
++
++static inline void ep0_idle (struct pxa27x_udc *dev)
++{
++ dev->ep0state = EP0_IDLE;
++ LED_EP0_OFF;
++}
++
++static int
++write_packet(volatile u32 *uddr, struct pxa27x_request *req, unsigned max)
++{
++ u32 *buf;
++ int length, count, remain;
++
++ buf = (u32*)(req->req.buf + req->req.actual);
++ prefetch(buf);
++
++ /* how big will this packet be? */
++ length = min(req->req.length - req->req.actual, max);
++ req->req.actual += length;
++
++ remain = length & 0x3;
++ count = length & ~(0x3);
++
++ while (likely(count)) {
++ *uddr = *buf++;
++ count -= 4;
++ }
++
++ if (remain) {
++ volatile u8* reg=(u8*)uddr;
++ char *rd =(u8*)buf;
++
++ while (remain--) {
++ *reg=*rd++;
++ }
++ }
++
++ return length;
++}
++
++/*
++ * write to an IN endpoint fifo, as many packets as possible.
++ * irqs will use this to write the rest later.
++ * caller guarantees at least one packet buffer is ready (or a zlp).
++ */
++static int
++write_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ unsigned max;
++
++ max = le16_to_cpu(ep->desc->wMaxPacketSize);
++ do {
++ int count;
++ int is_last, is_short;
++
++ count = write_packet(ep->reg_udcdr, req, max);
++
++ /* last packet is usually short (or a zlp) */
++ if (unlikely (count != max))
++ is_last = is_short = 1;
++ else {
++ if (likely(req->req.length != req->req.actual)
++ || req->req.zero)
++ is_last = 0;
++ else
++ is_last = 1;
++ /* interrupt/iso maxpacket may not fill the fifo */
++ is_short = unlikely (max < ep->fifo_size);
++ }
++
++ DMSG("wrote %s count:%d bytes%s%s %d left %p\n",
++ ep->ep.name, count,
++ is_last ? "/L" : "", is_short ? "/S" : "",
++ req->req.length - req->req.actual, &req->req);
++
++ /* let loose that packet. maybe try writing another one,
++ * double buffering might work. TSP, TPC, and TFS
++ * bit values are the same for all normal IN endpoints.
++ */
++ *ep->reg_udccsr = UDCCSR_PC;
++ if (is_short)
++ *ep->reg_udccsr = UDCCSR_SP;
++
++ /* requests complete when all IN data is in the FIFO */
++ if (is_last) {
++ done (ep, req, 0);
++ if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) {
++ pio_irq_disable (ep->ep_num);
++#ifdef USE_DMA
++ /* unaligned data and zlps couldn't use dma */
++ if (unlikely(!list_empty(&ep->queue))) {
++ req = list_entry(ep->queue.next,
++ struct pxa27x_request, queue);
++ kick_dma(ep,req);
++ return 0;
++ }
++#endif
++ }
++ return 1;
++ }
++
++ // TODO experiment: how robust can fifo mode tweaking be?
++ // double buffering is off in the default fifo mode, which
++ // prevents TFS from being set here.
++
++ } while (*ep->reg_udccsr & UDCCSR_FS);
++ return 0;
++}
++
++/* caller asserts req->pending (ep0 irq status nyet cleared); starts
++ * ep0 data stage. these chips want very simple state transitions.
++ */
++static inline
++void ep0start(struct pxa27x_udc *dev, u32 flags, const char *tag)
++{
++ UDCCSR0 = flags|UDCCSR0_SA|UDCCSR0_OPC;
++ UDCISR0 = UDCICR_INT(0, UDC_INT_FIFOERROR | UDC_INT_PACKETCMP);
++ dev->req_pending = 0;
++ DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",
++ __FUNCTION__, tag, UDCCSR0, flags);
++}
++
++static int
++write_ep0_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ unsigned count;
++ int is_short;
++
++ count = write_packet(&UDCDR0, req, EP0_FIFO_SIZE);
++ ep->dev->stats.write.bytes += count;
++
++ /* last packet "must be" short (or a zlp) */
++ is_short = (count != EP0_FIFO_SIZE);
++
++ DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count,
++ req->req.length - req->req.actual, &req->req);
++
++ if (unlikely (is_short)) {
++ if (ep->dev->req_pending)
++ ep0start(ep->dev, UDCCSR0_IPR, "short IN");
++ else
++ UDCCSR0 = UDCCSR0_IPR;
++
++ count = req->req.length;
++ done (ep, req, 0);
++ ep0_idle(ep->dev);
++#if 0
++ /* This seems to get rid of lost status irqs in some cases:
++ * host responds quickly, or next request involves config
++ * change automagic, or should have been hidden, or ...
++ *
++ * FIXME get rid of all udelays possible...
++ */
++ if (count >= EP0_FIFO_SIZE) {
++ count = 100;
++ do {
++ if ((UDCCSR0 & UDCCSR0_OPC) != 0) {
++ /* clear OPC, generate ack */
++ UDCCSR0 = UDCCSR0_OPC;
++ break;
++ }
++ count--;
++ udelay(1);
++ } while (count);
++ }
++#endif
++ } else if (ep->dev->req_pending)
++ ep0start(ep->dev, 0, "IN");
++ return is_short;
++}
++
++
++/*
++ * read_fifo - unload packet(s) from the fifo we use for usb OUT
++ * transfers and put them into the request. caller should have made
++ * sure there's at least one packet ready.
++ *
++ * returns true if the request completed because of short packet or the
++ * request buffer having filled (and maybe overran till end-of-packet).
++ */
++static int
++read_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ for (;;) {
++ u32 *buf;
++ int bufferspace, count, is_short;
++
++ /* make sure there's a packet in the FIFO.*/
++ if (unlikely ((*ep->reg_udccsr & UDCCSR_PC) == 0))
++ break;
++ buf =(u32*) (req->req.buf + req->req.actual);
++ prefetchw(buf);
++ bufferspace = req->req.length - req->req.actual;
++
++ /* read all bytes from this packet */
++ if (likely (*ep->reg_udccsr & UDCCSR_BNE)) {
++ count = 0x3ff & *ep->reg_udcbcr;
++ req->req.actual += min (count, bufferspace);
++ } else /* zlp */
++ count = 0;
++
++ is_short = (count < ep->ep.maxpacket);
++ DMSG("read %s udccsr:%02x, count:%d bytes%s req %p %d/%d\n",
++ ep->ep.name, *ep->reg_udccsr, count,
++ is_short ? "/S" : "",
++ &req->req, req->req.actual, req->req.length);
++
++// dump_regs(ep->ep_num );
++ count = min(count, bufferspace);
++ while (likely (count > 0)) {
++ *buf++ = *ep->reg_udcdr;
++ count -= 4;
++ }
++ DMSG("Buf:0x%p\n", req->req.buf);
++
++ *ep->reg_udccsr = UDCCSR_PC;
++ /* RPC/RSP/RNE could now reflect the other packet buffer */
++
++ /* completion */
++ if (is_short || req->req.actual == req->req.length) {
++ done (ep, req, 0);
++ if (list_empty(&ep->queue))
++ pio_irq_disable (ep->ep_num);
++ return 1;
++ }
++
++ /* finished that packet. the next one may be waiting... */
++ }
++ return 0;
++}
++
++/*
++ * special ep0 version of the above. no UBCR0 or double buffering; status
++ * handshaking is magic. most device protocols don't need control-OUT.
++ * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other
++ * protocols do use them.
++ */
++static int
++read_ep0_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ u32 *buf, word;
++ unsigned bufferspace;
++
++ buf = (u32*) (req->req.buf + req->req.actual);
++ bufferspace = req->req.length - req->req.actual;
++
++ while (UDCCSR0 & UDCCSR0_RNE) {
++ word = UDCDR0;
++
++ if (unlikely (bufferspace == 0)) {
++ /* this happens when the driver's buffer
++ * is smaller than what the host sent.
++ * discard the extra data.
++ */
++ if (req->req.status != -EOVERFLOW)
++ DMSG("%s overflow\n", ep->ep.name);
++ req->req.status = -EOVERFLOW;
++ } else {
++ *buf++ = word;
++ req->req.actual += 4;
++ bufferspace -= 4;
++ }
++ }
++
++ UDCCSR0 = UDCCSR0_OPC ;
++
++ /* completion */
++ if (req->req.actual >= req->req.length)
++ return 1;
++
++ /* finished that packet. the next one may be waiting... */
++ return 0;
++}
++
++#ifdef USE_DMA
++
++#define MAX_IN_DMA ((DCMD_LENGTH + 1) - BULK_FIFO_SIZE)
++static void kick_dma(struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ u32 dcmd = 0;
++ u32 len = req->req.length;
++ u32 buf = req->req.dma;
++ u32 fifo = io_v2p ((u32)ep->reg_udcdr);
++
++ buf += req->req.actual;
++ len -= req->req.actual;
++ ep->dma_con = 0;
++
++ DMSG("%s: req:0x%p length:%d, actual:%d dma:%d\n",
++ __FUNCTION__, &req->req, req->req.length,
++ req->req.actual,ep->dma);
++
++ /* no-descriptor mode can be simple for bulk-in, iso-in, iso-out */
++ DCSR(ep->dma) = DCSR_NODESC;
++ if (buf & 0x3)
++ DALGN |= 1 << ep->dma;
++ else
++ DALGN &= ~(1 << ep->dma);
++
++ if (ep->dir_in) {
++ DSADR(ep->dma) = buf;
++ DTADR(ep->dma) = fifo;
++ if (len > MAX_IN_DMA) {
++ len= MAX_IN_DMA;
++ ep->dma_con =1 ;
++ } else if (len >= ep->ep.maxpacket) {
++ if ((ep->dma_con = (len % ep->ep.maxpacket) != 0))
++ len = ep->ep.maxpacket;
++ }
++ dcmd = len | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN
++ | DCMD_FLOWTRG | DCMD_INCSRCADDR;
++ } else {
++ DSADR(ep->dma) = fifo;
++ DTADR(ep->dma) = buf;
++ dcmd = len | DCMD_BURST32 | DCMD_WIDTH4 | DCMD_ENDIRQEN
++ | DCMD_FLOWSRC | DCMD_INCTRGADDR;
++ }
++ *ep->reg_udccsr = UDCCSR_DME;
++ DCMD(ep->dma) = dcmd;
++ DCSR(ep->dma) = DCSR_NODESC | DCSR_EORIRQEN \
++ | ((ep->dir_in) ? DCSR_STOPIRQEN : 0);
++ *ep->reg_drcmr = ep->dma | DRCMR_MAPVLD;
++ DCSR(ep->dma) |= DCSR_RUN;
++}
++
++static void cancel_dma(struct pxa27x_ep *ep)
++{
++ struct pxa27x_request *req;
++ u32 tmp;
++
++ if (DCSR(ep->dma) == 0 || list_empty(&ep->queue))
++ return;
++
++ DMSG("hehe dma:%d,dcsr:0x%x\n", ep->dma, DCSR(ep->dma));
++ DCSR(ep->dma) = 0;
++ while ((DCSR(ep->dma) & DCSR_STOPSTATE) == 0)
++ cpu_relax();
++
++ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
++ tmp = DCMD(ep->dma) & DCMD_LENGTH;
++ req->req.actual = req->req.length - tmp;
++
++ /* the last tx packet may be incomplete, so flush the fifo.
++ * FIXME correct req.actual if we can
++ */
++ *ep->reg_udccsr = UDCCSR_FEF;
++}
++
++static void dma_nodesc_handler(int dmach, void *_ep, struct pt_regs *r)
++{
++ struct pxa27x_ep *ep = _ep;
++ struct pxa27x_request *req, *req_next;
++ u32 dcsr, tmp, completed;
++
++ local_irq_disable();
++
++ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
++
++ DMSG("%s, buf:0x%p\n",__FUNCTION__, req->req.buf);
++
++ ep->dma_irqs++;
++ ep->dev->stats.irqs++;
++ HEX_DISPLAY(ep->dev->stats.irqs);
++
++ completed = 0;
++
++ dcsr = DCSR(dmach);
++ DCSR(ep->dma) &= ~DCSR_RUN;
++
++ if (dcsr & DCSR_BUSERR) {
++ DCSR(dmach) = DCSR_BUSERR;
++ printk(KERN_ERR " Buss Error\n");
++ req->req.status = -EIO;
++ completed = 1;
++ } else if (dcsr & DCSR_ENDINTR) {
++ DCSR(dmach) = DCSR_ENDINTR;
++ if (ep->dir_in) {
++ tmp = req->req.length - req->req.actual;
++ /* Last packet is a short one*/
++ if ( tmp < ep->ep.maxpacket) {
++ int count = 0;
++
++ *ep->reg_udccsr = UDCCSR_SP | \
++ (*ep->reg_udccsr & UDCCSR_MASK);
++ /*Wait for packet out */
++ while( (count++ < 10000) && \
++ !(*ep->reg_udccsr & UDCCSR_FS));
++ if (count >= 10000)
++ DMSG("Failed to send packet\n");
++ else
++ DMSG("%s: short packet sent len:%d,"
++ "length:%d,actual:%d\n", __FUNCTION__,
++ tmp, req->req.length, req->req.actual);
++ req->req.actual = req->req.length;
++ completed = 1;
++ /* There are still packets to transfer */
++ } else if ( ep->dma_con) {
++ DMSG("%s: more packets,length:%d,actual:%d\n",
++ __FUNCTION__,req->req.length,
++ req->req.actual);
++ req->req.actual += ep->ep.maxpacket;
++ completed = 0;
++ } else {
++ DMSG("%s: no more packets,length:%d,"
++ "actual:%d\n", __FUNCTION__,
++ req->req.length, req->req.actual);
++ req->req.actual = req->req.length;
++ completed = 1;
++ }
++ } else {
++ req->req.actual = req->req.length;
++ completed = 1;
++ }
++ } else if (dcsr & DCSR_EORINTR) { //Only happened in OUT DMA
++ int remain,udccsr ;
++
++ DCSR(dmach) = DCSR_EORINTR;
++ remain = DCMD(dmach) & DCMD_LENGTH;
++ req->req.actual = req->req.length - remain;
++
++ udccsr = *ep->reg_udccsr;
++ if (udccsr & UDCCSR_SP) {
++ *ep->reg_udccsr = UDCCSR_PC | (udccsr & UDCCSR_MASK);
++ completed = 1;
++ }
++ DMSG("%s: length:%d actual:%d\n",
++ __FUNCTION__, req->req.length, req->req.actual);
++ } else
++ DMSG("%s: Others dma:%d DCSR:0x%x DCMD:0x%x\n",
++ __FUNCTION__, dmach, DCSR(dmach), DCMD(dmach));
++
++ if (likely(completed)) {
++ if (req->queue.next != &ep->queue) {
++ req_next = list_entry(req->queue.next,
++ struct pxa27x_request, queue);
++ kick_dma(ep, req_next);
++ }
++ done(ep, req, 0);
++ } else {
++ kick_dma(ep, req);
++ }
++
++ local_irq_enable();
++}
++
++#endif
++/*-------------------------------------------------------------------------*/
++
++static int pxa27x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
++{
++ struct pxa27x_ep *ep;
++ struct pxa27x_request *req;
++ struct pxa27x_udc *dev;
++ unsigned long flags;
++
++ req = container_of(_req, struct pxa27x_request, req);
++ if (unlikely (!_req || !_req->complete || !_req->buf||
++ !list_empty(&req->queue))) {
++ DMSG("%s, bad params\n", __FUNCTION__);
++ return -EINVAL;
++ }
++
++ ep = container_of(_ep, struct pxa27x_ep, ep);
++ if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
++ DMSG("%s, bad ep\n", __FUNCTION__);
++ return -EINVAL;
++ }
++
++ DMSG("%s, ep point %d is queue\n", __FUNCTION__, ep->ep_num);
++
++ dev = ep->dev;
++ if (unlikely (!dev->driver
++ || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
++ DMSG("%s, bogus device state\n", __FUNCTION__);
++ return -ESHUTDOWN;
++ }
++
++ /* iso is always one packet per request, that's the only way
++ * we can report per-packet status. that also helps with dma.
++ */
++ if (unlikely (ep->ep_type == USB_ENDPOINT_XFER_ISOC
++ && req->req.length > le16_to_cpu
++ (ep->desc->wMaxPacketSize)))
++ return -EMSGSIZE;
++
++#ifdef USE_DMA
++ // FIXME caller may already have done the dma mapping
++ if (ep->dma >= 0) {
++ _req->dma = dma_map_single(dev->dev, _req->buf, _req->length,
++ (ep->dir_in) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
++ }
++#endif
++
++ DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
++ _ep->name, _req, _req->length, _req->buf);
++
++ local_irq_save(flags);
++
++ _req->status = -EINPROGRESS;
++ _req->actual = 0;
++
++ /* kickstart this i/o queue? */
++ if (list_empty(&ep->queue) && !ep->stopped) {
++ if (ep->desc == 0 /* ep0 */) {
++ unsigned length = _req->length;
++
++ switch (dev->ep0state) {
++ case EP0_IN_DATA_PHASE:
++ dev->stats.write.ops++;
++ if (write_ep0_fifo(ep, req))
++ req = 0;
++ break;
++
++ case EP0_OUT_DATA_PHASE:
++ dev->stats.read.ops++;
++ if (dev->req_pending)
++ ep0start(dev, UDCCSR0_IPR, "OUT");
++ if (length == 0 || ((UDCCSR0 & UDCCSR0_RNE) != 0
++ && read_ep0_fifo(ep, req))) {
++ ep0_idle(dev);
++ done(ep, req, 0);
++ req = 0;
++ }
++ break;
++ case EP0_NO_ACTION:
++ ep0_idle(dev);
++ req=0;
++ break;
++ default:
++ DMSG("ep0 i/o, odd state %d\n", dev->ep0state);
++ local_irq_restore (flags);
++ return -EL2HLT;
++ }
++#ifdef USE_DMA
++ /* either start dma or prime pio pump */
++ } else if (ep->dma >= 0) {
++ kick_dma(ep, req);
++#endif
++ /* can the FIFO can satisfy the request immediately? */
++ } else if (ep->dir_in
++ && (*ep->reg_udccsr & UDCCSR_FS) != 0
++ && write_fifo(ep, req)) {
++ req = 0;
++ } else if ((*ep->reg_udccsr & UDCCSR_FS) != 0
++ && read_fifo(ep, req)) {
++ req = 0;
++ }
++ DMSG("req:%p,ep->desc:%p,ep->dma:%d\n", req, ep->desc, ep->dma);
++ if (likely (req && ep->desc) && ep->dma < 0)
++ pio_irq_enable(ep->ep_num);
++ }
++
++ /* pio or dma irq handler advances the queue. */
++ if (likely (req != 0))
++ list_add_tail(&req->queue, &ep->queue);
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++
++/*
++ * nuke - dequeue ALL requests
++ */
++static void nuke(struct pxa27x_ep *ep, int status)
++{
++ struct pxa27x_request *req;
++
++ /* called with irqs blocked */
++#ifdef USE_DMA
++ if (ep->dma >= 0 && !ep->stopped)
++ cancel_dma(ep);
++#endif
++ while (!list_empty(&ep->queue)) {
++ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
++ done(ep, req, status);
++ }
++ if (ep->desc)
++ pio_irq_disable (ep->ep_num);
++}
++
++
++/* dequeue JUST ONE request */
++static int pxa27x_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct pxa27x_ep *ep;
++ struct pxa27x_request *req;
++ unsigned long flags;
++
++ ep = container_of(_ep, struct pxa27x_ep, ep);
++ if (!_ep || ep->ep.name == ep0name)
++ return -EINVAL;
++
++ local_irq_save(flags);
++
++ /* make sure it's actually queued on this endpoint */
++ list_for_each_entry (req, &ep->queue, queue) {
++ if (&req->req == _req)
++ break;
++ }
++ if (&req->req != _req) {
++ local_irq_restore(flags);
++ return -EINVAL;
++ }
++
++#ifdef USE_DMA
++ if (ep->dma >= 0 && ep->queue.next == &req->queue && !ep->stopped) {
++ cancel_dma(ep);
++ done(ep, req, -ECONNRESET);
++ /* restart i/o */
++ if (!list_empty(&ep->queue)) {
++ req = list_entry(ep->queue.next,
++ struct pxa27x_request, queue);
++ kick_dma(ep, req);
++ }
++ } else
++#endif
++ done(ep, req, -ECONNRESET);
++
++ local_irq_restore(flags);
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static int pxa27x_ep_set_halt(struct usb_ep *_ep, int value)
++{
++ struct pxa27x_ep *ep;
++ unsigned long flags;
++
++ DMSG("%s is called\n", __FUNCTION__);
++ ep = container_of(_ep, struct pxa27x_ep, ep);
++ if (unlikely (!_ep
++ || (!ep->desc && ep->ep.name != ep0name))
++ || ep->ep_type == USB_ENDPOINT_XFER_ISOC) {
++ DMSG("%s, bad ep\n", __FUNCTION__);
++ return -EINVAL;
++ }
++ if (value == 0) {
++ /* this path (reset toggle+halt) is needed to implement
++ * SET_INTERFACE on normal hardware. but it can't be
++ * done from software on the PXA UDC, and the hardware
++ * forgets to do it as part of SET_INTERFACE automagic.
++ */
++ DMSG("only host can clear %s halt\n", _ep->name);
++ return -EROFS;
++ }
++
++ local_irq_save(flags);
++
++ if (ep->dir_in && ((*ep->reg_udccsr & UDCCSR_FS) == 0
++ || !list_empty(&ep->queue))) {
++ local_irq_restore(flags);
++ return -EAGAIN;
++ }
++
++ /* FST bit is the same for control, bulk in, bulk out, interrupt in */
++ *ep->reg_udccsr = UDCCSR_FST|UDCCSR_FEF;
++
++ /* ep0 needs special care */
++ if (!ep->desc) {
++ start_watchdog(ep->dev);
++ ep->dev->req_pending = 0;
++ ep->dev->ep0state = EP0_STALL;
++ LED_EP0_OFF;
++
++ /* and bulk/intr endpoints like dropping stalls too */
++ } else {
++ unsigned i;
++ for (i = 0; i < 1000; i += 20) {
++ if (*ep->reg_udccsr & UDCCSR_SST)
++ break;
++ udelay(20);
++ }
++ }
++ local_irq_restore(flags);
++
++ DBG(DBG_VERBOSE, "%s halt\n", _ep->name);
++ return 0;
++}
++
++static int pxa27x_ep_fifo_status(struct usb_ep *_ep)
++{
++ struct pxa27x_ep *ep;
++
++ ep = container_of(_ep, struct pxa27x_ep, ep);
++ if (!_ep) {
++ DMSG("%s, bad ep\n", __FUNCTION__);
++ return -ENODEV;
++ }
++ /* pxa can't report unclaimed bytes from IN fifos */
++ if (ep->dir_in)
++ return -EOPNOTSUPP;
++ if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN
++ || (*ep->reg_udccsr & UDCCSR_FS) == 0)
++ return 0;
++ else
++ return (*ep->reg_udcbcr & 0xfff) + 1;
++}
++
++static void pxa27x_ep_fifo_flush(struct usb_ep *_ep)
++{
++ struct pxa27x_ep *ep;
++
++ ep = container_of(_ep, struct pxa27x_ep, ep);
++ if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) {
++ DMSG("%s, bad ep\n", __FUNCTION__);
++ return;
++ }
++
++ /* toggle and halt bits stay unchanged */
++
++ /* for OUT, just read and discard the FIFO contents. */
++ if (!ep->dir_in) {
++ while (((*ep->reg_udccsr) & UDCCSR_BNE) != 0)
++ (void) *ep->reg_udcdr;
++ return;
++ }
++
++ /* most IN status is the same, but ISO can't stall */
++ *ep->reg_udccsr = UDCCSR_PC|UDCCSR_FST|UDCCSR_TRN
++ | (ep->ep_type == USB_ENDPOINT_XFER_ISOC)
++ ? 0 : UDCCSR_SST;
++}
++
++
++static struct usb_ep_ops pxa27x_ep_ops = {
++ .enable = pxa27x_ep_enable,
++ .disable = pxa27x_ep_disable,
++
++ .alloc_request = (void *)pxa27x_ep_alloc_request,
++ .free_request = pxa27x_ep_free_request,
++
++ .alloc_buffer = (void *)pxa27x_ep_alloc_buffer,
++ .free_buffer = pxa27x_ep_free_buffer,
++
++ .queue = (void *)pxa27x_ep_queue,
++ .dequeue = pxa27x_ep_dequeue,
++
++ .set_halt = pxa27x_ep_set_halt,
++ .fifo_status = pxa27x_ep_fifo_status,
++ .fifo_flush = pxa27x_ep_fifo_flush,
++};
++
++
++/* ---------------------------------------------------------------------------
++ * device-scoped parts of the api to the usb controller hardware
++ * ---------------------------------------------------------------------------
++ */
++
++static int pxa27x_udc_get_frame(struct usb_gadget *_gadget)
++{
++ return (UDCFNR & 0x3FF);
++}
++
++static int pxa27x_udc_wakeup(struct usb_gadget *_gadget)
++{
++ /* host may not have enabled remote wakeup */
++ if ((UDCCR & UDCCR_DWRE) == 0)
++ return -EHOSTUNREACH;
++ udc_set_mask_UDCCR(UDCCR_UDR);
++ return 0;
++}
++
++static const struct usb_gadget_ops pxa27x_udc_ops = {
++ .get_frame = pxa27x_udc_get_frame,
++ .wakeup = pxa27x_udc_wakeup,
++ // current versions must always be self-powered
++};
++
++
++/*-------------------------------------------------------------------------*/
++
++#ifdef UDC_PROC_FILE
++
++static const char proc_node_name [] = "driver/udc";
++
++static int
++udc_proc_read(char *page, char **start, off_t off, int count,
++ int *eof, void *_dev)
++{
++ char *buf = page;
++ struct pxa27x_udc *dev = _dev;
++ char *next = buf;
++ unsigned size = count;
++ unsigned long flags;
++ int i, t;
++ u32 tmp;
++
++ if (off != 0)
++ return 0;
++
++ local_irq_save(flags);
++
++ /* basic device status */
++ t = scnprintf(next, size, DRIVER_DESC "\n"
++ "%s version: %s\nGadget driver: %s\n",
++ driver_name, DRIVER_VERSION SIZE_STR DMASTR,
++ dev->driver ? dev->driver->driver.name : "(none)");
++ size -= t;
++ next += t;
++
++ /* registers for device and ep0 */
++ t = scnprintf(next, size,
++ "uicr %02X.%02X, usir %02X.%02x, ufnr %02X\n",
++ UDCICR1, UDCICR0, UDCISR1, UDCISR0, UDCFNR);
++ size -= t;
++ next += t;
++
++ tmp = UDCCR;
++ t = scnprintf(next, size,"udccr %02X =%s%s%s%s%s%s%s%s%s%s, con=%d,inter=%d,altinter=%d\n", tmp,
++ (tmp & UDCCR_OEN) ? " oen":"",
++ (tmp & UDCCR_AALTHNP) ? " aalthnp":"",
++ (tmp & UDCCR_AHNP) ? " rem" : "",
++ (tmp & UDCCR_BHNP) ? " rstir" : "",
++ (tmp & UDCCR_DWRE) ? " dwre" : "",
++ (tmp & UDCCR_SMAC) ? " smac" : "",
++ (tmp & UDCCR_EMCE) ? " emce" : "",
++ (tmp & UDCCR_UDR) ? " udr" : "",
++ (tmp & UDCCR_UDA) ? " uda" : "",
++ (tmp & UDCCR_UDE) ? " ude" : "",
++ (tmp & UDCCR_ACN) >> UDCCR_ACN_S,
++ (tmp & UDCCR_AIN) >> UDCCR_AIN_S,
++ (tmp & UDCCR_AAISN)>> UDCCR_AAISN_S );
++
++ size -= t;
++ next += t;
++
++ tmp = UDCCSR0;
++ t = scnprintf(next, size,
++ "udccsr0 %02X =%s%s%s%s%s%s%s\n", tmp,
++ (tmp & UDCCSR0_SA) ? " sa" : "",
++ (tmp & UDCCSR0_RNE) ? " rne" : "",
++ (tmp & UDCCSR0_FST) ? " fst" : "",
++ (tmp & UDCCSR0_SST) ? " sst" : "",
++ (tmp & UDCCSR0_DME) ? " dme" : "",
++ (tmp & UDCCSR0_IPR) ? " ipr" : "",
++ (tmp & UDCCSR0_OPC) ? " opc" : "");
++ size -= t;
++ next += t;
++
++ if (!dev->driver)
++ goto done;
++
++ t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
++ dev->stats.write.bytes, dev->stats.write.ops,
++ dev->stats.read.bytes, dev->stats.read.ops,
++ dev->stats.irqs);
++ size -= t;
++ next += t;
++
++ /* dump endpoint queues */
++ for (i = 0; i < UDC_EP_NUM; i++) {
++ struct pxa27x_ep *ep = &dev->ep [i];
++ struct pxa27x_request *req;
++ int t;
++
++ if (i != 0) {
++ const struct usb_endpoint_descriptor *d;
++
++ d = ep->desc;
++ if (!d)
++ continue;
++ tmp = *dev->ep [i].reg_udccsr;
++ t = scnprintf(next, size,
++ "%s max %d %s udccs %02x udccr:0x%x\n",
++ ep->ep.name, le16_to_cpu (d->wMaxPacketSize),
++ (ep->dma >= 0) ? "dma" : "pio", tmp,
++ *dev->ep[i].reg_udccr);
++ /* TODO translate all five groups of udccs bits! */
++
++ } else /* ep0 should only have one transfer queued */
++ t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n",
++ ep->pio_irqs);
++ if (t <= 0 || t > size)
++ goto done;
++ size -= t;
++ next += t;
++
++ if (list_empty(&ep->queue)) {
++ t = scnprintf(next, size, "\t(nothing queued)\n");
++ if (t <= 0 || t > size)
++ goto done;
++ size -= t;
++ next += t;
++ continue;
++ }
++ list_for_each_entry(req, &ep->queue, queue) {
++#ifdef USE_DMA
++ if (ep->dma >= 0 && req->queue.prev == &ep->queue)
++ t = scnprintf(next, size,
++ "\treq %p len %d/%d "
++ "buf %p (dma%d dcmd %08x)\n",
++ &req->req, req->req.actual,
++ req->req.length, req->req.buf,
++ ep->dma, DCMD(ep->dma)
++ // low 13 bits == bytes-to-go
++ );
++ else
++#endif
++ t = scnprintf(next, size,
++ "\treq %p len %d/%d buf %p\n",
++ &req->req, req->req.actual,
++ req->req.length, req->req.buf);
++ if (t <= 0 || t > size)
++ goto done;
++ size -= t;
++ next += t;
++ }
++ }
++
++done:
++ local_irq_restore(flags);
++ *eof = 1;
++ return count - size;
++}
++
++#define create_proc_files() \
++ create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev)
++#define remove_proc_files() \
++ remove_proc_entry(proc_node_name, NULL)
++
++#else /* !UDC_PROC_FILE */
++#define create_proc_files() do {} while (0)
++#define remove_proc_files() do {} while (0)
++
++#endif /* UDC_PROC_FILE */
++
++/* "function" sysfs attribute */
++static ssize_t
++show_function (struct device *_dev, char *buf)
++{
++ struct pxa27x_udc *dev = dev_get_drvdata (_dev);
++
++ if (!dev->driver
++ || !dev->driver->function
++ || strlen (dev->driver->function) > PAGE_SIZE)
++ return 0;
++ return scnprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function);
++}
++static DEVICE_ATTR (function, S_IRUGO, (void *)show_function, NULL);
++//static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
++/*-------------------------------------------------------------------------*/
++
++/*
++ * udc_disable - disable USB device controller
++ */
++static void udc_disable(struct pxa27x_udc *dev)
++{
++ UDCICR0 = UDCICR1 = 0x00000000;
++
++ udc_clear_mask_UDCCR(UDCCR_UDE);
++
++ /* Disable clock for USB device */
++ pxa_set_cken(CKEN11_USB, 0);
++
++ ep0_idle (dev);
++ dev->gadget.speed = USB_SPEED_UNKNOWN;
++ LED_CONNECTED_OFF;
++}
++
++
++/*
++ * udc_reinit - initialize software state
++ */
++static void udc_reinit(struct pxa27x_udc *dev)
++{
++ u32 i;
++
++ dev->ep0state = EP0_IDLE;
++
++ /* basic endpoint records init */
++ for (i = 0; i < UDC_EP_NUM; i++) {
++ struct pxa27x_ep *ep = &dev->ep[i];
++
++ ep->stopped = 0;
++ ep->pio_irqs = ep->dma_irqs = 0;
++ }
++ dev->configuration = 0;
++ dev->interface = 0;
++ dev->alternate = 0;
++ /* the rest was statically initialized, and is read-only */
++}
++
++/* until it's enabled, this UDC should be completely invisible
++ * to any USB host.
++ */
++static void udc_enable (struct pxa27x_udc *dev)
++{
++ udc_clear_mask_UDCCR(UDCCR_UDE);
++#ifdef CONFIG_MACH_MAINSTONE
++ MST_MSCWR2 &= ~(MST_MSCWR2_nUSBC_SC);
++#endif
++
++ /* Enable clock for USB device */
++ pxa_set_cken(CKEN11_USB, 1);
++
++ UDCICR0 = UDCICR1 = 0;
++
++ ep0_idle(dev);
++ dev->gadget.speed = USB_SPEED_FULL;
++ dev->stats.irqs = 0;
++
++ udc_set_mask_UDCCR(UDCCR_UDE);
++ udelay (2);
++ if (UDCCR & UDCCR_EMCE)
++ {
++ printk(KERN_ERR ": There are error in configuration, udc disabled\n");
++ }
++
++ /* caller must be able to sleep in order to cope
++ * with startup transients.
++ */
++ msleep(100);
++
++ /* enable suspend/resume and reset irqs */
++ UDCICR1 = UDCICR1_IECC | UDCICR1_IERU | UDCICR1_IESU | UDCICR1_IERS;
++
++ /* enable ep0 irqs */
++ UDCICR0 = UDCICR_INT(0,UDCICR_INT_MASK);
++#if 0
++ for(i=1; i < UDC_EP_NUM; i++) {
++ if (dev->ep[i].assigned)
++ pio_irq_enable(i);
++ }
++#endif
++}
++
++
++/* when a driver is successfully registered, it will receive
++ * control requests including set_configuration(), which enables
++ * non-control requests. then usb traffic follows until a
++ * disconnect is reported. then a host may connect again, or
++ * the driver might get unbound.
++ */
++int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++{
++ struct pxa27x_udc *dev = the_controller;
++ int retval;
++
++#if 0
++ DMSG("dev=0x%x, driver=0x%x, speed=%d,"
++ "bind=0x%x, unbind=0x%x, disconnect=0x%x, setup=0x%x\n",
++ (unsigned)dev, (unsigned)driver, driver->speed,
++ (unsigned)driver->bind, (unsigned)driver->unbind,
++ (unsigned)driver->disconnect, (unsigned)driver->setup);
++#endif
++ if (!driver || driver->speed != USB_SPEED_FULL
++ || !driver->bind
++ || !driver->unbind
++ || !driver->disconnect
++ || !driver->setup)
++ {
++ return -EINVAL;
++ }
++ if (!dev)
++ {
++ return -ENODEV;
++ }
++ if (dev->driver)
++ {
++ return -EBUSY;
++ }
++ /* first hook up the driver ... */
++ dev->driver = driver;
++ dev->gadget.dev.driver = &driver->driver;
++
++ device_add (&dev->gadget.dev);
++ retval = driver->bind(&dev->gadget);
++ if (retval) {
++ DMSG("bind to driver %s --> error %d\n",
++ driver->driver.name, retval);
++ device_del (&dev->gadget.dev);
++
++ dev->driver = 0;
++ dev->gadget.dev.driver = 0;
++ return retval;
++ }
++ device_create_file(dev->dev, &dev_attr_function);
++
++ /* ... then enable host detection and ep0; and we're ready
++ * for set_configuration as well as eventual disconnect.
++ * NOTE: this shouldn't power up until later.
++ */
++ DMSG("registered gadget driver '%s'\n", driver->driver.name);
++ udc_enable(dev);
++ dump_state(dev);
++ return 0;
++}
++EXPORT_SYMBOL(usb_gadget_register_driver);
++
++static void
++stop_activity(struct pxa27x_udc *dev, struct usb_gadget_driver *driver)
++{
++ int i;
++
++ DMSG("Trace path 1\n");
++ /* don't disconnect drivers more than once */
++ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
++ driver = 0;
++ dev->gadget.speed = USB_SPEED_UNKNOWN;
++
++ /* prevent new request submissions, kill any outstanding requests */
++ for (i = 0; i < UDC_EP_NUM; i++) {
++ struct pxa27x_ep *ep = &dev->ep[i];
++
++ ep->stopped = 1;
++ nuke(ep, -ESHUTDOWN);
++ }
++ del_timer_sync(&dev->timer);
++
++ /* report disconnect; the driver is already quiesced */
++ if (driver)
++ driver->disconnect(&dev->gadget);
++
++ /* re-init driver-visible data structures */
++ udc_reinit(dev);
++}
++
++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
++{
++ struct pxa27x_udc *dev = the_controller;
++
++ if (!dev)
++ return -ENODEV;
++ if (!driver || driver != dev->driver)
++ return -EINVAL;
++
++ local_irq_disable();
++ udc_disable(dev);
++ stop_activity(dev, driver);
++ local_irq_enable();
++
++ driver->unbind(&dev->gadget);
++ dev->driver = 0;
++
++ device_del (&dev->gadget.dev);
++ device_remove_file(dev->dev, &dev_attr_function);
++
++ DMSG("unregistered gadget driver '%s'\n", driver->driver.name);
++ dump_state(dev);
++ return 0;
++}
++EXPORT_SYMBOL(usb_gadget_unregister_driver);
++
++#ifndef enable_disconnect_irq
++#define enable_disconnect_irq() do {} while (0)
++#define disable_disconnect_irq() do {} while (0)
++#endif
++
++
++/*-------------------------------------------------------------------------*/
++
++static inline void clear_ep_state (struct pxa27x_udc *dev)
++{
++ unsigned i;
++
++ /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
++ * fifos, and pending transactions mustn't be continued in any case.
++ */
++ for (i = 1; i < UDC_EP_NUM; i++)
++ nuke(&dev->ep[i], -ECONNABORTED);
++}
++
++static void udc_watchdog(unsigned long _dev)
++{
++ struct pxa27x_udc *dev = (void *)_dev;
++
++ local_irq_disable();
++ if (dev->ep0state == EP0_STALL
++ && (UDCCSR0 & UDCCSR0_FST) == 0
++ && (UDCCSR0 & UDCCSR0_SST) == 0) {
++ UDCCSR0 = UDCCSR0_FST|UDCCSR0_FTF;
++ DBG(DBG_VERBOSE, "ep0 re-stall\n");
++ start_watchdog(dev);
++ }
++ local_irq_enable();
++}
++
++static void handle_ep0 (struct pxa27x_udc *dev)
++{
++ u32 udccsr0 = UDCCSR0;
++ struct pxa27x_ep *ep = &dev->ep [0];
++ struct pxa27x_request *req;
++ union {
++ struct usb_ctrlrequest r;
++ u8 raw [8];
++ u32 word [2];
++ } u;
++
++ if (list_empty(&ep->queue))
++ req = 0;
++ else
++ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
++
++ /* clear stall status */
++ if (udccsr0 & UDCCSR0_SST) {
++ nuke(ep, -EPIPE);
++ UDCCSR0 = UDCCSR0_SST;
++ del_timer(&dev->timer);
++ ep0_idle(dev);
++ }
++
++ /* previous request unfinished? non-error iff back-to-back ... */
++ if ((udccsr0 & UDCCSR0_SA) != 0 && dev->ep0state != EP0_IDLE) {
++ nuke(ep, 0);
++ del_timer(&dev->timer);
++ ep0_idle(dev);
++ }
++
++ switch (dev->ep0state) {
++ case EP0_NO_ACTION:
++ printk(KERN_INFO"%s: Busy\n", __FUNCTION__);
++ /*Fall through */
++ case EP0_IDLE:
++ /* late-breaking status? */
++ udccsr0 = UDCCSR0;
++
++ /* start control request? */
++ if (likely((udccsr0 & (UDCCSR0_OPC|UDCCSR0_SA|UDCCSR0_RNE))
++ == (UDCCSR0_OPC|UDCCSR0_SA|UDCCSR0_RNE))) {
++ int i;
++
++ nuke (ep, -EPROTO);
++ /* read SETUP packet */
++ for (i = 0; i < 2; i++) {
++ if (unlikely(!(UDCCSR0 & UDCCSR0_RNE))) {
++bad_setup:
++ DMSG("SETUP %d!\n", i);
++ goto stall;
++ }
++ u.word [i] = UDCDR0;
++ }
++ if (unlikely((UDCCSR0 & UDCCSR0_RNE) != 0))
++ goto bad_setup;
++
++ le16_to_cpus (&u.r.wValue);
++ le16_to_cpus (&u.r.wIndex);
++ le16_to_cpus (&u.r.wLength);
++
++ LED_EP0_ON;
++
++ DBG(DBG_VERBOSE, "SETUP %02x.%02x v%04x i%04x l%04x\n",
++ u.r.bRequestType, u.r.bRequest,
++ u.r.wValue, u.r.wIndex, u.r.wLength);
++ /* cope with automagic for some standard requests. */
++ dev->req_std = (u.r.bRequestType & USB_TYPE_MASK)
++ == USB_TYPE_STANDARD;
++ dev->req_config = 0;
++ dev->req_pending = 1;
++#if 0
++ switch (u.r.bRequest) {
++ /* hardware was supposed to hide this */
++ case USB_REQ_SET_CONFIGURATION:
++ case USB_REQ_SET_INTERFACE:
++ case USB_REQ_SET_ADDRESS:
++ printk(KERN_ERR "Should not come here\n");
++ break;
++ }
++
++#endif
++ if (u.r.bRequestType & USB_DIR_IN)
++ dev->ep0state = EP0_IN_DATA_PHASE;
++ else
++ dev->ep0state = EP0_OUT_DATA_PHASE;
++ i = dev->driver->setup(&dev->gadget, &u.r);
++
++ if (i < 0) {
++ /* hardware automagic preventing STALL... */
++ if (dev->req_config) {
++ /* hardware sometimes neglects to tell
++ * tell us about config change events,
++ * so later ones may fail...
++ */
++ WARN("config change %02x fail %d?\n",
++ u.r.bRequest, i);
++ return;
++ /* TODO experiment: if has_cfr,
++ * hardware didn't ACK; maybe we
++ * could actually STALL!
++ */
++ }
++ DBG(DBG_VERBOSE, "protocol STALL, "
++ "%02x err %d\n", UDCCSR0, i);
++stall:
++ /* the watchdog timer helps deal with cases
++ * where udc seems to clear FST wrongly, and
++ * then NAKs instead of STALLing.
++ */
++ ep0start(dev, UDCCSR0_FST|UDCCSR0_FTF, "stall");
++ start_watchdog(dev);
++ dev->ep0state = EP0_STALL;
++ LED_EP0_OFF;
++
++ /* deferred i/o == no response yet */
++ } else if (dev->req_pending) {
++ if (likely(dev->ep0state == EP0_IN_DATA_PHASE
++ || dev->req_std || u.r.wLength))
++ ep0start(dev, 0, "defer");
++ else
++ ep0start(dev, UDCCSR0_IPR, "defer/IPR");
++ }
++
++ /* expect at least one data or status stage irq */
++ return;
++
++ } else {
++ /* some random early IRQ:
++ * - we acked FST
++ * - IPR cleared
++ * - OPC got set, without SA (likely status stage)
++ */
++ UDCCSR0 = udccsr0 & (UDCCSR0_SA|UDCCSR0_OPC);
++ }
++ break;
++ case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */
++ if (udccsr0 & UDCCSR0_OPC) {
++ UDCCSR0 = UDCCSR0_OPC|UDCCSR0_FTF;
++ DBG(DBG_VERBOSE, "ep0in premature status\n");
++ if (req)
++ done(ep, req, 0);
++ ep0_idle(dev);
++ } else /* irq was IPR clearing */ {
++ if (req) {
++ /* this IN packet might finish the request */
++ (void) write_ep0_fifo(ep, req);
++ } /* else IN token before response was written */
++ }
++ break;
++ case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */
++ if (udccsr0 & UDCCSR0_OPC) {
++ if (req) {
++ /* this OUT packet might finish the request */
++ if (read_ep0_fifo(ep, req))
++ done(ep, req, 0);
++ /* else more OUT packets expected */
++ } /* else OUT token before read was issued */
++ } else /* irq was IPR clearing */ {
++ DBG(DBG_VERBOSE, "ep0out premature status\n");
++ if (req)
++ done(ep, req, 0);
++ ep0_idle(dev);
++ }
++ break;
++ case EP0_STALL:
++ UDCCSR0 = UDCCSR0_FST;
++ break;
++ }
++ UDCISR0 = UDCISR_INT(0, UDCISR_INT_MASK);
++}
++
++
++static void handle_ep(struct pxa27x_ep *ep)
++{
++ struct pxa27x_request *req;
++ int completed;
++ u32 udccsr=0;
++
++ DMSG("%s is called\n", __FUNCTION__);
++ do {
++ completed = 0;
++ if (likely (!list_empty(&ep->queue))) {
++ req = list_entry(ep->queue.next,
++ struct pxa27x_request, queue);
++ } else
++ req = 0;
++
++// udccsr = *ep->reg_udccsr;
++ DMSG("%s: req:%p, udcisr0:0x%x udccsr %p:0x%x\n", __FUNCTION__,
++ req, UDCISR0, ep->reg_udccsr, *ep->reg_udccsr);
++ if (unlikely(ep->dir_in)) {
++ udccsr = (UDCCSR_SST | UDCCSR_TRN) & *ep->reg_udccsr;
++ if (unlikely (udccsr))
++ *ep->reg_udccsr = udccsr;
++
++ if (req && likely ((*ep->reg_udccsr & UDCCSR_FS) != 0))
++ completed = write_fifo(ep, req);
++
++ } else {
++ udccsr = (UDCCSR_SST | UDCCSR_TRN) & *ep->reg_udccsr;
++ if (unlikely(udccsr))
++ *ep->reg_udccsr = udccsr;
++
++ /* fifos can hold packets, ready for reading... */
++ if (likely(req)) {
++ completed = read_fifo(ep, req);
++ } else {
++ pio_irq_disable (ep->ep_num);
++ *ep->reg_udccsr = UDCCSR_FEF;
++ DMSG("%s: no req for out data\n",
++ __FUNCTION__);
++ }
++ }
++ ep->pio_irqs++;
++ } while (completed);
++}
++
++static void pxa27x_change_configuration (struct pxa27x_udc *dev)
++{
++ struct usb_ctrlrequest req ;
++
++ req.bRequestType = 0;
++ req.bRequest = USB_REQ_SET_CONFIGURATION;
++ req.wValue = dev->configuration;
++ req.wIndex = 0;
++ req.wLength = 0;
++
++ dev->ep0state = EP0_NO_ACTION;
++ dev->driver->setup(&dev->gadget, &req);
++
++}
++
++static void pxa27x_change_interface (struct pxa27x_udc *dev)
++{
++ struct usb_ctrlrequest req;
++
++ req.bRequestType = USB_RECIP_INTERFACE;
++ req.bRequest = USB_REQ_SET_INTERFACE;
++ req.wValue = dev->alternate;
++ req.wIndex = dev->interface;
++ req.wLength = 0;
++
++ dev->ep0state = EP0_NO_ACTION;
++ dev->driver->setup(&dev->gadget, &req);
++}
++
++/*
++ * pxa27x_udc_irq - interrupt handler
++ *
++ * avoid delays in ep0 processing. the control handshaking isn't always
++ * under software control (pxa250c0 and the pxa255 are better), and delays
++ * could cause usb protocol errors.
++ */
++static irqreturn_t
++pxa27x_udc_irq(int irq, void *_dev, struct pt_regs *r)
++{
++ struct pxa27x_udc *dev = _dev;
++ int handled;
++
++ dev->stats.irqs++;
++ HEX_DISPLAY(dev->stats.irqs);
++
++// printk("\n");
++ DBG(DBG_VERBOSE, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, "
++ "UDCCR:0x%08x\n", UDCISR0, UDCISR1, UDCCR);
++ do {
++ u32 udcir = UDCISR1 & 0xF8000000;
++
++ handled = 0;
++
++ /* SUSpend Interrupt Request */
++ if (unlikely(udcir & UDCISR1_IRSU)) {
++ UDCISR1 = UDCISR1_IRSU;
++ handled = 1;
++ DBG(DBG_VERBOSE, "USB suspend\n");
++ if (dev->gadget.speed != USB_SPEED_UNKNOWN
++ && dev->driver
++ && dev->driver->suspend)
++ dev->driver->suspend(&dev->gadget);
++ ep0_idle (dev);
++ }
++
++ /* RESume Interrupt Request */
++ if (unlikely(udcir & UDCISR1_IRRU)) {
++ UDCISR1 = UDCISR1_IRRU;
++ handled = 1;
++ DBG(DBG_VERBOSE, "USB resume\n");
++
++ if (dev->gadget.speed != USB_SPEED_UNKNOWN
++ && dev->driver
++ && dev->driver->resume)
++ dev->driver->resume(&dev->gadget);
++ }
++
++ if (unlikely(udcir & UDCISR1_IRCC)) {
++ unsigned config, interface, alternate;
++
++ handled = 1;
++ DBG(DBG_VERBOSE, "USB SET_CONFIGURATION or "
++ "SET_INTERFACE command received\n");
++
++ UDCCR |= UDCCR_SMAC;
++
++ config = (UDCCR & UDCCR_ACN) >> UDCCR_ACN_S;
++
++ if (dev->configuration != config) {
++ dev->configuration = config;
++ pxa27x_change_configuration(dev) ;
++ }
++
++ interface = (UDCCR & UDCCR_AIN) >> UDCCR_AIN_S;
++ alternate = (UDCCR & UDCCR_AAISN) >> UDCCR_AAISN_S;
++
++ if ( (dev->configuration != interface) || \
++ (dev->alternate != alternate)){
++ dev->interface = config;
++ dev->alternate = alternate;
++ pxa27x_change_interface(dev);
++ }
++
++ UDCISR1 = UDCISR1_IRCC;
++ DMSG("%s: con:%d,inter:%d,alt:%d\n",
++ __FUNCTION__, config,interface, alternate);
++ }
++
++ /* ReSeT Interrupt Request - USB reset */
++ if (unlikely(udcir & UDCISR1_IRRS)) {
++ UDCISR1 = UDCISR1_IRRS;
++ handled = 1;
++
++ if ((UDCCR & UDCCR_UDA) == 0) {
++ DBG(DBG_VERBOSE, "USB reset start\n");
++
++ /* reset driver and endpoints,
++ * in case that's not yet done
++ */
++ stop_activity (dev, dev->driver);
++
++ }
++ INFO("USB reset\n");
++ dev->gadget.speed = USB_SPEED_FULL;
++ memset(&dev->stats, 0, sizeof dev->stats);
++
++ } else {
++ u32 udcisr0 = UDCISR0 ;
++ u32 udcisr1 = UDCISR1 & 0xFFFF;
++ int i;
++
++ if (unlikely (!udcisr0 && !udcisr1))
++ continue;
++
++ DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", udcisr1,udcisr0);
++
++ /* control traffic */
++ if (udcisr0 & UDCISR0_IR0) {
++ dev->ep[0].pio_irqs++;
++ handle_ep0(dev);
++ handled = 1;
++ }
++
++ udcisr0 >>= 2;
++ /* endpoint data transfers */
++ for (i = 1; udcisr0!=0 && i < 16; udcisr0>>=2,i++) {
++ UDCISR0 = UDCISR_INT(i, UDCISR_INT_MASK);
++
++ if (udcisr0 & UDC_INT_FIFOERROR)
++ printk(KERN_ERR" Endpoint %d Fifo error\n", i);
++ if (udcisr0 & UDC_INT_PACKETCMP) {
++ handle_ep(&dev->ep[i]);
++ handled = 1;
++ }
++
++ }
++
++ for (i = 0; udcisr1!=0 && i < 8; udcisr1 >>= 2, i++) {
++ UDCISR1 = UDCISR_INT(i, UDCISR_INT_MASK);
++
++ if (udcisr1 & UDC_INT_FIFOERROR) {
++ printk(KERN_ERR" Endpoint %d fifo error\n", (i+16));
++ }
++
++ if (udcisr1 & UDC_INT_PACKETCMP) {
++ handle_ep(&dev->ep[i+16]);
++ handled = 1;
++ }
++ }
++ }
++
++ /* we could also ask for 1 msec SOF (SIR) interrupts */
++
++ } while (handled);
++ return IRQ_HANDLED;
++}
++
++static inline void validate_fifo_size(struct pxa27x_ep *pxa_ep, u8 bmAttributes)
++{
++ switch (bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
++ case USB_ENDPOINT_XFER_CONTROL:
++ pxa_ep->fifo_size = EP0_FIFO_SIZE;
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ pxa_ep->fifo_size = ISO_FIFO_SIZE;
++ break;
++ case USB_ENDPOINT_XFER_BULK:
++ pxa_ep->fifo_size = BULK_FIFO_SIZE;
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ pxa_ep->fifo_size = INT_FIFO_SIZE;
++ break;
++ default:
++ break;
++ }
++}
++
++static void udc_init_ep(struct pxa27x_udc *dev)
++{
++ int i;
++#ifdef DEBUG
++ printk(" DEBUG line %d at %s()\n",__LINE__,__FUNCTION__);
++#endif
++ INIT_LIST_HEAD (&dev->gadget.ep_list);
++ INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
++
++ for (i = 0; i < UDC_EP_NUM; i++) {
++ struct pxa27x_ep *ep = &dev->ep[i];
++
++ ep->dma = -1;
++ if (i != 0) {
++ memset(ep, 0, sizeof(*ep));
++ }
++ INIT_LIST_HEAD (&ep->queue);
++ }
++}
++#define NAME_SIZE 18
++
++struct usb_ep* pxa27x_ep_config(
++ struct usb_gadget *gadget,
++ struct usb_endpoint_descriptor *desc,
++ int config, int interface, int alt
++)
++{
++ u32 tmp ;
++ unsigned i;
++ char* name;
++ struct usb_ep * ep = NULL;
++ struct pxa27x_ep *pxa_ep = NULL;
++ struct pxa27x_udc *dev = the_controller;
++
++ DMSG("pxa27x_config_ep is called\n");
++ DMSG(" usb endpoint descriptor is:\n"
++ " bLength:%d\n"
++ " bDescriptorType:%x\n"
++ " bEndpointAddress:%x\n"
++ " bmAttributes:%x\n"
++ " wMaxPacketSize:%d\n",
++ desc->bLength,
++ desc->bDescriptorType,desc->bEndpointAddress,
++ desc->bmAttributes,desc->wMaxPacketSize);
++
++ for (i = 1; i < UDC_EP_NUM; i++) {
++ if(!dev->ep[i].assigned) {
++ pxa_ep = &dev->ep[i];
++ pxa_ep->assigned = 1;
++ pxa_ep->ep_num = i;
++ break;
++ }
++ }
++ if (unlikely(i == UDC_EP_NUM)) {
++ printk(KERN_ERR __FILE__ ": Failed to find a spare endpoint\n");
++ return ep;
++ }
++
++
++ ep = &pxa_ep->ep;
++
++ pxa_ep->dev = dev;
++ pxa_ep->desc = desc;
++ pxa_ep->pio_irqs = pxa_ep->dma_irqs = 0;
++ pxa_ep->dma = -1;
++
++ if (!(desc->bEndpointAddress & 0xF))
++ desc->bEndpointAddress |= i;
++
++ if (!(desc->wMaxPacketSize)) {
++ validate_fifo_size(pxa_ep, desc->bmAttributes);
++ desc->wMaxPacketSize = pxa_ep->fifo_size;
++ } else
++ pxa_ep->fifo_size = desc->wMaxPacketSize;
++
++ pxa_ep->dir_in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0;
++ pxa_ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
++ pxa_ep->stopped = 1;
++ pxa_ep->dma_con = 0;
++ pxa_ep->config = config;
++ pxa_ep->interface = interface;
++ pxa_ep->aisn = alt;
++
++ pxa_ep->reg_udccsr = &UDCCSR0 + i;
++ pxa_ep->reg_udcbcr = &UDCBCR0 + i;
++ pxa_ep->reg_udcdr = &UDCDR0 + i ;
++ pxa_ep->reg_udccr = &UDCCRA - 1 + i;
++#ifdef USE_DMA
++ pxa_ep->reg_drcmr = &DRCMR24 + i;
++#endif
++
++#if 1
++ DMSG("udccsr=0x%8x, udcbcr=0x%8x, udcdr=0x%8x,"
++ "udccr0=0x%8x\n",
++ (unsigned)pxa_ep->reg_udccsr,
++ (unsigned)pxa_ep->reg_udcbcr,
++ (unsigned)pxa_ep->reg_udcdr,
++ (unsigned)pxa_ep->reg_udccr);
++#endif
++ /* Configure UDCCR */
++ tmp = 0;
++ tmp |= (pxa_ep->config << UDCCONR_CN_S) & UDCCONR_CN;
++ tmp |= (pxa_ep->interface << UDCCONR_IN_S) & UDCCONR_IN;
++ tmp |= (pxa_ep->aisn << UDCCONR_AISN_S) & UDCCONR_AISN;
++ tmp |= (desc->bEndpointAddress << UDCCONR_EN_S) & UDCCONR_EN;
++ tmp |= (pxa_ep->ep_type << UDCCONR_ET_S) & UDCCONR_ET;
++ tmp |= (pxa_ep->dir_in) ? UDCCONR_ED : 0;
++ tmp |= (min(pxa_ep->fifo_size, (unsigned)desc->wMaxPacketSize) \
++ << UDCCONR_MPS_S ) & UDCCONR_MPS;
++ tmp |= UDCCONR_DE | UDCCONR_EE;
++// tmp |= UDCCONR_EE;
++
++ *pxa_ep->reg_udccr = tmp;
++ DMSG("The value of the register stored in UDCCRA-X is %x\n",tmp);
++
++
++#ifdef USE_DMA
++ /* Only BULK use DMA */
++ if ((pxa_ep->ep_type & USB_ENDPOINT_XFERTYPE_MASK)\
++ == USB_ENDPOINT_XFER_BULK)
++ *pxa_ep->reg_udccsr = UDCCSR_DME;
++#endif
++
++ DMSG("UDCCR: 0x%p is 0x%x\n", pxa_ep->reg_udccr,*pxa_ep->reg_udccr);
++
++ /* Fill ep name*/
++ name = kmalloc(NAME_SIZE, GFP_KERNEL);
++ if (!name) {
++ printk(KERN_ERR "%s: Error\n", __FUNCTION__);
++ return NULL;
++ }
++
++ switch (pxa_ep->ep_type) {
++ case USB_ENDPOINT_XFER_BULK:
++#ifdef DEBUG
++ printk("Entering pxa27x_ep_config for naming %d\n",i);
++#endif
++ sprintf(name, "ep%d%s-bulk", i,(pxa_ep->dir_in ? "in":"out"));
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ sprintf(name, "Interrupt-%s-%d", (pxa_ep->dir_in ? \
++ "in":"out"), i);
++ break;
++ default:
++ sprintf(name, "endpoint-%s-%d", (pxa_ep->dir_in ? \
++ "in":"out"), i);
++ break;
++ }
++ ep->name = name;
++
++ ep->ops = &pxa27x_ep_ops;
++ ep->maxpacket = min((ushort)pxa_ep->fifo_size, desc->wMaxPacketSize);
++
++ list_add_tail (&ep->ep_list, &gadget->ep_list);
++ return ep;
++}
++
++EXPORT_SYMBOL(pxa27x_ep_config);
++
++/*-------------------------------------------------------------------------*/
++
++static void nop_release (struct device *dev)
++{
++ DMSG("%s %s\n", __FUNCTION__, dev->bus_id);
++}
++
++/* this uses load-time allocation and initialization (instead of
++ * doing it at run-time) to save code, eliminate fault paths, and
++ * be more obviously correct.
++ */
++static struct pxa27x_udc memory = {
++ .gadget = {
++ .ops = &pxa27x_udc_ops,
++ .ep0 = &memory.ep[0].ep,
++ .name = driver_name,
++ .dev = {
++ .bus_id = "gadget",
++ .release = nop_release,
++ },
++ },
++
++ /* control endpoint */
++ .ep[0] = {
++ .ep = {
++ .name = ep0name,
++ .ops = &pxa27x_ep_ops,
++ .maxpacket = EP0_FIFO_SIZE,
++ },
++ .dev = &memory,
++ .reg_udccsr = &UDCCSR0,
++ .reg_udcdr = &UDCDR0,
++ },
++ .ep[1] = {
++ .ep = {
++ .name = "ep1in-bulk",
++ .ops = &pxa27x_ep_ops,
++ .maxpacket = BULK_FIFO_SIZE,
++ },
++ .dev = &memory,
++ .reg_udccsr = &UDCCSRA,
++ .reg_udcdr = &UDCDRA,
++ .reg_udcbcr = &UDCBCRA,
++ .reg_udccr = &UDCCRA,
++ .ep_num = 1,
++ .dir_in = 1,
++ .assigned = 1,
++ .ep_type = 2,
++ },
++ .ep[2] = {
++ .ep = {
++ .name = "ep2out-bulk",
++ .ops = &pxa27x_ep_ops,
++ .maxpacket = BULK_FIFO_SIZE,
++ },
++ .dev = &memory,
++ .reg_udccsr = &UDCCSRB,
++ .reg_udcdr = &UDCDRB,
++ .reg_udcbcr = &UDCBCRB,
++ .reg_udccr = &UDCCRB,
++ .ep_num = 2,
++ .dir_in = 0,
++ .assigned = 1,
++ .ep_type = 2,
++ }
++};
++
++
++#define CP15R0_VENDOR_MASK 0xffffe000
++
++#define CP15R0_XSCALE_VALUE 0x69054000 /* intel/arm/xscale */
++
++/*
++ * probe - binds to the platform device
++ */
++static int __init pxa27x_udc_probe(struct device *_dev)
++{
++ struct pxa27x_udc *dev = &memory;
++ int retval;
++ u32 chiprev;
++
++ /* insist on Intel/ARM/XScale */
++ asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev));
++ if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) {
++ printk(KERN_ERR "%s: not XScale!\n", driver_name);
++ return -ENODEV;
++ }
++ /* other non-static parts of init */
++ dev->dev = _dev;
++ dev->mach = _dev->platform_data;
++
++ init_timer(&dev->timer);
++ dev->timer.function = udc_watchdog;
++ dev->timer.data = (unsigned long) dev;
++
++ device_initialize(&dev->gadget.dev);
++ dev->gadget.dev.parent = _dev;
++ dev->gadget.dev.dma_mask = _dev->dma_mask;
++
++ the_controller = dev;
++ dev_set_drvdata(_dev, dev);
++
++ udc_disable(dev);
++ udc_init_ep(dev);
++ udc_reinit(dev);
++
++ /* irq setup after old hardware state is cleaned up */
++ retval = request_irq(IRQ_USB, pxa27x_udc_irq,
++ SA_INTERRUPT, driver_name, dev);
++ if (retval != 0) {
++ printk(KERN_ERR "%s: can't get irq %i, err %d\n",
++ driver_name, IRQ_USB, retval);
++ return -EBUSY;
++ }
++ dev->got_irq = 1;
++
++ create_proc_files();
++
++ return 0;
++}
++
++static int __exit pxa27x_udc_remove(struct device *_dev)
++{
++ struct pxa27x_udc *dev = _dev->driver_data;
++
++ udc_disable(dev);
++ remove_proc_files();
++ usb_gadget_unregister_driver(dev->driver);
++
++ if (dev->got_irq) {
++ free_irq(IRQ_USB, dev);
++ dev->got_irq = 0;
++ }
++ if (machine_is_lubbock() && dev->got_disc) {
++ free_irq(LUBBOCK_USB_DISC_IRQ, dev);
++ dev->got_disc = 0;
++ }
++ dev_set_drvdata(_dev, 0);
++ the_controller = 0;
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int pxa27x_udc_suspend(struct device *_dev, u32 state, u32 level)
++{
++ int i;
++ struct pxa27x_udc *dev = (struct pxa27x_udc*)dev_get_drvdata(_dev);
++
++ DMSG("%s is called\n", __FUNCTION__);
++ if (level == SUSPEND_POWER_DOWN) {
++ DMSG("%s will go into SUSPEND_POWER_DOWN\n", __FUNCTION__);
++ dev->udccsr0 = UDCCSR0;
++ for(i=1; (i<UDC_EP_NUM); i++) {
++ if (dev->ep[i].assigned) {
++ struct pxa27x_ep *ep = &dev->ep[i];
++
++ ep->udccsr_value = *ep->reg_udccsr;
++ ep->udccr_value = *ep->reg_udccr;
++ DMSG("EP%d, udccsr:0x%x, udccr:0x%x\n",
++ i, *ep->reg_udccsr, *ep->reg_udccr);
++ }
++ }
++
++ udc_clear_mask_UDCCR(UDCCR_UDE);
++ pxa_set_cken(CKEN11_USB, 0);
++#ifdef CONFIG_MACH_MAINSTONE
++ MST_MSCWR2 |= MST_MSCWR2_nUSBC_SC;
++#endif
++ }
++
++ return 0;
++}
++
++static int pxa27x_udc_resume(struct device *_dev, u32 level)
++{
++ int i;
++ struct pxa27x_udc *dev = (struct pxa27x_udc*)dev_get_drvdata(_dev);
++
++ DMSG("%s is called\n", __FUNCTION__);
++ if (level == RESUME_POWER_ON) {
++ DMSG("%s: udc resume\n", __FUNCTION__);
++
++ UDCCSR0 = dev->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME);
++ for (i=1; i < UDC_EP_NUM; i++) {
++ if (dev->ep[i].assigned) {
++ struct pxa27x_ep *ep = &dev->ep[i];
++
++ *ep->reg_udccsr = ep->udccsr_value;
++ *ep->reg_udccr = ep->udccr_value;
++ DMSG("EP%d, udccsr:0x%x, udccr:0x%x\n",
++ i, *ep->reg_udccsr, *ep->reg_udccr);
++ }
++ }
++ udc_enable(dev);
++ /* OTGPH bit is set when sleep mode is entered.
++ * it indicates that OTG pad is retaining its state.
++ * Upon exit from sleep mode and before clearing OTGPH,
++ * Software must configure the USB OTG pad, UDC, and UHC
++ * to the state they were in before entering sleep mode.*/
++ PSSR |= PSSR_OTGPH;
++ }
++ return 0;
++}
++#endif
++
++/*-------------------------------------------------------------------------*/
++
++static struct device_driver udc_driver = {
++ .name = "pxa2xx-udc",
++ .bus = &platform_bus_type,
++ .probe = pxa27x_udc_probe,
++ .remove = __exit_p(pxa27x_udc_remove),
++
++#ifdef CONFIG_PM
++ // FIXME power management support
++ .suspend = pxa27x_udc_suspend,
++ .resume = pxa27x_udc_resume
++#endif
++};
++
++static int __init udc_init(void)
++{
++ printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
++ return driver_register(&udc_driver);
++}
++module_init(udc_init);
++
++static void __exit udc_exit(void)
++{
++ driver_unregister(&udc_driver);
++}
++module_exit(udc_exit);
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");
++MODULE_LICENSE("GPL");
++
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/pxa27x_udc.h linux-2.6.25/drivers/usb/gadget/pxa27x_udc.h
+--- linux-2.6.25_original/drivers/usb/gadget/pxa27x_udc.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/pxa27x_udc.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,332 @@
++/*
++ * linux/drivers/usb/gadget/pxa27x_udc.h
++ * Intel PXA27x on-chip full speed USB device controller
++ *
++ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
++ * Copyright (C) 2003 David Brownell
++ * Copyright (C) 2004 Intel Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef __LINUX_USB_GADGET_PXA27X_H
++#define __LINUX_USB_GADGET_PXA27X_H
++
++#include <linux/types.h>
++
++struct pxa27x_udc;
++
++struct pxa27x_ep {
++ struct usb_ep ep;
++ struct pxa27x_udc *dev;
++
++ const struct usb_endpoint_descriptor *desc;
++ struct list_head queue;
++ unsigned long pio_irqs;
++ unsigned long dma_irqs;
++
++ int dma;
++ unsigned fifo_size;
++ unsigned ep_num;
++ unsigned ep_type;
++
++ unsigned stopped : 1;
++ unsigned dma_con : 1;
++ unsigned dir_in : 1;
++ unsigned assigned : 1;
++
++ unsigned config;
++ unsigned interface;
++ unsigned aisn;
++ /* UDCCSR = UDC Control/Status Register for this EP
++ * UBCR = UDC Byte Count Remaining (contents of OUT fifo)
++ * UDCDR = UDC Endpoint Data Register (the fifo)
++ * UDCCR = UDC Endpoint Configuration Registers
++ * DRCM = DMA Request Channel Map
++ */
++ volatile u32 *reg_udccsr;
++ volatile u32 *reg_udcbcr;
++ volatile u32 *reg_udcdr;
++ volatile u32 *reg_udccr;
++#ifdef USE_DMA
++ volatile u32 *reg_drcmr;
++#define drcmr(n) .reg_drcmr = & DRCMR ## n ,
++#else
++#define drcmr(n)
++#endif
++
++#ifdef CONFIG_PM
++ unsigned udccsr_value;
++ unsigned udccr_value;
++#endif
++};
++
++struct pxa27x_request {
++ struct usb_request req;
++ struct list_head queue;
++};
++
++enum ep0_state {
++ EP0_IDLE,
++ EP0_IN_DATA_PHASE,
++ EP0_OUT_DATA_PHASE,
++// EP0_END_XFER,
++ EP0_STALL,
++ EP0_NO_ACTION
++};
++
++#define EP0_FIFO_SIZE ((unsigned)16)
++#define BULK_FIFO_SIZE ((unsigned)64)
++#define ISO_FIFO_SIZE ((unsigned)256)
++#define INT_FIFO_SIZE ((unsigned)8)
++
++struct udc_stats {
++ struct ep0stats {
++ unsigned long ops;
++ unsigned long bytes;
++ } read, write;
++ unsigned long irqs;
++};
++
++#ifdef CONFIG_USB_PXA27X_SMALL
++/* when memory's tight, SMALL config saves code+data. */
++//#undef USE_DMA
++//#define UDC_EP_NUM 3
++#endif
++
++#ifndef UDC_EP_NUM
++#define UDC_EP_NUM 24
++#endif
++
++struct pxa27x_udc {
++ struct usb_gadget gadget;
++ struct usb_gadget_driver *driver;
++
++ enum ep0_state ep0state;
++ struct udc_stats stats;
++ unsigned got_irq : 1,
++ got_disc : 1,
++ has_cfr : 1,
++ req_pending : 1,
++ req_std : 1,
++ req_config : 1;
++
++#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
++ struct timer_list timer;
++
++ struct device *dev;
++ struct pxa27x_udc_mach_info *mach;
++ u64 dma_mask;
++ struct pxa27x_ep ep [UDC_EP_NUM];
++
++ unsigned configuration,
++ interface,
++ alternate;
++#ifdef CONFIG_PM
++ unsigned udccsr0;
++#endif
++};
++
++/*-------------------------------------------------------------------------*/
++#if 0
++#ifdef DEBUG
++#define HEX_DISPLAY(n) do { \
++ if (machine_is_mainstone())\
++ { MST_LEDDAT1 = (n); } \
++ } while(0)
++
++#define HEX_DISPLAY1(n) HEX_DISPLAY(n)
++
++#define HEX_DISPLAY2(n) do { \
++ if (machine_is_mainstone()) \
++ { MST_LEDDAT2 = (n); } \
++ } while(0)
++
++#endif /* DEBUG */
++#endif
++/*-------------------------------------------------------------------------*/
++
++/* LEDs are only for debug */
++#ifndef HEX_DISPLAY
++#define HEX_DISPLAY(n) do {} while(0)
++#endif
++
++#ifndef LED_CONNECTED_ON
++#define LED_CONNECTED_ON do {} while(0)
++#define LED_CONNECTED_OFF do {} while(0)
++#endif
++#ifndef LED_EP0_ON
++#define LED_EP0_ON do {} while (0)
++#define LED_EP0_OFF do {} while (0)
++#endif
++
++static struct pxa27x_udc *the_controller;
++
++#if 0
++/*-------------------------------------------------------------------------*/
++
++
++/* one GPIO should be used to detect host disconnect */
++static inline int is_usb_connected(void)
++{
++ if (!the_controller->mach->udc_is_connected)
++ return 1;
++ return the_controller->mach->udc_is_connected();
++}
++
++/* one GPIO should force the host to see this device (or not) */
++static inline void make_usb_disappear(void)
++{
++ if (!the_controller->mach->udc_command)
++ return;
++ the_controller->mach->udc_command(PXA27X_UDC_CMD_DISCONNECT);
++}
++
++static inline void let_usb_appear(void)
++{
++ if (!the_controller->mach->udc_command)
++ return;
++ the_controller->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
++}
++#endif
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * Debugging support vanishes in non-debug builds. DBG_NORMAL should be
++ * mostly silent during normal use/testing, with no timing side-effects.
++ */
++#define DBG_NORMAL 1 /* error paths, device state transitions */
++#define DBG_VERBOSE 2 /* add some success path trace info */
++#define DBG_NOISY 3 /* ... even more: request level */
++#define DBG_VERY_NOISY 4 /* ... even more: packet level */
++
++#ifdef DEBUG
++
++static const char *state_name[] = {
++ "EP0_IDLE",
++ "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
++ "EP0_END_XFER", "EP0_STALL"
++};
++
++#define DMSG(stuff...) printk(KERN_ERR "udc: " stuff)
++
++#ifdef VERBOSE
++# define UDC_DEBUG DBG_VERBOSE
++#else
++# define UDC_DEBUG DBG_NORMAL
++#endif
++
++static void __attribute__ ((__unused__))
++dump_udccr(const char *label)
++{
++ u32 udccr = UDCCR;
++ DMSG("%s 0x%08x =%s%s%s%s%s%s%s%s%s%s, con=%d,inter=%d,altinter=%d\n",
++ label, udccr,
++ (udccr & UDCCR_OEN) ? " oen":"",
++ (udccr & UDCCR_AALTHNP) ? " aalthnp":"",
++ (udccr & UDCCR_AHNP) ? " rem" : "",
++ (udccr & UDCCR_BHNP) ? " rstir" : "",
++ (udccr & UDCCR_DWRE) ? " dwre" : "",
++ (udccr & UDCCR_SMAC) ? " smac" : "",
++ (udccr & UDCCR_EMCE) ? " emce" : "",
++ (udccr & UDCCR_UDR) ? " udr" : "",
++ (udccr & UDCCR_UDA) ? " uda" : "",
++ (udccr & UDCCR_UDE) ? " ude" : "",
++ (udccr & UDCCR_ACN) >> UDCCR_ACN_S,
++ (udccr & UDCCR_AIN) >> UDCCR_AIN_S,
++ (udccr & UDCCR_AAISN)>> UDCCR_AAISN_S );
++}
++
++static void __attribute__ ((__unused__))
++dump_udccsr0(const char *label)
++{
++ u32 udccsr0 = UDCCSR0;
++
++ DMSG("%s %s 0x%08x =%s%s%s%s%s%s%s\n",
++ label, state_name[the_controller->ep0state], udccsr0,
++ (udccsr0 & UDCCSR0_SA) ? " sa" : "",
++ (udccsr0 & UDCCSR0_RNE) ? " rne" : "",
++ (udccsr0 & UDCCSR0_FST) ? " fst" : "",
++ (udccsr0 & UDCCSR0_SST) ? " sst" : "",
++ (udccsr0 & UDCCSR0_DME) ? " dme" : "",
++ (udccsr0 & UDCCSR0_IPR) ? " ipr" : "",
++ (udccsr0 & UDCCSR0_OPC) ? " opr" : "");
++}
++
++static void __attribute__ ((__unused__))
++dump_state(struct pxa27x_udc *dev)
++{
++ unsigned i;
++
++ DMSG("%s, udcicr %02X.%02X, udcsir %02X.%02x, udcfnr %02X\n",
++ state_name[dev->ep0state],
++ UDCICR1, UDCICR0, UDCISR1, UDCISR0, UDCFNR);
++ dump_udccr("udccr");
++
++ if (!dev->driver) {
++ DMSG("no gadget driver bound\n");
++ return;
++ } else
++ DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
++
++
++ dump_udccsr0 ("udccsr0");
++ DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n",
++ dev->stats.write.bytes, dev->stats.write.ops,
++ dev->stats.read.bytes, dev->stats.read.ops);
++
++ for (i = 1; i < UDC_EP_NUM; i++) {
++ if (dev->ep [i].desc == 0)
++ continue;
++ DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccsr);
++ }
++}
++
++#if 0
++static void dump_regs(u8 ep)
++{
++ DMSG("EP:%d UDCCSR:0x%08x UDCBCR:0x%08x\n UDCCR:0x%08x\n",
++ ep,UDCCSN(ep), UDCBCN(ep), UDCCN(ep));
++}
++static void dump_req (struct pxa27x_request *req)
++{
++ struct usb_request *r = &req->req;
++
++ DMSG("%s: buf:0x%08x length:%d dma:0x%08x actual:%d\n",
++ __FUNCTION__, (unsigned)r->buf, r->length,
++ r->dma, r->actual);
++}
++#endif
++
++#else
++
++#define DMSG(stuff...) do{}while(0)
++
++#define dump_udccr(x) do{}while(0)
++#define dump_udccsr0(x) do{}while(0)
++#define dump_state(x) do{}while(0)
++
++#define UDC_DEBUG ((unsigned)0)
++
++#endif
++
++#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0)
++
++#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff)
++#define INFO(stuff...) printk(KERN_INFO "udc: " stuff)
++
++
++#endif /* __LINUX_USB_GADGET_PXA27X_H */
+diff -Naur linux-2.6.25_original/drivers/usb/gadget/serial.c linux-2.6.25/drivers/usb/gadget/serial.c
+--- linux-2.6.25_original/drivers/usb/gadget/serial.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/usb/gadget/serial.c 2009-05-16 18:43:58.000000000 +0530
+@@ -17,15 +17,33 @@
+ *
+ */
+
++#include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
+ #include <linux/utsname.h>
++#include <linux/wait.h>
++#include <linux/proc_fs.h>
+ #include <linux/device.h>
+ #include <linux/tty.h>
+ #include <linux/tty_flip.h>
+
++#include <asm/byteorder.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/unaligned.h>
++#include <asm/uaccess.h>
++
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/cdc.h>
+-#include <linux/usb/gadget.h>
++#include <linux/usb_gadget.h>
+
+ #include "gadget_chips.h"
+
+@@ -70,29 +88,30 @@
+ #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY
+ #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS
+
+-/* maxpacket and other transfer characteristics vary by speed. */
+-static inline struct usb_endpoint_descriptor *
+-choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
+- struct usb_endpoint_descriptor *fs)
+-{
+- if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+- return hs;
+- return fs;
+-}
+-
++/* select highspeed/fullspeed, hiding highspeed if not configured */
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++#define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs))
++#else
++#define GS_SPEED_SELECT(is_hs,hs,fs) (fs)
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
+
+ /* debug settings */
+-#ifdef DEBUG
++#ifdef GS_DEBUG
+ static int debug = 1;
++
++#define gs_debug(format, arg...) \
++ do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0)
++#define gs_debug_level(level, format, arg...) \
++ do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0)
++
+ #else
+-#define debug 0
+-#endif
+
+ #define gs_debug(format, arg...) \
+- do { if (debug) pr_debug(format, ## arg); } while (0)
++ do { } while(0)
+ #define gs_debug_level(level, format, arg...) \
+- do { if (debug >= level) pr_debug(format, ## arg); } while (0)
++ do { } while(0)
+
++#endif /* GS_DEBUG */
+
+ /* Thanks to NetChip Technologies for donating this product ID.
+ *
+@@ -127,10 +146,10 @@
+
+ /* the port structure holds info for each port, one for each minor number */
+ struct gs_port {
+- struct gs_dev *port_dev; /* pointer to device struct */
++ struct gs_dev *port_dev; /* pointer to device struct */
+ struct tty_struct *port_tty; /* pointer to tty struct */
+ spinlock_t port_lock;
+- int port_num;
++ int port_num;
+ int port_open_count;
+ int port_in_use; /* open/close in progress */
+ wait_queue_head_t port_write_wait;/* waiting to write */
+@@ -168,7 +187,7 @@
+ /* tty driver */
+ static int gs_open(struct tty_struct *tty, struct file *file);
+ static void gs_close(struct tty_struct *tty, struct file *file);
+-static int gs_write(struct tty_struct *tty,
++static int gs_write(struct tty_struct *tty,
+ const unsigned char *buf, int count);
+ static void gs_put_char(struct tty_struct *tty, unsigned char ch);
+ static void gs_flush_chars(struct tty_struct *tty);
+@@ -202,7 +221,7 @@
+ static void gs_disconnect(struct usb_gadget *gadget);
+ static int gs_set_config(struct gs_dev *dev, unsigned config);
+ static void gs_reset_config(struct gs_dev *dev);
+-static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
++static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
+ u8 type, unsigned int index, int is_otg);
+
+ static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
+@@ -239,7 +258,7 @@
+ static const char *EP_OUT_NAME;
+ static const char *EP_NOTIFY_NAME;
+
+-static struct mutex gs_open_close_lock[GS_NUM_PORTS];
++static struct semaphore gs_open_close_sem[GS_NUM_PORTS];
+
+ static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
+ static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
+@@ -395,18 +414,18 @@
+ };
+
+ static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = {
+- .bLength = sizeof(gs_call_mgmt_descriptor),
+- .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
+- .bmCapabilities = 0,
+- .bDataInterface = 1, /* index of data interface */
++ .bLength = sizeof(gs_call_mgmt_descriptor),
++ .bDescriptorType = USB_DT_CS_INTERFACE,
++ .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
++ .bmCapabilities = 0,
++ .bDataInterface = 1, /* index of data interface */
+ };
+
+ static struct usb_cdc_acm_descriptor gs_acm_descriptor = {
+- .bLength = sizeof(gs_acm_descriptor),
+- .bDescriptorType = USB_DT_CS_INTERFACE,
+- .bDescriptorSubType = USB_CDC_ACM_TYPE,
+- .bmCapabilities = 0,
++ .bLength = sizeof(gs_acm_descriptor),
++ .bDescriptorType = USB_DT_CS_INTERFACE,
++ .bDescriptorSubType = USB_CDC_ACM_TYPE,
++ .bmCapabilities = 0,
+ };
+
+ static const struct usb_cdc_union_desc gs_union_desc = {
+@@ -416,7 +435,7 @@
+ .bMasterInterface0 = 0, /* index of control interface */
+ .bSlaveInterface0 = 1, /* index of data interface */
+ };
+-
++
+ static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+@@ -462,6 +481,7 @@
+ NULL,
+ };
+
++#ifdef CONFIG_USB_GADGET_DUALSPEED
+ static struct usb_endpoint_descriptor gs_highspeed_notify_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+@@ -515,13 +535,15 @@
+ NULL,
+ };
+
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
++
+
+ /* Module */
+ MODULE_DESCRIPTION(GS_LONG_NAME);
+ MODULE_AUTHOR("Al Borchers");
+ MODULE_LICENSE("GPL");
+
+-#ifdef DEBUG
++#ifdef GS_DEBUG
+ module_param(debug, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
+ #endif
+@@ -553,8 +575,7 @@
+
+ retval = usb_gadget_register_driver(&gs_gadget_driver);
+ if (retval) {
+- pr_err("gs_module_init: cannot register gadget driver, "
+- "ret=%d\n", retval);
++ printk(KERN_ERR "gs_module_init: cannot register gadget driver, ret=%d\n", retval);
+ return retval;
+ }
+
+@@ -574,19 +595,17 @@
+ tty_set_operations(gs_tty_driver, &gs_tty_ops);
+
+ for (i=0; i < GS_NUM_PORTS; i++)
+- mutex_init(&gs_open_close_lock[i]);
++ sema_init(&gs_open_close_sem[i], 1);
+
+ retval = tty_register_driver(gs_tty_driver);
+ if (retval) {
+ usb_gadget_unregister_driver(&gs_gadget_driver);
+ put_tty_driver(gs_tty_driver);
+- pr_err("gs_module_init: cannot register tty driver, "
+- "ret=%d\n", retval);
++ printk(KERN_ERR "gs_module_init: cannot register tty driver, ret=%d\n", retval);
+ return retval;
+ }
+
+- pr_info("gs_module_init: %s %s loaded\n",
+- GS_LONG_NAME, GS_VERSION_STR);
++ printk(KERN_INFO "gs_module_init: %s %s loaded\n", GS_LONG_NAME, GS_VERSION_STR);
+ return 0;
+ }
+
+@@ -601,8 +620,7 @@
+ put_tty_driver(gs_tty_driver);
+ usb_gadget_unregister_driver(&gs_gadget_driver);
+
+- pr_info("gs_module_exit: %s %s unloaded\n",
+- GS_LONG_NAME, GS_VERSION_STR);
++ printk(KERN_INFO "gs_module_exit: %s %s unloaded\n", GS_LONG_NAME, GS_VERSION_STR);
+ }
+
+ /* TTY Driver */
+@@ -617,7 +635,7 @@
+ struct gs_port *port;
+ struct gs_dev *dev;
+ struct gs_buf *buf;
+- struct mutex *mtx;
++ struct semaphore *sem;
+ int ret;
+
+ port_num = tty->index;
+@@ -625,7 +643,7 @@
+ gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file);
+
+ if (port_num < 0 || port_num >= GS_NUM_PORTS) {
+- pr_err("gs_open: (%d,%p,%p) invalid port number\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) invalid port number\n",
+ port_num, tty, file);
+ return -ENODEV;
+ }
+@@ -633,14 +651,15 @@
+ dev = gs_device;
+
+ if (dev == NULL) {
+- pr_err("gs_open: (%d,%p,%p) NULL device pointer\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) NULL device pointer\n",
+ port_num, tty, file);
+ return -ENODEV;
+ }
+
+- mtx = &gs_open_close_lock[port_num];
+- if (mutex_lock_interruptible(mtx)) {
+- pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
++ sem = &gs_open_close_sem[port_num];
++ if (down_interruptible(sem)) {
++ printk(KERN_ERR
++ "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n",
+ port_num, tty, file);
+ return -ERESTARTSYS;
+ }
+@@ -648,7 +667,8 @@
+ spin_lock_irqsave(&dev->dev_lock, flags);
+
+ if (dev->dev_config == GS_NO_CONFIG_ID) {
+- pr_err("gs_open: (%d,%p,%p) device is not connected\n",
++ printk(KERN_ERR
++ "gs_open: (%d,%p,%p) device is not connected\n",
+ port_num, tty, file);
+ ret = -ENODEV;
+ goto exit_unlock_dev;
+@@ -657,7 +677,7 @@
+ port = dev->dev_port[port_num];
+
+ if (port == NULL) {
+- pr_err("gs_open: (%d,%p,%p) NULL port pointer\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) NULL port pointer\n",
+ port_num, tty, file);
+ ret = -ENODEV;
+ goto exit_unlock_dev;
+@@ -667,7 +687,7 @@
+ spin_unlock(&dev->dev_lock);
+
+ if (port->port_dev == NULL) {
+- pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (1)\n",
+ port_num, tty, file);
+ ret = -EIO;
+ goto exit_unlock_port;
+@@ -694,7 +714,8 @@
+
+ /* might have been disconnected while asleep, check */
+ if (port->port_dev == NULL) {
+- pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n",
++ printk(KERN_ERR
++ "gs_open: (%d,%p,%p) port disconnected (2)\n",
+ port_num, tty, file);
+ port->port_in_use = 0;
+ ret = -EIO;
+@@ -702,8 +723,7 @@
+ }
+
+ if ((port->port_write_buf=buf) == NULL) {
+- pr_err("gs_open: (%d,%p,%p) cannot allocate "
+- "port write buffer\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) cannot allocate port write buffer\n",
+ port_num, tty, file);
+ port->port_in_use = 0;
+ ret = -ENOMEM;
+@@ -716,7 +736,7 @@
+
+ /* might have been disconnected while asleep, check */
+ if (port->port_dev == NULL) {
+- pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n",
++ printk(KERN_ERR "gs_open: (%d,%p,%p) port disconnected (3)\n",
+ port_num, tty, file);
+ port->port_in_use = 0;
+ ret = -EIO;
+@@ -734,12 +754,12 @@
+
+ exit_unlock_port:
+ spin_unlock_irqrestore(&port->port_lock, flags);
+- mutex_unlock(mtx);
++ up(sem);
+ return ret;
+
+ exit_unlock_dev:
+ spin_unlock_irqrestore(&dev->dev_lock, flags);
+- mutex_unlock(mtx);
++ up(sem);
+ return ret;
+
+ }
+@@ -761,22 +781,23 @@
+ static void gs_close(struct tty_struct *tty, struct file *file)
+ {
+ struct gs_port *port = tty->driver_data;
+- struct mutex *mtx;
++ struct semaphore *sem;
+
+ if (port == NULL) {
+- pr_err("gs_close: NULL port pointer\n");
++ printk(KERN_ERR "gs_close: NULL port pointer\n");
+ return;
+ }
+
+ gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file);
+
+- mtx = &gs_open_close_lock[port->port_num];
+- mutex_lock(mtx);
++ sem = &gs_open_close_sem[port->port_num];
++ down(sem);
+
+ spin_lock_irq(&port->port_lock);
+
+ if (port->port_open_count == 0) {
+- pr_err("gs_close: (%d,%p,%p) port is already closed\n",
++ printk(KERN_ERR
++ "gs_close: (%d,%p,%p) port is already closed\n",
+ port->port_num, tty, file);
+ goto exit;
+ }
+@@ -825,7 +846,7 @@
+
+ exit:
+ spin_unlock_irq(&port->port_lock);
+- mutex_unlock(mtx);
++ up(sem);
+ }
+
+ /*
+@@ -838,7 +859,7 @@
+ int ret;
+
+ if (port == NULL) {
+- pr_err("gs_write: NULL port pointer\n");
++ printk(KERN_ERR "gs_write: NULL port pointer\n");
+ return -EIO;
+ }
+
+@@ -851,14 +872,14 @@
+ spin_lock_irqsave(&port->port_lock, flags);
+
+ if (port->port_dev == NULL) {
+- pr_err("gs_write: (%d,%p) port is not connected\n",
++ printk(KERN_ERR "gs_write: (%d,%p) port is not connected\n",
+ port->port_num, tty);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if (port->port_open_count == 0) {
+- pr_err("gs_write: (%d,%p) port is closed\n",
++ printk(KERN_ERR "gs_write: (%d,%p) port is closed\n",
+ port->port_num, tty);
+ ret = -EBADF;
+ goto exit;
+@@ -889,23 +910,22 @@
+ struct gs_port *port = tty->driver_data;
+
+ if (port == NULL) {
+- pr_err("gs_put_char: NULL port pointer\n");
++ printk(KERN_ERR "gs_put_char: NULL port pointer\n");
+ return;
+ }
+
+- gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
+- port->port_num, tty, ch, __builtin_return_address(0));
++ gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2));
+
+ spin_lock_irqsave(&port->port_lock, flags);
+
+ if (port->port_dev == NULL) {
+- pr_err("gs_put_char: (%d,%p) port is not connected\n",
++ printk(KERN_ERR "gs_put_char: (%d,%p) port is not connected\n",
+ port->port_num, tty);
+ goto exit;
+ }
+
+ if (port->port_open_count == 0) {
+- pr_err("gs_put_char: (%d,%p) port is closed\n",
++ printk(KERN_ERR "gs_put_char: (%d,%p) port is closed\n",
+ port->port_num, tty);
+ goto exit;
+ }
+@@ -925,7 +945,7 @@
+ struct gs_port *port = tty->driver_data;
+
+ if (port == NULL) {
+- pr_err("gs_flush_chars: NULL port pointer\n");
++ printk(KERN_ERR "gs_flush_chars: NULL port pointer\n");
+ return;
+ }
+
+@@ -934,13 +954,14 @@
+ spin_lock_irqsave(&port->port_lock, flags);
+
+ if (port->port_dev == NULL) {
+- pr_err("gs_flush_chars: (%d,%p) port is not connected\n",
++ printk(KERN_ERR
++ "gs_flush_chars: (%d,%p) port is not connected\n",
+ port->port_num, tty);
+ goto exit;
+ }
+
+ if (port->port_open_count == 0) {
+- pr_err("gs_flush_chars: (%d,%p) port is closed\n",
++ printk(KERN_ERR "gs_flush_chars: (%d,%p) port is closed\n",
+ port->port_num, tty);
+ goto exit;
+ }
+@@ -1038,7 +1059,7 @@
+ struct gs_port *port = tty->driver_data;
+
+ if (port == NULL) {
+- pr_err("gs_ioctl: NULL port pointer\n");
++ printk(KERN_ERR "gs_ioctl: NULL port pointer\n");
+ return -EIO;
+ }
+
+@@ -1076,7 +1097,7 @@
+ struct gs_req_entry *req_entry;
+
+ if (dev == NULL) {
+- pr_err("gs_send: NULL device pointer\n");
++ printk(KERN_ERR "gs_send: NULL device pointer\n");
+ return -ENODEV;
+ }
+
+@@ -1094,16 +1115,12 @@
+ len = gs_send_packet(dev, req->buf, ep->maxpacket);
+
+ if (len > 0) {
+- gs_debug_level(3, "gs_send: len=%d, 0x%2.2x "
+- "0x%2.2x 0x%2.2x ...\n", len,
+- *((unsigned char *)req->buf),
+- *((unsigned char *)req->buf+1),
+- *((unsigned char *)req->buf+2));
++gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2));
+ list_del(&req_entry->re_entry);
+ req->length = len;
+ spin_unlock_irqrestore(&dev->dev_lock, flags);
+ if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
+- pr_err(
++ printk(KERN_ERR
+ "gs_send: cannot queue read request, ret=%d\n",
+ ret);
+ spin_lock_irqsave(&dev->dev_lock, flags);
+@@ -1144,7 +1161,9 @@
+ port = dev->dev_port[0];
+
+ if (port == NULL) {
+- pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0);
++ printk(KERN_ERR
++ "gs_send_packet: port=%d, NULL port pointer\n",
++ 0);
+ return -EIO;
+ }
+
+@@ -1191,7 +1210,7 @@
+ port = dev->dev_port[0];
+
+ if (port == NULL) {
+- pr_err("gs_recv_packet: port=%d, NULL port pointer\n",
++ printk(KERN_ERR "gs_recv_packet: port=%d, NULL port pointer\n",
+ port->port_num);
+ return -EIO;
+ }
+@@ -1199,7 +1218,7 @@
+ spin_lock(&port->port_lock);
+
+ if (port->port_open_count == 0) {
+- pr_err("gs_recv_packet: port=%d, port is closed\n",
++ printk(KERN_ERR "gs_recv_packet: port=%d, port is closed\n",
+ port->port_num);
+ ret = -EIO;
+ goto exit;
+@@ -1209,14 +1228,14 @@
+ tty = port->port_tty;
+
+ if (tty == NULL) {
+- pr_err("gs_recv_packet: port=%d, NULL tty pointer\n",
++ printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n",
+ port->port_num);
+ ret = -EIO;
+ goto exit;
+ }
+
+ if (port->port_tty->magic != TTY_MAGIC) {
+- pr_err("gs_recv_packet: port=%d, bad tty magic\n",
++ printk(KERN_ERR "gs_recv_packet: port=%d, bad tty magic\n",
+ port->port_num);
+ ret = -EIO;
+ goto exit;
+@@ -1243,18 +1262,18 @@
+ struct gs_dev *dev = ep->driver_data;
+
+ if (dev == NULL) {
+- pr_err("gs_read_complete: NULL device pointer\n");
++ printk(KERN_ERR "gs_read_complete: NULL device pointer\n");
+ return;
+ }
+
+ switch(req->status) {
+ case 0:
+- /* normal completion */
++ /* normal completion */
+ gs_recv_packet(dev, req->buf, req->actual);
+ requeue:
+ req->length = ep->maxpacket;
+ if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
+- pr_err(
++ printk(KERN_ERR
+ "gs_read_complete: cannot queue read request, ret=%d\n",
+ ret);
+ }
+@@ -1268,7 +1287,7 @@
+
+ default:
+ /* unexpected */
+- pr_err(
++ printk(KERN_ERR
+ "gs_read_complete: unexpected status error, status=%d\n",
+ req->status);
+ goto requeue;
+@@ -1285,7 +1304,7 @@
+ struct gs_req_entry *gs_req = req->context;
+
+ if (dev == NULL) {
+- pr_err("gs_write_complete: NULL device pointer\n");
++ printk(KERN_ERR "gs_write_complete: NULL device pointer\n");
+ return;
+ }
+
+@@ -1294,7 +1313,8 @@
+ /* normal completion */
+ requeue:
+ if (gs_req == NULL) {
+- pr_err("gs_write_complete: NULL request pointer\n");
++ printk(KERN_ERR
++ "gs_write_complete: NULL request pointer\n");
+ return;
+ }
+
+@@ -1313,7 +1333,7 @@
+ break;
+
+ default:
+- pr_err(
++ printk(KERN_ERR
+ "gs_write_complete: unexpected status error, status=%d\n",
+ req->status);
+ goto requeue;
+@@ -1348,7 +1368,7 @@
+ gs_device_desc.bcdDevice =
+ cpu_to_le16(GS_VERSION_NUM | gcnum);
+ else {
+- pr_warning("gs_bind: controller '%s' not recognized\n",
++ printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
+ gadget->name);
+ /* unrecognized, but safe unless bulk is REALLY quirky */
+ gs_device_desc.bcdDevice =
+@@ -1372,7 +1392,7 @@
+ if (use_acm) {
+ ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
+ if (!ep) {
+- pr_err("gs_bind: cannot run ACM on %s\n", gadget->name);
++ printk(KERN_ERR "gs_bind: cannot run ACM on %s\n", gadget->name);
+ goto autoconf_fail;
+ }
+ gs_device_desc.idProduct = __constant_cpu_to_le16(
+@@ -1385,30 +1405,29 @@
+ ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
+ gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+
+- if (gadget_is_dualspeed(gadget)) {
+- gs_qualifier_desc.bDeviceClass = use_acm
+- ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
+- /* assume ep0 uses the same packet size for both speeds */
+- gs_qualifier_desc.bMaxPacketSize0 =
+- gs_device_desc.bMaxPacketSize0;
+- /* assume endpoints are dual-speed */
+- gs_highspeed_notify_desc.bEndpointAddress =
+- gs_fullspeed_notify_desc.bEndpointAddress;
+- gs_highspeed_in_desc.bEndpointAddress =
+- gs_fullspeed_in_desc.bEndpointAddress;
+- gs_highspeed_out_desc.bEndpointAddress =
+- gs_fullspeed_out_desc.bEndpointAddress;
+- }
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++ gs_qualifier_desc.bDeviceClass = use_acm
++ ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
++ /* assume ep0 uses the same packet size for both speeds */
++ gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0;
++ /* assume endpoints are dual-speed */
++ gs_highspeed_notify_desc.bEndpointAddress =
++ gs_fullspeed_notify_desc.bEndpointAddress;
++ gs_highspeed_in_desc.bEndpointAddress =
++ gs_fullspeed_in_desc.bEndpointAddress;
++ gs_highspeed_out_desc.bEndpointAddress =
++ gs_fullspeed_out_desc.bEndpointAddress;
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
+
+ usb_gadget_set_selfpowered(gadget);
+
+- if (gadget_is_otg(gadget)) {
++ if (gadget->is_otg) {
+ gs_otg_descriptor.bmAttributes |= USB_OTG_HNP,
+ gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+
+- gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
++ gs_device = dev = kmalloc(sizeof(struct gs_dev), GFP_KERNEL);
+ if (dev == NULL)
+ return -ENOMEM;
+
+@@ -1416,13 +1435,14 @@
+ init_utsname()->sysname, init_utsname()->release,
+ gadget->name);
+
++ memset(dev, 0, sizeof(struct gs_dev));
+ dev->dev_gadget = gadget;
+ spin_lock_init(&dev->dev_lock);
+ INIT_LIST_HEAD(&dev->dev_req_list);
+ set_gadget_data(gadget, dev);
+
+ if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) {
+- pr_err("gs_bind: cannot allocate ports\n");
++ printk(KERN_ERR "gs_bind: cannot allocate ports\n");
+ gs_unbind(gadget);
+ return ret;
+ }
+@@ -1438,13 +1458,13 @@
+
+ gadget->ep0->driver_data = dev;
+
+- pr_info("gs_bind: %s %s bound\n",
++ printk(KERN_INFO "gs_bind: %s %s bound\n",
+ GS_LONG_NAME, GS_VERSION_STR);
+
+ return 0;
+
+ autoconf_fail:
+- pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
++ printk(KERN_ERR "gs_bind: cannot autoconfigure on %s\n", gadget->name);
+ return -ENODEV;
+ }
+
+@@ -1467,17 +1487,11 @@
+ dev->dev_ctrl_req = NULL;
+ }
+ gs_free_ports(dev);
+- if (dev->dev_notify_ep)
+- usb_ep_disable(dev->dev_notify_ep);
+- if (dev->dev_in_ep)
+- usb_ep_disable(dev->dev_in_ep);
+- if (dev->dev_out_ep)
+- usb_ep_disable(dev->dev_out_ep);
+ kfree(dev);
+ set_gadget_data(gadget, NULL);
+ }
+
+- pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
++ printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME,
+ GS_VERSION_STR);
+ }
+
+@@ -1510,8 +1524,7 @@
+ break;
+
+ default:
+- pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
+- "value=%04x, index=%04x, length=%d\n",
++ printk(KERN_ERR "gs_setup: unknown request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ ctrl->bRequestType, ctrl->bRequest,
+ wValue, wIndex, wLength);
+ break;
+@@ -1524,7 +1537,7 @@
+ && (ret % gadget->ep0->maxpacket) == 0;
+ ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
+ if (ret < 0) {
+- pr_err("gs_setup: cannot queue response, ret=%d\n",
++ printk(KERN_ERR "gs_setup: cannot queue response, ret=%d\n",
+ ret);
+ req->status = 0;
+ gs_setup_complete(gadget->ep0, req);
+@@ -1557,8 +1570,9 @@
+ memcpy(req->buf, &gs_device_desc, ret);
+ break;
+
++#ifdef CONFIG_USB_GADGET_DUALSPEED
+ case USB_DT_DEVICE_QUALIFIER:
+- if (!gadget_is_dualspeed(gadget))
++ if (!gadget->is_dualspeed)
+ break;
+ ret = min(wLength,
+ (u16)sizeof(struct usb_qualifier_descriptor));
+@@ -1566,13 +1580,14 @@
+ break;
+
+ case USB_DT_OTHER_SPEED_CONFIG:
+- if (!gadget_is_dualspeed(gadget))
++ if (!gadget->is_dualspeed)
+ break;
+ /* fall through */
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
+ case USB_DT_CONFIG:
+- ret = gs_build_config_buf(req->buf, gadget,
++ ret = gs_build_config_buf(req->buf, gadget->speed,
+ wValue >> 8, wValue & 0xff,
+- gadget_is_otg(gadget));
++ gadget->is_otg);
+ if (ret >= 0)
+ ret = min(wLength, (u16)ret);
+ break;
+@@ -1654,8 +1669,7 @@
+ break;
+
+ default:
+- pr_err("gs_setup: unknown standard request, type=%02x, "
+- "request=%02x, value=%04x, index=%04x, length=%d\n",
++ printk(KERN_ERR "gs_setup: unknown standard request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ ctrl->bRequestType, ctrl->bRequest,
+ wValue, wIndex, wLength);
+ break;
+@@ -1677,12 +1691,14 @@
+
+ switch (ctrl->bRequest) {
+ case USB_CDC_REQ_SET_LINE_CODING:
+- /* FIXME Submit req to read the data; have its completion
+- * handler copy that data to port->port_line_coding (iff
+- * it's valid) and maybe pass it on. Until then, fail.
+- */
+- pr_warning("gs_setup: set_line_coding "
+- "unuspported\n");
++ ret = min(wLength,
++ (u16)sizeof(struct usb_cdc_line_coding));
++ if (port) {
++ spin_lock(&port->port_lock);
++ memcpy(&port->port_line_coding, req->buf, ret);
++ spin_unlock(&port->port_lock);
++ }
++ ret = 0;
+ break;
+
+ case USB_CDC_REQ_GET_LINE_CODING:
+@@ -1697,18 +1713,11 @@
+ break;
+
+ case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
+- /* FIXME Submit req to read the data; have its completion
+- * handler use that to set the state (iff it's valid) and
+- * maybe pass it on. Until then, fail.
+- */
+- pr_warning("gs_setup: set_control_line_state "
+- "unuspported\n");
++ ret = 0;
+ break;
+
+ default:
+- pr_err("gs_setup: unknown class request, "
+- "type=%02x, request=%02x, value=%04x, "
+- "index=%04x, length=%d\n",
++ printk(KERN_ERR "gs_setup: unknown class request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ ctrl->bRequestType, ctrl->bRequest,
+ wValue, wIndex, wLength);
+ break;
+@@ -1723,8 +1732,7 @@
+ static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+ if (req->status || req->actual != req->length) {
+- pr_err("gs_setup_complete: status error, status=%d, "
+- "actual=%d, length=%d\n",
++ printk(KERN_ERR "gs_setup_complete: status error, status=%d, actual=%d, length=%d\n",
+ req->status, req->actual, req->length);
+ }
+ }
+@@ -1751,11 +1759,11 @@
+
+ /* re-allocate ports for the next connection */
+ if (gs_alloc_ports(dev, GFP_ATOMIC) != 0)
+- pr_err("gs_disconnect: cannot re-allocate ports\n");
++ printk(KERN_ERR "gs_disconnect: cannot re-allocate ports\n");
+
+ spin_unlock_irqrestore(&dev->dev_lock, flags);
+
+- pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
++ printk(KERN_INFO "gs_disconnect: %s disconnected\n", GS_LONG_NAME);
+ }
+
+ /*
+@@ -1778,7 +1786,7 @@
+ struct gs_req_entry *req_entry;
+
+ if (dev == NULL) {
+- pr_err("gs_set_config: NULL device pointer\n");
++ printk(KERN_ERR "gs_set_config: NULL device pointer\n");
+ return 0;
+ }
+
+@@ -1814,7 +1822,8 @@
+
+ if (EP_NOTIFY_NAME
+ && strcmp(ep->name, EP_NOTIFY_NAME) == 0) {
+- ep_desc = choose_ep_desc(gadget,
++ ep_desc = GS_SPEED_SELECT(
++ gadget->speed == USB_SPEED_HIGH,
+ &gs_highspeed_notify_desc,
+ &gs_fullspeed_notify_desc);
+ ret = usb_ep_enable(ep,ep_desc);
+@@ -1823,16 +1832,16 @@
+ dev->dev_notify_ep = ep;
+ dev->dev_notify_ep_desc = ep_desc;
+ } else {
+- pr_err("gs_set_config: cannot enable NOTIFY "
+- "endpoint %s, ret=%d\n",
++ printk(KERN_ERR "gs_set_config: cannot enable notify endpoint %s, ret=%d\n",
+ ep->name, ret);
+ goto exit_reset_config;
+ }
+ }
+
+ else if (strcmp(ep->name, EP_IN_NAME) == 0) {
+- ep_desc = choose_ep_desc(gadget,
+- &gs_highspeed_in_desc,
++ ep_desc = GS_SPEED_SELECT(
++ gadget->speed == USB_SPEED_HIGH,
++ &gs_highspeed_in_desc,
+ &gs_fullspeed_in_desc);
+ ret = usb_ep_enable(ep,ep_desc);
+ if (ret == 0) {
+@@ -1840,15 +1849,15 @@
+ dev->dev_in_ep = ep;
+ dev->dev_in_ep_desc = ep_desc;
+ } else {
+- pr_err("gs_set_config: cannot enable IN "
+- "endpoint %s, ret=%d\n",
++ printk(KERN_ERR "gs_set_config: cannot enable in endpoint %s, ret=%d\n",
+ ep->name, ret);
+ goto exit_reset_config;
+ }
+ }
+
+ else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
+- ep_desc = choose_ep_desc(gadget,
++ ep_desc = GS_SPEED_SELECT(
++ gadget->speed == USB_SPEED_HIGH,
+ &gs_highspeed_out_desc,
+ &gs_fullspeed_out_desc);
+ ret = usb_ep_enable(ep,ep_desc);
+@@ -1857,8 +1866,7 @@
+ dev->dev_out_ep = ep;
+ dev->dev_out_ep_desc = ep_desc;
+ } else {
+- pr_err("gs_set_config: cannot enable OUT "
+- "endpoint %s, ret=%d\n",
++ printk(KERN_ERR "gs_set_config: cannot enable out endpoint %s, ret=%d\n",
+ ep->name, ret);
+ goto exit_reset_config;
+ }
+@@ -1868,7 +1876,7 @@
+
+ if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL
+ || (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) {
+- pr_err("gs_set_config: cannot find endpoints\n");
++ printk(KERN_ERR "gs_set_config: cannot find endpoints\n");
+ ret = -ENODEV;
+ goto exit_reset_config;
+ }
+@@ -1879,12 +1887,11 @@
+ if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) {
+ req->complete = gs_read_complete;
+ if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
+- pr_err("gs_set_config: cannot queue read "
+- "request, ret=%d\n", ret);
++ printk(KERN_ERR "gs_set_config: cannot queue read request, ret=%d\n",
++ ret);
+ }
+ } else {
+- pr_err("gs_set_config: cannot allocate "
+- "read requests\n");
++ printk(KERN_ERR "gs_set_config: cannot allocate read requests\n");
+ ret = -ENOMEM;
+ goto exit_reset_config;
+ }
+@@ -1897,14 +1904,13 @@
+ req_entry->re_req->complete = gs_write_complete;
+ list_add(&req_entry->re_entry, &dev->dev_req_list);
+ } else {
+- pr_err("gs_set_config: cannot allocate "
+- "write requests\n");
++ printk(KERN_ERR "gs_set_config: cannot allocate write requests\n");
+ ret = -ENOMEM;
+ goto exit_reset_config;
+ }
+ }
+
+- pr_info("gs_set_config: %s configured, %s speed %s config\n",
++ printk(KERN_INFO "gs_set_config: %s configured, %s speed %s config\n",
+ GS_LONG_NAME,
+ gadget->speed == USB_SPEED_HIGH ? "high" : "full",
+ config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM");
+@@ -1931,7 +1937,7 @@
+ struct gs_req_entry *req_entry;
+
+ if (dev == NULL) {
+- pr_err("gs_reset_config: NULL device pointer\n");
++ printk(KERN_ERR "gs_reset_config: NULL device pointer\n");
+ return;
+ }
+
+@@ -1970,11 +1976,11 @@
+ * Builds the config descriptors in the given buffer and returns the
+ * length, or a negative error number.
+ */
+-static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
++static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed,
+ u8 type, unsigned int index, int is_otg)
+ {
+ int len;
+- int high_speed = 0;
++ int high_speed;
+ const struct usb_config_descriptor *config_desc;
+ const struct usb_descriptor_header **function;
+
+@@ -1982,22 +1988,20 @@
+ return -EINVAL;
+
+ /* other speed switches high and full speed */
+- if (gadget_is_dualspeed(g)) {
+- high_speed = (g->speed == USB_SPEED_HIGH);
+- if (type == USB_DT_OTHER_SPEED_CONFIG)
+- high_speed = !high_speed;
+- }
++ high_speed = (speed == USB_SPEED_HIGH);
++ if (type == USB_DT_OTHER_SPEED_CONFIG)
++ high_speed = !high_speed;
+
+ if (use_acm) {
+ config_desc = &gs_acm_config_desc;
+- function = high_speed
+- ? gs_acm_highspeed_function
+- : gs_acm_fullspeed_function;
++ function = GS_SPEED_SELECT(high_speed,
++ gs_acm_highspeed_function,
++ gs_acm_fullspeed_function);
+ } else {
+ config_desc = &gs_bulk_config_desc;
+- function = high_speed
+- ? gs_bulk_highspeed_function
+- : gs_bulk_fullspeed_function;
++ function = GS_SPEED_SELECT(high_speed,
++ gs_bulk_highspeed_function,
++ gs_bulk_fullspeed_function);
+ }
+
+ /* for now, don't advertise srp-only devices */
+@@ -2211,7 +2215,7 @@
+ *
+ * Free the buffer and all associated memory.
+ */
+-static void gs_buf_free(struct gs_buf *gb)
++void gs_buf_free(struct gs_buf *gb)
+ {
+ if (gb) {
+ kfree(gb->buf_buf);
+@@ -2224,7 +2228,7 @@
+ *
+ * Clear out all data in the circular buffer.
+ */
+-static void gs_buf_clear(struct gs_buf *gb)
++void gs_buf_clear(struct gs_buf *gb)
+ {
+ if (gb != NULL)
+ gb->buf_get = gb->buf_put;
+@@ -2237,7 +2241,7 @@
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+-static unsigned int gs_buf_data_avail(struct gs_buf *gb)
++unsigned int gs_buf_data_avail(struct gs_buf *gb)
+ {
+ if (gb != NULL)
+ return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size;
+@@ -2251,7 +2255,7 @@
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+-static unsigned int gs_buf_space_avail(struct gs_buf *gb)
++unsigned int gs_buf_space_avail(struct gs_buf *gb)
+ {
+ if (gb != NULL)
+ return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size;
+@@ -2267,8 +2271,7 @@
+ *
+ * Return the number of bytes copied.
+ */
+-static unsigned int
+-gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
++unsigned int gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
+ {
+ unsigned int len;
+
+@@ -2306,8 +2309,7 @@
+ *
+ * Return the number of bytes copied.
+ */
+-static unsigned int
+-gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
++unsigned int gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
+ {
+ unsigned int len;
+
+diff -Naur linux-2.6.25_original/drivers/video/Kconfig linux-2.6.25/drivers/video/Kconfig
+--- linux-2.6.25_original/drivers/video/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/video/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -1759,6 +1759,32 @@
+
+ <file:Documentation/fb/pxafb.txt> describes the available parameters.
+
++if 0
++if FB_PXA
++choice
++ prompt "Display Type for REGULUS Board"
++ depends on MACH_REGULUS
++
++config LCD_DISPLAY_3P5_INCH_320_240
++ bool "LCD Display 3.5 Inch 320x240 resolution"
++ depends on MACH_REGULUS && FB_PXA
++
++config LCD_DISPLAY_5P7_INCH_640_480
++ bool "LCD Display 5.7 Inch 640x480 resolution"
++ depends on MACH_REGULUS && FB_PXA
++
++config LCD_DISPLAY_6P5_INCH_640_480
++ bool "LCD Display 6.5 Inch 640x480 resolution"
++ depends on MACH_REGULUS && FB_PXA
++
++config CRT_DISPLAY_640_480
++ bool "CRT Display 640x480 resolution"
++ depends on MACH_REGULUS && FB_PXA
++
++endchoice
++endif
++endif
++
+ config FB_MBX
+ tristate "2700G LCD framebuffer support"
+ depends on FB && ARCH_PXA
+diff -Naur linux-2.6.25_original/drivers/video/pxafb.c linux-2.6.25/drivers/video/pxafb.c
+--- linux-2.6.25_original/drivers/video/pxafb.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/drivers/video/pxafb.c 2009-05-16 18:43:58.000000000 +0530
+@@ -22,6 +22,98 @@
+ *
+ */
+
++
++/*
++
++driver supports the following options, either via
++options=<OPTIONS> when modular or video=pxafb:<OPTIONS> when built in.
++
++For example:
++ modprobe pxafb options=mode:640x480-8,passive
++or on the kernel command line
++ video=pxafb:mode:640x480-8,passive
++
++mode:XRESxYRES[-BPP]
++ XRES == LCCR1_PPL + 1
++ YRES == LLCR2_LPP + 1
++ The resolution of the display in pixels
++ BPP == The bit depth. Valid values are 1, 2, 4, 8 and 16.
++
++pixclock:PIXCLOCK
++ Pixel clock in picoseconds
++
++left:LEFT == LCCR1_BLW + 1
++right:RIGHT == LCCR1_ELW + 1
++hsynclen:HSYNC == LCCR1_HSW + 1
++upper:UPPER == LCCR2_BFW
++lower:LOWER == LCCR2_EFR
++vsynclen:VSYNC == LCCR2_VSW + 1
++ Display margins and sync times
++
++color | mono => LCCR0_CMS
++ umm...
++
++active | passive => LCCR0_PAS
++ Active (TFT) or Passive (STN) display
++
++single | dual => LCCR0_SDS
++ Single or dual panel passive display
++
++4pix | 8pix => LCCR0_DPD
++ 4 or 8 pixel monochrome single panel data
++
++hsync:HSYNC
++vsync:VSYNC
++ Horizontal and vertical sync. 0 => active low, 1 => active
++ high.
++
++dpc:DPC
++ Double pixel clock. 1=>true, 0=>false
++
++outputen:POLARITY
++ Output Enable Polarity. 0 => active low, 1 => active high
++
++pixclockpol:POLARITY
++ pixel clock polarity
++ 0 => falling edge, 1 => rising edge
++
++LCD Display 3.5 Inch 240x320 resln:
++###################################
++LCLK = 104MHz, PCD=7, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(7+1)) = 6.5Mhz.
++pixelclock in seconds = 1/6.5Mhz = 0.153846*(10^-6) = 153846*(10^-12) = 153846 picoseconds
++
++insmod pxafb.ko options=mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 5.7 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 6.5 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++CRT Display 640x480 resln:
++##########################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single
++
++#define BOOTARGS_FOR_LCD3P5 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD5P7 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD6P5 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_CRT "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++
++
++*/
++
++
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/kernel.h>
+@@ -48,6 +140,69 @@
+ #include <asm/arch/bitfield.h>
+ #include <asm/arch/pxafb.h>
+
++#if 0
++#define pr_debug(fmt, arg...) \
++ printk(fmt, ##arg)
++#define dev_dbg(dev, format, arg...) \
++ printk(format , ## arg)
++#endif
++
++#if CONFIG_MACH_REGULUS
++//#ifdef CONFIG_CRT_DISPLAY_640_480
++//#undef CONFIG_CRT_DISPLAY_640_480
++//#define CONFIG_CRT_DISPLAY_800_600 1
++//#endif
++#ifdef CONFIG_LCD_DISPLAY_3P5_INCH_320_240
++#warning "LCD Display 3.5 inch 320x240 resln is selected"
++#define PPL 239
++#define LPP 319
++#define LCCR0_DATA 0x07B008f8
++#define LCCR1_DATA ( 0x3A103400 | PPL )
++#define LCCR2_DATA ( 0x00041C00 | LPP )
++#define LCCR3_DATA 0x04440007
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_LCD_DISPLAY_5P7_INCH_640_480)
++#warning "LCD Display 5.7 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x5050127F
++#define LCCR2_DATA 0x131309DF
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_LCD_DISPLAY_6P5_INCH_640_480)
++#warning "LCD Display 6.5 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008d9
++#define LCCR1_DATA 0x0600127f
++#define LCCR2_DATA 0x131309df
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_CRT_DISPLAY_640_480)
++#warning "CRT Display 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x3030FE7F
++#define LCCR2_DATA 0x251109DF
++#define LCCR3_DATA 0x04000001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_CRT_DISPLAY_800_600)
++#warning "CRT Display 800x600 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0xB528FF1F
++#define LCCR2_DATA 0x18014257
++#define LCCR3_DATA 0x04000001
++#define LCCR4_DATA 0x80000000
++#define LCCR5_DATA 0x00000000
++#define LCCR0_DATA_CRT_800_600 0x07b008f8
++#define LCCR1_DATA_CRT_800_600 0xB528FF1F //0xFD104F1F
++#define LCCR2_DATA_CRT_800_600 0x18014257 //0x20010E57
++#define LCCR3_DATA_CRT_800_600 0x04000001
++#define LCCR4_DATA_CRT_800_600 0x80000000
++#endif
++#endif // CONFIG_MACH_REGULUS_REGULUS
++
++
+ /*
+ * Complain if VAR is out of range.
+ */
+@@ -58,7 +213,6 @@
+ /* Bits which should not be set in machine configuration structures */
+ #define LCCR0_INVALID_CONFIG_MASK (LCCR0_OUM|LCCR0_BM|LCCR0_QDM|LCCR0_DIS|LCCR0_EFM|LCCR0_IUM|LCCR0_SFM|LCCR0_LDM|LCCR0_ENB)
+ #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
+-
+ static void (*pxafb_backlight_power)(int);
+ static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
+
+@@ -635,6 +789,12 @@
+ fbi->fb.fix.id, var->lower_margin);
+ #endif
+
++
++// Added by e-con for RGB 565 Format and Overlays are above the base layer
++#if CONFIG_MACH_REGULUS
++ fbi->lccr0 = (fbi->lccr0|LCCR0_LDDALT|LCCR0_OUC|LCCR0_CMDIM|LCCR0_RDSTM);
++#endif
++
+ new_regs.lccr0 = fbi->lccr0 |
+ (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
+ LCCR0_QDM | LCCR0_BM | LCCR0_OUM);
+@@ -741,10 +901,25 @@
+ pr_debug("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
+ #endif
+
++
++ pr_debug("FDADR0 0x%08x\n", (unsigned int) FDADR0);
++ pr_debug("FDADR1 0x%08x\n", (unsigned int) FDADR1);
++ pr_debug("LCCR0 0x%08x\n", (unsigned int) LCCR0);
++ pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
++ pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
++ pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
++
++#if (CONFIG_LCD_DISPLAY_3P5_INCH_320_240 || CONFIG_LCD_DISPLAY_5P7_INCH_320_240 || CONFIG_LCD_DISPLAY_6P5_INCH_320_240 || CONFIG_CRT_DISPLAY_640_480 || CONFIG_CRT_DISPLAY_800_600)
++ fbi->reg_lccr0 = LCCR0_DATA; //new_regs.lccr0;
++ fbi->reg_lccr1 = LCCR1_DATA; //new_regs.lccr1;
++ fbi->reg_lccr2 = LCCR2_DATA; //new_regs.lccr2;
++ fbi->reg_lccr3 = LCCR3_DATA; //new_regs.lccr3;
++#else
+ fbi->reg_lccr0 = new_regs.lccr0;
+ fbi->reg_lccr1 = new_regs.lccr1;
+ fbi->reg_lccr2 = new_regs.lccr2;
+ fbi->reg_lccr3 = new_regs.lccr3;
++#endif
+ fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
+ fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
+ set_hsync_time(fbi, pcd);
+@@ -838,6 +1013,9 @@
+ clk_enable(fbi->clk);
+
+ /* Sequence from 11.7.10 */
++#if (CONFIG_LCD_DISPLAY_3P5_INCH_320_240 || CONFIG_LCD_DISPLAY_5P7_INCH_320_240 || CONFIG_LCD_DISPLAY_6P5_INCH_320_240 || CONFIG_CRT_DISPLAY_640_480 || CONFIG_CRT_DISPLAY_800_600)
++ LCCR4 = LCCR4_DATA;
++#endif
+ LCCR3 = fbi->reg_lccr3;
+ LCCR2 = fbi->reg_lccr2;
+ LCCR1 = fbi->reg_lccr1;
+@@ -853,7 +1031,6 @@
+ pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
+ pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
+ pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
+- pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
+ }
+
+ static void pxafb_disable_controller(struct pxafb_info *fbi)
+@@ -1513,7 +1690,15 @@
+ return platform_driver_register(&pxafb_driver);
+ }
+
++static void __devinit pxafb_exit(void)
++{
++ platform_driver_unregister(&pxafb_driver);
++ return ;
++}
++
++
+ module_init(pxafb_init);
++module_exit(pxafb_exit);
+
+ MODULE_DESCRIPTION("loadable framebuffer driver for PXA");
+ MODULE_LICENSE("GPL");
+diff -Naur linux-2.6.25_original/fs/Kconfig linux-2.6.25/fs/Kconfig
+--- linux-2.6.25_original/fs/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/fs/Kconfig 2009-05-25 11:12:40.000000000 +0530
+@@ -1347,6 +1347,8 @@
+
+ endchoice
+
++source "fs/yaffs2/Kconfig"
++
+ config CRAMFS
+ tristate "Compressed ROM file system support (cramfs)"
+ depends on BLOCK
+diff -Naur linux-2.6.25_original/fs/Makefile linux-2.6.25/fs/Makefile
+--- linux-2.6.25_original/fs/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/fs/Makefile 2009-05-25 11:12:40.000000000 +0530
+@@ -119,3 +119,4 @@
+ obj-$(CONFIG_DEBUG_FS) += debugfs/
+ obj-$(CONFIG_OCFS2_FS) += ocfs2/
+ obj-$(CONFIG_GFS2_FS) += gfs2/
++obj-$(CONFIG_YAFFS_FS) +=yaffs2/
+diff -Naur linux-2.6.25_original/fs/partitions/check.c linux-2.6.25/fs/partitions/check.c
+--- linux-2.6.25_original/fs/partitions/check.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/fs/partitions/check.c 2009-05-16 18:43:58.000000000 +0530
+@@ -189,9 +189,17 @@
+ /* The partition is unrecognized. So report I/O errors if there were any */
+ res = err;
+ if (!res)
++ {
++#if !CONFIG_MACH_REGULUS
+ printk(" unknown partition table\n");
++#endif
++ }
+ else if (warn_no_part)
++ {
++#if !CONFIG_MACH_REGULUS
+ printk(" unable to read partition table\n");
++#endif
++ }
+ kfree(state);
+ return ERR_PTR(res);
+ }
+diff -Naur linux-2.6.25_original/fs/yaffs2/devextras.h linux-2.6.25/fs/yaffs2/devextras.h
+--- linux-2.6.25_original/fs/yaffs2/devextras.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/devextras.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,196 @@
++/*
++ * 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.
++ */
++
++/*
++ * 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 __KERNEL__)
++
++/* Definition of types */
++typedef unsigned char __u8;
++typedef unsigned short __u16;
++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__)
++
++
++#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
++#define DT_DIR 4
++#define DT_BLK 6
++#define DT_REG 8
++#define DT_LNK 10
++#define DT_SOCK 12
++#define DT_WHT 14
++
++
++#ifndef WIN32
++#include <sys/stat.h>
++#endif
++
++/*
++ * Attribute flags. These should be or-ed together to figure out what
++ * has been changed!
++ */
++#define ATTR_MODE 1
++#define ATTR_UID 2
++#define ATTR_GID 4
++#define ATTR_SIZE 8
++#define ATTR_ATIME 16
++#define ATTR_MTIME 32
++#define ATTR_CTIME 64
++
++struct iattr {
++ unsigned int ia_valid;
++ unsigned ia_mode;
++ unsigned ia_uid;
++ unsigned ia_gid;
++ unsigned ia_size;
++ unsigned ia_atime;
++ unsigned ia_mtime;
++ unsigned ia_ctime;
++ unsigned int ia_attr_flags;
++};
++
++#endif
++
++#else
++
++#include <linux/types.h>
++#include <linux/fs.h>
++#include <linux/stat.h>
++
++#endif
++
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/Kconfig linux-2.6.25/fs/yaffs2/Kconfig
+--- linux-2.6.25_original/fs/yaffs2/Kconfig 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/Kconfig 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,156 @@
++#
++# YAFFS file system configurations
++#
++
++config YAFFS_FS
++ tristate "YAFFS2 file system support"
++ default n
++ depends on MTD_BLOCK
++ select YAFFS_YAFFS1
++ select YAFFS_YAFFS2
++ help
++ YAFFS2, or Yet Another Flash Filing System, is a filing system
++ optimised for NAND Flash chips.
++
++ To compile the YAFFS2 file system support as a module, choose M
++ here: the module will be called yaffs2.
++
++ If unsure, say N.
++
++ Further information on YAFFS2 is available at
++ <http://www.aleph1.co.uk/yaffs/>.
++
++config YAFFS_YAFFS1
++ bool "512 byte / page devices"
++ depends on YAFFS_FS
++ default y
++ help
++ Enable YAFFS1 support -- yaffs for 512 byte / page devices
++
++ Not needed for 2K-page devices.
++
++ If unsure, say Y.
++
++config YAFFS_9BYTE_TAGS
++ bool "Use older-style on-NAND data format with pageStatus byte"
++ depends on YAFFS_YAFFS1
++ default n
++ help
++
++ Older-style on-NAND data format has a "pageStatus" byte to record
++ chunk/page state. This byte is zero when the page is discarded.
++ Choose this option if you have existing on-NAND data using this
++ 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
++ in yaffs_mtdif1.c.
++
++ If unsure, say N.
++
++config YAFFS_DOES_ECC
++ bool "Lets Yaffs do its own ECC"
++ depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
++ default n
++ help
++ This enables Yaffs to use its own ECC functions instead of using
++ the ones from the generic MTD-NAND driver.
++
++ If unsure, say N.
++
++config YAFFS_ECC_WRONG_ORDER
++ bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
++ depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
++ default n
++ help
++ This makes yaffs_ecc.c use the same ecc byte order as Steven
++ Hill's nand_ecc.c. If not set, then you get the same ecc byte
++ order as SmartMedia.
++
++ If unsure, say N.
++
++config YAFFS_YAFFS2
++ bool "2048 byte (or larger) / page devices"
++ depends on YAFFS_FS
++ default y
++ help
++ Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
++
++ If unsure, say Y.
++
++config YAFFS_AUTO_YAFFS2
++ bool "Autoselect yaffs2 format"
++ depends on YAFFS_YAFFS2
++ default y
++ help
++ Without this, you need to explicitely use yaffs2 as the file
++ system type. With this, you can say "yaffs" and yaffs or yaffs2
++ will be used depending on the device page size (yaffs on
++ 512-byte page devices, yaffs2 on 2K page devices).
++
++ If unsure, say Y.
++
++config YAFFS_DISABLE_LAZY_LOAD
++ bool "Disable lazy loading"
++ depends on 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.
++
++ If unsure, say N.
++
++
++config YAFFS_DISABLE_WIDE_TNODES
++ bool "Turn off wide tnodes"
++ depends on YAFFS_FS
++ default n
++ help
++ Wide tnodes are only used for NAND arrays >=32MB for 512-byte
++ page devices and >=128MB for 2k page devices. They use slightly
++ more RAM but are faster since they eliminate chunk group
++ searching.
++
++ Setting this to 'y' will force tnode width to 16 bits and save
++ memory but make large arrays slower.
++
++ If unsure, say N.
++
++config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
++ bool "Force chunk erase check"
++ depends on YAFFS_FS
++ default n
++ help
++ Normally YAFFS only checks chunks before writing until an erased
++ chunk is found. This helps to detect any partially written
++ chunks that might have happened due to power loss.
++
++ Enabling this forces on the test that chunks are erased in flash
++ before writing to them. This takes more time but is potentially
++ a bit more secure.
++
++ Suggest setting Y during development and ironing out driver
++ issues etc. Suggest setting to N if you want faster writing.
++
++ If unsure, say Y.
++
++config YAFFS_SHORT_NAMES_IN_RAM
++ bool "Cache short names in RAM"
++ depends on YAFFS_FS
++ default y
++ help
++ If this config is set, then short names are stored with the
++ yaffs_Object. This costs an extra 16 bytes of RAM per object,
++ but makes look-ups faster.
++
++ If unsure, say Y.
+diff -Naur linux-2.6.25_original/fs/yaffs2/Makefile linux-2.6.25/fs/yaffs2/Makefile
+--- linux-2.6.25_original/fs/yaffs2/Makefile 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/Makefile 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,11 @@
++#
++# Makefile for the linux YAFFS filesystem routines.
++#
++
++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_tagscompat.o yaffs_tagsvalidity.o
++yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
++#yaffs-y := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o
+diff -Naur linux-2.6.25_original/fs/yaffs2/moduleconfig.h linux-2.6.25/fs/yaffs2/moduleconfig.h
+--- linux-2.6.25_original/fs/yaffs2/moduleconfig.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/moduleconfig.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,65 @@
++/*
++ * 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 Martin Fouts <Martin.Fouts@palmsource.com>
++ *
++ * 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_CONFIG_H__
++#define __YAFFS_CONFIG_H__
++
++#ifdef YAFFS_OUT_OF_TREE
++
++/* DO NOT UNSET THESE THREE. YAFFS2 will not compile if you do. */
++#define CONFIG_YAFFS_FS
++#define CONFIG_YAFFS_YAFFS1
++#define CONFIG_YAFFS_YAFFS2
++
++/* These options are independent of each other. Select those that matter. */
++
++/* Default: Not selected */
++/* Meaning: Yaffs does its own ECC, rather than using MTD 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 */
++
++/* Default: Selected */
++/* Meaning: Disables testing whether chunks are erased before writing to them*/
++#define CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK
++
++/* 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
++
++/*
++Older-style on-NAND data format has a "pageStatus" 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
++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 in yaffs_mtdif1.c.
++*/
++/* Default: Not selected */
++/* Meaning: Use older-style on-NAND data format with pageStatus byte */
++/* #define CONFIG_YAFFS_9BYTE_TAGS */
++
++#endif /* YAFFS_OUT_OF_TREE */
++
++#endif /* __YAFFS_CONFIG_H__ */
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_checkptrw.c linux-2.6.25/fs/yaffs2/yaffs_checkptrw.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_checkptrw.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_checkptrw.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,394 @@
++/*
++ * 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 General Public License version 2 as
++ * 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)
++{
++ 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)
++ return 0;
++ 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 */)) {
++ bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
++ dev->nErasedBlocks++;
++ dev->nFreeChunks += dev->nChunksPerBlock;
++ } else {
++ dev->markNANDBlockBad(dev, i);
++ bi->blockState = YAFFS_BLOCK_STATE_DEAD;
++ }
++ }
++ }
++
++ dev->blocksInCheckpoint = 0;
++
++ return 1;
++}
++
++
++static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev)
++{
++ int i;
++ 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));
++
++ 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));
++ return;
++ }
++ }
++ }
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
++
++ dev->checkpointNextBlock = -1;
++ dev->checkpointCurrentBlock = -1;
++}
++
++static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
++{
++ int i;
++ yaffs_ExtendedTags tags;
++
++ 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++) {
++ 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));
++
++ 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));
++ return;
++ }
++ }
++
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
++
++ dev->checkpointNextBlock = -1;
++ dev->checkpointCurrentBlock = -1;
++}
++
++
++int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
++{
++
++ /* Got the functions we need? */
++ if (!dev->writeChunkWithTagsToNAND ||
++ !dev->readChunkWithTagsFromNAND ||
++ !dev->eraseBlockInNAND ||
++ !dev->markNANDBlockBad)
++ return 0;
++
++ if (forWriting && !yaffs_CheckpointSpaceOk(dev))
++ return 0;
++
++ if (!dev->checkpointBuffer)
++ dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
++ if (!dev->checkpointBuffer)
++ 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;
++
++ /* Erase all the blocks in the checkpoint area */
++ 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 */
++ dev->checkpointByteOffset = dev->nDataBytesPerChunk;
++ /* 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;
++ }
++
++ return 1;
++}
++
++int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum)
++{
++ __u32 compositeSum;
++ compositeSum = (dev->checkpointSum << 8) | (dev->checkpointXor & 0xFF);
++ *sum = compositeSum;
++ return 1;
++}
++
++static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
++{
++ int chunk;
++ int realignedChunk;
++
++ yaffs_ExtendedTags tags;
++
++ if (dev->checkpointCurrentBlock < 0) {
++ yaffs_CheckpointFindNextErasedBlock(dev);
++ dev->checkpointCurrentChunk = 0;
++ }
++
++ if (dev->checkpointCurrentBlock < 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) {
++ /* 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++;
++ }
++
++ 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));
++
++ realignedChunk = chunk - dev->chunkOffset;
++
++ 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;
++ }
++ memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
++
++ return 1;
++}
++
++
++int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
++{
++ int i = 0;
++ int ok = 1;
++
++
++ __u8 * dataBytes = (__u8 *)data;
++
++
++
++ if (!dev->checkpointBuffer)
++ return 0;
++
++ if (!dev->checkpointOpenForWrite)
++ return -1;
++
++ while (i < nBytes && ok) {
++ dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
++ dev->checkpointSum += *dataBytes;
++ dev->checkpointXor ^= *dataBytes;
++
++ dev->checkpointByteOffset++;
++ i++;
++ dataBytes++;
++ dev->checkpointByteCount++;
++
++
++ if (dev->checkpointByteOffset < 0 ||
++ dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
++ ok = yaffs_CheckpointFlushBuffer(dev);
++ }
++
++ return i;
++}
++
++int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
++{
++ int i = 0;
++ int ok = 1;
++ yaffs_ExtendedTags tags;
++
++
++ int chunk;
++ int realignedChunk;
++
++ __u8 *dataBytes = (__u8 *)data;
++
++ if (!dev->checkpointBuffer)
++ return 0;
++
++ if (dev->checkpointOpenForWrite)
++ return -1;
++
++ while (i < nBytes && ok) {
++
++
++ if (dev->checkpointByteOffset < 0 ||
++ dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
++
++ if (dev->checkpointCurrentBlock < 0) {
++ yaffs_CheckpointFindNextCheckpointBlock(dev);
++ dev->checkpointCurrentChunk = 0;
++ }
++
++ if (dev->checkpointCurrentBlock < 0)
++ ok = 0;
++ else {
++ 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.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)
++ dev->checkpointCurrentBlock = -1;
++ }
++ }
++
++ if (ok) {
++ *dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
++ dev->checkpointSum += *dataBytes;
++ dev->checkpointXor ^= *dataBytes;
++ dev->checkpointByteOffset++;
++ i++;
++ dataBytes++;
++ dev->checkpointByteCount++;
++ }
++ }
++
++ return i;
++}
++
++int yaffs_CheckpointClose(yaffs_Device *dev)
++{
++
++ 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)
++ bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
++ else {
++ /* Todo this looks odd... */
++ }
++ }
++ YFREE(dev->checkpointBlockList);
++ dev->checkpointBlockList = NULL;
++ }
++
++ dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock;
++ dev->nErasedBlocks -= dev->blocksInCheckpoint;
++
++
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
++ dev->checkpointByteCount));
++
++ if (dev->checkpointBuffer) {
++ /* free the buffer */
++ YFREE(dev->checkpointBuffer);
++ dev->checkpointBuffer = NULL;
++ return 1;
++ } else
++ return 0;
++}
++
++int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
++{
++ /* Erase the first checksum block */
++
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
++
++ if (!yaffs_CheckpointSpaceOk(dev))
++ return 0;
++
++ return yaffs_CheckpointErase(dev);
++}
++
++
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_checkptrw.h linux-2.6.25/fs/yaffs2/yaffs_checkptrw.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_checkptrw.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_checkptrw.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,35 @@
++/*
++ * 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_CHECKPTRW_H__
++#define __YAFFS_CHECKPTRW_H__
++
++#include "yaffs_guts.h"
++
++int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
++
++int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
++
++int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
++
++int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
++
++int yaffs_CheckpointClose(yaffs_Device *dev);
++
++int yaffs_CheckpointInvalidateStream(yaffs_Device *dev);
++
++
++#endif
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_ecc.c linux-2.6.25/fs/yaffs2/yaffs_ecc.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_ecc.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_ecc.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,326 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++/*
++ * 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.
++ *
++ */
++
++/* Table generated by gen-ecc.c
++ * Using a table means we do not have to calculate p1..p4 and p1'..p4'
++ * for each byte of data. These are instead provided in a table in bits7..2.
++ * Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore
++ * 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"
++
++static const unsigned char column_parity_table[] = {
++ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
++ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
++ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
++ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
++ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
++ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
++ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
++ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
++ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
++ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
++ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
++ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
++ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
++ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
++ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
++ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
++ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
++ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
++ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
++ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
++ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
++ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
++ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
++ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
++ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
++ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
++ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
++ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
++ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
++ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
++ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
++ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
++};
++
++/* Count the bits in an unsigned char or a U32 */
++
++static int yaffs_CountBits(unsigned char x)
++{
++ int r = 0;
++ while (x) {
++ if (x & 1)
++ r++;
++ x >>= 1;
++ }
++ return r;
++}
++
++static int yaffs_CountBits32(unsigned x)
++{
++ int r = 0;
++ while (x) {
++ if (x & 1)
++ r++;
++ x >>= 1;
++ }
++ return r;
++}
++
++/* Calculate the ECC for a 256-byte block of data */
++void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
++{
++ unsigned int i;
++
++ unsigned char col_parity = 0;
++ unsigned char line_parity = 0;
++ unsigned char line_parity_prime = 0;
++ unsigned char t;
++ unsigned char b;
++
++ for (i = 0; i < 256; i++) {
++ b = column_parity_table[*data++];
++ col_parity ^= b;
++
++ if (b & 0x01) { /* odd number of bits in the byte */
++ line_parity ^= i;
++ line_parity_prime ^= ~i;
++ }
++ }
++
++ ecc[2] = (~col_parity) | 0x03;
++
++ t = 0;
++ if (line_parity & 0x80)
++ t |= 0x80;
++ if (line_parity_prime & 0x80)
++ t |= 0x40;
++ if (line_parity & 0x40)
++ t |= 0x20;
++ if (line_parity_prime & 0x40)
++ t |= 0x10;
++ if (line_parity & 0x20)
++ t |= 0x08;
++ if (line_parity_prime & 0x20)
++ t |= 0x04;
++ if (line_parity & 0x10)
++ t |= 0x02;
++ if (line_parity_prime & 0x10)
++ t |= 0x01;
++ ecc[1] = ~t;
++
++ t = 0;
++ if (line_parity & 0x08)
++ t |= 0x80;
++ if (line_parity_prime & 0x08)
++ t |= 0x40;
++ if (line_parity & 0x04)
++ t |= 0x20;
++ if (line_parity_prime & 0x04)
++ t |= 0x10;
++ if (line_parity & 0x02)
++ t |= 0x08;
++ if (line_parity_prime & 0x02)
++ t |= 0x04;
++ if (line_parity & 0x01)
++ t |= 0x02;
++ if (line_parity_prime & 0x01)
++ t |= 0x01;
++ ecc[0] = ~t;
++
++#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
++ /* Swap the bytes into the wrong order */
++ t = ecc[0];
++ ecc[0] = ecc[1];
++ ecc[1] = t;
++#endif
++}
++
++
++/* Correct the ECC on a 256 byte block of data */
++
++int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
++ const unsigned char *test_ecc)
++{
++ unsigned char d0, d1, d2; /* deltas */
++
++ d0 = read_ecc[0] ^ test_ecc[0];
++ d1 = read_ecc[1] ^ test_ecc[1];
++ d2 = read_ecc[2] ^ test_ecc[2];
++
++ if ((d0 | d1 | d2) == 0)
++ return 0; /* no error */
++
++ if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 &&
++ ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 &&
++ ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) {
++ /* Single bit (recoverable) error in data */
++
++ unsigned byte;
++ unsigned bit;
++
++#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
++ /* swap the bytes to correct for the wrong order */
++ unsigned char t;
++
++ t = d0;
++ d0 = d1;
++ d1 = t;
++#endif
++
++ bit = byte = 0;
++
++ if (d1 & 0x80)
++ byte |= 0x80;
++ if (d1 & 0x20)
++ byte |= 0x40;
++ if (d1 & 0x08)
++ byte |= 0x20;
++ if (d1 & 0x02)
++ byte |= 0x10;
++ if (d0 & 0x80)
++ byte |= 0x08;
++ if (d0 & 0x20)
++ byte |= 0x04;
++ if (d0 & 0x08)
++ byte |= 0x02;
++ if (d0 & 0x02)
++ byte |= 0x01;
++
++ if (d2 & 0x80)
++ bit |= 0x04;
++ if (d2 & 0x20)
++ bit |= 0x02;
++ if (d2 & 0x08)
++ bit |= 0x01;
++
++ data[byte] ^= (1 << bit);
++
++ return 1; /* Corrected the error */
++ }
++
++ if ((yaffs_CountBits(d0) +
++ yaffs_CountBits(d1) +
++ yaffs_CountBits(d2)) == 1) {
++ /* Reccoverable error in ecc */
++
++ read_ecc[0] = test_ecc[0];
++ read_ecc[1] = test_ecc[1];
++ read_ecc[2] = test_ecc[2];
++
++ return 1; /* Corrected the error */
++ }
++
++ /* Unrecoverable error */
++
++ return -1;
++
++}
++
++
++/*
++ * ECCxxxOther does ECC calcs on arbitrary n bytes of data
++ */
++void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
++ yaffs_ECCOther *eccOther)
++{
++ unsigned int i;
++
++ unsigned char col_parity = 0;
++ unsigned line_parity = 0;
++ unsigned line_parity_prime = 0;
++ unsigned char b;
++
++ for (i = 0; i < nBytes; i++) {
++ b = column_parity_table[*data++];
++ col_parity ^= b;
++
++ if (b & 0x01) {
++ /* odd number of bits in the byte */
++ line_parity ^= i;
++ line_parity_prime ^= ~i;
++ }
++
++ }
++
++ eccOther->colParity = (col_parity >> 2) & 0x3f;
++ eccOther->lineParity = line_parity;
++ eccOther->lineParityPrime = line_parity_prime;
++}
++
++int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
++ yaffs_ECCOther *read_ecc,
++ const yaffs_ECCOther *test_ecc)
++{
++ unsigned char cDelta; /* column parity delta */
++ unsigned lDelta; /* line parity delta */
++ unsigned lDeltaPrime; /* line parity delta */
++ unsigned bit;
++
++ cDelta = read_ecc->colParity ^ test_ecc->colParity;
++ lDelta = read_ecc->lineParity ^ test_ecc->lineParity;
++ lDeltaPrime = read_ecc->lineParityPrime ^ test_ecc->lineParityPrime;
++
++ if ((cDelta | lDelta | lDeltaPrime) == 0)
++ return 0; /* no error */
++
++ if (lDelta == ~lDeltaPrime &&
++ (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) {
++ /* Single bit (recoverable) error in data */
++
++ bit = 0;
++
++ if (cDelta & 0x20)
++ bit |= 0x04;
++ if (cDelta & 0x08)
++ bit |= 0x02;
++ if (cDelta & 0x02)
++ bit |= 0x01;
++
++ if (lDelta >= nBytes)
++ return -1;
++
++ data[lDelta] ^= (1 << bit);
++
++ return 1; /* corrected */
++ }
++
++ if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
++ yaffs_CountBits(cDelta)) == 1) {
++ /* Reccoverable error in ecc */
++
++ *read_ecc = *test_ecc;
++ return 1; /* corrected */
++ }
++
++ /* Unrecoverable error */
++
++ return -1;
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_ecc.h linux-2.6.25/fs/yaffs2/yaffs_ecc.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_ecc.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_ecc.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,44 @@
++/*
++ * 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.
++ */
++
++/*
++ * 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__
++
++typedef struct {
++ unsigned char colParity;
++ unsigned lineParity;
++ unsigned lineParityPrime;
++} yaffs_ECCOther;
++
++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);
++
++void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
++ yaffs_ECCOther *ecc);
++int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
++ yaffs_ECCOther *read_ecc,
++ const yaffs_ECCOther *test_ecc);
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_fs.c linux-2.6.25/fs/yaffs2/yaffs_fs.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_fs.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_fs.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,2529 @@
++/*
++ * 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.80 2009/05/12 02:23:51 charles 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) && (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_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");
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_getblockinfo.h linux-2.6.25/fs/yaffs2/yaffs_getblockinfo.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_getblockinfo.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_getblockinfo.h 2009-05-25 11:14:58.000000000 +0530
+@@ -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
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_guts.c linux-2.6.25/fs/yaffs2/yaffs_guts.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_guts.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_guts.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,7552 @@
++/*
++ * 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 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 "yaffsinterface.h"
++#include "yaffs_guts.h"
++#include "yaffs_tagsvalidity.h"
++#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_nand.h"
++#include "yaffs_packedtags2.h"
++
++
++#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);
++
++/* 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 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 int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
++ int chunkInNAND);
++
++static int yaffs_UnlinkWorker(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 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);
++#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_InvalidateCheckpoint(yaffs_Device *dev);
++
++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);
++
++
++/* Function to calculate chunk and offset */
++
++static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut,
++ __u32 *offsetOut)
++{
++ 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);
++ }
++
++ *chunkOut = chunk;
++ *offsetOut = offset;
++}
++
++/* 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.
++ */
++
++static __u32 ShiftsGE(__u32 x)
++{
++ int extraBits;
++ int nShifts;
++
++ nShifts = extraBits = 0;
++
++ while (x > 1) {
++ if (x & 1)
++ extraBits++;
++ x >>= 1;
++ nShifts++;
++ }
++
++ if (extraBits)
++ nShifts++;
++
++ return nShifts;
++}
++
++/* Function to return the number of shifts to get a 1 in bit 0
++ */
++
++static __u32 Shifts(__u32 x)
++{
++ int nShifts;
++
++ nShifts = 0;
++
++ if (!x)
++ return 0;
++
++ while (!(x&1)) {
++ x >>= 1;
++ nShifts++;
++ }
++
++ return nShifts;
++}
++
++
++
++/*
++ * Temporary buffer manipulations.
++ */
++
++static int yaffs_InitialiseTempBuffers(yaffs_Device *dev)
++{
++ int i;
++ __u8 *buf = (__u8 *)1;
++
++ 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->totalBytesPerChunk);
++ }
++
++ return buf ? YAFFS_OK : YAFFS_FAIL;
++}
++
++__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;
++ if ((i + 1) > dev->maxTemp) {
++ dev->maxTemp = i + 1;
++ for (j = 0; j <= i; j++)
++ dev->tempBuffer[j].maxLine =
++ dev->tempBuffer[j].line;
++ }
++
++ return dev->tempBuffer[i].buffer;
++ }
++ }
++
++ 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++)
++ T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
++
++ T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR)));
++
++ /*
++ * If we got here then we have to allocate an unmanaged one
++ * This is not good.
++ */
++
++ dev->unmanagedTempAllocations++;
++ return YMALLOC(dev->nDataBytesPerChunk);
++
++}
++
++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;
++ return;
++ }
++ }
++
++ if (buffer) {
++ /* assume it is an unmanaged one. */
++ T(YAFFS_TRACE_BUFFERS,
++ (TSTR("Releasing unmanaged temp buffer in line %d" TENDSTR),
++ lineNo));
++ YFREE(buffer);
++ dev->unmanagedTempDeallocations++;
++ }
++
++}
++
++/*
++ * Determine if we have a managed 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;
++ }
++
++ if (buffer == dev->checkpointBuffer)
++ return 1;
++
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR("yaffs: unmaged buffer detected.\n" TENDSTR)));
++ return 0;
++}
++
++
++
++/*
++ * Chunk bitmap manipulations
++ */
++
++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);
++}
++
++static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device *dev, int blk, int chunk)
++{
++ __u8 *blkBits = yaffs_BlockBits(dev, blk);
++
++ yaffs_VerifyChunkBitId(dev, blk, chunk);
++
++ blkBits[chunk / 8] &= ~(1 << (chunk & 7));
++}
++
++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));
++}
++
++static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device *dev, int blk, int chunk)
++{
++ __u8 *blkBits = yaffs_BlockBits(dev, blk);
++ 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)
++{
++ __u8 *blkBits = yaffs_BlockBits(dev, blk);
++ int i;
++ for (i = 0; i < dev->chunkBitmapStride; i++) {
++ if (*blkBits)
++ return 1;
++ blkBits++;
++ }
++ return 0;
++}
++
++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
++ */
++
++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)
++{
++ return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_NAND));
++}
++
++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)
++{
++ int actuallyUsed;
++ int inUse;
++
++ if (yaffs_SkipVerification(dev))
++ return;
++
++ /* 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));
++
++ 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 ||
++ 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));
++
++
++ /* 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));
++
++ /* 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)
++{
++ yaffs_VerifyBlock(dev, bi, n);
++
++ /* After collection the block should be in the erased state */
++ /* This will need to change if we do partial gc */
++
++ 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));
++ }
++}
++
++static void yaffs_VerifyBlocks(yaffs_Device *dev)
++{
++ 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++;
++ }
++
++ 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),
++ blockStateName[i], nBlocksPerState[i]));
++
++ 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])
++ 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)
++ 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.
++ */
++static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, yaffs_ExtendedTags *tags, int parentCheck)
++{
++ 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));
++ 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));
++
++
++ /*
++ * Check that the object's parent ids match if parentCheck requested.
++ *
++ * 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 (tags->objectId > 1 && oh->name[0] == 0) /* Null name */
++ T(YAFFS_TRACE_VERIFY,
++ (TSTR("Obj %d header name is NULL"TENDSTR),
++ obj->objectId));
++
++ 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));
++}
++
++
++
++static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
++ __u32 level, int chunkOffset)
++{
++ int i;
++ yaffs_Device *dev = obj->myDev;
++ int ok = 1;
++
++ if (tn) {
++ if (level > 0) {
++
++ 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;
++
++ chunkOffset <<= YAFFS_TNODES_LEVEL0_BITS;
++
++ for (i = 0; i < YAFFS_NTNODES_LEVEL0; i++) {
++ __u32 theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
++
++ 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++;
++ }
++ }
++ }
++
++ return ok;
++
++}
++
++
++static void yaffs_VerifyFile(yaffs_Object *obj)
++{
++ int requiredTallness;
++ int actualTallness;
++ __u32 lastChunk;
++ __u32 x;
++ __u32 i;
++ yaffs_Device *dev;
++ yaffs_ExtendedTags tags;
++ yaffs_Tnode *tn;
++ __u32 objectId;
++
++ if (!obj)
++ return;
++
++ if (yaffs_SkipVerification(obj->myDev))
++ return;
++
++ dev = obj->myDev;
++ objectId = obj->objectId;
++
++ /* 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;
++
++ if (requiredTallness > actualTallness)
++ T(YAFFS_TRACE_VERIFY,
++ (TSTR("Obj %d had tnode tallness %d, needs to be %d"TENDSTR),
++ obj->objectId, actualTallness, requiredTallness));
++
++
++ /* 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_SkipNANDVerification(dev))
++ return;
++
++ 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) {
++ /* 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 void yaffs_VerifyHardLink(yaffs_Object *obj)
++{
++ if (obj && yaffs_SkipVerification(obj->myDev))
++ return;
++
++ /* Verify sane equivalent object */
++}
++
++static void yaffs_VerifySymlink(yaffs_Object *obj)
++{
++ if (obj && yaffs_SkipVerification(obj->myDev))
++ return;
++
++ /* Verify symlink string */
++}
++
++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;
++
++ dev = obj->myDev;
++
++ if (yaffs_SkipVerification(dev))
++ return;
++
++ /* Check sane object header chunk */
++
++ chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
++ chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
++
++ 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;
++
++ 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 (chunkValid && !yaffs_SkipNANDVerification(dev)) {
++ yaffs_ExtendedTags tags;
++ yaffs_ObjectHeader *oh;
++ __u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
++
++ oh = (yaffs_ObjectHeader *)buffer;
++
++ yaffs_ReadChunkWithTagsFromNAND(dev, obj->hdrChunk, buffer,
++ &tags);
++
++ yaffs_VerifyObjectHeader(obj, oh, &tags, 1);
++
++ 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));
++ }
++
++ /* 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));
++ }
++
++ 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;
++ }
++}
++
++static void yaffs_VerifyObjects(yaffs_Device *dev)
++{
++ yaffs_Object *obj;
++ int i;
++ struct ylist_head *lh;
++
++ if (yaffs_SkipVerification(dev))
++ return;
++
++ /* Iterate through the objects in each hash entry */
++
++ 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);
++ }
++ }
++ }
++}
++
++
++/*
++ * Simple hash function. Needs to have a reasonable spread
++ */
++
++static Y_INLINE int yaffs_HashFunction(int n)
++{
++ n = abs(n);
++ return n % YAFFS_NOBJECT_BUCKETS;
++}
++
++/*
++ * 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)
++{
++ return dev->rootDir;
++}
++
++yaffs_Object *yaffs_LostNFound(yaffs_Device *dev)
++{
++ return dev->lostNFoundDir;
++}
++
++
++/*
++ * Erased NAND checking functions
++ */
++
++int yaffs_CheckFF(__u8 *buffer, int nBytes)
++{
++ /* Horrible, slow implementation */
++ while (nBytes--) {
++ if (*buffer != 0xFF)
++ return 0;
++ buffer++;
++ }
++ 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;
++
++ result = yaffs_ReadChunkWithTagsFromNAND(dev, chunkInNAND, data, &tags);
++
++ 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));
++ retval = YAFFS_FAIL;
++ }
++
++ yaffs_ReleaseTempBuffer(dev, data, __LINE__);
++
++ return retval;
++
++}
++
++static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
++ const __u8 *data,
++ yaffs_ExtendedTags *tags,
++ int useReserve)
++{
++ int attempts = 0;
++ int writeOk = 0;
++ int chunk;
++
++ yaffs_InvalidateCheckpoint(dev);
++
++ do {
++ yaffs_BlockInfo *bi = 0;
++ int erasedOk = 0;
++
++ 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;
++ }
++
++ /* let's give it a try */
++ attempts++;
++
++#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
++ bi->skipErasedCheck = 0;
++#endif
++ if (!bi->skipErasedCheck) {
++ erasedOk = yaffs_CheckChunkErased(dev, chunk);
++ if (erasedOk != YAFFS_OK) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("**>> yaffs chunk %d was not erased"
++ TENDSTR), chunk));
++
++ /* try another chunk */
++ continue;
++ }
++ bi->skipErasedCheck = 1;
++ }
++
++ writeOk = yaffs_WriteChunkWithTagsToNAND(dev, chunk,
++ data, tags);
++ if (writeOk != YAFFS_OK) {
++ yaffs_HandleWriteChunkError(dev, chunk, erasedOk);
++ /* try another chunk */
++ continue;
++ }
++
++ /* Copy the data into the robustification buffer */
++ yaffs_HandleWriteChunkOk(dev, chunk, data, tags);
++
++ } while (writeOk != YAFFS_OK &&
++ (yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
++
++ if (!writeOk)
++ chunk = -1;
++
++ if (attempts > 1) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("**>> yaffs write required %d attempts" TENDSTR),
++ attempts));
++
++ dev->nRetriedWrites += (attempts - 1);
++ }
++
++ return chunk;
++}
++
++/*
++ * Block retiring for handling a broken block.
++ */
++
++static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND)
++{
++ yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
++
++ yaffs_InvalidateCheckpoint(dev);
++
++ 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;
++ bi->needsRetiring = 0;
++
++ dev->nRetiredBlocks++;
++}
++
++/*
++ * Functions for robustisizing TODO
++ *
++ */
++
++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)
++{
++}
++
++void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi)
++{
++ if (!bi->gcPrioritise) {
++ bi->gcPrioritise = 1;
++ dev->hasPendingPrioritisedGCs = 1;
++ bi->chunkErrorStrikes++;
++
++ 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)
++{
++ int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
++ yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
++
++ yaffs_HandleChunkError(dev, bi);
++
++ 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 */
++ yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
++}
++
++
++/*---------------- Name handling functions ------------*/
++
++static __u16 yaffs_CalcNameSum(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_SetObjectName(yaffs_Object *obj, const YCHAR *name)
++{
++#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);
++}
++
++/*-------------------- 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
++ */
++
++static int yaffs_CreateTnodes(yaffs_Device *dev, int nTnodes)
++{
++ int i;
++ int tnodeSize;
++ yaffs_Tnode *newTnodes;
++ __u8 *mem;
++ yaffs_Tnode *curr;
++ yaffs_Tnode *next;
++ yaffs_TnodeList *tnl;
++
++ if (nTnodes < 1)
++ return YAFFS_OK;
++
++ /* 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 (tnodeSize < sizeof(yaffs_Tnode))
++ tnodeSize = sizeof(yaffs_Tnode);
++
++ /* make these things */
++
++ newTnodes = YMALLOC(nTnodes * tnodeSize);
++ mem = (__u8 *)newTnodes;
++
++ if (!newTnodes) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
++ return YAFFS_FAIL;
++ }
++
++ /* 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;
++ }
++
++ curr = (yaffs_Tnode *) &mem[(nTnodes - 1) * tnodeSize];
++ curr->internal[0] = dev->freeTnodes;
++ dev->freeTnodes = (yaffs_Tnode *)mem;
++
++#endif
++
++
++ dev->nFreeTnodes += nTnodes;
++ dev->nTnodesCreated += nTnodes;
++
++ /* 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));
++ 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;
++ }
++
++ 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 */
++
++static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev)
++{
++ yaffs_Tnode *tn = NULL;
++
++ /* 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--;
++ }
++
++ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
++
++ return tn;
++}
++
++static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev)
++{
++ yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);
++ int tnodeSize = (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)
++{
++ 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++;
++ }
++ dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
++}
++
++static void yaffs_DeinitialiseTnodes(yaffs_Device *dev)
++{
++ /* Free the list of allocated tnodes */
++ yaffs_TnodeList *tmp;
++
++ while (dev->allocatedTnodeList) {
++ tmp = dev->allocatedTnodeList->next;
++
++ YFREE(dev->allocatedTnodeList->tnodes);
++ YFREE(dev->allocatedTnodeList);
++ dev->allocatedTnodeList = tmp;
++
++ }
++
++ dev->freeTnodes = NULL;
++ dev->nFreeTnodes = 0;
++}
++
++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)
++{
++ __u32 *map = (__u32 *)tn;
++ __u32 bitInMap;
++ __u32 bitInWord;
++ __u32 wordInMap;
++ __u32 mask;
++
++ pos &= YAFFS_TNODES_LEVEL0_MASK;
++ val >>= dev->chunkGroupBits;
++
++ bitInMap = pos * dev->tnodeWidth;
++ wordInMap = bitInMap / 32;
++ bitInWord = bitInMap & (32 - 1);
++
++ mask = dev->tnodeMask << 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)
++{
++ __u32 *map = (__u32 *)tn;
++ __u32 bitInMap;
++ __u32 bitInWord;
++ __u32 wordInMap;
++ __u32 val;
++
++ pos &= YAFFS_TNODES_LEVEL0_MASK;
++
++ bitInMap = pos * dev->tnodeWidth;
++ wordInMap = bitInMap / 32;
++ bitInWord = bitInMap & (32 - 1);
++
++ val = map[wordInMap] >> bitInWord;
++
++ if (dev->tnodeWidth > (32 - bitInWord)) {
++ bitInWord = (32 - bitInWord);
++ wordInMap++;;
++ val |= (map[wordInMap] << bitInWord);
++ }
++
++ val &= dev->tnodeMask;
++ val <<= dev->chunkGroupBits;
++
++ return val;
++}
++
++/* ------------------- 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)
++{
++ 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;
++
++ if (chunkId > YAFFS_MAX_CHUNK_ID)
++ return NULL;
++
++ /* First check we're tall enough (ie enough topLevel) */
++
++ i = chunkId >> YAFFS_TNODES_LEVEL0_BITS;
++ requiredTallness = 0;
++ while (i) {
++ i >>= YAFFS_TNODES_INTERNAL_BITS;
++ requiredTallness++;
++ }
++
++ 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];
++ level--;
++ }
++
++ return tn;
++}
++
++/* 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)
++{
++ int requiredTallness;
++ int i;
++ int l;
++ yaffs_Tnode *tn;
++
++ __u32 x;
++
++
++ /* Check sane level and page Id */
++ if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)
++ return NULL;
++
++ if (chunkId > YAFFS_MAX_CHUNK_ID)
++ return NULL;
++
++ /* First check we're tall enough (ie enough topLevel) */
++
++ x = chunkId >> YAFFS_TNODES_LEVEL0_BITS;
++ requiredTallness = 0;
++ while (x) {
++ x >>= YAFFS_TNODES_INTERNAL_BITS;
++ requiredTallness++;
++ }
++
++
++ if (requiredTallness > fStruct->topLevel) {
++ /* Not tall enough, gotta make the tree taller */
++ for (i = fStruct->topLevel; i < requiredTallness; i++) {
++
++ tn = yaffs_GetTnode(dev);
++
++ if (tn) {
++ tn->internal[0] = fStruct->top;
++ fStruct->top = tn;
++ } else {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("yaffs: no more tnodes" TENDSTR)));
++ }
++ }
++
++ fStruct->topLevel = requiredTallness;
++ }
++
++ /* Traverse down to level 0, adding anything we need */
++
++ l = fStruct->topLevel;
++ tn = fStruct->top;
++
++ if (l > 0) {
++ while (l > 0 && tn) {
++ x = (chunkId >>
++ (YAFFS_TNODES_LEVEL0_BITS +
++ (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &
++ YAFFS_TNODES_INTERNAL_MASK;
++
++
++ if ((l > 1) && !tn->internal[x]) {
++ /* Add missing non-level-zero tnode */
++ tn->internal[x] = yaffs_GetTnode(dev);
++
++ } 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;
++
++ } else if (!tn->internal[x]) {
++ /* Don't have one, none passed in */
++ tn->internal[x] = yaffs_GetTnode(dev);
++ }
++ }
++
++ 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 tn;
++}
++
++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)) {
++ yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
++ tags);
++ if (yaffs_TagsMatch(tags, objectId, chunkInInode)) {
++ /* found it; */
++ return theChunk;
++ }
++ }
++ theChunk++;
++ }
++ return -1;
++}
++
++
++/* 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.
++ */
++
++static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
++ int chunkOffset, int *limit)
++{
++ 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_strcpy(oldName, _Y("silly old name"));
++
++
++ if (!in->fake ||
++ in == dev->rootDir || /* The rootDir should also be saved */
++ force) {
++
++ yaffs_CheckGarbageCollection(dev);
++ yaffs_CheckObjectDetailsLoaded(in);
++
++ buffer = yaffs_GetTempBuffer(in->myDev, __LINE__);
++ oh = (yaffs_ObjectHeader *) buffer;
++
++ 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);
++
++ oh->type = in->variantType;
++ oh->yst_mode = in->yst_mode;
++ oh->shadowsObject = oh->inbandShadowsObject = shadows;
++
++#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];
++#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->parentObjectId = in->parent->objectId;
++ 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)
++ memcpy(oh->name, oldName, sizeof(oh->name));
++ else
++ memset(oh->name, 0, sizeof(oh->name));
++
++ oh->isShrink = isShrink;
++
++ 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;
++ break;
++ case YAFFS_OBJECT_TYPE_HARDLINK:
++ oh->equivalentObjectId =
++ in->variant.hardLinkVariant.equivalentObjectId;
++ break;
++ case YAFFS_OBJECT_TYPE_SPECIAL:
++ /* Do nothing */
++ break;
++ 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;
++ 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;
++ }
++
++ }
++
++ retVal = newChunkId;
++
++ }
++
++ if (buffer)
++ yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
++
++ return retVal;
++}
++
++/*------------------------ 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_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 0;
++}
++
++
++static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
++{
++ yaffs_Device *dev = obj->myDev;
++ int lowest = -99; /* Stop compiler whining. */
++ int i;
++ yaffs_ChunkCache *cache;
++ int chunkWritten = 0;
++ int nCaches = obj->myDev->nShortOpCaches;
++
++ if (nCaches > 0) {
++ do {
++ cache = NULL;
++
++ /* 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 (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;
++ }
++
++ } while (cache && chunkWritten > 0);
++
++ if (cache) {
++ /* Hoosterman, disk full while writing cache out. */
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("yaffs tragedy: no space during cache write" TENDSTR)));
++
++ }
++ }
++
++}
++
++/*yaffs_FlushEntireDeviceCache(dev)
++ *
++ *
++ */
++
++void yaffs_FlushEntireDeviceCache(yaffs_Device *dev)
++{
++ yaffs_Object *obj;
++ int nCaches = dev->nShortOpCaches;
++ int i;
++
++ /* 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->srCache[i].object &&
++ dev->srCache[i].dirty)
++ obj = dev->srCache[i].object;
++
++ }
++ if (obj)
++ yaffs_FlushFilesChunkCache(obj);
++
++ } while (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 (dev->nShortOpCaches > 0) {
++ for (i = 0; i < dev->nShortOpCaches; i++) {
++ if (!dev->srCache[i].object)
++ return &dev->srCache[i];
++ }
++ }
++
++ return NULL;
++}
++
++static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
++{
++ 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);
++
++ 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 */
++
++ theObj = NULL;
++ usage = -1;
++ cache = NULL;
++ pushout = -1;
++
++ 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;
++ }
++ }
++
++ if (!cache || cache->dirty) {
++ /* Flush and try again */
++ yaffs_FlushFilesChunkCache(theObj);
++ cache = yaffs_GrabChunkCacheWorker(dev);
++ }
++
++ }
++ return cache;
++ } else
++ return NULL;
++
++}
++
++/* 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++;
++
++ return &dev->srCache[i];
++ }
++ }
++ }
++ return NULL;
++}
++
++/* Mark the chunk for the least recently used algorithym */
++static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache,
++ int isAWrite)
++{
++
++ 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->srLastUse = 0;
++ }
++
++ dev->srLastUse++;
++
++ cache->lastUse = dev->srLastUse;
++
++ 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_InvalidateChunkCache(yaffs_Object *object, int chunkId)
++{
++ if (object->myDev->nShortOpCaches > 0) {
++ yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId);
++
++ 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)
++{
++ int i;
++ yaffs_Device *dev = in->myDev;
++
++ if (dev->nShortOpCaches > 0) {
++ /* Invalidate it. */
++ for (i = 0; i < dev->nShortOpCaches; i++) {
++ if (dev->srCache[i].object == in)
++ dev->srCache[i].object = NULL;
++ }
++ }
++}
++
++/*--------------------- Checkpointing --------------------*/
++
++
++static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev, int head)
++{
++ yaffs_CheckpointValidity 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)) ?
++ 1 : 0;
++}
++
++static int yaffs_ReadCheckpointValidityMarker(yaffs_Device *dev, int head)
++{
++ yaffs_CheckpointValidity cp;
++ int ok;
++
++ ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
++
++ 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;
++}
++
++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;
++
++ cp->nDeletedFiles = dev->nDeletedFiles;
++ cp->nUnlinkedFiles = dev->nUnlinkedFiles;
++ cp->nBackgroundDeletions = dev->nBackgroundDeletions;
++ cp->sequenceNumber = dev->sequenceNumber;
++ cp->oldestDirtySequence = dev->oldestDirtySequence;
++
++}
++
++static void yaffs_CheckpointDeviceToDevice(yaffs_Device *dev,
++ yaffs_CheckpointDevice *cp)
++{
++ 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;
++}
++
++
++static int yaffs_WriteCheckpointDevice(yaffs_Device *dev)
++{
++ yaffs_CheckpointDevice cp;
++ __u32 nBytes;
++ __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
++
++ int ok;
++
++ /* Write device runtime values*/
++ yaffs_DeviceToCheckpointDevice(&cp, dev);
++ cp.structType = sizeof(cp);
++
++ ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
++
++ /* Write block info */
++ if (ok) {
++ nBytes = nBlocks * sizeof(yaffs_BlockInfo);
++ ok = (yaffs_CheckpointWrite(dev, dev->blockInfo, nBytes) == nBytes);
++ }
++
++ /* Write chunk bits */
++ if (ok) {
++ nBytes = nBlocks * dev->chunkBitmapStride;
++ ok = (yaffs_CheckpointWrite(dev, dev->chunkBits, nBytes) == nBytes);
++ }
++ return ok ? 1 : 0;
++
++}
++
++static int yaffs_ReadCheckpointDevice(yaffs_Device *dev)
++{
++ yaffs_CheckpointDevice cp;
++ __u32 nBytes;
++ __u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
++
++ int ok;
++
++ ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
++ if (!ok)
++ return 0;
++
++ if (cp.structType != sizeof(cp))
++ return 0;
++
++
++ yaffs_CheckpointDeviceToDevice(dev, &cp);
++
++ nBytes = nBlocks * sizeof(yaffs_BlockInfo);
++
++ ok = (yaffs_CheckpointRead(dev, dev->blockInfo, nBytes) == nBytes);
++
++ if (!ok)
++ return 0;
++ nBytes = nBlocks * dev->chunkBitmapStride;
++
++ ok = (yaffs_CheckpointRead(dev, dev->chunkBits, nBytes) == nBytes);
++
++ return ok ? 1 : 0;
++}
++
++static void yaffs_ObjectToCheckpointObject(yaffs_CheckpointObject *cp,
++ yaffs_Object *obj)
++{
++
++ 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;
++
++ 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;
++}
++
++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)
++ 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_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)
++{
++ 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);
++
++
++ if (tn) {
++ if (level > 0) {
++
++ 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);
++ }
++ }
++
++ return ok;
++
++}
++
++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));
++ }
++
++ return ok ? 1 : 0;
++}
++
++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 (tnodeSize < sizeof(yaffs_Tnode))
++ tnodeSize = sizeof(yaffs_Tnode);
++
++ ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
++
++ while (ok && (~baseChunk)) {
++ nread++;
++ /* Read level 0 tnode */
++
++
++ tn = yaffs_GetTnodeRaw(dev);
++ if (tn)
++ ok = (yaffs_CheckpointRead(dev, tn, tnodeSize) == tnodeSize);
++ else
++ ok = 0;
++
++ if (tn && ok)
++ ok = yaffs_AddOrFindLevel0Tnode(dev,
++ fileStructPtr,
++ baseChunk,
++ tn) ? 1 : 0;
++
++ if (ok)
++ ok = (yaffs_CheckpointRead(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 yaffs_WriteCheckpointObjects(yaffs_Device *dev)
++{
++ yaffs_Object *obj;
++ yaffs_CheckpointObject 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->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));
++
++ ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
++
++ if (ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE)
++ ok = yaffs_WriteCheckpointTnodes(obj);
++ }
++ }
++ }
++ }
++
++ /* 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));
++
++ return ok ? 1 : 0;
++}
++
++static int yaffs_ReadCheckpointObjects(yaffs_Device *dev)
++{
++ yaffs_Object *obj;
++ yaffs_CheckpointObject cp;
++ int ok = 1;
++ 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));
++ 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 (ok)
++ yaffs_HardlinkFixup(dev, hardList);
++
++ return ok ? 1 : 0;
++}
++
++static int yaffs_WriteCheckpointSum(yaffs_Device *dev)
++{
++ __u32 checkpointSum;
++ int ok;
++
++ yaffs_GetCheckpointSum(dev, &checkpointSum);
++
++ ok = (yaffs_CheckpointWrite(dev, &checkpointSum, sizeof(checkpointSum)) == sizeof(checkpointSum));
++
++ if (!ok)
++ return 0;
++
++ return 1;
++}
++
++static int yaffs_ReadCheckpointSum(yaffs_Device *dev)
++{
++ __u32 checkpointSum0;
++ __u32 checkpointSum1;
++ int ok;
++
++ yaffs_GetCheckpointSum(dev, &checkpointSum0);
++
++ ok = (yaffs_CheckpointRead(dev, &checkpointSum1, sizeof(checkpointSum1)) == sizeof(checkpointSum1));
++
++ if (!ok)
++ return 0;
++
++ if (checkpointSum0 != checkpointSum1)
++ return 0;
++
++ return 1;
++}
++
++
++static int yaffs_WriteCheckpointData(yaffs_Device *dev)
++{
++ int ok = 1;
++
++ 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);
++ }
++
++ if (ok)
++ ok = yaffs_WriteCheckpointSum(dev);
++
++ if (!yaffs_CheckpointClose(dev))
++ ok = 0;
++
++ if (ok)
++ dev->isCheckpointed = 1;
++ else
++ dev->isCheckpointed = 0;
++
++ return dev->isCheckpointed;
++}
++
++static int yaffs_ReadCheckpointData(yaffs_Device *dev)
++{
++ int ok = 1;
++
++ 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) {
++ 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 (ok) {
++ ok = yaffs_ReadCheckpointSum(dev);
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint checksum %d" TENDSTR), ok));
++ }
++
++ if (!yaffs_CheckpointClose(dev))
++ ok = 0;
++
++ if (ok)
++ dev->isCheckpointed = 1;
++ else
++ dev->isCheckpointed = 0;
++
++ return ok ? 1 : 0;
++
++}
++
++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);
++ }
++}
++
++
++int yaffs_CheckpointSave(yaffs_Device *dev)
++{
++
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("save entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
++
++ yaffs_VerifyObjects(dev);
++ yaffs_VerifyBlocks(dev);
++ yaffs_VerifyFreeChunks(dev);
++
++ if (!dev->isCheckpointed) {
++ yaffs_InvalidateCheckpoint(dev);
++ yaffs_WriteCheckpointData(dev);
++ }
++
++ T(YAFFS_TRACE_ALWAYS, (TSTR("save exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
++
++ return dev->isCheckpointed;
++}
++
++int yaffs_CheckpointRestore(yaffs_Device *dev)
++{
++ int retval;
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
++
++ retval = yaffs_ReadCheckpointData(dev);
++
++ if (dev->isCheckpointed) {
++ yaffs_VerifyObjects(dev);
++ yaffs_VerifyBlocks(dev);
++ yaffs_VerifyFreeChunks(dev);
++ }
++
++ T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
++
++ return retval;
++}
++
++/*--------------------- 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.
++ */
++
++int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 *buffer, loff_t offset,
++ int nBytes)
++{
++
++ 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 (!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;
++ }
++
++ yaffs_UseChunkCache(dev, cache, 0);
++
++ cache->locked = 1;
++
++
++ memcpy(buffer, &cache->data[start], nToCopy);
++
++ cache->locked = 0;
++ } else {
++ /* Read into the local buffer then copy..*/
++
++ __u8 *localBuffer =
++ yaffs_GetTempBuffer(dev, __LINE__);
++ yaffs_ReadChunkDataFromObject(in, chunk,
++ localBuffer);
++
++ memcpy(buffer, &localBuffer[start], nToCopy);
++
++
++ yaffs_ReleaseTempBuffer(dev, localBuffer,
++ __LINE__);
++ }
++
++ } else {
++
++ /* A full chunk. Read directly into the supplied buffer. */
++ yaffs_ReadChunkDataFromObject(in, chunk, buffer);
++
++ }
++
++ n -= nToCopy;
++ offset += nToCopy;
++ buffer += nToCopy;
++ nDone += nToCopy;
++
++ }
++
++ return nDone;
++}
++
++int yaffs_WriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
++ int nBytes, int writeThrough)
++{
++
++ int chunk;
++ __u32 start;
++ int nToCopy;
++ int n = nBytes;
++ int nDone = 0;
++ int nToWriteBack;
++ int startOfWrite = offset;
++ int chunkWritten = 0;
++ __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);
++
++ 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;
++
++ /* 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.
++ */
++
++ 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)
++ 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 || 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);
++
++ 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 (cache) {
++ yaffs_UseChunkCache(dev, cache, 1);
++ cache->locked = 1;
++
++
++ memcpy(&cache->data[start], buffer,
++ nToCopy);
++
++
++ cache->locked = 0;
++ cache->nBytes = nToWriteBack;
++
++ if (writeThrough) {
++ chunkWritten =
++ yaffs_WriteChunkDataToObject
++ (cache->object,
++ cache->chunkId,
++ cache->data, cache->nBytes,
++ 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.
++ */
++
++ __u8 *localBuffer =
++ yaffs_GetTempBuffer(dev, __LINE__);
++
++ yaffs_ReadChunkDataFromObject(in, chunk,
++ localBuffer);
++
++
++
++ memcpy(&localBuffer[start], buffer, nToCopy);
++
++ chunkWritten =
++ yaffs_WriteChunkDataToObject(in, chunk,
++ localBuffer,
++ nToWriteBack,
++ 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);
++
++ /* Since we've overwritten the cached data, we better invalidate it. */
++ yaffs_InvalidateChunkCache(in, chunk);
++ }
++
++ if (chunkWritten >= 0) {
++ n -= nToCopy;
++ offset += nToCopy;
++ buffer += nToCopy;
++ nDone += nToCopy;
++ }
++
++ }
++
++ /* Update file object */
++
++ if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize)
++ in->variant.fileVariant.fileSize = (startOfWrite + nDone);
++
++ in->dirty = 1;
++
++ return nDone;
++}
++
++
++/* ---------------------- File resizing stuff ------------------ */
++
++static void yaffs_PruneResizedChunks(yaffs_Object *in, int newSize)
++{
++
++ yaffs_Device *dev = in->myDev;
++ int oldFileSize = in->variant.fileVariant.fileSize;
++
++ int lastDel = 1 + (oldFileSize - 1) / dev->nDataBytesPerChunk;
++
++ 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.
++ */
++ for (i = lastDel; i >= startDel; i--) {
++ /* NB this could be optimised somewhat,
++ * eg. could retrieve the tags and write them without
++ * using yaffs_DeleteChunk
++ */
++
++ 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__);
++ }
++ }
++ }
++
++}
++
++int yaffs_ResizeFile(yaffs_Object *in, loff_t newSize)
++{
++
++ int oldFileSize = in->variant.fileVariant.fileSize;
++ __u32 newSizeOfPartialChunk;
++ int newFullChunks;
++
++ yaffs_Device *dev = in->myDev;
++
++ yaffs_AddrToChunk(dev, newSize, &newFullChunks, &newSizeOfPartialChunk);
++
++ yaffs_FlushFilesChunkCache(in);
++ yaffs_InvalidateWholeChunkCache(in);
++
++ yaffs_CheckGarbageCollection(dev);
++
++ if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
++ return YAFFS_FAIL;
++
++ if (newSize == oldFileSize)
++ return YAFFS_OK;
++
++ if (newSize < oldFileSize) {
++
++ yaffs_PruneResizedChunks(in, newSize);
++
++ if (newSizeOfPartialChunk != 0) {
++ int lastChunk = 1 + newFullChunks;
++
++ __u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
++
++ /* 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);
++
++ yaffs_WriteChunkDataToObject(in, lastChunk, localBuffer,
++ newSizeOfPartialChunk, 1);
++
++ yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
++ }
++
++ in->variant.fileVariant.fileSize = newSize;
++
++ yaffs_PruneFileStructure(dev, &in->variant.fileVariant);
++ } else {
++ /* newsSize > oldFileSize */
++ in->variant.fileVariant.fileSize = newSize;
++ }
++
++
++ /* 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);
++
++ return YAFFS_OK;
++}
++
++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;
++ }
++}
++
++
++
++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);
++#else
++
++ in->yst_mtime = Y_CURRENT_TIME;
++
++#endif
++ }
++
++ retVal = (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >=
++ 0) ? YAFFS_OK : YAFFS_FAIL;
++ } else {
++ retVal = YAFFS_OK;
++ }
++
++ return retVal;
++
++}
++
++static int yaffs_DoGenericObjectDeletion(yaffs_Object *in)
++{
++
++ /* First off, invalidate the file's data in the cache, without flushing. */
++ yaffs_InvalidateWholeChunkCache(in);
++
++ 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_RemoveObjectFromDirectory(in);
++ yaffs_DeleteChunk(in->myDev, in->hdrChunk, 1, __LINE__);
++ in->hdrChunk = 0;
++
++ yaffs_FreeObject(in);
++ return YAFFS_OK;
++
++}
++
++/* 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)
++{
++
++ int retVal;
++ int immediateDeletion = 0;
++
++#ifdef __KERNEL__
++ if (!in->myInode)
++ immediateDeletion = 1;
++#else
++ if (in->inUse <= 0)
++ immediateDeletion = 1;
++#endif
++
++ 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 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;
++ }
++}
++
++static int yaffs_DeleteDirectory(yaffs_Object *in)
++{
++ /* First check that the directory is empty. */
++ if (ylist_empty(&in->variant.directoryVariant.children))
++ return yaffs_DoGenericObjectDeletion(in);
++
++ return YAFFS_FAIL;
++
++}
++
++static int yaffs_DeleteSymLink(yaffs_Object *in)
++{
++ YFREE(in->variant.symLinkVariant.alias);
++
++ return yaffs_DoGenericObjectDeletion(in);
++}
++
++static int yaffs_DeleteHardLink(yaffs_Object *in)
++{
++ /* remove this hardlink from the list assocaited with the equivalent
++ * object
++ */
++ ylist_del_init(&in->hardLinks);
++ return yaffs_DoGenericObjectDeletion(in);
++}
++
++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. */
++ }
++
++ return retVal;
++}
++
++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 (!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
++ */
++
++ 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_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
++
++ retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0);
++
++ if (retVal == YAFFS_OK)
++ retVal = yaffs_DoGenericObjectDeletion(hl);
++
++ return retVal;
++
++ } 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)
++{
++
++ if (obj && obj->unlinkAllowed)
++ return yaffs_UnlinkWorker(obj);
++
++ return YAFFS_FAIL;
++
++}
++int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name)
++{
++ yaffs_Object *obj;
++
++ obj = yaffs_FindObjectByName(dir, name);
++ return yaffs_UnlinkObject(obj);
++}
++
++/*----------------------- Initialisation Scanning ---------------------- */
++
++static void yaffs_HandleShadowedObject(yaffs_Device *dev, int objId,
++ int backwardScanning)
++{
++ yaffs_Object *obj;
++
++ if (!backwardScanning) {
++ /* Handle YAFFS1 forward scanning case
++ * For YAFFS1 we always do the deletion
++ */
++
++ } else {
++ /* Handle YAFFS2 case (backward scanning)
++ * If the shadowed object exists then ignore.
++ */
++ 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.
++ * 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 */
++
++}
++
++typedef struct {
++ int seq;
++ int block;
++} yaffs_BlockIndex;
++
++
++static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList)
++{
++ yaffs_Object *hl;
++ yaffs_Object *in;
++
++ while (hardList) {
++ hl = hardList;
++ hardList = (yaffs_Object *) (hardList->hardLinks.next);
++
++ 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);
++
++ }
++ }
++}
++
++
++
++
++
++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);
++ }
++ }
++
++ 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)
++{
++ 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;
++
++ int alloc_failed = 0;
++
++ struct yaffs_ShadowFixerStruct *shadowFixerList = NULL;
++
++
++ __u8 *chunkData;
++
++
++
++ T(YAFFS_TRACE_SCAN,
++ (TSTR("yaffs_Scan starts intstartblk %d intendblk %d..." TENDSTR),
++ dev->internalStartBlock, dev->internalEndBlock));
++
++ chunkData = yaffs_GetTempBuffer(dev, __LINE__);
++
++ dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
++
++ /* 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_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_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;
++ }
++ }
++
++ startIterator = dev->internalStartBlock;
++ endIterator = dev->internalEndBlock;
++
++ /* For each block.... */
++ for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator;
++ blockIterator++) {
++
++ YYIELD();
++
++ YYIELD();
++
++ blk = blockIterator;
++
++ bi = yaffs_GetBlockInfo(dev, blk);
++ state = bi->blockState;
++
++ 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;
++
++ result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
++ &tags);
++
++ /* Let's have a good look at this chunk... */
++
++ 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
++ */
++
++ 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->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 (!in)
++ alloc_failed = 1;
++
++ if (in) {
++ if (!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk, 1))
++ alloc_failed = 1;
++ }
++
++ 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;
++ }
++
++ }
++ /* 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++;
++
++ 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.
++ */
++
++ yaffs_DeleteObject(in);
++
++ in = 0;
++ }
++
++ 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 (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.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__);
++ }
++ }
++
++ 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;
++
++ 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;
++
++ } 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;
++
++ yaffs_SetObjectName(in, oh->name);
++ in->dirty = 0;
++
++ /* directory stuff...
++ * hook up to parent
++ */
++
++ 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;
++ }
++
++ 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;
++ }
++
++/*
++ if (parent == dev->deletedDir) {
++ yaffs_DestroyObject(in);
++ bi->hasShrinkHeader = 1;
++ }
++*/
++ }
++ }
++ }
++
++ 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->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);
++ }
++
++ }
++
++
++ /* 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);
++
++ /* 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);
++
++ YFREE(fixer);
++ }
++ }
++
++ yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
++
++ if (alloc_failed)
++ return YAFFS_FAIL;
++
++ T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR)));
++
++
++ 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;
++
++ dev = in->myDev;
++
++#if 0
++ T(YAFFS_TRACE_SCAN, (TSTR("details for object %d %s loaded" TENDSTR),
++ in->objectId,
++ in->lazyLoaded ? "not yet" : "already"));
++#endif
++
++ if (in->lazyLoaded && in->hdrChunk > 0) {
++ in->lazyLoaded = 0;
++ chunkData = yaffs_GetTempBuffer(dev, __LINE__);
++
++ result = yaffs_ReadChunkWithTagsFromNAND(dev, in->hdrChunk, chunkData, &tags);
++ oh = (yaffs_ObjectHeader *) chunkData;
++
++ 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
++ yaffs_SetObjectName(in, oh->name);
++
++ 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 */
++ }
++
++ yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
++ }
++}
++
++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;
++
++
++ yaffs_BlockIndex *blockIndex = NULL;
++ int altBlockIndex = 0;
++
++ if (!dev->isYaffs2) {
++ T(YAFFS_TRACE_SCAN,
++ (TSTR("yaffs_ScanBackwards is only for YAFFS2!" TENDSTR)));
++ return YAFFS_FAIL;
++ }
++
++ T(YAFFS_TRACE_SCAN,
++ (TSTR
++ ("yaffs_ScanBackwards starts intstartblk %d intendblk %d..."
++ TENDSTR), dev->internalStartBlock, dev->internalEndBlock));
++
++
++ dev->sequenceNumber = 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("yaffs_Scan() could not allocate block index!" TENDSTR)));
++ return YAFFS_FAIL;
++ }
++
++ 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;
++
++ T(YAFFS_TRACE_SCAN_DEBUG,
++ (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
++ state, sequenceNumber));
++
++
++ if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
++ dev->blocksInCheckpoint++;
++
++ } 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) {
++
++ /* Determine the highest sequence number */
++ if (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 {
++ /* TODO: Nasty sequence number! */
++ T(YAFFS_TRACE_SCAN,
++ (TSTR
++ ("Block scanning block %d has bad sequence number %d"
++ TENDSTR), blk, sequenceNumber));
++
++ }
++ }
++ }
++
++ T(YAFFS_TRACE_SCAN,
++ (TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan));
++
++
++
++ YYIELD();
++
++ /* 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... */
++
++ 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;
++ }
++ }
++#endif
++
++ 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_GetBlockInfo(dev, blk);
++
++
++ state = bi->blockState;
++
++ deleted = 0;
++
++ /* 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
++ */
++
++ chunk = blk * dev->nChunksPerBlock + c;
++
++ result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
++ &tags);
++
++ /* Let's have a good look at this chunk... */
++
++ 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
++ */
++
++ 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));
++ }
++ }
++ }
++
++ 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;
++ __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;
++ }
++
++ 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;
++ }
++
++ /* 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;
++ }
++
++ } else if (in) {
++ /* This chunk has been invalidated by a resize, so delete */
++ yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
++
++ }
++ } else {
++ /* chunkId == 0, so it is an ObjectHeader.
++ * Thus, we read in the object header and make the object
++ */
++ foundChunksInBlock = 1;
++
++ yaffs_SetChunkBit(dev, blk, c);
++ bi->pagesInUse++;
++
++ oh = NULL;
++ in = NULL;
++
++ if (tags.extraHeaderInfoAvailable) {
++ in = yaffs_FindOrCreateObjectByNumber
++ (dev, tags.objectId,
++ tags.extraObjectType);
++ if (!in)
++ alloc_failed = 1;
++ }
++
++ 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.
++ */
++
++ 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;
++ }
++
++ if (!in) {
++ in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, 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.objectId, 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->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;
++ }
++
++ if (isShrink &&
++ in->variant.fileVariant.
++ shrinkSize > thisSize) {
++ in->variant.fileVariant.
++ shrinkSize =
++ thisSize;
++ }
++
++ if (isShrink)
++ bi->hasShrinkHeader = 1;
++
++ }
++ /* Use existing - destroy this one. */
++ yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
++
++ }
++
++ 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;
++
++ if (oh) {
++ 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
++ } else {
++ in->variantType = tags.extraObjectType;
++ in->lazyLoaded = 1;
++ }
++
++ in->hdrChunk = chunk;
++
++ } else if (!in->valid) {
++ /* we need to load this info */
++
++ in->valid = 1;
++ in->hdrChunk = chunk;
++
++ if (oh) {
++ 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
++
++ 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;
++
++ } 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;
++
++ /* directory stuff...
++ * hook up to parent
++ */
++
++ 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;
++ }
++
++ yaffs_AddObjectToDirectory(parent, in);
++
++ itsUnlinked = (parent == dev->deletedDir) ||
++ (parent == dev->unlinkedDir);
++
++ if (isShrink) {
++ /* Mark the block as having a shrinkHeader */
++ bi->hasShrinkHeader = 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->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;
++ }
++
++ if (isShrink &&
++ in->variant.fileVariant.shrinkSize > fileSize) {
++ in->variant.fileVariant.shrinkSize = fileSize;
++ }
++
++ 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;
++ }
++
++ }
++
++ }
++
++ } /* 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->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);
++ }
++
++ }
++
++ 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_HardlinkFixup(dev, hardList);
++
++
++ yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
++
++ if (alloc_failed)
++ return YAFFS_FAIL;
++
++ T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR)));
++
++ 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();
++ }
++}
++
++static void yaffs_VerifyDirectory(yaffs_Object *directory)
++{
++ struct ylist_head *lh;
++ yaffs_Object *listObj;
++
++ if (!directory) {
++ YBUG();
++ return;
++ }
++
++ if (yaffs_SkipFullVerification(directory->myDev))
++ return;
++
++ 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);
++ }
++ }
++}
++
++
++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)
++ dev->removeObjectCallback(obj);
++
++
++ ylist_del_init(&obj->siblings);
++ obj->parent = NULL;
++
++ yaffs_VerifyDirectory(parent);
++}
++
++
++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,
++ (TSTR
++ ("tragedy: Trying to add an object to a non-directory"
++ TENDSTR)));
++ YBUG();
++ }
++
++ if (obj->siblings.prev == NULL) {
++ /* Not initialised */
++ YBUG();
++ }
++
++
++ yaffs_VerifyDirectory(directory);
++
++ yaffs_RemoveObjectFromDirectory(obj);
++
++
++ /* Now add it */
++ ylist_add(&obj->siblings, &directory->variant.directoryVariant.children);
++ obj->parent = directory;
++
++ if (directory == obj->myDev->unlinkedDir
++ || 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)
++{
++ int sum;
++
++ struct ylist_head *i;
++ YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
++
++ yaffs_Object *l;
++
++ if (!name)
++ return NULL;
++
++ if (!directory) {
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR
++ ("tragedy: yaffs_FindObjectByName: null pointer directory"
++ TENDSTR)));
++ YBUG();
++ return NULL;
++ }
++ if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR
++ ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
++ YBUG();
++ }
++
++ sum = yaffs_CalcNameSum(name);
++
++ ylist_for_each(i, &directory->variant.directoryVariant.children) {
++ if (i) {
++ 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)
++ return l;
++ } 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)
++ return l;
++ }
++ }
++ }
++
++ return NULL;
++}
++
++
++#if 0
++int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
++ int (*fn) (yaffs_Object *))
++{
++ struct ylist_head *i;
++ yaffs_Object *l;
++
++ if (!theDir) {
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR
++ ("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;
++ }
++
++ ylist_for_each(i, &theDir->variant.directoryVariant.children) {
++ if (i) {
++ l = ylist_entry(i, yaffs_Object, siblings);
++ if (l && !fn(l))
++ return YAFFS_FAIL;
++ }
++ }
++
++ return YAFFS_OK;
++
++}
++#endif
++
++/* GetEquivalentObject dereferences any hard links to get to the
++ * actual object.
++ */
++
++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 */
++ obj = obj->variant.hardLinkVariant.equivalentObject;
++ yaffs_CheckObjectDetailsLoaded(obj);
++ }
++ return obj;
++}
++
++int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize)
++{
++ memset(name, 0, buffSize * sizeof(YCHAR));
++
++ yaffs_CheckObjectDetailsLoaded(obj);
++
++ if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
++ yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1);
++ } 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_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])
++ yaffs_strcpy(name, obj->shortName);
++#endif
++ else {
++ int result;
++ __u8 *buffer = yaffs_GetTempBuffer(obj->myDev, __LINE__);
++
++ yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *) buffer;
++
++ memset(buffer, 0, obj->myDev->nDataBytesPerChunk);
++
++ if (obj->hdrChunk > 0) {
++ result = yaffs_ReadChunkWithTagsFromNAND(obj->myDev,
++ obj->hdrChunk, buffer,
++ NULL);
++ }
++ yaffs_strncpy(name, oh->name, buffSize - 1);
++
++ yaffs_ReleaseTempBuffer(obj->myDev, buffer, __LINE__);
++ }
++
++ return yaffs_strlen(name);
++}
++
++int yaffs_GetObjectFileLength(yaffs_Object *obj)
++{
++ /* Dereference any hard linking */
++ obj = yaffs_GetEquivalentObject(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 {
++ /* Only a directory should drop through to here */
++ return obj->myDev->nDataBytesPerChunk;
++ }
++}
++
++int yaffs_GetObjectLinkCount(yaffs_Object *obj)
++{
++ int count = 0;
++ struct ylist_head *i;
++
++ 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)
++{
++ obj = yaffs_GetEquivalentObject(obj);
++
++ return obj->objectId;
++}
++
++unsigned yaffs_GetObjectType(yaffs_Object *obj)
++{
++ obj = yaffs_GetEquivalentObject(obj);
++
++ switch (obj->variantType) {
++ case YAFFS_OBJECT_TYPE_FILE:
++ return DT_REG;
++ break;
++ case YAFFS_OBJECT_TYPE_DIRECTORY:
++ return DT_DIR;
++ break;
++ case YAFFS_OBJECT_TYPE_SYMLINK:
++ return DT_LNK;
++ break;
++ case YAFFS_OBJECT_TYPE_HARDLINK:
++ return DT_REG;
++ break;
++ case YAFFS_OBJECT_TYPE_SPECIAL:
++ if (S_ISFIFO(obj->yst_mode))
++ return DT_FIFO;
++ if (S_ISCHR(obj->yst_mode))
++ return DT_CHR;
++ if (S_ISBLK(obj->yst_mode))
++ return DT_BLK;
++ if (S_ISSOCK(obj->yst_mode))
++ return DT_SOCK;
++ default:
++ return DT_REG;
++ break;
++ }
++}
++
++YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj)
++{
++ obj = yaffs_GetEquivalentObject(obj);
++ if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
++ return yaffs_CloneString(obj->variant.symLinkVariant.alias);
++ else
++ return yaffs_CloneString(_Y(""));
++}
++
++#ifndef CONFIG_YAFFS_WINCE
++
++int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr)
++{
++ unsigned int valid = attr->ia_valid;
++
++ if (valid & ATTR_MODE)
++ obj->yst_mode = attr->ia_mode;
++ if (valid & ATTR_UID)
++ obj->yst_uid = attr->ia_uid;
++ if (valid & ATTR_GID)
++ obj->yst_gid = attr->ia_gid;
++
++ if (valid & ATTR_ATIME)
++ obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
++ if (valid & ATTR_CTIME)
++ obj->yst_ctime = Y_TIME_CONVERT(attr->ia_ctime);
++ if (valid & ATTR_MTIME)
++ obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime);
++
++ if (valid & ATTR_SIZE)
++ yaffs_ResizeFile(obj, attr->ia_size);
++
++ yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0);
++
++ return YAFFS_OK;
++
++}
++int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr)
++{
++ unsigned int valid = 0;
++
++ attr->ia_mode = obj->yst_mode;
++ valid |= ATTR_MODE;
++ attr->ia_uid = obj->yst_uid;
++ valid |= ATTR_UID;
++ attr->ia_gid = obj->yst_gid;
++ valid |= ATTR_GID;
++
++ Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;
++ valid |= ATTR_ATIME;
++ Y_TIME_CONVERT(attr->ia_ctime) = obj->yst_ctime;
++ valid |= ATTR_CTIME;
++ Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime;
++ valid |= ATTR_MTIME;
++
++ attr->ia_size = yaffs_GetFileSize(obj);
++ valid |= ATTR_SIZE;
++
++ attr->ia_valid = valid;
++
++ return YAFFS_OK;
++}
++
++#endif
++
++#if 0
++int yaffs_DumpObject(yaffs_Object *obj)
++{
++ YCHAR name[257];
++
++ yaffs_GetObjectName(obj, name, 256);
++
++ 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)));
++
++ return YAFFS_OK;
++}
++#endif
++
++/*---------------------------- Initialisation code -------------------------------------- */
++
++static int yaffs_CheckDevFunctions(const yaffs_Device *dev)
++{
++
++ /* Common functions, gotta have */
++ if (!dev->eraseBlockInNAND || !dev->initialiseNAND)
++ 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)
++ 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)
++ return 1;
++
++ return 0; /* bad */
++}
++
++
++static int yaffs_CreateInitialDirectories(yaffs_Device *dev)
++{
++ /* Initialise the unlinked, deleted, root and lost and found directories */
++
++ dev->lostNFoundDir = dev->rootDir = NULL;
++ dev->unlinkedDir = dev->deletedDir = NULL;
++
++ dev->unlinkedDir =
++ yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
++
++ dev->deletedDir =
++ yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
++
++ dev->rootDir =
++ yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_ROOT,
++ YAFFS_ROOT_MODE | S_IFDIR);
++ dev->lostNFoundDir =
++ yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_LOSTNFOUND,
++ YAFFS_LOSTNFOUND_MODE | S_IFDIR);
++
++ if (dev->lostNFoundDir && dev->rootDir && dev->unlinkedDir && dev->deletedDir) {
++ yaffs_AddObjectToDirectory(dev->rootDir, dev->lostNFoundDir);
++ return YAFFS_OK;
++ }
++
++ return YAFFS_FAIL;
++}
++
++int yaffs_GutsInitialise(yaffs_Device *dev)
++{
++ int init_failed = 0;
++ unsigned x;
++ int bits;
++
++ T(YAFFS_TRACE_TRACING, (TSTR("yaffs: yaffs_GutsInitialise()" TENDSTR)));
++
++ /* Check stuff that must be set */
++
++ if (!dev) {
++ T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Need a device" TENDSTR)));
++ 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;
++ }
++
++ /* 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 */
++ 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));
++ return YAFFS_FAIL;
++ }
++
++ if (yaffs_InitialiseNAND(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);
++ else
++ dev->nDataBytesPerChunk = dev->totalBytesPerChunk;
++
++ /* Got the right mix of functions? */
++ if (!yaffs_CheckDevFunctions(dev)) {
++ /* Function missing */
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR
++ ("yaffs: device function(s) missing or wrong\n" TENDSTR)));
++
++ return YAFFS_FAIL;
++ }
++
++ /* This is really a compilation check. */
++ if (!yaffs_CheckStructures()) {
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR("yaffs_CheckStructures failed\n" TENDSTR)));
++ return YAFFS_FAIL;
++ }
++
++ if (dev->isMounted) {
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR("yaffs: device already mounted\n" TENDSTR)));
++ return YAFFS_FAIL;
++ }
++
++ /* Finished with most checks. One or two more checks happen later on too. */
++
++ dev->isMounted = 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;
++
++ /*
++ * Calculate chunkGroupBits.
++ * We need to find the next power of 2 > than internalEndBlock
++ */
++
++ x = dev->nChunksPerBlock * (dev->internalEndBlock + 1);
++
++ bits = ShiftsGE(x);
++
++ /* Set up tnode width if wide tnodes are enabled. */
++ if (!dev->wideTnodesDisabled) {
++ /* bits must be even so that we end up with 32-bit words */
++ if (bits & 1)
++ bits++;
++ if (bits < 16)
++ dev->tnodeWidth = 16;
++ else
++ dev->tnodeWidth = bits;
++ } else
++ dev->tnodeWidth = 16;
++
++ dev->tnodeMask = (1<<dev->tnodeWidth)-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
++ */
++
++ if (bits <= dev->tnodeWidth)
++ dev->chunkGroupBits = 0;
++ else
++ dev->chunkGroupBits = bits - dev->tnodeWidth;
++
++
++ dev->chunkGroupSize = 1 << dev->chunkGroupBits;
++
++ if (dev->nChunksPerBlock < dev->chunkGroupSize) {
++ /* 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".
++ */
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR("yaffs: chunk group too large\n" TENDSTR)));
++
++ return YAFFS_FAIL;
++ }
++
++ /* 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 */
++
++ /* Initialise temporary buffers and caches. */
++ if (!yaffs_InitialiseTempBuffers(dev))
++ init_failed = 1;
++
++ dev->srCache = NULL;
++ dev->gcCleanupList = NULL;
++
++
++ if (!init_failed &&
++ dev->nShortOpCaches > 0) {
++ int i;
++ void *buf;
++ int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
++
++ if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
++ dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
++
++ dev->srCache = YMALLOC(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->totalBytesPerChunk);
++ }
++ if (!buf)
++ init_failed = 1;
++
++ dev->srLastUse = 0;
++ }
++
++ dev->cacheHits = 0;
++
++ if (!init_failed) {
++ dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32));
++ if (!dev->gcCleanupList)
++ init_failed = 1;
++ }
++
++ if (dev->isYaffs2)
++ dev->useHeaderFileSize = 1;
++
++ if (!init_failed && !yaffs_InitialiseBlocks(dev))
++ init_failed = 1;
++
++ yaffs_InitialiseTnodes(dev);
++ yaffs_InitialiseObjects(dev);
++
++ if (!init_failed && !yaffs_CreateInitialDirectories(dev))
++ init_failed = 1;
++
++
++ if (!init_failed) {
++ /* Now scan the flash. */
++ if (dev->isYaffs2) {
++ if (yaffs_CheckpointRestore(dev)) {
++ yaffs_CheckObjectDetailsLoaded(dev->rootDir);
++ T(YAFFS_TRACE_ALWAYS,
++ (TSTR("yaffs: restored from checkpoint" TENDSTR)));
++ } else {
++
++ /* Clean up the mess caused by an aborted checkpoint load
++ * and scan backwards.
++ */
++ yaffs_DeinitialiseBlocks(dev);
++ yaffs_DeinitialiseTnodes(dev);
++ yaffs_DeinitialiseObjects(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;
++
++ if (!init_failed && !yaffs_InitialiseBlocks(dev))
++ init_failed = 1;
++
++ yaffs_InitialiseTnodes(dev);
++ yaffs_InitialiseObjects(dev);
++
++ if (!init_failed && !yaffs_CreateInitialDirectories(dev))
++ init_failed = 1;
++
++ if (!init_failed && !yaffs_ScanBackwards(dev))
++ init_failed = 1;
++ }
++ } else if (!yaffs_Scan(dev))
++ init_failed = 1;
++
++ yaffs_StripDeletedObjects(dev);
++ }
++
++ if (init_failed) {
++ /* Clean up the mess */
++ T(YAFFS_TRACE_TRACING,
++ (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
++
++ 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);
++
++
++ T(YAFFS_TRACE_TRACING,
++ (TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR)));
++ return YAFFS_OK;
++
++}
++
++void yaffs_Deinitialise(yaffs_Device *dev)
++{
++ if (dev->isMounted) {
++ int i;
++
++ yaffs_DeinitialiseBlocks(dev);
++ yaffs_DeinitialiseTnodes(dev);
++ yaffs_DeinitialiseObjects(dev);
++ if (dev->nShortOpCaches > 0 &&
++ dev->srCache) {
++
++ for (i = 0; i < dev->nShortOpCaches; i++) {
++ if (dev->srCache[i].data)
++ YFREE(dev->srCache[i].data);
++ dev->srCache[i].data = NULL;
++ }
++
++ YFREE(dev->srCache);
++ dev->srCache = NULL;
++ }
++
++ YFREE(dev->gcCleanupList);
++
++ 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)
++{
++ int nFree;
++ int b;
++
++ yaffs_BlockInfo *blk;
++
++ for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock;
++ b++) {
++ blk = yaffs_GetBlockInfo(dev, b);
++
++ switch (blk->blockState) {
++ 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);
++ break;
++ default:
++ break;
++ }
++ }
++
++ return nFree;
++}
++
++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;
++#else
++ nFree = yaffs_CountFreeChunks(dev);
++#endif
++
++ nFree += dev->nDeletedFiles;
++
++ /* 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)
++ nDirtyCacheChunks++;
++ }
++
++ nFree -= nDirtyCacheChunks;
++
++ nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
++
++ /* 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;
++
++ nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
++
++ if (nFree < 0)
++ nFree = 0;
++
++ return nFree;
++
++}
++
++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) \
++ 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"); */
++#ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG
++ yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode");
++#endif
++#ifndef CONFIG_YAFFS_WINCE
++ yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");
++#endif
++ return YAFFS_OK;
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_guts.h linux-2.6.25/fs/yaffs2/yaffs_guts.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_guts.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_guts.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,904 @@
++/*
++ * 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_GUTS_H__
++#define __YAFFS_GUTS_H__
++
++#include "devextras.h"
++#include "yportenv.h"
++
++#define YAFFS_OK 1
++#define YAFFS_FAIL 0
++
++/* Give us a Y=0x59,
++ * Give us an A=0x41,
++ * Give us an FF=0xFF
++ * Give us an S=0x53
++ * And what have we got...
++ */
++#define YAFFS_MAGIC 0x5941FF53
++
++#define YAFFS_NTNODES_LEVEL0 16
++#define YAFFS_TNODES_LEVEL0_BITS 4
++#define YAFFS_TNODES_LEVEL0_MASK 0xf
++
++#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2)
++#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1)
++#define YAFFS_TNODES_INTERNAL_MASK 0x7
++#define YAFFS_TNODES_MAX_LEVEL 6
++
++#ifndef CONFIG_YAFFS_NO_YAFFS1
++#define YAFFS_BYTES_PER_SPARE 16
++#define YAFFS_BYTES_PER_CHUNK 512
++#define YAFFS_CHUNK_SIZE_SHIFT 9
++#define YAFFS_CHUNKS_PER_BLOCK 32
++#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
++#endif
++
++#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024
++#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32
++
++#define YAFFS_MAX_CHUNK_ID 0x000FFFFF
++
++#define YAFFS_UNUSED_OBJECT_ID 0x0003FFFF
++
++#define YAFFS_ALLOCATION_NOBJECTS 100
++#define YAFFS_ALLOCATION_NTNODES 100
++#define YAFFS_ALLOCATION_NLINKS 100
++
++#define YAFFS_NOBJECT_BUCKETS 256
++
++
++#define YAFFS_OBJECT_SPACE 0x40000
++
++#define YAFFS_CHECKPOINT_VERSION 3
++
++#ifdef CONFIG_YAFFS_UNICODE
++#define YAFFS_MAX_NAME_LENGTH 127
++#define YAFFS_MAX_ALIAS_LENGTH 79
++#else
++#define YAFFS_MAX_NAME_LENGTH 255
++#define YAFFS_MAX_ALIAS_LENGTH 159
++#endif
++
++#define YAFFS_SHORT_NAME_LENGTH 15
++
++/* Some special object ids for pseudo objects */
++#define YAFFS_OBJECTID_ROOT 1
++#define YAFFS_OBJECTID_LOSTNFOUND 2
++#define YAFFS_OBJECTID_UNLINKED 3
++#define YAFFS_OBJECTID_DELETED 4
++
++/* Sseudo 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
++
++#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.
++ * Default to something in the order of 5 to 10 blocks worth of chunks.
++ */
++#define YAFFS_WR_ATTEMPTS (5*64)
++
++/* Sequence numbers are used in YAFFS2 to determine block allocation order.
++ * The range is limited slightly to help distinguish bad numbers from good.
++ * This also allows us to perhaps in the future use special numbers for
++ * special purposes.
++ * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years,
++ * and is a larger number than the lifetime of a 2GB device.
++ */
++#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;
++ int chunkId;
++ int lastUse;
++ int dirty;
++ int nBytes; /* 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;
++
++
++
++/* Tags structures in RAM
++ * NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
++ * the structure size will get blown out.
++ */
++
++#ifndef CONFIG_YAFFS_NO_YAFFS1
++typedef struct {
++ unsigned chunkId:20;
++ unsigned serialNumber:2;
++ unsigned byteCountLSB:10;
++ unsigned objectId:18;
++ unsigned ecc:12;
++ unsigned byteCountMSB:2;
++} yaffs_Tags;
++
++typedef union {
++ yaffs_Tags asTags;
++ __u8 asBytes[8];
++} yaffs_TagsUnion;
++
++#endif
++
++/* Stuff used for extended tags in YAFFS2 */
++
++typedef enum {
++ YAFFS_ECC_RESULT_UNKNOWN,
++ YAFFS_ECC_RESULT_NO_ERROR,
++ YAFFS_ECC_RESULT_FIXED,
++ YAFFS_ECC_RESULT_UNFIXED
++} yaffs_ECCResult;
++
++typedef enum {
++ YAFFS_OBJECT_TYPE_UNKNOWN,
++ YAFFS_OBJECT_TYPE_FILE,
++ YAFFS_OBJECT_TYPE_SYMLINK,
++ YAFFS_OBJECT_TYPE_DIRECTORY,
++ YAFFS_OBJECT_TYPE_HARDLINK,
++ YAFFS_OBJECT_TYPE_SPECIAL
++} yaffs_ObjectType;
++
++#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 */
++
++ /* The following stuff only has meaning when we read */
++ yaffs_ECCResult eccResult;
++ unsigned blockBad;
++
++ /* YAFFS 1 stuff */
++ unsigned chunkDeleted; /* The chunk is marked deleted */
++ unsigned serialNumber; /* Yaffs1 2-bit serial number */
++
++ /* YAFFS2 stuff */
++ unsigned sequenceNumber; /* 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? */
++
++ yaffs_ObjectType extraObjectType; /* What object type? */
++
++ unsigned extraFileLength; /* Length if it is a file */
++ unsigned extraEquivalentObjectId; /* Equivalent object Id if it is a hard link */
++
++ unsigned validMarker1;
++
++} yaffs_ExtendedTags;
++
++/* 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 ecc1[3];
++ __u8 tagByte6;
++ __u8 tagByte7;
++ __u8 ecc2[3];
++} yaffs_Spare;
++
++/*Special structure for passing through to mtd */
++struct yaffs_NANDSpare {
++ yaffs_Spare spare;
++ int eccres1;
++ int eccres2;
++};
++
++/* Block data in RAM */
++
++typedef enum {
++ YAFFS_BLOCK_STATE_UNKNOWN = 0,
++
++ YAFFS_BLOCK_STATE_SCANNING,
++ 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.
++ * This state is only valid during yaffs_Scan.
++ * NB We tolerate empty because the pre-scanner might be incapable of deciding
++ * However, if this state is returned on a YAFFS2 device, then we expect a sequence number
++ */
++
++ YAFFS_BLOCK_STATE_EMPTY,
++ /* This block is empty */
++
++ YAFFS_BLOCK_STATE_ALLOCATING,
++ /* 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
++ */
++
++ YAFFS_BLOCK_STATE_FULL,
++ /* All the pages in this block have been allocated.
++ */
++
++ YAFFS_BLOCK_STATE_DIRTY,
++ /* All pages have been allocated and deleted.
++ * Erase me, reuse me.
++ */
++
++ YAFFS_BLOCK_STATE_CHECKPOINT,
++ /* 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;
++
++#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 */
++ /* 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 */
++
++#ifdef CONFIG_YAFFS_YAFFS2
++ __u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
++ __u32 sequenceNumber; /* block sequence number for yaffs2 */
++#endif
++
++} yaffs_BlockInfo;
++
++/* -------------------------- Object structure -------------------------------*/
++/* This is the object structure as stored on NAND */
++
++typedef struct {
++ yaffs_ObjectType type;
++
++ /* Apply to everything */
++ int parentObjectId;
++ __u16 sum__NoLongerUsed; /* 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];
++#else
++ __u32 yst_uid;
++ __u32 yst_gid;
++ __u32 yst_atime;
++ __u32 yst_mtime;
++ __u32 yst_ctime;
++#endif
++
++ /* File size applies to files only */
++ int fileSize;
++
++ /* Equivalent object id applies to hard links only. */
++ int equivalentObjectId;
++
++ /* Alias is for symlinks only. */
++ YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
++
++ __u32 yst_rdev; /* device stuff for block and char devices (major/min) */
++
++#ifdef CONFIG_YAFFS_WINCE
++ __u32 win_ctime[2];
++ __u32 win_atime[2];
++ __u32 win_mtime[2];
++#else
++ __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) */
++ __u32 isShrink;
++
++} yaffs_ObjectHeader;
++
++/*--------------------------- 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]; */
++
++};
++
++typedef union yaffs_Tnode_union yaffs_Tnode;
++
++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:
++ * - a directory (no data, has children links
++ * - a regular file (data.... not prunes :->).
++ * - a symlink [symbolic link] (the alias).
++ * - a hard link
++ */
++
++typedef struct {
++ __u32 fileSize;
++ __u32 scannedFileSize;
++ __u32 shrinkSize;
++ int topLevel;
++ yaffs_Tnode *top;
++} yaffs_FileStructure;
++
++typedef struct {
++ struct ylist_head children; /* list of child links */
++} yaffs_DirectoryStructure;
++
++typedef struct {
++ YCHAR *alias;
++} yaffs_SymLinkStructure;
++
++typedef struct {
++ struct yaffs_ObjectStruct *equivalentObject;
++ __u32 equivalentObjectId;
++} yaffs_HardLinkStructure;
++
++typedef union {
++ yaffs_FileStructure fileVariant;
++ yaffs_DirectoryStructure directoryVariant;
++ yaffs_SymLinkStructure symLinkVariant;
++ yaffs_HardLinkStructure hardLinkVariant;
++} yaffs_ObjectVariant;
++
++struct yaffs_ObjectStruct {
++ __u8 deleted:1; /* This should only apply to unlinked files. */
++ __u8 softDeleted: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 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 deferedFree: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 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 ylist_head hashLink; /* list of objects in this hash bucket */
++
++ 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 ylist_head siblings;
++
++ /* Where's my object header in NAND? */
++ int hdrChunk;
++
++ int nDataChunks; /* Number of data chunks attached to the file. */
++
++ __u32 objectId; /* 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;
++#endif
++
++#ifdef CONFIG_YAFFS_WINCE
++ __u32 win_ctime[2];
++ __u32 win_mtime[2];
++ __u32 win_atime[2];
++#else
++ __u32 yst_uid;
++ __u32 yst_gid;
++ __u32 yst_atime;
++ __u32 yst_mtime;
++ __u32 yst_ctime;
++#endif
++
++ __u32 yst_rdev;
++
++#ifdef __KERNEL__
++ struct inode *myInode;
++
++#endif
++
++ yaffs_ObjectType variantType;
++
++ 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 {
++ struct ylist_head list;
++ int count;
++} yaffs_ObjectBucket;
++
++
++/* yaffs_CheckpointObject holds the definition of an object as dumped
++ * by checkpointing.
++ */
++
++typedef struct {
++ int structType;
++ __u32 objectId;
++ __u32 parentId;
++ int hdrChunk;
++ yaffs_ObjectType variantType:3;
++ __u8 deleted:1;
++ __u8 softDeleted:1;
++ __u8 unlinked:1;
++ __u8 fake:1;
++ __u8 renameAllowed:1;
++ __u8 unlinkAllowed:1;
++ __u8 serial;
++
++ int nDataChunks;
++ __u32 fileSizeOrEquivalentObjectId;
++} yaffs_CheckpointObject;
++
++/*--------------------- Temporary buffers ----------------
++ *
++ * These are chunk-sized working buffers. Each device has a few
++ */
++
++typedef struct {
++ __u8 *buffer;
++ int line; /* track from whence this buffer was allocated */
++ int maxLine;
++} yaffs_TempBuffer;
++
++/*----------------- 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 */
++
++/* int nCheckpointReservedBlocks; */ /* Blocks to reserve for checkpoint data */
++
++
++ int nShortOpCaches; /* If <= 0, then short op caching is disabled, else
++ * the number of short op caches (don't use too many)
++ */
++
++ int useHeaderFileSize; /* Flag to determine if we should use file sizes from the header */
++
++ int useNANDECC; /* Flag to decide whether or not to use NANDECC */
++
++ void *genericDevice; /* Pointer to device context
++ * On an mtd this holds the mtd pointer.
++ */
++ 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 (*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, __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
++ */
++ void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
++
++ /* Callback to mark the superblock dirsty */
++ 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. */
++
++ /* Checkpoint control. Can be set before or after initialisation */
++ __u8 skipCheckpointRead;
++ __u8 skipCheckpointWrite;
++
++ /* Runtime parameters. Set up by YAFFS. */
++
++ __u16 chunkGroupBits; /* 0 for devices <= 32MB. else log2(nchunks) - 16 */
++ __u16 chunkGroupSize; /* == 2^^chunkGroupBits */
++
++ /* Stuff to support wide tnodes */
++ __u32 tnodeWidth;
++ __u32 tnodeMask;
++
++ /* 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
++
++ int isMounted;
++
++ int isCheckpointed;
++
++
++ /* Stuff to support block offsetting to support start block zero */
++ int internalStartBlock;
++ int internalEndBlock;
++ int blockOffset;
++ int chunkOffset;
++
++
++ /* 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 nCheckpointBlocksRequired; /* 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.
++ */
++
++ 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 */
++
++ /* Special directories */
++ yaffs_Object *rootDir;
++ yaffs_Object *lostNFoundDir;
++
++ /* 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];
++ */
++
++ int bufferedBlock; /* Which block is buffered here? */
++ int doingBufferedBlockRewrite;
++
++ yaffs_ChunkCache *srCache;
++ int srLastUse;
++
++ int cacheHits;
++
++ /* 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. */
++
++
++ /* Temporary buffer management */
++ yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
++ int maxTemp;
++ int tempInUse;
++ int unmanagedTempAllocations;
++ int unmanagedTempDeallocations;
++
++ /* yaffs2 runtime stuff */
++ unsigned sequenceNumber; /* Sequence number of currently allocating block */
++ unsigned oldestDirtySequence;
++
++};
++
++typedef struct yaffs_DeviceStruct yaffs_Device;
++
++/* 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 rfu[100];
++} yaffs_SuperBlockHeader;
++
++/* 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. */
++
++ /* yaffs2 runtime stuff */
++ unsigned sequenceNumber; /* Sequence number of currently allocating block */
++ unsigned oldestDirtySequence;
++
++} yaffs_CheckpointDevice;
++
++
++typedef struct {
++ int structType;
++ __u32 magic;
++ __u32 version;
++ __u32 head;
++} yaffs_CheckpointValidity;
++
++
++/*----------------------- YAFFS Functions -----------------------*/
++
++int yaffs_GutsInitialise(yaffs_Device *dev);
++void yaffs_Deinitialise(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_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_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);
++
++/* Flushing and checkpointing */
++void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
++
++int yaffs_CheckpointSave(yaffs_Device *dev);
++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,
++ int (*fn) (yaffs_Object *));
++
++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_GetEquivalentObject(yaffs_Object *obj);
++
++/* Symlink operations */
++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);
++
++/* Special inodes (fifos, sockets and devices) */
++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);
++
++#ifdef CONFIG_YAFFS_WINCE
++/* CONFIG_YAFFS_WINCE special stuff */
++void yfsd_WinFileTimeNow(__u32 target[2]);
++#endif
++
++#ifdef __KERNEL__
++
++void yaffs_HandleDeferedFree(yaffs_Object *obj);
++#endif
++
++/* Debug dump */
++int yaffs_DumpObject(yaffs_Object *obj);
++
++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_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
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffsinterface.h linux-2.6.25/fs/yaffs2/yaffsinterface.h
+--- linux-2.6.25_original/fs/yaffs2/yaffsinterface.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffsinterface.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,21 @@
++/*
++ * 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 __YAFFSINTERFACE_H__
++#define __YAFFSINTERFACE_H__
++
++int yaffs_Initialise(unsigned nBlocks);
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif1.c linux-2.6.25/fs/yaffs2/yaffs_mtdif1.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif1.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif1.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,365 @@
++/*
++ * 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 (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
++# 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);
++
++ dev->nPageWrites++;
++
++ 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;
++
++ dev->nPageReads++;
++
++ 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 (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.
++ */
++ 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
++ deleted = (yaffs_CountBits(((__u8 *)&pt1)[8]) < 7);
++#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++;
++ if (eccres == YAFFS_ECC_RESULT_NO_ERROR)
++ 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 */
++ etags->chunkDeleted = deleted;
++ 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\n", 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\n",
++ 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, __u32 *pSequenceNumber)
++{
++ 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;
++ 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);
++ etags.blockBad = (mtd->block_isbad)(mtd, addr);
++ if (etags.blockBad) {
++ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
++ "block %d is marked bad\n", blockNo);
++ state = YAFFS_BLOCK_STATE_DEAD;
++ } 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 {
++ state = YAFFS_BLOCK_STATE_EMPTY;
++ }
++
++ *pState = state;
++ *pSequenceNumber = seqnum;
++
++ /* query always succeeds */
++ return YAFFS_OK;
++}
++
++#endif /*MTD_VERSION*/
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif1.h linux-2.6.25/fs/yaffs2/yaffs_mtdif1.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif1.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif1.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,28 @@
++/*
++ * 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
++ *
++ * 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_MTDIF1_H__
++#define __YAFFS_MTDIF1_H__
++
++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_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
++
++int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
++ yaffs_BlockState *state, __u32 *sequenceNumber);
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif2.c linux-2.6.25/fs/yaffs2/yaffs_mtdif2.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif2.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif2.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,246 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++/* 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_mtdif2.h"
++
++#include "linux/mtd/mtd.h"
++#include "linux/types.h"
++#include "linux/time.h"
++
++#include "yaffs_packedtags2.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,
++ const __u8 *data,
++ const yaffs_ExtendedTags *tags)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++#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;
++
++ yaffs_PackedTags2 pt;
++
++ T(YAFFS_TRACE_MTD,
++ (TSTR
++ ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
++ TENDSTR), chunkInNAND, data, tags));
++
++
++ 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
++ yaffs_PackTags2(&pt, tags);
++
++#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
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
++ __u8 *data, yaffs_ExtendedTags *tags)
++{
++ 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;
++ int localData = 0;
++
++ loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
++
++ yaffs_PackedTags2 pt;
++
++ T(YAFFS_TRACE_MTD,
++ (TSTR
++ ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
++ TENDSTR), chunkInNAND, data, tags));
++
++ 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;
++ ops.ooblen = sizeof(pt);
++ ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt);
++ ops.ooboffs = 0;
++ ops.datbuf = data;
++ ops.oobbuf = dev->spareBuffer;
++ retval = mtd->read_oob(mtd, addr, &ops);
++ }
++#else
++ 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 (!dev->inbandTags && tags)
++ retval =
++ mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
++ dev->spareBuffer);
++ }
++#endif
++
++
++ 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)
++ tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++ int retval;
++ T(YAFFS_TRACE_MTD,
++ (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo));
++
++ retval =
++ mtd->block_markbad(mtd,
++ blockNo * dev->nChunksPerBlock *
++ dev->totalBytesPerChunk);
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++
++}
++
++int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
++ yaffs_BlockState *state, __u32 *sequenceNumber)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++ int retval;
++
++ T(YAFFS_TRACE_MTD,
++ (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo));
++ retval =
++ mtd->block_isbad(mtd,
++ blockNo * dev->nChunksPerBlock *
++ dev->totalBytesPerChunk);
++
++ if (retval) {
++ T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
++
++ *state = YAFFS_BLOCK_STATE_DEAD;
++ *sequenceNumber = 0;
++ } else {
++ yaffs_ExtendedTags t;
++ nandmtd2_ReadChunkWithTagsFromNAND(dev,
++ blockNo *
++ dev->nChunksPerBlock, NULL,
++ &t);
++
++ if (t.chunkUsed) {
++ *sequenceNumber = t.sequenceNumber;
++ *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
++ } else {
++ *sequenceNumber = 0;
++ *state = YAFFS_BLOCK_STATE_EMPTY;
++ }
++ }
++ T(YAFFS_TRACE_MTD,
++ (TSTR("block is bad seq %d state %d" TENDSTR), *sequenceNumber,
++ *state));
++
++ if (retval == 0)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif2.h linux-2.6.25/fs/yaffs2/yaffs_mtdif2.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif2.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif2.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,29 @@
++/*
++ * 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_MTDIF2_H__
++#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_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
++int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
++ yaffs_BlockState *state, __u32 *sequenceNumber);
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif.c linux-2.6.25/fs/yaffs2/yaffs_mtdif.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,241 @@
++/*
++ * 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 General Public License version 2 as
++ * 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"
++
++
++#include "yaffs_mtdif.h"
++
++#include "linux/mtd/mtd.h"
++#include "linux/types.h"
++#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;
++
++ 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)
++{
++ struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
++ __u32 addr =
++ ((loff_t) blockNumber) * dev->nDataBytesPerChunk
++ * dev->nChunksPerBlock;
++ struct erase_info ei;
++ int retval = 0;
++
++ ei.mtd = mtd;
++ ei.addr = addr;
++ ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
++ 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)
++ return YAFFS_OK;
++ else
++ return YAFFS_FAIL;
++}
++
++int nandmtd_InitialiseNAND(yaffs_Device *dev)
++{
++ return YAFFS_OK;
++}
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_mtdif.h linux-2.6.25/fs/yaffs2/yaffs_mtdif.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_mtdif.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_mtdif.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,32 @@
++/*
++ * 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_MTDIF_H__
++#define __YAFFS_MTDIF_H__
++
++#include "yaffs_guts.h"
++
++#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
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_nand.c linux-2.6.25/fs/yaffs2/yaffs_nand.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_nand.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_nand.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,135 @@
++/*
++ * 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 General Public License version 2 as
++ * 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,
++ __u8 *buffer,
++ yaffs_ExtendedTags *tags)
++{
++ int result;
++ yaffs_ExtendedTags localTags;
++
++ int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
++
++ /* 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,
++ tags);
++ else
++ result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
++ realignedChunkInNAND,
++ buffer,
++ tags);
++ if (tags &&
++ tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
++
++ yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
++ yaffs_HandleChunkError(dev, bi);
++ }
++
++ return result;
++}
++
++int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
++ int chunkInNAND,
++ const __u8 *buffer,
++ yaffs_ExtendedTags *tags)
++{
++ chunkInNAND -= dev->chunkOffset;
++
++
++ if (tags) {
++ tags->sequenceNumber = dev->sequenceNumber;
++ tags->chunkUsed = 1;
++ if (!yaffs_ValidateTags(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));
++ } else {
++ T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
++ YBUG();
++ }
++
++ if (dev->writeChunkWithTagsToNAND)
++ return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
++ tags);
++ else
++ return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
++ chunkInNAND,
++ buffer,
++ tags);
++}
++
++int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
++{
++ blockNo -= dev->blockOffset;
++
++;
++ if (dev->markNANDBlockBad)
++ return dev->markNANDBlockBad(dev, blockNo);
++ else
++ return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
++}
++
++int yaffs_QueryInitialBlockState(yaffs_Device *dev,
++ int blockNo,
++ yaffs_BlockState *state,
++ __u32 *sequenceNumber)
++{
++ blockNo -= dev->blockOffset;
++
++ if (dev->queryNANDBlock)
++ return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
++ else
++ return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
++ state,
++ sequenceNumber);
++}
++
++
++int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
++ int blockInNAND)
++{
++ int result;
++
++ blockInNAND -= dev->blockOffset;
++
++
++ dev->nBlockErasures++;
++ result = dev->eraseBlockInNAND(dev, blockInNAND);
++
++ return result;
++}
++
++int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
++{
++ return dev->initialiseNAND(dev);
++}
++
++
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_nandemul2k.h linux-2.6.25/fs/yaffs2/yaffs_nandemul2k.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_nandemul2k.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_nandemul2k.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,39 @@
++/*
++ * 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.
++ */
++
++/* Interface to emulated NAND functions (2k page size) */
++
++#ifndef __YAFFS_NANDEMUL2K_H__
++#define __YAFFS_NANDEMUL2K_H__
++
++#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_GetBytesPerChunk(void);
++int nandemul2k_GetChunksPerBlock(void);
++int nandemul2k_GetNumberOfBlocks(void);
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_nand.h linux-2.6.25/fs/yaffs2/yaffs_nand.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_nand.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_nand.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,44 @@
++/*
++ * 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_NAND_H__
++#define __YAFFS_NAND_H__
++#include "yaffs_guts.h"
++
++
++
++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);
++
++int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev);
++
++#endif
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_packedtags1.c linux-2.6.25/fs/yaffs2/yaffs_packedtags1.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_packedtags1.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,50 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "yaffs_packedtags1.h"
++#include "yportenv.h"
++
++void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t)
++{
++ pt->chunkId = t->chunkId;
++ pt->serialNumber = t->serialNumber;
++ pt->byteCount = t->byteCount;
++ pt->objectId = t->objectId;
++ pt->ecc = 0;
++ pt->deleted = (t->chunkDeleted) ? 0 : 1;
++ pt->unusedStuff = 0;
++ pt->shouldBeFF = 0xFFFFFFFF;
++
++}
++
++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,
++0xff };
++
++ if (memcmp(allFF, pt, sizeof(yaffs_PackedTags1))) {
++ t->blockBad = 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;
++ } else {
++ memset(t, 0, sizeof(yaffs_ExtendedTags));
++ }
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_packedtags1.h linux-2.6.25/fs/yaffs2/yaffs_packedtags1.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_packedtags1.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_packedtags1.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,37 @@
++/*
++ * 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.
++ */
++
++/* This is used to pack YAFFS1 tags, not YAFFS2 tags. */
++
++#ifndef __YAFFS_PACKEDTAGS1_H__
++#define __YAFFS_PACKEDTAGS1_H__
++
++#include "yaffs_guts.h"
++
++typedef struct {
++ unsigned chunkId:20;
++ unsigned serialNumber:2;
++ unsigned byteCount:10;
++ unsigned objectId:18;
++ unsigned ecc:12;
++ unsigned deleted:1;
++ unsigned unusedStuff:1;
++ unsigned shouldBeFF;
++
++} yaffs_PackedTags1;
++
++void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t);
++void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt);
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_packedtags2.c linux-2.6.25/fs/yaffs2/yaffs_packedtags2.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_packedtags2.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_packedtags2.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,206 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "yaffs_packedtags2.h"
++#include "yportenv.h"
++#include "yaffs_tagsvalidity.h"
++
++/* This code packs a set of extended tags into a binary structure for
++ * NAND storage
++ */
++
++/* Some of the information is "extra" struff which can be packed in to
++ * speed scanning
++ * This is defined by having the EXTRA_HEADER_INFO_FLAG set.
++ */
++
++/* Extra flags applied to chunkId */
++
++#define EXTRA_HEADER_INFO_FLAG 0x80000000
++#define EXTRA_SHRINK_FLAG 0x40000000
++#define EXTRA_SHADOWS_FLAG 0x20000000
++#define EXTRA_SPARE_FLAGS 0x10000000
++
++#define ALL_EXTRA_FLAGS 0xF0000000
++
++/* Also, the top 4 bits of the object Id are set to the object type. */
++#define EXTRA_OBJECT_TYPE_SHIFT (28)
++#define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
++
++
++static void yaffs_DumpPackedTags2TagsPart(const yaffs_PackedTags2TagsPart *ptt)
++{
++ T(YAFFS_TRACE_MTD,
++ (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
++ 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)
++{
++ 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));
++
++}
++
++void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *ptt,
++ const yaffs_ExtendedTags *t)
++{
++ 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 */
++ 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;
++ else
++ ptt->byteCount = 0;
++ }
++
++ 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
++ {
++ yaffs_ECCCalculateOther((unsigned char *)&pt->t,
++ sizeof(yaffs_PackedTags2TagsPart),
++ &pt->ecc);
++ }
++#endif
++}
++
++
++void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t,
++ yaffs_PackedTags2TagsPart *ptt)
++{
++
++ memset(t, 0, sizeof(yaffs_ExtendedTags));
++
++ yaffs_InitialiseTags(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;
++
++ /* 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 (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);
++
++}
++
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_packedtags2.h linux-2.6.25/fs/yaffs2/yaffs_packedtags2.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_packedtags2.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_packedtags2.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,43 @@
++/*
++ * 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.
++ */
++
++/* This is used to pack YAFFS2 tags, not YAFFS1tags. */
++
++#ifndef __YAFFS_PACKEDTAGS2_H__
++#define __YAFFS_PACKEDTAGS2_H__
++
++#include "yaffs_guts.h"
++#include "yaffs_ecc.h"
++
++typedef struct {
++ unsigned sequenceNumber;
++ unsigned objectId;
++ unsigned chunkId;
++ unsigned byteCount;
++} yaffs_PackedTags2TagsPart;
++
++typedef struct {
++ yaffs_PackedTags2TagsPart t;
++ yaffs_ECCOther ecc;
++} 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);
++
++/* 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
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_qsort.c linux-2.6.25/fs/yaffs2/yaffs_qsort.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_qsort.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_qsort.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,163 @@
++/*
++ * Copyright (c) 1992, 1993
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#include "yportenv.h"
++/* #include <linux/string.h> */
++
++/*
++ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
++ */
++#define swapcode(TYPE, parmi, parmj, n) do { \
++ long i = (n) / sizeof (TYPE); \
++ register TYPE *pi = (TYPE *) (parmi); \
++ register TYPE *pj = (TYPE *) (parmj); \
++ do { \
++ register TYPE t = *pi; \
++ *pi++ = *pj; \
++ *pj++ = t; \
++ } 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;
++
++static __inline void
++swapfunc(char *a, char *b, int n, int swaptype)
++{
++ if (swaptype <= 1)
++ swapcode(long, a, b, n);
++ else
++ swapcode(char, a, b, n);
++}
++
++#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); \
++} while (0)
++
++#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
++
++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));
++}
++
++#ifndef min
++#define min(a, b) (((a) < (b)) ? (a) : (b))
++#endif
++
++void
++yaffs_qsort(void *aa, size_t n, size_t es,
++ int (*cmp)(const void *, const void *))
++{
++ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
++ int d, r, swaptype, swap_cnt;
++ register char *a = aa;
++
++loop: SWAPINIT(a, es);
++ swap_cnt = 0;
++ if (n < 7) {
++ 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)
++ yswap(pl, pl - es);
++ return;
++ }
++ pm = (char *)a + (n / 2) * es;
++ if (n > 7) {
++ pl = (char *)a;
++ pn = (char *)a + (n - 1) * es;
++ if (n > 40) {
++ d = (n / 8) * es;
++ pl = med3(pl, pl + d, pl + 2 * d, cmp);
++ pm = med3(pm - d, pm, pm + d, cmp);
++ pn = med3(pn - 2 * d, pn - d, pn, cmp);
++ }
++ pm = med3(pl, pm, pn, cmp);
++ }
++ yswap(a, pm);
++ pa = pb = (char *)a + es;
++
++ pc = pd = (char *)a + (n - 1) * es;
++ for (;;) {
++ while (pb <= pc && (r = cmp(pb, a)) <= 0) {
++ if (r == 0) {
++ swap_cnt = 1;
++ yswap(pa, pb);
++ pa += es;
++ }
++ pb += es;
++ }
++ while (pb <= pc && (r = cmp(pc, a)) >= 0) {
++ if (r == 0) {
++ swap_cnt = 1;
++ yswap(pc, pd);
++ pd -= es;
++ }
++ pc -= es;
++ }
++ if (pb > pc)
++ break;
++ yswap(pb, pc);
++ swap_cnt = 1;
++ pb += es;
++ pc -= es;
++ }
++ if (swap_cnt == 0) { /* Switch to insertion sort */
++ 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)
++ yswap(pl, pl - es);
++ return;
++ }
++
++ pn = (char *)a + n * es;
++ r = min(pa - (char *)a, pb - pa);
++ vecswap(a, pb - r, r);
++ r = min((long)(pd - pc), (long)(pn - pd - es));
++ vecswap(pb, pn - r, r);
++ r = pb - pa;
++ if (r > es)
++ yaffs_qsort(a, r / es, es, cmp);
++ r = pd - pc;
++ if (r > es) {
++ /* Iterate rather than recurse to save stack space */
++ a = pn - r;
++ n = r / es;
++ goto loop;
++ }
++/* yaffs_qsort(pn - r, r / es, es, cmp);*/
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_qsort.h linux-2.6.25/fs/yaffs2/yaffs_qsort.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_qsort.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_qsort.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,23 @@
++/*
++ * 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_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 *));
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_tagscompat.c linux-2.6.25/fs/yaffs2/yaffs_tagscompat.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_tagscompat.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_tagscompat.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,541 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#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);
++#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);
++#endif
++
++static const char yaffs_countBitsTable[256] = {
++ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
++ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
++ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
++ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
++ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
++ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
++ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
++ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
++};
++
++int yaffs_CountBits(__u8 x)
++{
++ int retVal;
++ retVal = yaffs_countBitsTable[x];
++ return retVal;
++}
++
++/********** Tags ECC calculations *********/
++
++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)
++{
++ /* Calculate an ecc */
++
++ unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes;
++ unsigned i, j;
++ unsigned ecc = 0;
++ unsigned bit = 0;
++
++ tags->ecc = 0;
++
++ for (i = 0; i < 8; i++) {
++ for (j = 1; j & 0xff; j <<= 1) {
++ bit++;
++ if (b[i] & j)
++ ecc ^= bit;
++ }
++ }
++
++ tags->ecc = ecc;
++
++}
++
++int yaffs_CheckECCOnTags(yaffs_Tags *tags)
++{
++ unsigned ecc = tags->ecc;
++
++ yaffs_CalcTagsECC(tags);
++
++ ecc ^= tags->ecc;
++
++ if (ecc && ecc <= 64) {
++ /* TODO: Handle the failure better. Retire? */
++ unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes;
++
++ ecc--;
++
++ b[ecc / 8] ^= (1 << (ecc & 7));
++
++ /* Now recvalc the ecc */
++ yaffs_CalcTagsECC(tags);
++
++ return 1; /* recovered error */
++ } else if (ecc) {
++ /* Wierd ecc failure value */
++ /* TODO Need to do somethiong here */
++ return -1; /* unrecovered error */
++ }
++
++ return 0;
++}
++
++/********** Tags **********/
++
++static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr,
++ yaffs_Tags *tagsPtr)
++{
++ yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
++
++ yaffs_CalcTagsECC(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];
++}
++
++static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,
++ yaffs_Tags *tagsPtr)
++{
++ yaffs_TagsUnion *tu = (yaffs_TagsUnion *) 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;
++
++ result = yaffs_CheckECCOnTags(tagsPtr);
++ if (result > 0)
++ dev->tagsEccFixed++;
++ else if (result < 0)
++ dev->tagsEccUnfixed++;
++}
++
++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)
++{
++ if (chunkInNAND < dev->startBlock * dev->nChunksPerBlock) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR("**>> yaffs chunk %d is not valid" TENDSTR),
++ chunkInNAND));
++ return YAFFS_FAIL;
++ }
++
++ dev->nPageWrites++;
++ return dev->writeChunkToNAND(dev, chunkInNAND, data, spare);
++}
++
++static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
++ int chunkInNAND,
++ __u8 *data,
++ yaffs_Spare *spare,
++ yaffs_ECCResult *eccResult,
++ int doErrorCorrection)
++{
++ int retVal;
++ yaffs_Spare localSpare;
++
++ dev->nPageReads++;
++
++ if (!spare && data) {
++ /* If we don't have a real spare, then we use a local one. */
++ /* Need this for the calculation of the ecc */
++ spare = &localSpare;
++ }
++
++ if (!dev->useNANDECC) {
++ retVal = dev->readChunkFromNAND(dev, chunkInNAND, data, spare);
++ if (data && doErrorCorrection) {
++ /* Do ECC correction */
++ /* Todo handle any errors */
++ int eccResult1, eccResult2;
++ __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);
++
++ if (eccResult1 > 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>yaffs ecc error fix performed on chunk %d:0"
++ TENDSTR), chunkInNAND));
++ dev->eccFixed++;
++ } else if (eccResult1 < 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>yaffs ecc error unfixed on chunk %d:0"
++ TENDSTR), chunkInNAND));
++ dev->eccUnfixed++;
++ }
++
++ if (eccResult2 > 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>yaffs ecc error fix performed on chunk %d:1"
++ TENDSTR), chunkInNAND));
++ dev->eccFixed++;
++ } else if (eccResult2 < 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>yaffs ecc error unfixed on chunk %d:1"
++ TENDSTR), chunkInNAND));
++ dev->eccUnfixed++;
++ }
++
++ if (eccResult1 || eccResult2) {
++ /* We had a data problem on this page */
++ yaffs_HandleReadDataError(dev, chunkInNAND);
++ }
++
++ if (eccResult1 < 0 || eccResult2 < 0)
++ *eccResult = YAFFS_ECC_RESULT_UNFIXED;
++ else if (eccResult1 > 0 || eccResult2 > 0)
++ *eccResult = YAFFS_ECC_RESULT_FIXED;
++ else
++ *eccResult = YAFFS_ECC_RESULT_NO_ERROR;
++ }
++ } else {
++ /* Must allocate enough memory for spare+2*sizeof(int) */
++ /* for ecc results from device. */
++ struct yaffs_NANDSpare 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) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>mtd ecc error fix performed on chunk %d:0"
++ TENDSTR), chunkInNAND));
++ } else if (nspare.eccres1 < 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>mtd ecc error unfixed on chunk %d:0"
++ TENDSTR), chunkInNAND));
++ }
++
++ if (nspare.eccres2 > 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>mtd ecc error fix performed on chunk %d:1"
++ TENDSTR), chunkInNAND));
++ } else if (nspare.eccres2 < 0) {
++ T(YAFFS_TRACE_ERROR,
++ (TSTR
++ ("**>>mtd ecc error unfixed on chunk %d:1"
++ TENDSTR), chunkInNAND));
++ }
++
++ if (nspare.eccres1 || nspare.eccres2) {
++ /* We had a data problem on this page */
++ yaffs_HandleReadDataError(dev, chunkInNAND);
++ }
++
++ if (nspare.eccres1 < 0 || nspare.eccres2 < 0)
++ *eccResult = YAFFS_ECC_RESULT_UNFIXED;
++ else if (nspare.eccres1 > 0 || nspare.eccres2 > 0)
++ *eccResult = YAFFS_ECC_RESULT_FIXED;
++ else
++ *eccResult = YAFFS_ECC_RESULT_NO_ERROR;
++
++ }
++ }
++ return retVal;
++}
++
++#ifdef NOTYET
++static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
++ int chunkInNAND)
++{
++ 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->readChunkFromNAND(dev, chunkInNAND, data, (yaffs_Spare *) spare);
++
++ if (!init) {
++ memset(cmpbuf, 0xff, YAFFS_BYTES_PER_CHUNK);
++ init = 1;
++ }
++
++ if (memcmp(cmpbuf, data, YAFFS_BYTES_PER_CHUNK))
++ return YAFFS_FAIL;
++ if (memcmp(cmpbuf, spare, 16))
++ return YAFFS_FAIL;
++
++ return YAFFS_OK;
++
++}
++#endif
++
++/*
++ * Functions for robustisizing
++ */
++
++static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND)
++{
++ int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
++
++ /* Mark the block for retirement */
++ yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
++ T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
++ (TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND));
++
++ /* TODO:
++ * Just do a garbage collection on the affected block
++ * then retire the block
++ * NB recursion
++ */
++}
++
++#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)
++{
++ int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
++
++ /* Mark the block for retirement */
++ yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
++ /* Delete the chunk */
++ yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
++}
++
++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 ||
++ 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->ecc1[0] != s1->ecc1[0] ||
++ s0->ecc1[1] != s1->ecc1[1] ||
++ s0->ecc1[2] != s1->ecc1[2] ||
++ s0->ecc2[0] != s1->ecc2[0] ||
++ s0->ecc2[1] != s1->ecc2[1] || s0->ecc2[2] != s1->ecc2[2]) {
++ return 0;
++ }
++
++ return 1;
++}
++#endif /* NOTYET */
++
++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)
++ spare.pageStatus = 0;
++ else {
++ tags.objectId = eTags->objectId;
++ tags.chunkId = eTags->chunkId;
++
++ 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)
++ yaffs_CalcECC(data, &spare);
++
++ yaffs_LoadTagsIntoSpare(&spare, &tags);
++
++ }
++
++ return yaffs_WriteChunkToNAND(dev, chunkInNAND, data, &spare);
++}
++
++int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
++ int chunkInNAND,
++ __u8 *data,
++ yaffs_ExtendedTags *eTags)
++{
++
++ yaffs_Spare spare;
++ yaffs_Tags tags;
++ yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_UNKNOWN;
++
++ static yaffs_Spare spareFF;
++ static int init;
++
++ if (!init) {
++ memset(&spareFF, 0xFF, sizeof(spareFF));
++ init = 1;
++ }
++
++ if (yaffs_ReadChunkFromNAND
++ (dev, chunkInNAND, data, &spare, &eccResult, 1)) {
++ /* eTags may be NULL */
++ if (eTags) {
++
++ int deleted =
++ (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0;
++
++ eTags->chunkDeleted = deleted;
++ eTags->eccResult = eccResult;
++ eTags->blockBad = 0; /* We're reading it */
++ /* therefore it is not a bad block */
++ eTags->chunkUsed =
++ (memcmp(&spareFF, &spare, sizeof(spareFF)) !=
++ 0) ? 1 : 0;
++
++ if (eTags->chunkUsed) {
++ yaffs_GetTagsFromSpare(dev, &spare, &tags);
++
++ eTags->objectId = tags.objectId;
++ eTags->chunkId = tags.chunkId;
++ eTags->byteCount = tags.byteCountLSB;
++
++ if (dev->nDataBytesPerChunk >= 1024)
++ eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
++
++ eTags->serialNumber = tags.serialNumber;
++ }
++ }
++
++ return YAFFS_OK;
++ } else {
++ return YAFFS_FAIL;
++ }
++}
++
++int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
++ int blockInNAND)
++{
++
++ yaffs_Spare spare;
++
++ memset(&spare, 0xff, sizeof(yaffs_Spare));
++
++ spare.blockStatus = 'Y';
++
++ yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL,
++ &spare);
++ yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1,
++ NULL, &spare);
++
++ return YAFFS_OK;
++
++}
++
++int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
++ int blockNo,
++ yaffs_BlockState *state,
++ __u32 *sequenceNumber)
++{
++
++ yaffs_Spare spare0, spare1;
++ static yaffs_Spare spareFF;
++ static int init;
++ yaffs_ECCResult dummy;
++
++ if (!init) {
++ memset(&spareFF, 0xFF, sizeof(spareFF));
++ init = 1;
++ }
++
++ *sequenceNumber = 0;
++
++ yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock, NULL,
++ &spare0, &dummy, 1);
++ yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock + 1, NULL,
++ &spare1, &dummy, 1);
++
++ if (yaffs_CountBits(spare0.blockStatus & spare1.blockStatus) < 7)
++ *state = YAFFS_BLOCK_STATE_DEAD;
++ else if (memcmp(&spareFF, &spare0, sizeof(spareFF)) == 0)
++ *state = YAFFS_BLOCK_STATE_EMPTY;
++ else
++ *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
++
++ return YAFFS_OK;
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_tagscompat.h linux-2.6.25/fs/yaffs2/yaffs_tagscompat.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_tagscompat.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_tagscompat.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,39 @@
++/*
++ * 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_TAGSCOMPAT_H__
++#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_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
++ int blockNo);
++int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
++ int blockNo,
++ yaffs_BlockState *state,
++ __u32 *sequenceNumber);
++
++void yaffs_CalcTagsECC(yaffs_Tags *tags);
++int yaffs_CheckECCOnTags(yaffs_Tags *tags);
++int yaffs_CountBits(__u8 byte);
++
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_tagsvalidity.c linux-2.6.25/fs/yaffs2/yaffs_tagsvalidity.c
+--- linux-2.6.25_original/fs/yaffs2/yaffs_tagsvalidity.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_tagsvalidity.c 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,28 @@
++/*
++ * 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 General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "yaffs_tagsvalidity.h"
++
++void yaffs_InitialiseTags(yaffs_ExtendedTags *tags)
++{
++ memset(tags, 0, sizeof(yaffs_ExtendedTags));
++ tags->validMarker0 = 0xAAAAAAAA;
++ tags->validMarker1 = 0x55555555;
++}
++
++int yaffs_ValidateTags(yaffs_ExtendedTags *tags)
++{
++ return (tags->validMarker0 == 0xAAAAAAAA &&
++ tags->validMarker1 == 0x55555555);
++
++}
+diff -Naur linux-2.6.25_original/fs/yaffs2/yaffs_tagsvalidity.h linux-2.6.25/fs/yaffs2/yaffs_tagsvalidity.h
+--- linux-2.6.25_original/fs/yaffs2/yaffs_tagsvalidity.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yaffs_tagsvalidity.h 2009-05-25 11:14:58.000000000 +0530
+@@ -0,0 +1,24 @@
++/*
++ * 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_TAGS_VALIDITY_H__
++#define __YAFFS_TAGS_VALIDITY_H__
++
++#include "yaffs_guts.h"
++
++void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
++int yaffs_ValidateTags(yaffs_ExtendedTags *tags);
++#endif
+diff -Naur linux-2.6.25_original/fs/yaffs2/yportenv.h linux-2.6.25/fs/yaffs2/yportenv.h
+--- linux-2.6.25_original/fs/yaffs2/yportenv.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/fs/yaffs2/yportenv.h 2009-06-05 09:57:49.000000000 +0530
+@@ -0,0 +1,204 @@
++/*
++ * 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 __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__
++
++#include "moduleconfig.h"
++
++/* Linux kernel */
++
++#include <linux/version.h>
++#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>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++
++#define YCHAR char
++#define YUCHAR unsigned char
++#define _Y(x) x
++#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
++
++#define YAFFS_LOSTNFOUND_NAME "lost+found"
++#define YAFFS_LOSTNFOUND_PREFIX "obj"
++
++/* #define YPRINTF(x) printk x */
++#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. */
++#define YYIELD() schedule()
++
++#define YAFFS_ROOT_MODE 0666
++#define YAFFS_LOSTNFOUND_MODE 0666
++
++#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
++#define Y_CURRENT_TIME CURRENT_TIME
++#define Y_TIME_CONVERT(x) (x)
++#endif
++
++#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...) \
++ 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; })
++
++#elif defined CONFIG_YAFFS_DIRECT
++
++#define MTD_VERSION_CODE MTD_VERSION(2, 6, 22)
++
++/* Direct interface */
++#include "ydirectenv.h"
++
++#elif defined CONFIG_YAFFS_UTIL
++
++/* Stuff for YAFFS utilities */
++
++#include "stdlib.h"
++#include "stdio.h"
++#include "string.h"
++
++#include "devextras.h"
++
++#define YMALLOC(x) malloc(x)
++#define YFREE(x) free(x)
++#define YMALLOC_ALT(x) malloc(x)
++#define YFREE_ALT(x) free(x)
++
++#define YCHAR char
++#define YUCHAR unsigned char
++#define _Y(x) x
++#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
++
++/* #define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) */
++/* #define YALERT(s) YINFO(s) */
++
++#define TENDSTR "\n"
++#define TSTR(x) x
++#define TOUT(p) printf p
++
++#define YAFFS_LOSTNFOUND_NAME "lost+found"
++#define YAFFS_LOSTNFOUND_PREFIX "obj"
++/* #define YPRINTF(x) printf x */
++
++#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)
++
++#else
++/* Should have specified a configuration type */
++#error Unknown configuration
++
++#endif
++
++/* see yaffs_fs.c */
++extern unsigned int yaffs_traceMask;
++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_ERROR 0x40000000
++#define YAFFS_TRACE_BUG 0x80000000
++#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 { } while (0)
++
++#ifndef YBUG
++#define YBUG() do {T(YAFFS_TRACE_BUG, (TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR), __LINE__)); } while (0)
++#endif
++
++#endif
+diff -Naur linux-2.6.25_original/include/asm-arm/arch-pxa/regulus.h linux-2.6.25/include/asm-arm/arch-pxa/regulus.h
+--- linux-2.6.25_original/include/asm-arm/arch-pxa/regulus.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/asm-arm/arch-pxa/regulus.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,15 @@
++/*
++ * linux/include/asm-arm/arch-pxa/regulus.h
++ *
++ * Author: Nicolas Pitre
++ * Created: Nov 14, 2002
++ * Copyright: MontaVista Software Inc.
++ *
++ * 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 ASM_ARCH_REGULUS_H
++#define ASM_ARCH_REGULUS_H
++#endif
+diff -Naur linux-2.6.25_original/include/asm-arm/arch-pxa/uncompress.h linux-2.6.25/include/asm-arm/arch-pxa/uncompress.h
+--- linux-2.6.25_original/include/asm-arm/arch-pxa/uncompress.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/asm-arm/arch-pxa/uncompress.h 2009-05-16 18:43:58.000000000 +0530
+@@ -14,7 +14,8 @@
+
+ #define __REG(x) ((volatile unsigned long *)x)
+
+-#define UART FFUART
++//#define UART FFUART
++#define UART STUART
+
+
+ static inline void putc(char c)
+diff -Naur linux-2.6.25_original/include/asm-arm/kgdb.h linux-2.6.25/include/asm-arm/kgdb.h
+--- linux-2.6.25_original/include/asm-arm/kgdb.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/asm-arm/kgdb.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,92 @@
++/*
++ * include/asm-arm/kgdb.h
++ *
++ * ARM KGDB support
++ *
++ * Author: Deepak Saxena <dsaxena@mvista.com>
++ *
++ * Copyright (C) 2002 MontaVista Software Inc.
++ *
++ */
++
++#ifndef __ASM_KGDB_H__
++#define __ASM_KGDB_H__
++
++#include <linux/config.h>
++#include <asm/ptrace.h>
++#include <asm-generic/kgdb.h>
++
++
++/*
++ * GDB assumes that we're a user process being debugged, so
++ * it will send us an SWI command to write into memory as the
++ * debug trap. When an SWI occurs, the next instruction addr is
++ * placed into R14_svc before jumping to the vector trap.
++ * This doesn't work for kernel debugging as we are already in SVC
++ * we would loose the kernel's LR, which is a bad thing. This
++ * is bad thing.
++ *
++ * By doing this as an undefined instruction trap, we force a mode
++ * switch from SVC to UND mode, allowing us to save full kernel state.
++ *
++ * We also define a KGDB_COMPILED_BREAK which can be used to compile
++ * in breakpoints. This is important for things like sysrq-G and for
++ * the initial breakpoint from trap_init().
++ *
++ * Note to ARM HW designers: Add real trap support like SH && PPC to
++ * make our lives much much simpler. :)
++ */
++#define BREAK_INSTR_SIZE 4
++#define GDB_BREAKINST 0xef9f0001
++#define KGDB_BREAKINST 0xe7ffdefe
++#define KGDB_COMPILED_BREAK 0xe7ffdeff
++#define CACHE_FLUSH_IS_SAFE 1
++
++#ifndef __ASSEMBLY__
++
++#define BREAKPOINT() asm(".word 0xe7ffdeff")
++
++
++extern void kgdb_handle_bus_error(void);
++extern int kgdb_fault_expected;
++#endif /* !__ASSEMBLY__ */
++
++/*
++ * From Amit S. Kale:
++ *
++ * In the register packet, words 0-15 are R0 to R10, FP, IP, SP, LR, PC. But
++ * Register 16 isn't cpsr. GDB passes CPSR in word 25. There are 9 words in
++ * between which are unused. Passing only 26 words to gdb is sufficient.
++ * GDB can figure out that floating point registers are not passed.
++ * GDB_MAX_REGS should be 26.
++ */
++#define GDB_MAX_REGS (26)
++
++#define KGDB_MAX_NO_CPUS 1
++#define BUFMAX 400
++#define NUMREGBYTES (GDB_MAX_REGS << 2)
++#define NUMCRITREGBYTES (32 << 2)
++
++#define _R0 0
++#define _R1 1
++#define _R2 2
++#define _R3 3
++#define _R4 4
++#define _R5 5
++#define _R6 6
++#define _R7 7
++#define _R8 8
++#define _R9 9
++#define _R10 10
++#define _FP 11
++#define _IP 12
++#define _SP 13
++#define _LR 14
++#define _PC 15
++#define _CPSR (GDB_MAX_REGS - 1)
++
++/* So that we can denote the end of a frame for tracing, in the simple
++ * case. */
++#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC,_SP,func)
++
++#endif /* __ASM_KGDB_H__ */
+diff -Naur linux-2.6.25_original/include/asm-arm/system.h linux-2.6.25/include/asm-arm/system.h
+--- linux-2.6.25_original/include/asm-arm/system.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/asm-arm/system.h 2009-05-16 18:43:58.000000000 +0530
+@@ -378,6 +378,50 @@
+ #include <asm-generic/cmpxchg.h>
+ #endif
+
++#define __HAVE_ARCH_CMPXCHG 1
++
++#include <asm/types.h>
++
++static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
++ unsigned long new)
++{
++ u32 retval;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ retval = *m;
++ if (retval == old)
++ *m = new;
++ local_irq_restore(flags); /* implies memory barrier */
++
++ return retval;
++}
++
++/* This function doesn't exist, so you'll get a linker error
++ if something tries to do an invalid cmpxchg(). */
++extern void __cmpxchg_called_with_bad_pointer(void);
++
++static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
++ unsigned long new, int size)
++{
++ switch (size) {
++ case 4:
++ return __cmpxchg_u32(ptr, old, new);
++ }
++ __cmpxchg_called_with_bad_pointer();
++ return old;
++}
++#ifdef cmpxcfg
++#undef cmpxcfg
++#define cmpxchg(ptr,o,n) \
++ ({ \
++ __typeof__(*(ptr)) _o_ = (o); \
++ __typeof__(*(ptr)) _n_ = (n); \
++ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
++ (unsigned long)_n_, sizeof(*(ptr))); \
++ })
++#endif
++
+ #endif /* __ASSEMBLY__ */
+
+ #define arch_align_stack(x) (x)
+diff -Naur linux-2.6.25_original/include/asm-generic/cmpxchg.h linux-2.6.25/include/asm-generic/cmpxchg.h
+--- linux-2.6.25_original/include/asm-generic/cmpxchg.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/asm-generic/cmpxchg.h 2009-05-16 18:43:58.000000000 +0530
+@@ -18,5 +18,4 @@
+ */
+ #define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n))
+ #define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
+-
+ #endif
+diff -Naur linux-2.6.25_original/include/asm-generic/kgdb.h linux-2.6.25/include/asm-generic/kgdb.h
+--- linux-2.6.25_original/include/asm-generic/kgdb.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/asm-generic/kgdb.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,35 @@
++/*
++ * include/asm-generic/kgdb.h
++ *
++ * This provides the assembly level information so that KGDB can provide
++ * a GDB that has been patched with enough information to know to stop
++ * trying to unwind the function.
++ *
++ * Author: Tom Rini <trini@kernel.crashing.org>
++ *
++ * 2005 (c) MontaVista Software, Inc. This file is licensed under the terms
++ * of the GNU General Public License version 2. This program is licensed
++ * "as is" without any warranty of any kind, whether express or implied.
++ */
++
++#ifndef __ASM_GENERIC_KGDB_H__
++#define __ASM_GENERIC_KGDB_H__
++
++#include <linux/dwarf2-lang.h>
++#ifdef __ASSEMBLY__
++#ifdef CONFIG_KGDB
++/* This MUST be put at the end of a given assembly function */
++#define __CFI_END_FRAME(pc,sp,func) \
++CAT3(.Lend_,func,:) \
++ CFI_preamble(func,pc,0x1,-DATA_ALIGN_FACTOR) \
++ CFA_define_reference(sp, 0) \
++ CFA_undefine_reg(pc) \
++ CFI_postamble() \
++ FDE_preamble(func,func,CAT3(.Lend,_,func)) \
++ FDE_postamble()
++#else
++#define __CFI_END_FRAME(pc,sp,fn)
++#endif /* CONFIG_KGDB */
++#endif /* __ASSEMBLY__ */
++#endif /* __ASM_GENERIC_KGDB_H__ */
++
+diff -Naur linux-2.6.25_original/include/linux/config.h linux-2.6.25/include/linux/config.h
+--- linux-2.6.25_original/include/linux/config.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/config.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,8 @@
++#ifndef _LINUX_CONFIG_H
++#define _LINUX_CONFIG_H
++/* This file is no longer in use and kept only for backward compatibility.
++ * autoconf.h is now included via -imacros on the commandline
++ */
++#include <linux/autoconf.h>
++
++#endif
+diff -Naur linux-2.6.25_original/include/linux/dwarf2-defs.h linux-2.6.25/include/linux/dwarf2-defs.h
+--- linux-2.6.25_original/include/linux/dwarf2-defs.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/dwarf2-defs.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,515 @@
++#ifndef _ELF_DWARF_H
++/* Machine generated from dwarf2.h by scripts/dwarfh.awk */
++#define _ELF_DWARF2_H
++#define DW_TAG_padding 0x00
++#define DW_TAG_array_type 0x01
++#define DW_TAG_class_type 0x02
++#define DW_TAG_entry_point 0x03
++#define DW_TAG_enumeration_type 0x04
++#define DW_TAG_formal_parameter 0x05
++#define DW_TAG_imported_declaration 0x08
++#define DW_TAG_label 0x0a
++#define DW_TAG_lexical_block 0x0b
++#define DW_TAG_member 0x0d
++#define DW_TAG_pointer_type 0x0f
++#define DW_TAG_reference_type 0x10
++#define DW_TAG_compile_unit 0x11
++#define DW_TAG_string_type 0x12
++#define DW_TAG_structure_type 0x13
++#define DW_TAG_subroutine_type 0x15
++#define DW_TAG_typedef 0x16
++#define DW_TAG_union_type 0x17
++#define DW_TAG_unspecified_parameters 0x18
++#define DW_TAG_variant 0x19
++#define DW_TAG_common_block 0x1a
++#define DW_TAG_common_inclusion 0x1b
++#define DW_TAG_inheritance 0x1c
++#define DW_TAG_inlined_subroutine 0x1d
++#define DW_TAG_module 0x1e
++#define DW_TAG_ptr_to_member_type 0x1f
++#define DW_TAG_set_type 0x20
++#define DW_TAG_subrange_type 0x21
++#define DW_TAG_with_stmt 0x22
++#define DW_TAG_access_declaration 0x23
++#define DW_TAG_base_type 0x24
++#define DW_TAG_catch_block 0x25
++#define DW_TAG_const_type 0x26
++#define DW_TAG_constant 0x27
++#define DW_TAG_enumerator 0x28
++#define DW_TAG_file_type 0x29
++#define DW_TAG_friend 0x2a
++#define DW_TAG_namelist 0x2b
++#define DW_TAG_namelist_item 0x2c
++#define DW_TAG_packed_type 0x2d
++#define DW_TAG_subprogram 0x2e
++#define DW_TAG_template_type_param 0x2f
++#define DW_TAG_template_value_param 0x30
++#define DW_TAG_thrown_type 0x31
++#define DW_TAG_try_block 0x32
++#define DW_TAG_variant_part 0x33
++#define DW_TAG_variable 0x34
++#define DW_TAG_volatile_type 0x35
++#define DW_TAG_dwarf_procedure 0x36
++#define DW_TAG_restrict_type 0x37
++#define DW_TAG_interface_type 0x38
++#define DW_TAG_namespace 0x39
++#define DW_TAG_imported_module 0x3a
++#define DW_TAG_unspecified_type 0x3b
++#define DW_TAG_partial_unit 0x3c
++#define DW_TAG_imported_unit 0x3d
++#define DW_TAG_MIPS_loop 0x4081
++#define DW_TAG_HP_array_descriptor 0x4090
++#define DW_TAG_format_label 0x4101
++#define DW_TAG_function_template 0x4102
++#define DW_TAG_class_template 0x4103
++#define DW_TAG_GNU_BINCL 0x4104
++#define DW_TAG_GNU_EINCL 0x4105
++#define DW_TAG_upc_shared_type 0x8765
++#define DW_TAG_upc_strict_type 0x8766
++#define DW_TAG_upc_relaxed_type 0x8767
++#define DW_TAG_PGI_kanji_type 0xA000
++#define DW_TAG_PGI_interface_block 0xA020
++#define DW_TAG_lo_user 0x4080
++#define DW_TAG_hi_user 0xffff
++#define DW_children_no 0
++#define DW_children_yes 1
++#define DW_FORM_addr 0x01
++#define DW_FORM_block2 0x03
++#define DW_FORM_block4 0x04
++#define DW_FORM_data2 0x05
++#define DW_FORM_data4 0x06
++#define DW_FORM_data8 0x07
++#define DW_FORM_string 0x08
++#define DW_FORM_block 0x09
++#define DW_FORM_block1 0x0a
++#define DW_FORM_data1 0x0b
++#define DW_FORM_flag 0x0c
++#define DW_FORM_sdata 0x0d
++#define DW_FORM_strp 0x0e
++#define DW_FORM_udata 0x0f
++#define DW_FORM_ref_addr 0x10
++#define DW_FORM_ref1 0x11
++#define DW_FORM_ref2 0x12
++#define DW_FORM_ref4 0x13
++#define DW_FORM_ref8 0x14
++#define DW_FORM_ref_udata 0x15
++#define DW_FORM_indirect 0x16
++#define DW_AT_sibling 0x01
++#define DW_AT_location 0x02
++#define DW_AT_name 0x03
++#define DW_AT_ordering 0x09
++#define DW_AT_subscr_data 0x0a
++#define DW_AT_byte_size 0x0b
++#define DW_AT_bit_offset 0x0c
++#define DW_AT_bit_size 0x0d
++#define DW_AT_element_list 0x0f
++#define DW_AT_stmt_list 0x10
++#define DW_AT_low_pc 0x11
++#define DW_AT_high_pc 0x12
++#define DW_AT_language 0x13
++#define DW_AT_member 0x14
++#define DW_AT_discr 0x15
++#define DW_AT_discr_value 0x16
++#define DW_AT_visibility 0x17
++#define DW_AT_import 0x18
++#define DW_AT_string_length 0x19
++#define DW_AT_common_reference 0x1a
++#define DW_AT_comp_dir 0x1b
++#define DW_AT_const_value 0x1c
++#define DW_AT_containing_type 0x1d
++#define DW_AT_default_value 0x1e
++#define DW_AT_inline 0x20
++#define DW_AT_is_optional 0x21
++#define DW_AT_lower_bound 0x22
++#define DW_AT_producer 0x25
++#define DW_AT_prototyped 0x27
++#define DW_AT_return_addr 0x2a
++#define DW_AT_start_scope 0x2c
++#define DW_AT_stride_size 0x2e
++#define DW_AT_upper_bound 0x2f
++#define DW_AT_abstract_origin 0x31
++#define DW_AT_accessibility 0x32
++#define DW_AT_address_class 0x33
++#define DW_AT_artificial 0x34
++#define DW_AT_base_types 0x35
++#define DW_AT_calling_convention 0x36
++#define DW_AT_count 0x37
++#define DW_AT_data_member_location 0x38
++#define DW_AT_decl_column 0x39
++#define DW_AT_decl_file 0x3a
++#define DW_AT_decl_line 0x3b
++#define DW_AT_declaration 0x3c
++#define DW_AT_discr_list 0x3d
++#define DW_AT_encoding 0x3e
++#define DW_AT_external 0x3f
++#define DW_AT_frame_base 0x40
++#define DW_AT_friend 0x41
++#define DW_AT_identifier_case 0x42
++#define DW_AT_macro_info 0x43
++#define DW_AT_namelist_items 0x44
++#define DW_AT_priority 0x45
++#define DW_AT_segment 0x46
++#define DW_AT_specification 0x47
++#define DW_AT_static_link 0x48
++#define DW_AT_type 0x49
++#define DW_AT_use_location 0x4a
++#define DW_AT_variable_parameter 0x4b
++#define DW_AT_virtuality 0x4c
++#define DW_AT_vtable_elem_location 0x4d
++#define DW_AT_allocated 0x4e
++#define DW_AT_associated 0x4f
++#define DW_AT_data_location 0x50
++#define DW_AT_stride 0x51
++#define DW_AT_entry_pc 0x52
++#define DW_AT_use_UTF8 0x53
++#define DW_AT_extension 0x54
++#define DW_AT_ranges 0x55
++#define DW_AT_trampoline 0x56
++#define DW_AT_call_column 0x57
++#define DW_AT_call_file 0x58
++#define DW_AT_call_line 0x59
++#define DW_AT_MIPS_fde 0x2001
++#define DW_AT_MIPS_loop_begin 0x2002
++#define DW_AT_MIPS_tail_loop_begin 0x2003
++#define DW_AT_MIPS_epilog_begin 0x2004
++#define DW_AT_MIPS_loop_unroll_factor 0x2005
++#define DW_AT_MIPS_software_pipeline_depth 0x2006
++#define DW_AT_MIPS_linkage_name 0x2007
++#define DW_AT_MIPS_stride 0x2008
++#define DW_AT_MIPS_abstract_name 0x2009
++#define DW_AT_MIPS_clone_origin 0x200a
++#define DW_AT_MIPS_has_inlines 0x200b
++#define DW_AT_HP_block_index 0x2000
++#define DW_AT_HP_unmodifiable 0x2001
++#define DW_AT_HP_actuals_stmt_list 0x2010
++#define DW_AT_HP_proc_per_section 0x2011
++#define DW_AT_HP_raw_data_ptr 0x2012
++#define DW_AT_HP_pass_by_reference 0x2013
++#define DW_AT_HP_opt_level 0x2014
++#define DW_AT_HP_prof_version_id 0x2015
++#define DW_AT_HP_opt_flags 0x2016
++#define DW_AT_HP_cold_region_low_pc 0x2017
++#define DW_AT_HP_cold_region_high_pc 0x2018
++#define DW_AT_HP_all_variables_modifiable 0x2019
++#define DW_AT_HP_linkage_name 0x201a
++#define DW_AT_HP_prof_flags 0x201b
++#define DW_AT_sf_names 0x2101
++#define DW_AT_src_info 0x2102
++#define DW_AT_mac_info 0x2103
++#define DW_AT_src_coords 0x2104
++#define DW_AT_body_begin 0x2105
++#define DW_AT_body_end 0x2106
++#define DW_AT_GNU_vector 0x2107
++#define DW_AT_VMS_rtnbeg_pd_address 0x2201
++#define DW_AT_upc_threads_scaled 0x3210
++#define DW_AT_PGI_lbase 0x3a00
++#define DW_AT_PGI_soffset 0x3a01
++#define DW_AT_PGI_lstride 0x3a02
++#define DW_AT_lo_user 0x2000 /* Implementation-defined range start. */
++#define DW_AT_hi_user 0x3ff0 /* Implementation-defined range end. */
++#define DW_OP_addr 0x03
++#define DW_OP_deref 0x06
++#define DW_OP_const1u 0x08
++#define DW_OP_const1s 0x09
++#define DW_OP_const2u 0x0a
++#define DW_OP_const2s 0x0b
++#define DW_OP_const4u 0x0c
++#define DW_OP_const4s 0x0d
++#define DW_OP_const8u 0x0e
++#define DW_OP_const8s 0x0f
++#define DW_OP_constu 0x10
++#define DW_OP_consts 0x11
++#define DW_OP_dup 0x12
++#define DW_OP_drop 0x13
++#define DW_OP_over 0x14
++#define DW_OP_pick 0x15
++#define DW_OP_swap 0x16
++#define DW_OP_rot 0x17
++#define DW_OP_xderef 0x18
++#define DW_OP_abs 0x19
++#define DW_OP_and 0x1a
++#define DW_OP_div 0x1b
++#define DW_OP_minus 0x1c
++#define DW_OP_mod 0x1d
++#define DW_OP_mul 0x1e
++#define DW_OP_neg 0x1f
++#define DW_OP_not 0x20
++#define DW_OP_or 0x21
++#define DW_OP_plus 0x22
++#define DW_OP_plus_uconst 0x23
++#define DW_OP_shl 0x24
++#define DW_OP_shr 0x25
++#define DW_OP_shra 0x26
++#define DW_OP_xor 0x27
++#define DW_OP_bra 0x28
++#define DW_OP_eq 0x29
++#define DW_OP_ge 0x2a
++#define DW_OP_gt 0x2b
++#define DW_OP_le 0x2c
++#define DW_OP_lt 0x2d
++#define DW_OP_ne 0x2e
++#define DW_OP_skip 0x2f
++#define DW_OP_lit0 0x30
++#define DW_OP_lit1 0x31
++#define DW_OP_lit2 0x32
++#define DW_OP_lit3 0x33
++#define DW_OP_lit4 0x34
++#define DW_OP_lit5 0x35
++#define DW_OP_lit6 0x36
++#define DW_OP_lit7 0x37
++#define DW_OP_lit8 0x38
++#define DW_OP_lit9 0x39
++#define DW_OP_lit10 0x3a
++#define DW_OP_lit11 0x3b
++#define DW_OP_lit12 0x3c
++#define DW_OP_lit13 0x3d
++#define DW_OP_lit14 0x3e
++#define DW_OP_lit15 0x3f
++#define DW_OP_lit16 0x40
++#define DW_OP_lit17 0x41
++#define DW_OP_lit18 0x42
++#define DW_OP_lit19 0x43
++#define DW_OP_lit20 0x44
++#define DW_OP_lit21 0x45
++#define DW_OP_lit22 0x46
++#define DW_OP_lit23 0x47
++#define DW_OP_lit24 0x48
++#define DW_OP_lit25 0x49
++#define DW_OP_lit26 0x4a
++#define DW_OP_lit27 0x4b
++#define DW_OP_lit28 0x4c
++#define DW_OP_lit29 0x4d
++#define DW_OP_lit30 0x4e
++#define DW_OP_lit31 0x4f
++#define DW_OP_reg0 0x50
++#define DW_OP_reg1 0x51
++#define DW_OP_reg2 0x52
++#define DW_OP_reg3 0x53
++#define DW_OP_reg4 0x54
++#define DW_OP_reg5 0x55
++#define DW_OP_reg6 0x56
++#define DW_OP_reg7 0x57
++#define DW_OP_reg8 0x58
++#define DW_OP_reg9 0x59
++#define DW_OP_reg10 0x5a
++#define DW_OP_reg11 0x5b
++#define DW_OP_reg12 0x5c
++#define DW_OP_reg13 0x5d
++#define DW_OP_reg14 0x5e
++#define DW_OP_reg15 0x5f
++#define DW_OP_reg16 0x60
++#define DW_OP_reg17 0x61
++#define DW_OP_reg18 0x62
++#define DW_OP_reg19 0x63
++#define DW_OP_reg20 0x64
++#define DW_OP_reg21 0x65
++#define DW_OP_reg22 0x66
++#define DW_OP_reg23 0x67
++#define DW_OP_reg24 0x68
++#define DW_OP_reg25 0x69
++#define DW_OP_reg26 0x6a
++#define DW_OP_reg27 0x6b
++#define DW_OP_reg28 0x6c
++#define DW_OP_reg29 0x6d
++#define DW_OP_reg30 0x6e
++#define DW_OP_reg31 0x6f
++#define DW_OP_breg0 0x70
++#define DW_OP_breg1 0x71
++#define DW_OP_breg2 0x72
++#define DW_OP_breg3 0x73
++#define DW_OP_breg4 0x74
++#define DW_OP_breg5 0x75
++#define DW_OP_breg6 0x76
++#define DW_OP_breg7 0x77
++#define DW_OP_breg8 0x78
++#define DW_OP_breg9 0x79
++#define DW_OP_breg10 0x7a
++#define DW_OP_breg11 0x7b
++#define DW_OP_breg12 0x7c
++#define DW_OP_breg13 0x7d
++#define DW_OP_breg14 0x7e
++#define DW_OP_breg15 0x7f
++#define DW_OP_breg16 0x80
++#define DW_OP_breg17 0x81
++#define DW_OP_breg18 0x82
++#define DW_OP_breg19 0x83
++#define DW_OP_breg20 0x84
++#define DW_OP_breg21 0x85
++#define DW_OP_breg22 0x86
++#define DW_OP_breg23 0x87
++#define DW_OP_breg24 0x88
++#define DW_OP_breg25 0x89
++#define DW_OP_breg26 0x8a
++#define DW_OP_breg27 0x8b
++#define DW_OP_breg28 0x8c
++#define DW_OP_breg29 0x8d
++#define DW_OP_breg30 0x8e
++#define DW_OP_breg31 0x8f
++#define DW_OP_regx 0x90
++#define DW_OP_fbreg 0x91
++#define DW_OP_bregx 0x92
++#define DW_OP_piece 0x93
++#define DW_OP_deref_size 0x94
++#define DW_OP_xderef_size 0x95
++#define DW_OP_nop 0x96
++#define DW_OP_push_object_address 0x97
++#define DW_OP_call2 0x98
++#define DW_OP_call4 0x99
++#define DW_OP_call_ref 0x9a
++#define DW_OP_GNU_push_tls_address 0xe0
++#define DW_OP_HP_unknown 0xe0
++#define DW_OP_HP_is_value 0xe1
++#define DW_OP_HP_fltconst4 0xe2
++#define DW_OP_HP_fltconst8 0xe3
++#define DW_OP_HP_mod_range 0xe4
++#define DW_OP_HP_unmod_range 0xe5
++#define DW_OP_HP_tls 0xe6
++#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
++#define DW_OP_hi_user 0xff /* Implementation-defined range end. */
++#define DW_ATE_void 0x0
++#define DW_ATE_address 0x1
++#define DW_ATE_boolean 0x2
++#define DW_ATE_complex_float 0x3
++#define DW_ATE_float 0x4
++#define DW_ATE_signed 0x5
++#define DW_ATE_signed_char 0x6
++#define DW_ATE_unsigned 0x7
++#define DW_ATE_unsigned_char 0x8
++#define DW_ATE_imaginary_float 0x9
++#define DW_ATE_HP_float80 0x80
++#define DW_ATE_HP_complex_float80 0x81
++#define DW_ATE_HP_float128 0x82
++#define DW_ATE_HP_complex_float128 0x83
++#define DW_ATE_HP_floathpintel 0x84
++#define DW_ATE_HP_imaginary_float80 0x85
++#define DW_ATE_HP_imaginary_float128 0x86
++#define DW_ATE_lo_user 0x80
++#define DW_ATE_hi_user 0xff
++#define DW_ORD_row_major 0
++#define DW_ORD_col_major 1
++#define DW_ACCESS_public 1
++#define DW_ACCESS_protected 2
++#define DW_ACCESS_private 3
++#define DW_VIS_local 1
++#define DW_VIS_exported 2
++#define DW_VIS_qualified 3
++#define DW_VIRTUALITY_none 0
++#define DW_VIRTUALITY_virtual 1
++#define DW_VIRTUALITY_pure_virtual 2
++#define DW_ID_case_sensitive 0
++#define DW_ID_up_case 1
++#define DW_ID_down_case 2
++#define DW_ID_case_insensitive 3
++#define DW_CC_normal 0x1
++#define DW_CC_program 0x2
++#define DW_CC_nocall 0x3
++#define DW_CC_lo_user 0x40
++#define DW_CC_hi_user 0xff
++#define DW_INL_not_inlined 0
++#define DW_INL_inlined 1
++#define DW_INL_declared_not_inlined 2
++#define DW_INL_declared_inlined 3
++#define DW_DSC_label 0
++#define DW_DSC_range 1
++#define DW_LNS_extended_op 0
++#define DW_LNS_copy 1
++#define DW_LNS_advance_pc 2
++#define DW_LNS_advance_line 3
++#define DW_LNS_set_file 4
++#define DW_LNS_set_column 5
++#define DW_LNS_negate_stmt 6
++#define DW_LNS_set_basic_block 7
++#define DW_LNS_const_add_pc 8
++#define DW_LNS_fixed_advance_pc 9
++#define DW_LNS_set_prologue_end 10
++#define DW_LNS_set_epilogue_begin 11
++#define DW_LNS_set_isa 12
++#define DW_LNE_end_sequence 1
++#define DW_LNE_set_address 2
++#define DW_LNE_define_file 3
++#define DW_LNE_HP_negate_is_UV_update 0x11
++#define DW_LNE_HP_push_context 0x12
++#define DW_LNE_HP_pop_context 0x13
++#define DW_LNE_HP_set_file_line_column 0x14
++#define DW_LNE_HP_set_routine_name 0x15
++#define DW_LNE_HP_set_sequence 0x16
++#define DW_LNE_HP_negate_post_semantics 0x17
++#define DW_LNE_HP_negate_function_exit 0x18
++#define DW_LNE_HP_negate_front_end_logical 0x19
++#define DW_LNE_HP_define_proc 0x20
++#define DW_CFA_advance_loc 0x40
++#define DW_CFA_offset 0x80
++#define DW_CFA_restore 0xc0
++#define DW_CFA_nop 0x00
++#define DW_CFA_set_loc 0x01
++#define DW_CFA_advance_loc1 0x02
++#define DW_CFA_advance_loc2 0x03
++#define DW_CFA_advance_loc4 0x04
++#define DW_CFA_offset_extended 0x05
++#define DW_CFA_restore_extended 0x06
++#define DW_CFA_undefined 0x07
++#define DW_CFA_same_value 0x08
++#define DW_CFA_register 0x09
++#define DW_CFA_remember_state 0x0a
++#define DW_CFA_restore_state 0x0b
++#define DW_CFA_def_cfa 0x0c
++#define DW_CFA_def_cfa_register 0x0d
++#define DW_CFA_def_cfa_offset 0x0e
++#define DW_CFA_def_cfa_expression 0x0f
++#define DW_CFA_expression 0x10
++#define DW_CFA_offset_extended_sf 0x11
++#define DW_CFA_def_cfa_sf 0x12
++#define DW_CFA_def_cfa_offset_sf 0x13
++#define DW_CFA_MIPS_advance_loc8 0x1d
++#define DW_CFA_GNU_window_save 0x2d
++#define DW_CFA_GNU_args_size 0x2e
++#define DW_CFA_GNU_negative_offset_extended 0x2f
++#define DW_CIE_ID 0xffffffff
++#define DW_CIE_VERSION 1
++#define DW_CFA_extended 0
++#define DW_CFA_lo_user 0x1c
++#define DW_CFA_hi_user 0x3f
++#define DW_CHILDREN_no 0x00
++#define DW_CHILDREN_yes 0x01
++#define DW_ADDR_none 0
++#define DW_LANG_C89 0x0001
++#define DW_LANG_C 0x0002
++#define DW_LANG_Ada83 0x0003
++#define DW_LANG_C_plus_plus 0x0004
++#define DW_LANG_Cobol74 0x0005
++#define DW_LANG_Cobol85 0x0006
++#define DW_LANG_Fortran77 0x0007
++#define DW_LANG_Fortran90 0x0008
++#define DW_LANG_Pascal83 0x0009
++#define DW_LANG_Modula2 0x000a
++#define DW_LANG_Java 0x000b
++#define DW_LANG_C99 0x000c
++#define DW_LANG_Ada95 0x000d
++#define DW_LANG_Fortran95 0x000e
++#define DW_LANG_Mips_Assembler 0x8001
++#define DW_LANG_Upc 0x8765
++#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start. */
++#define DW_LANG_hi_user 0xffff /* Implementation-defined range start. */
++#define DW_MACINFO_define 1
++#define DW_MACINFO_undef 2
++#define DW_MACINFO_start_file 3
++#define DW_MACINFO_end_file 4
++#define DW_MACINFO_vendor_ext 255
++#define DW_EH_PE_absptr 0x00
++#define DW_EH_PE_omit 0xff
++#define DW_EH_PE_uleb128 0x01
++#define DW_EH_PE_udata2 0x02
++#define DW_EH_PE_udata4 0x03
++#define DW_EH_PE_udata8 0x04
++#define DW_EH_PE_sleb128 0x09
++#define DW_EH_PE_sdata2 0x0A
++#define DW_EH_PE_sdata4 0x0B
++#define DW_EH_PE_sdata8 0x0C
++#define DW_EH_PE_signed 0x08
++#define DW_EH_PE_pcrel 0x10
++#define DW_EH_PE_textrel 0x20
++#define DW_EH_PE_datarel 0x30
++#define DW_EH_PE_funcrel 0x40
++#define DW_EH_PE_aligned 0x50
++#define DW_EH_PE_indirect 0x80
++#endif
+diff -Naur linux-2.6.25_original/include/linux/dwarf2.h linux-2.6.25/include/linux/dwarf2.h
+--- linux-2.6.25_original/include/linux/dwarf2.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/dwarf2.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,776 @@
++/* Declarations and definitions of codes relating to the DWARF2 symbolic
++ debugging information format.
++ Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
++ 2003 Free Software Foundation, Inc.
++
++ Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
++ Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
++ provided support for this effort -- June 21, 1995.
++
++ Derived from the DWARF 1 implementation written by Ron Guilmette
++ (rfg@netcom.com), November 1990.
++
++ This file is part of GCC.
++
++ GCC is free software; you can redistribute it and/or modify it under
++ the terms of the GNU General Public License as published by the Free
++ Software Foundation; either version 2, or (at your option) any later
++ version.
++
++ GCC 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 GCC; see the file COPYING. If not, write to the Free
++ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
++ 02111-1307, USA. */
++
++/* This file is derived from the DWARF specification (a public document)
++ Revision 2.0.0 (July 27, 1993) developed by the UNIX International
++ Programming Languages Special Interest Group (UI/PLSIG) and distributed
++ by UNIX International. Copies of this specification are available from
++ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
++
++ This file also now contains definitions from the DWARF 3 specification. */
++
++/* This file is shared between GCC and GDB, and should not contain
++ prototypes. */
++
++#ifndef _ELF_DWARF2_H
++#define _ELF_DWARF2_H
++
++/* Structure found in the .debug_line section. */
++typedef struct
++{
++ unsigned char li_length [4];
++ unsigned char li_version [2];
++ unsigned char li_prologue_length [4];
++ unsigned char li_min_insn_length [1];
++ unsigned char li_default_is_stmt [1];
++ unsigned char li_line_base [1];
++ unsigned char li_line_range [1];
++ unsigned char li_opcode_base [1];
++}
++DWARF2_External_LineInfo;
++
++typedef struct
++{
++ unsigned long li_length;
++ unsigned short li_version;
++ unsigned int li_prologue_length;
++ unsigned char li_min_insn_length;
++ unsigned char li_default_is_stmt;
++ int li_line_base;
++ unsigned char li_line_range;
++ unsigned char li_opcode_base;
++}
++DWARF2_Internal_LineInfo;
++
++/* Structure found in .debug_pubnames section. */
++typedef struct
++{
++ unsigned char pn_length [4];
++ unsigned char pn_version [2];
++ unsigned char pn_offset [4];
++ unsigned char pn_size [4];
++}
++DWARF2_External_PubNames;
++
++typedef struct
++{
++ unsigned long pn_length;
++ unsigned short pn_version;
++ unsigned long pn_offset;
++ unsigned long pn_size;
++}
++DWARF2_Internal_PubNames;
++
++/* Structure found in .debug_info section. */
++typedef struct
++{
++ unsigned char cu_length [4];
++ unsigned char cu_version [2];
++ unsigned char cu_abbrev_offset [4];
++ unsigned char cu_pointer_size [1];
++}
++DWARF2_External_CompUnit;
++
++typedef struct
++{
++ unsigned long cu_length;
++ unsigned short cu_version;
++ unsigned long cu_abbrev_offset;
++ unsigned char cu_pointer_size;
++}
++DWARF2_Internal_CompUnit;
++
++typedef struct
++{
++ unsigned char ar_length [4];
++ unsigned char ar_version [2];
++ unsigned char ar_info_offset [4];
++ unsigned char ar_pointer_size [1];
++ unsigned char ar_segment_size [1];
++}
++DWARF2_External_ARange;
++
++typedef struct
++{
++ unsigned long ar_length;
++ unsigned short ar_version;
++ unsigned long ar_info_offset;
++ unsigned char ar_pointer_size;
++ unsigned char ar_segment_size;
++}
++DWARF2_Internal_ARange;
++
++
++/* Tag names and codes. */
++enum dwarf_tag
++ {
++ DW_TAG_padding = 0x00,
++ DW_TAG_array_type = 0x01,
++ DW_TAG_class_type = 0x02,
++ DW_TAG_entry_point = 0x03,
++ DW_TAG_enumeration_type = 0x04,
++ DW_TAG_formal_parameter = 0x05,
++ DW_TAG_imported_declaration = 0x08,
++ DW_TAG_label = 0x0a,
++ DW_TAG_lexical_block = 0x0b,
++ DW_TAG_member = 0x0d,
++ DW_TAG_pointer_type = 0x0f,
++ DW_TAG_reference_type = 0x10,
++ DW_TAG_compile_unit = 0x11,
++ DW_TAG_string_type = 0x12,
++ DW_TAG_structure_type = 0x13,
++ DW_TAG_subroutine_type = 0x15,
++ DW_TAG_typedef = 0x16,
++ DW_TAG_union_type = 0x17,
++ DW_TAG_unspecified_parameters = 0x18,
++ DW_TAG_variant = 0x19,
++ DW_TAG_common_block = 0x1a,
++ DW_TAG_common_inclusion = 0x1b,
++ DW_TAG_inheritance = 0x1c,
++ DW_TAG_inlined_subroutine = 0x1d,
++ DW_TAG_module = 0x1e,
++ DW_TAG_ptr_to_member_type = 0x1f,
++ DW_TAG_set_type = 0x20,
++ DW_TAG_subrange_type = 0x21,
++ DW_TAG_with_stmt = 0x22,
++ DW_TAG_access_declaration = 0x23,
++ DW_TAG_base_type = 0x24,
++ DW_TAG_catch_block = 0x25,
++ DW_TAG_const_type = 0x26,
++ DW_TAG_constant = 0x27,
++ DW_TAG_enumerator = 0x28,
++ DW_TAG_file_type = 0x29,
++ DW_TAG_friend = 0x2a,
++ DW_TAG_namelist = 0x2b,
++ DW_TAG_namelist_item = 0x2c,
++ DW_TAG_packed_type = 0x2d,
++ DW_TAG_subprogram = 0x2e,
++ DW_TAG_template_type_param = 0x2f,
++ DW_TAG_template_value_param = 0x30,
++ DW_TAG_thrown_type = 0x31,
++ DW_TAG_try_block = 0x32,
++ DW_TAG_variant_part = 0x33,
++ DW_TAG_variable = 0x34,
++ DW_TAG_volatile_type = 0x35,
++ /* DWARF 3. */
++ DW_TAG_dwarf_procedure = 0x36,
++ DW_TAG_restrict_type = 0x37,
++ DW_TAG_interface_type = 0x38,
++ DW_TAG_namespace = 0x39,
++ DW_TAG_imported_module = 0x3a,
++ DW_TAG_unspecified_type = 0x3b,
++ DW_TAG_partial_unit = 0x3c,
++ DW_TAG_imported_unit = 0x3d,
++ /* SGI/MIPS Extensions. */
++ DW_TAG_MIPS_loop = 0x4081,
++ /* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
++ DW_TAG_HP_array_descriptor = 0x4090,
++ /* GNU extensions. */
++ DW_TAG_format_label = 0x4101, /* For FORTRAN 77 and Fortran 90. */
++ DW_TAG_function_template = 0x4102, /* For C++. */
++ DW_TAG_class_template = 0x4103, /* For C++. */
++ DW_TAG_GNU_BINCL = 0x4104,
++ DW_TAG_GNU_EINCL = 0x4105,
++ /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
++ DW_TAG_upc_shared_type = 0x8765,
++ DW_TAG_upc_strict_type = 0x8766,
++ DW_TAG_upc_relaxed_type = 0x8767,
++ /* PGI (STMicroelectronics) extensions. No documentation available. */
++ DW_TAG_PGI_kanji_type = 0xA000,
++ DW_TAG_PGI_interface_block = 0xA020
++ };
++
++#define DW_TAG_lo_user 0x4080
++#define DW_TAG_hi_user 0xffff
++
++/* Flag that tells whether entry has a child or not. */
++#define DW_children_no 0
++#define DW_children_yes 1
++
++/* Form names and codes. */
++enum dwarf_form
++ {
++ DW_FORM_addr = 0x01,
++ DW_FORM_block2 = 0x03,
++ DW_FORM_block4 = 0x04,
++ DW_FORM_data2 = 0x05,
++ DW_FORM_data4 = 0x06,
++ DW_FORM_data8 = 0x07,
++ DW_FORM_string = 0x08,
++ DW_FORM_block = 0x09,
++ DW_FORM_block1 = 0x0a,
++ DW_FORM_data1 = 0x0b,
++ DW_FORM_flag = 0x0c,
++ DW_FORM_sdata = 0x0d,
++ DW_FORM_strp = 0x0e,
++ DW_FORM_udata = 0x0f,
++ DW_FORM_ref_addr = 0x10,
++ DW_FORM_ref1 = 0x11,
++ DW_FORM_ref2 = 0x12,
++ DW_FORM_ref4 = 0x13,
++ DW_FORM_ref8 = 0x14,
++ DW_FORM_ref_udata = 0x15,
++ DW_FORM_indirect = 0x16
++ };
++
++/* Attribute names and codes. */
++enum dwarf_attribute
++ {
++ DW_AT_sibling = 0x01,
++ DW_AT_location = 0x02,
++ DW_AT_name = 0x03,
++ DW_AT_ordering = 0x09,
++ DW_AT_subscr_data = 0x0a,
++ DW_AT_byte_size = 0x0b,
++ DW_AT_bit_offset = 0x0c,
++ DW_AT_bit_size = 0x0d,
++ DW_AT_element_list = 0x0f,
++ DW_AT_stmt_list = 0x10,
++ DW_AT_low_pc = 0x11,
++ DW_AT_high_pc = 0x12,
++ DW_AT_language = 0x13,
++ DW_AT_member = 0x14,
++ DW_AT_discr = 0x15,
++ DW_AT_discr_value = 0x16,
++ DW_AT_visibility = 0x17,
++ DW_AT_import = 0x18,
++ DW_AT_string_length = 0x19,
++ DW_AT_common_reference = 0x1a,
++ DW_AT_comp_dir = 0x1b,
++ DW_AT_const_value = 0x1c,
++ DW_AT_containing_type = 0x1d,
++ DW_AT_default_value = 0x1e,
++ DW_AT_inline = 0x20,
++ DW_AT_is_optional = 0x21,
++ DW_AT_lower_bound = 0x22,
++ DW_AT_producer = 0x25,
++ DW_AT_prototyped = 0x27,
++ DW_AT_return_addr = 0x2a,
++ DW_AT_start_scope = 0x2c,
++ DW_AT_stride_size = 0x2e,
++ DW_AT_upper_bound = 0x2f,
++ DW_AT_abstract_origin = 0x31,
++ DW_AT_accessibility = 0x32,
++ DW_AT_address_class = 0x33,
++ DW_AT_artificial = 0x34,
++ DW_AT_base_types = 0x35,
++ DW_AT_calling_convention = 0x36,
++ DW_AT_count = 0x37,
++ DW_AT_data_member_location = 0x38,
++ DW_AT_decl_column = 0x39,
++ DW_AT_decl_file = 0x3a,
++ DW_AT_decl_line = 0x3b,
++ DW_AT_declaration = 0x3c,
++ DW_AT_discr_list = 0x3d,
++ DW_AT_encoding = 0x3e,
++ DW_AT_external = 0x3f,
++ DW_AT_frame_base = 0x40,
++ DW_AT_friend = 0x41,
++ DW_AT_identifier_case = 0x42,
++ DW_AT_macro_info = 0x43,
++ DW_AT_namelist_items = 0x44,
++ DW_AT_priority = 0x45,
++ DW_AT_segment = 0x46,
++ DW_AT_specification = 0x47,
++ DW_AT_static_link = 0x48,
++ DW_AT_type = 0x49,
++ DW_AT_use_location = 0x4a,
++ DW_AT_variable_parameter = 0x4b,
++ DW_AT_virtuality = 0x4c,
++ DW_AT_vtable_elem_location = 0x4d,
++ /* DWARF 3 values. */
++ DW_AT_allocated = 0x4e,
++ DW_AT_associated = 0x4f,
++ DW_AT_data_location = 0x50,
++ DW_AT_stride = 0x51,
++ DW_AT_entry_pc = 0x52,
++ DW_AT_use_UTF8 = 0x53,
++ DW_AT_extension = 0x54,
++ DW_AT_ranges = 0x55,
++ DW_AT_trampoline = 0x56,
++ DW_AT_call_column = 0x57,
++ DW_AT_call_file = 0x58,
++ DW_AT_call_line = 0x59,
++ /* SGI/MIPS extensions. */
++ DW_AT_MIPS_fde = 0x2001,
++ DW_AT_MIPS_loop_begin = 0x2002,
++ DW_AT_MIPS_tail_loop_begin = 0x2003,
++ DW_AT_MIPS_epilog_begin = 0x2004,
++ DW_AT_MIPS_loop_unroll_factor = 0x2005,
++ DW_AT_MIPS_software_pipeline_depth = 0x2006,
++ DW_AT_MIPS_linkage_name = 0x2007,
++ DW_AT_MIPS_stride = 0x2008,
++ DW_AT_MIPS_abstract_name = 0x2009,
++ DW_AT_MIPS_clone_origin = 0x200a,
++ DW_AT_MIPS_has_inlines = 0x200b,
++ /* HP extensions. */
++ DW_AT_HP_block_index = 0x2000,
++ DW_AT_HP_unmodifiable = 0x2001, /* Same as DW_AT_MIPS_fde. */
++ DW_AT_HP_actuals_stmt_list = 0x2010,
++ DW_AT_HP_proc_per_section = 0x2011,
++ DW_AT_HP_raw_data_ptr = 0x2012,
++ DW_AT_HP_pass_by_reference = 0x2013,
++ DW_AT_HP_opt_level = 0x2014,
++ DW_AT_HP_prof_version_id = 0x2015,
++ DW_AT_HP_opt_flags = 0x2016,
++ DW_AT_HP_cold_region_low_pc = 0x2017,
++ DW_AT_HP_cold_region_high_pc = 0x2018,
++ DW_AT_HP_all_variables_modifiable = 0x2019,
++ DW_AT_HP_linkage_name = 0x201a,
++ DW_AT_HP_prof_flags = 0x201b, /* In comp unit of procs_info for -g. */
++ /* GNU extensions. */
++ DW_AT_sf_names = 0x2101,
++ DW_AT_src_info = 0x2102,
++ DW_AT_mac_info = 0x2103,
++ DW_AT_src_coords = 0x2104,
++ DW_AT_body_begin = 0x2105,
++ DW_AT_body_end = 0x2106,
++ DW_AT_GNU_vector = 0x2107,
++ /* VMS extensions. */
++ DW_AT_VMS_rtnbeg_pd_address = 0x2201,
++ /* UPC extension. */
++ DW_AT_upc_threads_scaled = 0x3210,
++ /* PGI (STMicroelectronics) extensions. */
++ DW_AT_PGI_lbase = 0x3a00,
++ DW_AT_PGI_soffset = 0x3a01,
++ DW_AT_PGI_lstride = 0x3a02
++ };
++
++#define DW_AT_lo_user 0x2000 /* Implementation-defined range start. */
++#define DW_AT_hi_user 0x3ff0 /* Implementation-defined range end. */
++
++/* Location atom names and codes. */
++enum dwarf_location_atom
++ {
++ DW_OP_addr = 0x03,
++ DW_OP_deref = 0x06,
++ DW_OP_const1u = 0x08,
++ DW_OP_const1s = 0x09,
++ DW_OP_const2u = 0x0a,
++ DW_OP_const2s = 0x0b,
++ DW_OP_const4u = 0x0c,
++ DW_OP_const4s = 0x0d,
++ DW_OP_const8u = 0x0e,
++ DW_OP_const8s = 0x0f,
++ DW_OP_constu = 0x10,
++ DW_OP_consts = 0x11,
++ DW_OP_dup = 0x12,
++ DW_OP_drop = 0x13,
++ DW_OP_over = 0x14,
++ DW_OP_pick = 0x15,
++ DW_OP_swap = 0x16,
++ DW_OP_rot = 0x17,
++ DW_OP_xderef = 0x18,
++ DW_OP_abs = 0x19,
++ DW_OP_and = 0x1a,
++ DW_OP_div = 0x1b,
++ DW_OP_minus = 0x1c,
++ DW_OP_mod = 0x1d,
++ DW_OP_mul = 0x1e,
++ DW_OP_neg = 0x1f,
++ DW_OP_not = 0x20,
++ DW_OP_or = 0x21,
++ DW_OP_plus = 0x22,
++ DW_OP_plus_uconst = 0x23,
++ DW_OP_shl = 0x24,
++ DW_OP_shr = 0x25,
++ DW_OP_shra = 0x26,
++ DW_OP_xor = 0x27,
++ DW_OP_bra = 0x28,
++ DW_OP_eq = 0x29,
++ DW_OP_ge = 0x2a,
++ DW_OP_gt = 0x2b,
++ DW_OP_le = 0x2c,
++ DW_OP_lt = 0x2d,
++ DW_OP_ne = 0x2e,
++ DW_OP_skip = 0x2f,
++ DW_OP_lit0 = 0x30,
++ DW_OP_lit1 = 0x31,
++ DW_OP_lit2 = 0x32,
++ DW_OP_lit3 = 0x33,
++ DW_OP_lit4 = 0x34,
++ DW_OP_lit5 = 0x35,
++ DW_OP_lit6 = 0x36,
++ DW_OP_lit7 = 0x37,
++ DW_OP_lit8 = 0x38,
++ DW_OP_lit9 = 0x39,
++ DW_OP_lit10 = 0x3a,
++ DW_OP_lit11 = 0x3b,
++ DW_OP_lit12 = 0x3c,
++ DW_OP_lit13 = 0x3d,
++ DW_OP_lit14 = 0x3e,
++ DW_OP_lit15 = 0x3f,
++ DW_OP_lit16 = 0x40,
++ DW_OP_lit17 = 0x41,
++ DW_OP_lit18 = 0x42,
++ DW_OP_lit19 = 0x43,
++ DW_OP_lit20 = 0x44,
++ DW_OP_lit21 = 0x45,
++ DW_OP_lit22 = 0x46,
++ DW_OP_lit23 = 0x47,
++ DW_OP_lit24 = 0x48,
++ DW_OP_lit25 = 0x49,
++ DW_OP_lit26 = 0x4a,
++ DW_OP_lit27 = 0x4b,
++ DW_OP_lit28 = 0x4c,
++ DW_OP_lit29 = 0x4d,
++ DW_OP_lit30 = 0x4e,
++ DW_OP_lit31 = 0x4f,
++ DW_OP_reg0 = 0x50,
++ DW_OP_reg1 = 0x51,
++ DW_OP_reg2 = 0x52,
++ DW_OP_reg3 = 0x53,
++ DW_OP_reg4 = 0x54,
++ DW_OP_reg5 = 0x55,
++ DW_OP_reg6 = 0x56,
++ DW_OP_reg7 = 0x57,
++ DW_OP_reg8 = 0x58,
++ DW_OP_reg9 = 0x59,
++ DW_OP_reg10 = 0x5a,
++ DW_OP_reg11 = 0x5b,
++ DW_OP_reg12 = 0x5c,
++ DW_OP_reg13 = 0x5d,
++ DW_OP_reg14 = 0x5e,
++ DW_OP_reg15 = 0x5f,
++ DW_OP_reg16 = 0x60,
++ DW_OP_reg17 = 0x61,
++ DW_OP_reg18 = 0x62,
++ DW_OP_reg19 = 0x63,
++ DW_OP_reg20 = 0x64,
++ DW_OP_reg21 = 0x65,
++ DW_OP_reg22 = 0x66,
++ DW_OP_reg23 = 0x67,
++ DW_OP_reg24 = 0x68,
++ DW_OP_reg25 = 0x69,
++ DW_OP_reg26 = 0x6a,
++ DW_OP_reg27 = 0x6b,
++ DW_OP_reg28 = 0x6c,
++ DW_OP_reg29 = 0x6d,
++ DW_OP_reg30 = 0x6e,
++ DW_OP_reg31 = 0x6f,
++ DW_OP_breg0 = 0x70,
++ DW_OP_breg1 = 0x71,
++ DW_OP_breg2 = 0x72,
++ DW_OP_breg3 = 0x73,
++ DW_OP_breg4 = 0x74,
++ DW_OP_breg5 = 0x75,
++ DW_OP_breg6 = 0x76,
++ DW_OP_breg7 = 0x77,
++ DW_OP_breg8 = 0x78,
++ DW_OP_breg9 = 0x79,
++ DW_OP_breg10 = 0x7a,
++ DW_OP_breg11 = 0x7b,
++ DW_OP_breg12 = 0x7c,
++ DW_OP_breg13 = 0x7d,
++ DW_OP_breg14 = 0x7e,
++ DW_OP_breg15 = 0x7f,
++ DW_OP_breg16 = 0x80,
++ DW_OP_breg17 = 0x81,
++ DW_OP_breg18 = 0x82,
++ DW_OP_breg19 = 0x83,
++ DW_OP_breg20 = 0x84,
++ DW_OP_breg21 = 0x85,
++ DW_OP_breg22 = 0x86,
++ DW_OP_breg23 = 0x87,
++ DW_OP_breg24 = 0x88,
++ DW_OP_breg25 = 0x89,
++ DW_OP_breg26 = 0x8a,
++ DW_OP_breg27 = 0x8b,
++ DW_OP_breg28 = 0x8c,
++ DW_OP_breg29 = 0x8d,
++ DW_OP_breg30 = 0x8e,
++ DW_OP_breg31 = 0x8f,
++ DW_OP_regx = 0x90,
++ DW_OP_fbreg = 0x91,
++ DW_OP_bregx = 0x92,
++ DW_OP_piece = 0x93,
++ DW_OP_deref_size = 0x94,
++ DW_OP_xderef_size = 0x95,
++ DW_OP_nop = 0x96,
++ /* DWARF 3 extensions. */
++ DW_OP_push_object_address = 0x97,
++ DW_OP_call2 = 0x98,
++ DW_OP_call4 = 0x99,
++ DW_OP_call_ref = 0x9a,
++ /* GNU extensions. */
++ DW_OP_GNU_push_tls_address = 0xe0,
++ /* HP extensions. */
++ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
++ DW_OP_HP_is_value = 0xe1,
++ DW_OP_HP_fltconst4 = 0xe2,
++ DW_OP_HP_fltconst8 = 0xe3,
++ DW_OP_HP_mod_range = 0xe4,
++ DW_OP_HP_unmod_range = 0xe5,
++ DW_OP_HP_tls = 0xe6
++ };
++
++#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
++#define DW_OP_hi_user 0xff /* Implementation-defined range end. */
++
++/* Type encodings. */
++enum dwarf_type
++ {
++ DW_ATE_void = 0x0,
++ DW_ATE_address = 0x1,
++ DW_ATE_boolean = 0x2,
++ DW_ATE_complex_float = 0x3,
++ DW_ATE_float = 0x4,
++ DW_ATE_signed = 0x5,
++ DW_ATE_signed_char = 0x6,
++ DW_ATE_unsigned = 0x7,
++ DW_ATE_unsigned_char = 0x8,
++ /* DWARF 3. */
++ DW_ATE_imaginary_float = 0x9,
++ /* HP extensions. */
++ DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */
++ DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */
++ DW_ATE_HP_float128 = 0x82, /* Floating-point (128 bit). */
++ DW_ATE_HP_complex_float128 = 0x83, /* Complex floating-point (128 bit). */
++ DW_ATE_HP_floathpintel = 0x84, /* Floating-point (82 bit IA64). */
++ DW_ATE_HP_imaginary_float80 = 0x85,
++ DW_ATE_HP_imaginary_float128 = 0x86
++ };
++
++#define DW_ATE_lo_user 0x80
++#define DW_ATE_hi_user 0xff
++
++/* Array ordering names and codes. */
++enum dwarf_array_dim_ordering
++ {
++ DW_ORD_row_major = 0,
++ DW_ORD_col_major = 1
++ };
++
++/* Access attribute. */
++enum dwarf_access_attribute
++ {
++ DW_ACCESS_public = 1,
++ DW_ACCESS_protected = 2,
++ DW_ACCESS_private = 3
++ };
++
++/* Visibility. */
++enum dwarf_visibility_attribute
++ {
++ DW_VIS_local = 1,
++ DW_VIS_exported = 2,
++ DW_VIS_qualified = 3
++ };
++
++/* Virtuality. */
++enum dwarf_virtuality_attribute
++ {
++ DW_VIRTUALITY_none = 0,
++ DW_VIRTUALITY_virtual = 1,
++ DW_VIRTUALITY_pure_virtual = 2
++ };
++
++/* Case sensitivity. */
++enum dwarf_id_case
++ {
++ DW_ID_case_sensitive = 0,
++ DW_ID_up_case = 1,
++ DW_ID_down_case = 2,
++ DW_ID_case_insensitive = 3
++ };
++
++/* Calling convention. */
++enum dwarf_calling_convention
++ {
++ DW_CC_normal = 0x1,
++ DW_CC_program = 0x2,
++ DW_CC_nocall = 0x3
++ };
++
++#define DW_CC_lo_user 0x40
++#define DW_CC_hi_user 0xff
++
++/* Inline attribute. */
++enum dwarf_inline_attribute
++ {
++ DW_INL_not_inlined = 0,
++ DW_INL_inlined = 1,
++ DW_INL_declared_not_inlined = 2,
++ DW_INL_declared_inlined = 3
++ };
++
++/* Discriminant lists. */
++enum dwarf_discrim_list
++ {
++ DW_DSC_label = 0,
++ DW_DSC_range = 1
++ };
++
++/* Line number opcodes. */
++enum dwarf_line_number_ops
++ {
++ DW_LNS_extended_op = 0,
++ DW_LNS_copy = 1,
++ DW_LNS_advance_pc = 2,
++ DW_LNS_advance_line = 3,
++ DW_LNS_set_file = 4,
++ DW_LNS_set_column = 5,
++ DW_LNS_negate_stmt = 6,
++ DW_LNS_set_basic_block = 7,
++ DW_LNS_const_add_pc = 8,
++ DW_LNS_fixed_advance_pc = 9,
++ /* DWARF 3. */
++ DW_LNS_set_prologue_end = 10,
++ DW_LNS_set_epilogue_begin = 11,
++ DW_LNS_set_isa = 12
++ };
++
++/* Line number extended opcodes. */
++enum dwarf_line_number_x_ops
++ {
++ DW_LNE_end_sequence = 1,
++ DW_LNE_set_address = 2,
++ DW_LNE_define_file = 3,
++ /* HP extensions. */
++ DW_LNE_HP_negate_is_UV_update = 0x11,
++ DW_LNE_HP_push_context = 0x12,
++ DW_LNE_HP_pop_context = 0x13,
++ DW_LNE_HP_set_file_line_column = 0x14,
++ DW_LNE_HP_set_routine_name = 0x15,
++ DW_LNE_HP_set_sequence = 0x16,
++ DW_LNE_HP_negate_post_semantics = 0x17,
++ DW_LNE_HP_negate_function_exit = 0x18,
++ DW_LNE_HP_negate_front_end_logical = 0x19,
++ DW_LNE_HP_define_proc = 0x20
++ };
++
++/* Call frame information. */
++enum dwarf_call_frame_info
++ {
++ DW_CFA_advance_loc = 0x40,
++ DW_CFA_offset = 0x80,
++ DW_CFA_restore = 0xc0,
++ DW_CFA_nop = 0x00,
++ DW_CFA_set_loc = 0x01,
++ DW_CFA_advance_loc1 = 0x02,
++ DW_CFA_advance_loc2 = 0x03,
++ DW_CFA_advance_loc4 = 0x04,
++ DW_CFA_offset_extended = 0x05,
++ DW_CFA_restore_extended = 0x06,
++ DW_CFA_undefined = 0x07,
++ DW_CFA_same_value = 0x08,
++ DW_CFA_register = 0x09,
++ DW_CFA_remember_state = 0x0a,
++ DW_CFA_restore_state = 0x0b,
++ DW_CFA_def_cfa = 0x0c,
++ DW_CFA_def_cfa_register = 0x0d,
++ DW_CFA_def_cfa_offset = 0x0e,
++ /* DWARF 3. */
++ DW_CFA_def_cfa_expression = 0x0f,
++ DW_CFA_expression = 0x10,
++ DW_CFA_offset_extended_sf = 0x11,
++ DW_CFA_def_cfa_sf = 0x12,
++ DW_CFA_def_cfa_offset_sf = 0x13,
++ /* SGI/MIPS specific. */
++ DW_CFA_MIPS_advance_loc8 = 0x1d,
++ /* GNU extensions. */
++ DW_CFA_GNU_window_save = 0x2d,
++ DW_CFA_GNU_args_size = 0x2e,
++ DW_CFA_GNU_negative_offset_extended = 0x2f
++ };
++
++#define DW_CIE_ID 0xffffffff
++#define DW_CIE_VERSION 1
++
++#define DW_CFA_extended 0
++#define DW_CFA_lo_user 0x1c
++#define DW_CFA_hi_user 0x3f
++
++#define DW_CHILDREN_no 0x00
++#define DW_CHILDREN_yes 0x01
++
++#define DW_ADDR_none 0
++
++/* Source language names and codes. */
++enum dwarf_source_language
++ {
++ DW_LANG_C89 = 0x0001,
++ DW_LANG_C = 0x0002,
++ DW_LANG_Ada83 = 0x0003,
++ DW_LANG_C_plus_plus = 0x0004,
++ DW_LANG_Cobol74 = 0x0005,
++ DW_LANG_Cobol85 = 0x0006,
++ DW_LANG_Fortran77 = 0x0007,
++ DW_LANG_Fortran90 = 0x0008,
++ DW_LANG_Pascal83 = 0x0009,
++ DW_LANG_Modula2 = 0x000a,
++ DW_LANG_Java = 0x000b,
++ /* DWARF 3. */
++ DW_LANG_C99 = 0x000c,
++ DW_LANG_Ada95 = 0x000d,
++ DW_LANG_Fortran95 = 0x000e,
++ /* MIPS. */
++ DW_LANG_Mips_Assembler = 0x8001,
++ /* UPC. */
++ DW_LANG_Upc = 0x8765
++ };
++
++#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start. */
++#define DW_LANG_hi_user 0xffff /* Implementation-defined range start. */
++
++/* Names and codes for macro information. */
++enum dwarf_macinfo_record_type
++ {
++ DW_MACINFO_define = 1,
++ DW_MACINFO_undef = 2,
++ DW_MACINFO_start_file = 3,
++ DW_MACINFO_end_file = 4,
++ DW_MACINFO_vendor_ext = 255
++ };
++\f
++/* @@@ For use with GNU frame unwind information. */
++
++#define DW_EH_PE_absptr 0x00
++#define DW_EH_PE_omit 0xff
++
++#define DW_EH_PE_uleb128 0x01
++#define DW_EH_PE_udata2 0x02
++#define DW_EH_PE_udata4 0x03
++#define DW_EH_PE_udata8 0x04
++#define DW_EH_PE_sleb128 0x09
++#define DW_EH_PE_sdata2 0x0A
++#define DW_EH_PE_sdata4 0x0B
++#define DW_EH_PE_sdata8 0x0C
++#define DW_EH_PE_signed 0x08
++
++#define DW_EH_PE_pcrel 0x10
++#define DW_EH_PE_textrel 0x20
++#define DW_EH_PE_datarel 0x30
++#define DW_EH_PE_funcrel 0x40
++#define DW_EH_PE_aligned 0x50
++
++#define DW_EH_PE_indirect 0x80
++
++#endif /* _ELF_DWARF2_H */
++
+diff -Naur linux-2.6.25_original/include/linux/dwarf2-lang.h linux-2.6.25/include/linux/dwarf2-lang.h
+--- linux-2.6.25_original/include/linux/dwarf2-lang.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/dwarf2-lang.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,301 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++
++/*
++ * This is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2, or (at your option) any later
++ * version.
++ */
++/*
++ * This file defines macros that allow generation of DWARF debug records
++ * for asm files. This file is platform independent. Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++/*
++ * We need this to work for both asm and C. In asm we are using the
++ * old comment trick to concatenate while C uses the new ANSI thing.
++ * Here we have concat macro... The multi level thing is to allow and
++ * macros used in the names to be resolved prior to the cat (at which
++ * time they are no longer the same string).
++ */
++#define CAT3(a,b,c) _CAT3(a,b,c)
++#define _CAT3(a,b,c) __CAT3(a,b,c)
++#ifndef __STDC__
++#define __CAT3(a,b,c) a/**/b/**/c
++#else
++#define __CAT3(a,b,c) a##b##c
++#endif
++#ifdef __ASSEMBLY__
++#define IFC(a)
++#define IFN_C(a) a
++#define NL ;
++#define QUOTE_THIS(a) a
++#define DWARF_preamble .section .debug_frame,"",%progbits;
++#else
++#define IFC(a) a
++#define IFN_C(a)
++#define NL \n\t
++#define QUOTE_THIS(a) _QUOTE_THIS(a)
++#define _QUOTE_THIS(a) #a
++/* Don't let CPP see the " and , \042=" \054=, */
++#define DWARF_preamble .section .debug_frame \054\042\042\054%progbits
++#endif
++
++#ifdef CONFIG_64BIT
++#define DATA_ALIGN_FACTOR 8
++#define ADDR_LOC .quad
++#else
++#define DATA_ALIGN_FACTOR 4
++#define ADDR_LOC .long
++#endif
++
++#include <linux/dwarf2-defs.h>
++/*
++ * This macro starts a debug frame section. The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc, pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply. If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets. If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that. This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number). The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example). So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset. If <40> was the 40th
++ * 4-byte element in that structure you would want 4. And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align) \
++ DWARF_preamble NL \
++ .align DATA_ALIGN_FACTOR NL \
++ .globl CAT3(frame,_,ORD) NL \
++CAT3(frame,_,ORD): NL \
++ .long 7f-6f NL \
++6: \
++ .long DW_CIE_ID NL \
++ .byte DW_CIE_VERSION NL \
++ .byte 0 NL \
++ .uleb128 code_align NL \
++ .sleb128 data_align NL \
++ .byte pc NL
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state. This starts with defining the reference
++ * register and, usually the pc. Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset) \
++ .byte DW_CFA_def_cfa NL \
++ .uleb128 reg NL \
++ .uleb128 (offset) NL
++
++#define CFA_define_offset(reg, offset) \
++ .byte (DW_CFA_offset + reg) NL \
++ .uleb128 (offset) NL
++
++#define CFA_restore(reg) \
++ .byte (DW_CFA_restore + reg) NL
++
++#define CFI_postamble() \
++ .align DATA_ALIGN_FACTOR NL \
++7: NL \
++.previous NL
++
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do. This starts a running description of
++ * the call frame. You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?). Like the
++ * above, it has a preamble and a postamble. It also is tied to the CFI
++ * above.
++ * The preamble macro is tied to the CFI thru the first parameter. The
++ * second is the code start address and then the code end address+1.
++ */
++#define FDE_preamble(ORD, initial_address, end_address) \
++ DWARF_preamble NL \
++ .align DATA_ALIGN_FACTOR NL \
++ .long 9f-8f NL \
++8: \
++ .long CAT3(frame,_,ORD) NL \
++ ADDR_LOC initial_address NL \
++ ADDR_LOC (end_address - initial_address) NL
++
++#define FDE_postamble() \
++ .align DATA_ALIGN_FACTOR NL \
++9: NL \
++.previous NL
++
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference. You can also define a new
++ * area of code the info applies to. For discontinuous bits you should
++ * start a new FDE. You may have as many as you like.
++ */
++
++/*
++ * To advance the stack address by <bytes> (0x3f max)
++ */
++
++#define CFA_advance_loc(bytes) \
++ .byte DW_CFA_advance_loc+bytes NL
++
++/*
++ * This one is good for 0xff or 255
++ */
++#define CFA_advance_loc1(bytes) \
++ .byte DW_CFA_advance_loc1 NL \
++ .byte bytes NL
++
++#define CFA_undefine_reg(reg) \
++ .byte DW_CFA_undefined NL \
++ .uleb128 reg NL
++/*
++ * With the above you can define all the register locations. But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment. This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset) \
++ .byte DW_CFA_def_cfa_offset NL \
++ .uleb128 (offset) NL
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg) \
++ .byte DW_CFA_def_cfa_register NL \
++ .uleb128 reg NL
++
++/*
++ * If you want to mess with the stack pointer, here is the expression.
++ * The stack starts empty.
++ */
++#define CFA_def_cfa_expression \
++ .byte DW_CFA_def_cfa_expression NL \
++ .uleb128 20f-10f NL \
++10: NL
++/*
++ * This expression is to be used for other regs. The stack starts with the
++ * stack address.
++ */
++
++#define CFA_expression(reg) \
++ .byte DW_CFA_expression NL \
++ .uleb128 reg NL \
++ .uleb128 20f-10f NL \
++10: NL
++/*
++ * Here we do the expression stuff. You should code the above followed
++ * by expression OPs followed by CFA_expression_end.
++ */
++
++
++#define CFA_expression_end \
++20: NL
++
++#define CFA_exp_OP_const4s(a) \
++ .byte DW_OP_const4s NL \
++ .long a NL
++
++#define CFA_exp_OP_swap .byte DW_OP_swap NL
++#define CFA_exp_OP_dup .byte DW_OP_dup NL
++#define CFA_exp_OP_drop .byte DW_OP_drop NL
++/*
++ * All these work on the top two elements on the stack, replacing them
++ * with the result. Top comes first where it matters. True is 1, false 0.
++ */
++#define CFA_exp_OP_deref .byte DW_OP_deref NL
++#define CFA_exp_OP_and .byte DW_OP_and NL
++#define CFA_exp_OP_div .byte DW_OP_div NL
++#define CFA_exp_OP_minus .byte DW_OP_minus NL
++#define CFA_exp_OP_mod .byte DW_OP_mod NL
++#define CFA_exp_OP_neg .byte DW_OP_neg NL
++#define CFA_exp_OP_plus .byte DW_OP_plus NL
++#define CFA_exp_OP_not .byte DW_OP_not NL
++#define CFA_exp_OP_or .byte DW_OP_or NL
++#define CFA_exp_OP_xor .byte DW_OP_xor NL
++#define CFA_exp_OP_le .byte DW_OP_le NL
++#define CFA_exp_OP_ge .byte DW_OP_ge NL
++#define CFA_exp_OP_eq .byte DW_OP_eq NL
++#define CFA_exp_OP_lt .byte DW_OP_lt NL
++#define CFA_exp_OP_gt .byte DW_OP_gt NL
++#define CFA_exp_OP_ne .byte DW_OP_ne NL
++/*
++ * These take a parameter as noted
++ */
++/*
++ * Unconditional skip to loc. loc is a label (loc:)
++ */
++#define CFA_exp_OP_skip(loc) \
++ .byte DW_OP_skip NL \
++ .hword loc-.-2 NL
++/*
++ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
++ */
++#define CFA_exp_OP_bra(loc) \
++ .byte DW_OP_bra NL \
++ .hword loc-.-2 NL
++
++/*
++ * TOS += no (an unsigned number)
++ */
++#define CFA_exp_OP_plus_uconst(no) \
++ .byte DW_OP_plus_uconst NL \
++ .uleb128 no NL
++
++/*
++ * ++TOS = no (a unsigned number)
++ */
++#define CFA_exp_OP_constu(no) \
++ .byte DW_OP_constu NL \
++ .uleb128 no NL
++/*
++ * ++TOS = no (a signed number)
++ */
++#define CFA_exp_OP_consts(no) \
++ .byte DW_OP_consts NL \
++ .sleb128 no NL
++/*
++ * ++TOS = no (an unsigned byte)
++ */
++#define CFA_exp_OP_const1u(no) \
++ .byte DW_OP_const1u NL \
++ .byte no NL
++
++
++/*
++ * ++TOS = no (a address)
++ */
++#define CFA_exp_OP_addr(no) \
++ .byte DW_OP_addr NL \
++ .long no NL
++
++/*
++ * Push current frames value for "reg" + offset
++ * We take advantage of the opcode assignments to make this a litteral reg
++ * rather than use the DW_OP_bregx opcode.
++ */
++
++#define CFA_exp_OP_breg(reg,offset) \
++ .byte DW_OP_breg0+reg NL \
++ .sleb128 offset NL
++#endif
++
+diff -Naur linux-2.6.25_original/include/linux/kgdb.h linux-2.6.25/include/linux/kgdb.h
+--- linux-2.6.25_original/include/linux/kgdb.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/kgdb.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,271 @@
++/*
++ * include/linux/kgdb.h
++ *
++ * This provides the hooks and functions that KGDB needs to share between
++ * the core, I/O and arch-specific portions.
++ *
++ * Author: Amit Kale <amitkale@linsyssoft.com> and
++ * Tom Rini <trini@kernel.crashing.org>
++ *
++ * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc.
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++#ifdef __KERNEL__
++#ifndef _KGDB_H_
++#define _KGDB_H_
++
++#include <asm/atomic.h>
++
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#include <linux/serial_8250.h>
++#include <linux/linkage.h>
++#include <linux/init.h>
++
++struct tasklet_struct;
++struct pt_regs;
++struct task_struct;
++struct uart_port;
++
++
++/* To enter the debugger explicitly. */
++extern void breakpoint(void);
++extern int kgdb_connected;
++extern int kgdb_may_fault;
++extern struct tasklet_struct kgdb_tasklet_breakpoint;
++
++extern atomic_t kgdb_setting_breakpoint;
++extern atomic_t cpu_doing_single_step;
++extern atomic_t kgdb_sync_softlockup[NR_CPUS];
++
++extern struct task_struct *kgdb_usethread, *kgdb_contthread;
++
++enum kgdb_bptype {
++ bp_breakpoint = '0',
++ bp_hardware_breakpoint,
++ bp_write_watchpoint,
++ bp_read_watchpoint,
++ bp_access_watchpoint
++};
++
++enum kgdb_bpstate {
++ bp_none = 0,
++ bp_removed,
++ bp_set,
++ bp_active
++};
++
++struct kgdb_bkpt {
++ unsigned long bpt_addr;
++ unsigned char saved_instr[BREAK_INSTR_SIZE];
++ enum kgdb_bptype type;
++ enum kgdb_bpstate state;
++};
++
++/* The maximum number of KGDB I/O modules that can be loaded */
++#define MAX_KGDB_IO_HANDLERS 3
++
++#ifndef MAX_BREAKPOINTS
++#define MAX_BREAKPOINTS 1000
++#endif
++
++#define KGDB_HW_BREAKPOINT 1
++
++/* Required functions. */
++/**
++ * regs_to_gdb_regs - Convert ptrace regs to GDB regs
++ * @gdb_regs: A pointer to hold the registers in the order GDB wants.
++ * @regs: The &struct pt_regs of the current process.
++ *
++ * Convert the pt_regs in @regs into the format for registers that
++ * GDB expects, stored in @gdb_regs.
++ */
++extern void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs);
++
++/**
++ * sleeping_regs_to_gdb_regs - Convert ptrace regs to GDB regs
++ * @gdb_regs: A pointer to hold the registers in the order GDB wants.
++ * @p: The &struct task_struct of the desired process.
++ *
++ * Convert the register values of the sleeping process in @p to
++ * the format that GDB expects.
++ * This function is called when kgdb does not have access to the
++ * &struct pt_regs and therefore it should fill the gdb registers
++ * @gdb_regs with what has been saved in &struct thread_struct
++ * thread field during switch_to.
++ */
++extern void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
++ struct task_struct *p);
++
++/**
++ * gdb_regs_to_regs - Convert GDB regs to ptrace regs.
++ * @gdb_regs: A pointer to hold the registers we've recieved from GDB.
++ * @regs: A pointer to a &struct pt_regs to hold these values in.
++ *
++ * Convert the GDB regs in @gdb_regs into the pt_regs, and store them
++ * in @regs.
++ */
++extern void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs);
++
++/**
++ * kgdb_arch_handle_exception - Handle architecture specific GDB packets.
++ * @vector: The error vector of the exception that happened.
++ * @signo: The signal number of the exception that happened.
++ * @err_code: The error code of the exception that happened.
++ * @remcom_in_buffer: The buffer of the packet we have read.
++ * @remcom_out_buffer: The buffer, of %BUFMAX to write a packet into.
++ * @regs: The &struct pt_regs of the current process.
++ *
++ * This function MUST handle the 'c' and 's' command packets,
++ * as well packets to set / remove a hardware breakpoint, if used.
++ * If there are additional packets which the hardware needs to handle,
++ * they are handled here. The code should return -1 if it wants to
++ * process more packets, and a %0 or %1 if it wants to exit from the
++ * kgdb hook.
++ */
++extern int kgdb_arch_handle_exception(int vector, int signo, int err_code,
++ char *remcom_in_buffer,
++ char *remcom_out_buffer,
++ struct pt_regs *regs);
++
++#ifndef JMP_REGS_ALIGNMENT
++#define JMP_REGS_ALIGNMENT
++#endif
++
++extern unsigned long kgdb_fault_jmp_regs[];
++
++/**
++ * kgdb_fault_setjmp - Store state in case we fault.
++ * @curr_context: An array to store state into.
++ *
++ * Certain functions may try and access memory, and in doing so may
++ * cause a fault. When this happens, we trap it, restore state to
++ * this call, and let ourself know that something bad has happened.
++ */
++extern asmlinkage int kgdb_fault_setjmp(unsigned long *curr_context);
++
++/**
++ * kgdb_fault_longjmp - Restore state when we have faulted.
++ * @curr_context: The previously stored state.
++ *
++ * When something bad does happen, this function is called to
++ * restore the known good state, and set the return value to 1, so
++ * we know something bad happened.
++ */
++extern asmlinkage void kgdb_fault_longjmp(unsigned long *curr_context);
++
++/* Optional functions. */
++extern int kgdb_arch_init(void);
++extern void kgdb_disable_hw_debug(struct pt_regs *regs);
++extern void kgdb_post_master_code(struct pt_regs *regs, int e_vector,
++ int err_code);
++extern void kgdb_roundup_cpus(unsigned long flags);
++extern int kgdb_set_hw_break(unsigned long addr);
++extern int kgdb_remove_hw_break(unsigned long addr);
++extern void kgdb_remove_all_hw_break(void);
++extern void kgdb_correct_hw_break(void);
++extern void kgdb_shadowinfo(struct pt_regs *regs, char *buffer,
++ unsigned threadid);
++extern struct task_struct *kgdb_get_shadow_thread(struct pt_regs *regs,
++ int threadid);
++extern struct pt_regs *kgdb_shadow_regs(struct pt_regs *regs, int threadid);
++extern int kgdb_validate_break_address(unsigned long addr);
++extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr);
++extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle);
++
++/**
++ * struct kgdb_arch - Desribe architecture specific values.
++ * @gdb_bpt_instr: The instruction to trigger a breakpoint.
++ * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT.
++ * @shadowth: A value of %1 indicates we shadow information on processes.
++ * @set_breakpoint: Allow an architecture to specify how to set a software
++ * breakpoint.
++ * @remove_breakpoint: Allow an architecture to specify how to remove a
++ * software breakpoint.
++ * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware
++ * breakpoint.
++ * @remove_hw_breakpoint: Allow an architecture to specify how to remove a
++ * hardware breakpoint.
++ *
++ * The @shadowth flag is an option to shadow information not retrievable by
++ * gdb otherwise. This is deprecated in favor of a binutils which supports
++ * CFI macros.
++ */
++struct kgdb_arch {
++ unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE];
++ unsigned long flags;
++ unsigned shadowth;
++ int (*set_breakpoint) (unsigned long, char *);
++ int (*remove_breakpoint)(unsigned long, char *);
++ int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
++ int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
++};
++
++/* Thread reference */
++typedef unsigned char threadref[8];
++
++/**
++ * struct kgdb_io - Desribe the interface for an I/O driver to talk with KGDB.
++ * @read_char: Pointer to a function that will return one char.
++ * @write_char: Pointer to a function that will write one char.
++ * @flush: Pointer to a function that will flush any pending writes.
++ * @init: Pointer to a function that will initialize the device.
++ * @late_init: Pointer to a function that will do any setup that has
++ * other dependencies.
++ * @pre_exception: Pointer to a function that will do any prep work for
++ * the I/O driver.
++ * @post_exception: Pointer to a function that will do any cleanup work
++ * for the I/O driver.
++ *
++ * The @init and @late_init function pointers allow for an I/O driver
++ * such as a serial driver to fully initialize the port with @init and
++ * be called very early, yet safely call request_irq() later in the boot
++ * sequence.
++ *
++ * @init is allowed to return a non-0 return value to indicate failure.
++ * If this is called early on, then KGDB will try again when it would call
++ * @late_init. If it has failed later in boot as well, the user will be
++ * notified.
++ */
++struct kgdb_io {
++ int (*read_char) (void);
++ void (*write_char) (u8);
++ void (*flush) (void);
++ int (*init) (void);
++ void (*late_init) (void);
++ void (*pre_exception) (void);
++ void (*post_exception) (void);
++};
++
++extern struct kgdb_io kgdb_io_ops;
++extern struct kgdb_arch arch_kgdb_ops;
++extern int kgdb_initialized;
++
++extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
++extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
++
++extern void __init kgdb8250_add_port(int i, struct uart_port *serial_req);
++extern void __init kgdb8250_add_platform_port(int i, struct plat_serial8250_port *serial_req);
++
++extern int kgdb_hex2long(char **ptr, long *long_val);
++extern char *kgdb_mem2hex(char *mem, char *buf, int count);
++extern char *kgdb_hex2mem(char *buf, char *mem, int count);
++extern int kgdb_get_mem(char *addr, unsigned char *buf, int count);
++extern int kgdb_set_mem(char *addr, unsigned char *buf, int count);
++
++int kgdb_isremovedbreak(unsigned long addr);
++int kgdb_skipexception(int exception, struct pt_regs *regs);
++
++extern int kgdb_handle_exception(int ex_vector, int signo, int err_code,
++ struct pt_regs *regs);
++extern void kgdb_nmihook(int cpu, void *regs);
++extern int debugger_step;
++extern atomic_t debugger_active;
++#else
++/* Stubs for when KGDB is not set. */
++static const atomic_t debugger_active = ATOMIC_INIT(0);
++#endif /* CONFIG_KGDB */
++#endif /* _KGDB_H_ */
++#endif /* __KERNEL__ */
+diff -Naur linux-2.6.25_original/include/linux/mmc/sdio_ids.h linux-2.6.25/include/linux/mmc/sdio_ids.h
+--- linux-2.6.25_original/include/linux/mmc/sdio_ids.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/linux/mmc/sdio_ids.h 2009-08-11 17:41:43.000000000 +0530
+@@ -25,5 +25,7 @@
+
+ #define SDIO_VENDOR_ID_MARVELL 0x02df
+ #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
++#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104
++#define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105
+
+ #endif
+diff -Naur linux-2.6.25_original/include/linux/module.h linux-2.6.25/include/linux/module.h
+--- linux-2.6.25_original/include/linux/module.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/linux/module.h 2009-05-16 18:43:58.000000000 +0530
+@@ -227,8 +227,17 @@
+ MODULE_STATE_LIVE,
+ MODULE_STATE_COMING,
+ MODULE_STATE_GOING,
++ MODULE_STATE_GONE,
+ };
+
++#ifdef CONFIG_KGDB
++#define MAX_SECTNAME 31
++struct mod_section {
++ void *address;
++ char name[MAX_SECTNAME + 1];
++};
++#endif
++
+ /* Similar stuff for section attributes. */
+ struct module_sect_attr
+ {
+@@ -256,6 +265,13 @@
+ /* Unique handle for this module */
+ char name[MODULE_NAME_LEN];
+
++#ifdef CONFIG_KGDB
++ /* keep kgdb info at the begining so that gdb doesn't have a chance to
++ * miss out any fields */
++ unsigned long num_sections;
++ struct mod_section *mod_sections;
++#endif
++
+ /* Sysfs stuff. */
+ struct module_kobject mkobj;
+ struct module_param_attrs *param_attrs;
+diff -Naur linux-2.6.25_original/include/linux/sched.h linux-2.6.25/include/linux/sched.h
+--- linux-2.6.25_original/include/linux/sched.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/linux/sched.h 2009-05-16 18:43:58.000000000 +0530
+@@ -993,6 +993,7 @@
+
+ struct task_struct {
+ volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
++ struct thread_info *thread_info;
+ void *stack;
+ atomic_t usage;
+ unsigned int flags; /* per process flags, defined below */
+diff -Naur linux-2.6.25_original/include/linux/serial_8250.h linux-2.6.25/include/linux/serial_8250.h
+--- linux-2.6.25_original/include/linux/serial_8250.h 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/include/linux/serial_8250.h 2009-05-16 18:43:58.000000000 +0530
+@@ -58,6 +58,7 @@
+
+ int serial8250_register_port(struct uart_port *);
+ void serial8250_unregister_port(int line);
++void serial8250_unregister_by_port(struct uart_port *port);
+ void serial8250_suspend_port(int line);
+ void serial8250_resume_port(int line);
+
+diff -Naur linux-2.6.25_original/include/linux/usb_ch9.h linux-2.6.25/include/linux/usb_ch9.h
+--- linux-2.6.25_original/include/linux/usb_ch9.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/usb_ch9.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,553 @@
++/*
++ * This file holds USB constants and structures that are needed for USB
++ * device APIs. These are used by the USB device model, which is defined
++ * in chapter 9 of the USB 2.0 specification. Linux has several APIs in C
++ * that need these:
++ *
++ * - the master/host side Linux-USB kernel driver API;
++ * - the "usbfs" user space API; and
++ * - the Linux "gadget" slave/device/peripheral side driver API.
++ *
++ * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
++ * act either as a USB master/host or as a USB slave/device. That means
++ * the master and slave side APIs benefit from working well together.
++ *
++ * There's also "Wireless USB", using low power short range radios for
++ * peripheral interconnection but otherwise building on the USB framework.
++ */
++
++#ifndef __LINUX_USB_CH9_H
++#define __LINUX_USB_CH9_H
++
++#include <linux/types.h> /* __u8 etc */
++
++/*-------------------------------------------------------------------------*/
++
++/* CONTROL REQUEST SUPPORT */
++
++/*
++ * USB directions
++ *
++ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
++ * It's also one of three fields in control requests bRequestType.
++ */
++#define USB_DIR_OUT 0 /* to device */
++#define USB_DIR_IN 0x80 /* to host */
++
++/*
++ * USB types, the second of three bRequestType fields
++ */
++#define USB_TYPE_MASK (0x03 << 5)
++#define USB_TYPE_STANDARD (0x00 << 5)
++#define USB_TYPE_CLASS (0x01 << 5)
++#define USB_TYPE_VENDOR (0x02 << 5)
++#define USB_TYPE_RESERVED (0x03 << 5)
++
++/*
++ * USB recipients, the third of three bRequestType fields
++ */
++#define USB_RECIP_MASK 0x1f
++#define USB_RECIP_DEVICE 0x00
++#define USB_RECIP_INTERFACE 0x01
++#define USB_RECIP_ENDPOINT 0x02
++#define USB_RECIP_OTHER 0x03
++
++/*
++ * Standard requests, for the bRequest field of a SETUP packet.
++ *
++ * These are qualified by the bRequestType field, so that for example
++ * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
++ * by a GET_STATUS request.
++ */
++#define USB_REQ_GET_STATUS 0x00
++#define USB_REQ_CLEAR_FEATURE 0x01
++#define USB_REQ_SET_FEATURE 0x03
++#define USB_REQ_SET_ADDRESS 0x05
++#define USB_REQ_GET_DESCRIPTOR 0x06
++#define USB_REQ_SET_DESCRIPTOR 0x07
++#define USB_REQ_GET_CONFIGURATION 0x08
++#define USB_REQ_SET_CONFIGURATION 0x09
++#define USB_REQ_GET_INTERFACE 0x0A
++#define USB_REQ_SET_INTERFACE 0x0B
++#define USB_REQ_SYNCH_FRAME 0x0C
++
++#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */
++#define USB_REQ_GET_ENCRYPTION 0x0E
++#define USB_REQ_SET_HANDSHAKE 0x0F
++#define USB_REQ_GET_HANDSHAKE 0x10
++#define USB_REQ_SET_CONNECTION 0x11
++#define USB_REQ_SET_SECURITY_DATA 0x12
++#define USB_REQ_GET_SECURITY_DATA 0x13
++#define USB_REQ_SET_WUSB_DATA 0x14
++#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
++#define USB_REQ_LOOPBACK_DATA_READ 0x16
++#define USB_REQ_SET_INTERFACE_DS 0x17
++
++/*
++ * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
++ * are read as a bit array returned by USB_REQ_GET_STATUS. (So there
++ * are at most sixteen features of each type.)
++ */
++#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
++#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
++#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
++#define USB_DEVICE_BATTERY 2 /* (wireless) */
++#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
++#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
++#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
++#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
++#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
++
++#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
++
++
++/**
++ * struct usb_ctrlrequest - SETUP data for a USB device control request
++ * @bRequestType: matches the USB bmRequestType field
++ * @bRequest: matches the USB bRequest field
++ * @wValue: matches the USB wValue field (le16 byte order)
++ * @wIndex: matches the USB wIndex field (le16 byte order)
++ * @wLength: matches the USB wLength field (le16 byte order)
++ *
++ * This structure is used to send control requests to a USB device. It matches
++ * the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
++ * USB spec for a fuller description of the different fields, and what they are
++ * used for.
++ *
++ * Note that the driver for any interface can issue control requests.
++ * For most devices, interfaces don't coordinate with each other, so
++ * such requests may be made at any time.
++ */
++struct usb_ctrlrequest {
++ __u8 bRequestType;
++ __u8 bRequest;
++ __le16 wValue;
++ __le16 wIndex;
++ __le16 wLength;
++} __attribute__ ((packed));
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
++ * (rarely) accepted by SET_DESCRIPTOR.
++ *
++ * Note that all multi-byte values here are encoded in little endian
++ * byte order "on the wire". But when exposed through Linux-USB APIs,
++ * they've been converted to cpu byte order.
++ */
++
++/*
++ * Descriptor types ... USB 2.0 spec table 9.5
++ */
++#define USB_DT_DEVICE 0x01
++#define USB_DT_CONFIG 0x02
++#define USB_DT_STRING 0x03
++#define USB_DT_INTERFACE 0x04
++#define USB_DT_ENDPOINT 0x05
++#define USB_DT_DEVICE_QUALIFIER 0x06
++#define USB_DT_OTHER_SPEED_CONFIG 0x07
++#define USB_DT_INTERFACE_POWER 0x08
++/* these are from a minor usb 2.0 revision (ECN) */
++#define USB_DT_OTG 0x09
++#define USB_DT_DEBUG 0x0a
++#define USB_DT_INTERFACE_ASSOCIATION 0x0b
++/* these are from the Wireless USB spec */
++#define USB_DT_SECURITY 0x0c
++#define USB_DT_KEY 0x0d
++#define USB_DT_ENCRYPTION_TYPE 0x0e
++#define USB_DT_BOS 0x0f
++#define USB_DT_DEVICE_CAPABILITY 0x10
++#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
++
++/* conventional codes for class-specific descriptors */
++#define USB_DT_CS_DEVICE 0x21
++#define USB_DT_CS_CONFIG 0x22
++#define USB_DT_CS_STRING 0x23
++#define USB_DT_CS_INTERFACE 0x24
++#define USB_DT_CS_ENDPOINT 0x25
++
++/* All standard descriptors have these 2 fields at the beginning */
++struct usb_descriptor_header {
++ __u8 bLength;
++ __u8 bDescriptorType;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE: Device descriptor */
++struct usb_device_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 bcdUSB;
++ __u8 bDeviceClass;
++ __u8 bDeviceSubClass;
++ __u8 bDeviceProtocol;
++ __u8 bMaxPacketSize0;
++ __le16 idVendor;
++ __le16 idProduct;
++ __le16 bcdDevice;
++ __u8 iManufacturer;
++ __u8 iProduct;
++ __u8 iSerialNumber;
++ __u8 bNumConfigurations;
++} __attribute__ ((packed));
++
++#define USB_DT_DEVICE_SIZE 18
++
++
++/*
++ * Device and/or Interface Class codes
++ * as found in bDeviceClass or bInterfaceClass
++ * and defined by www.usb.org documents
++ */
++#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
++#define USB_CLASS_AUDIO 1
++#define USB_CLASS_COMM 2
++#define USB_CLASS_HID 3
++#define USB_CLASS_PHYSICAL 5
++#define USB_CLASS_STILL_IMAGE 6
++#define USB_CLASS_PRINTER 7
++#define USB_CLASS_MASS_STORAGE 8
++#define USB_CLASS_HUB 9
++#define USB_CLASS_CDC_DATA 0x0a
++#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
++#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
++#define USB_CLASS_VIDEO 0x0e
++#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
++#define USB_CLASS_APP_SPEC 0xfe
++#define USB_CLASS_VENDOR_SPEC 0xff
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_CONFIG: Configuration descriptor information.
++ *
++ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
++ * descriptor type is different. Highspeed-capable devices can look
++ * different depending on what speed they're currently running. Only
++ * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
++ * descriptors.
++ */
++struct usb_config_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumInterfaces;
++ __u8 bConfigurationValue;
++ __u8 iConfiguration;
++ __u8 bmAttributes;
++ __u8 bMaxPower;
++} __attribute__ ((packed));
++
++#define USB_DT_CONFIG_SIZE 9
++
++/* from config descriptor bmAttributes */
++#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
++#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
++#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
++#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_STRING: String descriptor */
++struct usb_string_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wData[1]; /* UTF-16LE encoded */
++} __attribute__ ((packed));
++
++/* note that "string" zero is special, it holds language codes that
++ * the device supports, not Unicode characters.
++ */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_INTERFACE: Interface descriptor */
++struct usb_interface_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bInterfaceNumber;
++ __u8 bAlternateSetting;
++ __u8 bNumEndpoints;
++ __u8 bInterfaceClass;
++ __u8 bInterfaceSubClass;
++ __u8 bInterfaceProtocol;
++ __u8 iInterface;
++} __attribute__ ((packed));
++
++#define USB_DT_INTERFACE_SIZE 9
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_ENDPOINT: Endpoint descriptor */
++struct usb_endpoint_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bEndpointAddress;
++ __u8 bmAttributes;
++ __le16 wMaxPacketSize;
++ __u8 bInterval;
++
++ /* NOTE: these two are _only_ in audio endpoints. */
++ /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
++ __u8 bRefresh;
++ __u8 bSynchAddress;
++} __attribute__ ((packed));
++
++#define USB_DT_ENDPOINT_SIZE 7
++#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
++
++
++/*
++ * Endpoints
++ */
++#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
++#define USB_ENDPOINT_DIR_MASK 0x80
++
++#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
++#define USB_ENDPOINT_XFER_CONTROL 0
++#define USB_ENDPOINT_XFER_ISOC 1
++#define USB_ENDPOINT_XFER_BULK 2
++#define USB_ENDPOINT_XFER_INT 3
++#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
++struct usb_qualifier_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 bcdUSB;
++ __u8 bDeviceClass;
++ __u8 bDeviceSubClass;
++ __u8 bDeviceProtocol;
++ __u8 bMaxPacketSize0;
++ __u8 bNumConfigurations;
++ __u8 bRESERVED;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_OTG (from OTG 1.0a supplement) */
++struct usb_otg_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bmAttributes; /* support for HNP, SRP, etc */
++} __attribute__ ((packed));
++
++/* from usb_otg_descriptor.bmAttributes */
++#define USB_OTG_SRP (1 << 0)
++#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
++struct usb_debug_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ /* bulk endpoints with 8 byte maxpacket */
++ __u8 bDebugInEndpoint;
++ __u8 bDebugOutEndpoint;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
++struct usb_interface_assoc_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bFirstInterface;
++ __u8 bInterfaceCount;
++ __u8 bFunctionClass;
++ __u8 bFunctionSubClass;
++ __u8 bFunctionProtocol;
++ __u8 iFunction;
++} __attribute__ ((packed));
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_SECURITY: group of wireless security descriptors, including
++ * encryption types available for setting up a CC/association.
++ */
++struct usb_security_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumEncryptionTypes;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys
++ * may be retrieved.
++ */
++struct usb_key_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 tTKID[3];
++ __u8 bReserved;
++ __u8 bKeyData[0];
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */
++struct usb_encryption_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bEncryptionType;
++#define USB_ENC_TYPE_UNSECURE 0
++#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */
++#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */
++#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
++ __u8 bEncryptionValue; /* use in SET_ENCRYPTION */
++ __u8 bAuthKeyIndex;
++};
++
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_BOS: group of wireless capabilities */
++struct usb_bos_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __le16 wTotalLength;
++ __u8 bNumDeviceCaps;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */
++struct usb_dev_cap_header {
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDevCapabilityType;
++};
++
++#define USB_CAP_TYPE_WIRELESS_USB 1
++
++struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
++ __u8 bLength;
++ __u8 bDescriptorType;
++ __u8 bDevCapabilityType;
++
++ __u8 bmAttributes;
++#define USB_WIRELESS_P2P_DRD (1 << 1)
++#define USB_WIRELESS_BEACON_MASK (3 << 2)
++#define USB_WIRELESS_BEACON_SELF (1 << 2)
++#define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
++#define USB_WIRELESS_BEACON_NONE (3 << 2)
++ __le16 wPHYRates; /* bit rates, Mbps */
++#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */
++#define USB_WIRELESS_PHY_80 (1 << 1)
++#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */
++#define USB_WIRELESS_PHY_160 (1 << 3)
++#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */
++#define USB_WIRELESS_PHY_320 (1 << 5)
++#define USB_WIRELESS_PHY_400 (1 << 6)
++#define USB_WIRELESS_PHY_480 (1 << 7)
++ __u8 bmTFITXPowerInfo; /* TFI power levels */
++ __u8 bmFFITXPowerInfo; /* FFI power levels */
++ __le16 bmBandGroup;
++ __u8 bReserved;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with
++ * each endpoint descriptor for a wireless device
++ */
++struct usb_wireless_ep_comp_descriptor {
++ __u8 bLength;
++ __u8 bDescriptorType;
++
++ __u8 bMaxBurst;
++ __u8 bMaxSequence;
++ __le16 wMaxStreamDelay;
++ __le16 wOverTheAirPacketSize;
++ __u8 bOverTheAirInterval;
++ __u8 bmCompAttributes;
++#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */
++#define USB_ENDPOINT_SWITCH_NO 0
++#define USB_ENDPOINT_SWITCH_SWITCH 1
++#define USB_ENDPOINT_SWITCH_SCALE 2
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
++ * host and a device for connection set up, mutual authentication, and
++ * exchanging short lived session keys. The handshake depends on a CC.
++ */
++struct usb_handshake {
++ __u8 bMessageNumber;
++ __u8 bStatus;
++ __u8 tTKID[3];
++ __u8 bReserved;
++ __u8 CDID[16];
++ __u8 nonce[16];
++ __u8 MIC[8];
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
++ * A CC may also be set up using non-wireless secure channels (including
++ * wired USB!), and some devices may support CCs with multiple hosts.
++ */
++struct usb_connection_context {
++ __u8 CHID[16]; /* persistent host id */
++ __u8 CDID[16]; /* device id (unique w/in host context) */
++ __u8 CK[16]; /* connection key */
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* USB 2.0 defines three speeds, here's how Linux identifies them */
++
++enum usb_device_speed {
++ USB_SPEED_UNKNOWN = 0, /* enumerating */
++ USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
++ USB_SPEED_HIGH, /* usb 2.0 */
++ USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
++};
++
++enum usb_device_state {
++ /* NOTATTACHED isn't in the USB spec, and this state acts
++ * the same as ATTACHED ... but it's clearer this way.
++ */
++ USB_STATE_NOTATTACHED = 0,
++
++ /* the chapter 9 device states */
++ USB_STATE_ATTACHED,
++ USB_STATE_POWERED,
++ USB_STATE_DEFAULT, /* limited function */
++ USB_STATE_ADDRESS,
++ USB_STATE_CONFIGURED, /* most functions */
++
++ USB_STATE_SUSPENDED
++
++ /* NOTE: there are actually four different SUSPENDED
++ * states, returning to POWERED, DEFAULT, ADDRESS, or
++ * CONFIGURED respectively when SOF tokens flow again.
++ */
++};
++
++#endif /* __LINUX_USB_CH9_H */
+diff -Naur linux-2.6.25_original/include/linux/usb_gadget.h linux-2.6.25/include/linux/usb_gadget.h
+--- linux-2.6.25_original/include/linux/usb_gadget.h 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/include/linux/usb_gadget.h 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,881 @@
++/*
++ * <linux/usb_gadget.h>
++ *
++ * We call the USB code inside a Linux-based peripheral device a "gadget"
++ * driver, except for the hardware-specific bus glue. One USB host can
++ * master many USB gadgets, but the gadgets are only slaved to one host.
++ *
++ *
++ * (C) Copyright 2002-2004 by David Brownell
++ * All Rights Reserved.
++ *
++ * This software is licensed under the GNU GPL version 2.
++ */
++
++#ifndef __LINUX_USB_GADGET_H
++#define __LINUX_USB_GADGET_H
++
++#ifdef __KERNEL__
++
++struct usb_ep;
++
++/**
++ * struct usb_request - describes one i/o request
++ * @buf: Buffer used for data. Always provide this; some controllers
++ * only use PIO, or don't use DMA for some endpoints.
++ * @dma: DMA address corresponding to 'buf'. If you don't set this
++ * field, and the usb controller needs one, it is responsible
++ * for mapping and unmapping the buffer.
++ * @length: Length of that data
++ * @no_interrupt: If true, hints that no completion irq is needed.
++ * Helpful sometimes with deep request queues that are handled
++ * directly by DMA controllers.
++ * @zero: If true, when writing data, makes the last packet be "short"
++ * by adding a zero length packet as needed;
++ * @short_not_ok: When reading data, makes short packets be
++ * treated as errors (queue stops advancing till cleanup).
++ * @complete: Function called when request completes, so this request and
++ * its buffer may be re-used.
++ * Reads terminate with a short packet, or when the buffer fills,
++ * whichever comes first. When writes terminate, some data bytes
++ * will usually still be in flight (often in a hardware fifo).
++ * Errors (for reads or writes) stop the queue from advancing
++ * until the completion function returns, so that any transfers
++ * invalidated by the error may first be dequeued.
++ * @context: For use by the completion callback
++ * @list: For use by the gadget driver.
++ * @status: Reports completion code, zero or a negative errno.
++ * Normally, faults block the transfer queue from advancing until
++ * the completion callback returns.
++ * Code "-ESHUTDOWN" indicates completion caused by device disconnect,
++ * or when the driver disabled the endpoint.
++ * @actual: Reports bytes transferred to/from the buffer. For reads (OUT
++ * transfers) this may be less than the requested length. If the
++ * short_not_ok flag is set, short reads are treated as errors
++ * even when status otherwise indicates successful completion.
++ * Note that for writes (IN transfers) some data bytes may still
++ * reside in a device-side FIFO when the request is reported as
++ * complete.
++ *
++ * These are allocated/freed through the endpoint they're used with. The
++ * hardware's driver can add extra per-request data to the memory it returns,
++ * which often avoids separate memory allocations (potential failures),
++ * later when the request is queued.
++ *
++ * Request flags affect request handling, such as whether a zero length
++ * packet is written (the "zero" flag), whether a short read should be
++ * treated as an error (blocking request queue advance, the "short_not_ok"
++ * flag), or hinting that an interrupt is not required (the "no_interrupt"
++ * flag, for use with deep request queues).
++ *
++ * Bulk endpoints can use any size buffers, and can also be used for interrupt
++ * transfers. interrupt-only endpoints can be much less functional.
++ */
++ // NOTE this is analagous to 'struct urb' on the host side,
++ // except that it's thinner and promotes more pre-allocation.
++
++struct usb_request {
++ void *buf;
++ unsigned length;
++ dma_addr_t dma;
++
++ unsigned no_interrupt:1;
++ unsigned zero:1;
++ unsigned short_not_ok:1;
++
++ void (*complete)(struct usb_ep *ep,
++ struct usb_request *req);
++ void *context;
++ struct list_head list;
++
++ int status;
++ unsigned actual;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/* endpoint-specific parts of the api to the usb controller hardware.
++ * unlike the urb model, (de)multiplexing layers are not required.
++ * (so this api could slash overhead if used on the host side...)
++ *
++ * note that device side usb controllers commonly differ in how many
++ * endpoints they support, as well as their capabilities.
++ */
++struct usb_ep_ops {
++ int (*enable) (struct usb_ep *ep,
++ const struct usb_endpoint_descriptor *desc);
++ int (*disable) (struct usb_ep *ep);
++
++ struct usb_request *(*alloc_request) (struct usb_ep *ep,
++ gfp_t gfp_flags);
++ void (*free_request) (struct usb_ep *ep, struct usb_request *req);
++
++ void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
++ dma_addr_t *dma, gfp_t gfp_flags);
++ void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
++ unsigned bytes);
++ // NOTE: on 2.6, drivers may also use dma_map() and
++ // dma_sync_single_*() to directly manage dma overhead.
++
++ int (*queue) (struct usb_ep *ep, struct usb_request *req,
++ gfp_t gfp_flags);
++ int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
++
++ int (*set_halt) (struct usb_ep *ep, int value);
++ int (*fifo_status) (struct usb_ep *ep);
++ void (*fifo_flush) (struct usb_ep *ep);
++};
++
++/**
++ * struct usb_ep - device side representation of USB endpoint
++ * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk"
++ * @ops: Function pointers used to access hardware-specific operations.
++ * @ep_list:the gadget's ep_list holds all of its endpoints
++ * @maxpacket:The maximum packet size used on this endpoint. The initial
++ * value can sometimes be reduced (hardware allowing), according to
++ * the endpoint descriptor used to configure the endpoint.
++ * @driver_data:for use by the gadget driver. all other fields are
++ * read-only to gadget drivers.
++ *
++ * the bus controller driver lists all the general purpose endpoints in
++ * gadget->ep_list. the control endpoint (gadget->ep0) is not in that list,
++ * and is accessed only in response to a driver setup() callback.
++ */
++struct usb_ep {
++ void *driver_data;
++
++ const char *name;
++ const struct usb_ep_ops *ops;
++ struct list_head ep_list;
++ unsigned maxpacket:16;
++};
++
++/*-------------------------------------------------------------------------*/
++
++/**
++ * usb_ep_enable - configure endpoint, making it usable
++ * @ep:the endpoint being configured. may not be the endpoint named "ep0".
++ * drivers discover endpoints through the ep_list of a usb_gadget.
++ * @desc:descriptor for desired behavior. caller guarantees this pointer
++ * remains valid until the endpoint is disabled; the data byte order
++ * is little-endian (usb-standard).
++ *
++ * when configurations are set, or when interface settings change, the driver
++ * will enable or disable the relevant endpoints. while it is enabled, an
++ * endpoint may be used for i/o until the driver receives a disconnect() from
++ * the host or until the endpoint is disabled.
++ *
++ * the ep0 implementation (which calls this routine) must ensure that the
++ * hardware capabilities of each endpoint match the descriptor provided
++ * for it. for example, an endpoint named "ep2in-bulk" would be usable
++ * for interrupt transfers as well as bulk, but it likely couldn't be used
++ * for iso transfers or for endpoint 14. some endpoints are fully
++ * configurable, with more generic names like "ep-a". (remember that for
++ * USB, "in" means "towards the USB master".)
++ *
++ * returns zero, or a negative error code.
++ */
++static inline int
++usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc)
++{
++ return ep->ops->enable (ep, desc);
++}
++
++/**
++ * usb_ep_disable - endpoint is no longer usable
++ * @ep:the endpoint being unconfigured. may not be the endpoint named "ep0".
++ *
++ * no other task may be using this endpoint when this is called.
++ * any pending and uncompleted requests will complete with status
++ * indicating disconnect (-ESHUTDOWN) before this call returns.
++ * gadget drivers must call usb_ep_enable() again before queueing
++ * requests to the endpoint.
++ *
++ * returns zero, or a negative error code.
++ */
++static inline int
++usb_ep_disable (struct usb_ep *ep)
++{
++ return ep->ops->disable (ep);
++}
++
++/**
++ * usb_ep_alloc_request - allocate a request object to use with this endpoint
++ * @ep:the endpoint to be used with with the request
++ * @gfp_flags:GFP_* flags to use
++ *
++ * Request objects must be allocated with this call, since they normally
++ * need controller-specific setup and may even need endpoint-specific
++ * resources such as allocation of DMA descriptors.
++ * Requests may be submitted with usb_ep_queue(), and receive a single
++ * completion callback. Free requests with usb_ep_free_request(), when
++ * they are no longer needed.
++ *
++ * Returns the request, or null if one could not be allocated.
++ */
++static inline struct usb_request *
++usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags)
++{
++ return ep->ops->alloc_request (ep, gfp_flags);
++}
++
++/**
++ * usb_ep_free_request - frees a request object
++ * @ep:the endpoint associated with the request
++ * @req:the request being freed
++ *
++ * Reverses the effect of usb_ep_alloc_request().
++ * Caller guarantees the request is not queued, and that it will
++ * no longer be requeued (or otherwise used).
++ */
++static inline void
++usb_ep_free_request (struct usb_ep *ep, struct usb_request *req)
++{
++ ep->ops->free_request (ep, req);
++}
++
++/**
++ * usb_ep_alloc_buffer - allocate an I/O buffer
++ * @ep:the endpoint associated with the buffer
++ * @len:length of the desired buffer
++ * @dma:pointer to the buffer's DMA address; must be valid
++ * @gfp_flags:GFP_* flags to use
++ *
++ * Returns a new buffer, or null if one could not be allocated.
++ * The buffer is suitably aligned for dma, if that endpoint uses DMA,
++ * and the caller won't have to care about dma-inconsistency
++ * or any hidden "bounce buffer" mechanism. No additional per-request
++ * DMA mapping will be required for such buffers.
++ * Free it later with usb_ep_free_buffer().
++ *
++ * You don't need to use this call to allocate I/O buffers unless you
++ * want to make sure drivers don't incur costs for such "bounce buffer"
++ * copies or per-request DMA mappings.
++ */
++static inline void *
++usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
++ gfp_t gfp_flags)
++{
++ return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
++}
++
++/**
++ * usb_ep_free_buffer - frees an i/o buffer
++ * @ep:the endpoint associated with the buffer
++ * @buf:CPU view address of the buffer
++ * @dma:the buffer's DMA address
++ * @len:length of the buffer
++ *
++ * reverses the effect of usb_ep_alloc_buffer().
++ * caller guarantees the buffer will no longer be accessed
++ */
++static inline void
++usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len)
++{
++ ep->ops->free_buffer (ep, buf, dma, len);
++}
++
++/**
++ * usb_ep_queue - queues (submits) an I/O request to an endpoint.
++ * @ep:the endpoint associated with the request
++ * @req:the request being submitted
++ * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't
++ * pre-allocate all necessary memory with the request.
++ *
++ * This tells the device controller to perform the specified request through
++ * that endpoint (reading or writing a buffer). When the request completes,
++ * including being canceled by usb_ep_dequeue(), the request's completion
++ * routine is called to return the request to the driver. Any endpoint
++ * (except control endpoints like ep0) may have more than one transfer
++ * request queued; they complete in FIFO order. Once a gadget driver
++ * submits a request, that request may not be examined or modified until it
++ * is given back to that driver through the completion callback.
++ *
++ * Each request is turned into one or more packets. The controller driver
++ * never merges adjacent requests into the same packet. OUT transfers
++ * will sometimes use data that's already buffered in the hardware.
++ * Drivers can rely on the fact that the first byte of the request's buffer
++ * always corresponds to the first byte of some USB packet, for both
++ * IN and OUT transfers.
++ *
++ * Bulk endpoints can queue any amount of data; the transfer is packetized
++ * automatically. The last packet will be short if the request doesn't fill it
++ * out completely. Zero length packets (ZLPs) should be avoided in portable
++ * protocols since not all usb hardware can successfully handle zero length
++ * packets. (ZLPs may be explicitly written, and may be implicitly written if
++ * the request 'zero' flag is set.) Bulk endpoints may also be used
++ * for interrupt transfers; but the reverse is not true, and some endpoints
++ * won't support every interrupt transfer. (Such as 768 byte packets.)
++ *
++ * Interrupt-only endpoints are less functional than bulk endpoints, for
++ * example by not supporting queueing or not handling buffers that are
++ * larger than the endpoint's maxpacket size. They may also treat data
++ * toggle differently.
++ *
++ * Control endpoints ... after getting a setup() callback, the driver queues
++ * one response (even if it would be zero length). That enables the
++ * status ack, after transfering data as specified in the response. Setup
++ * functions may return negative error codes to generate protocol stalls.
++ * (Note that some USB device controllers disallow protocol stall responses
++ * in some cases.) When control responses are deferred (the response is
++ * written after the setup callback returns), then usb_ep_set_halt() may be
++ * used on ep0 to trigger protocol stalls.
++ *
++ * For periodic endpoints, like interrupt or isochronous ones, the usb host
++ * arranges to poll once per interval, and the gadget driver usually will
++ * have queued some data to transfer at that time.
++ *
++ * Returns zero, or a negative error code. Endpoints that are not enabled
++ * report errors; errors will also be
++ * reported when the usb peripheral is disconnected.
++ */
++static inline int
++usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags)
++{
++ return ep->ops->queue (ep, req, gfp_flags);
++}
++
++/**
++ * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint
++ * @ep:the endpoint associated with the request
++ * @req:the request being canceled
++ *
++ * if the request is still active on the endpoint, it is dequeued and its
++ * completion routine is called (with status -ECONNRESET); else a negative
++ * error code is returned.
++ *
++ * note that some hardware can't clear out write fifos (to unlink the request
++ * at the head of the queue) except as part of disconnecting from usb. such
++ * restrictions prevent drivers from supporting configuration changes,
++ * even to configuration zero (a "chapter 9" requirement).
++ */
++static inline int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req)
++{
++ return ep->ops->dequeue (ep, req);
++}
++
++/**
++ * usb_ep_set_halt - sets the endpoint halt feature.
++ * @ep: the non-isochronous endpoint being stalled
++ *
++ * Use this to stall an endpoint, perhaps as an error report.
++ * Except for control endpoints,
++ * the endpoint stays halted (will not stream any data) until the host
++ * clears this feature; drivers may need to empty the endpoint's request
++ * queue first, to make sure no inappropriate transfers happen.
++ *
++ * Note that while an endpoint CLEAR_FEATURE will be invisible to the
++ * gadget driver, a SET_INTERFACE will not be. To reset endpoints for the
++ * current altsetting, see usb_ep_clear_halt(). When switching altsettings,
++ * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints.
++ *
++ * Returns zero, or a negative error code. On success, this call sets
++ * underlying hardware state that blocks data transfers.
++ * Attempts to halt IN endpoints will fail (returning -EAGAIN) if any
++ * transfer requests are still queued, or if the controller hardware
++ * (usually a FIFO) still holds bytes that the host hasn't collected.
++ */
++static inline int
++usb_ep_set_halt (struct usb_ep *ep)
++{
++ return ep->ops->set_halt (ep, 1);
++}
++
++/**
++ * usb_ep_clear_halt - clears endpoint halt, and resets toggle
++ * @ep:the bulk or interrupt endpoint being reset
++ *
++ * Use this when responding to the standard usb "set interface" request,
++ * for endpoints that aren't reconfigured, after clearing any other state
++ * in the endpoint's i/o queue.
++ *
++ * Returns zero, or a negative error code. On success, this call clears
++ * the underlying hardware state reflecting endpoint halt and data toggle.
++ * Note that some hardware can't support this request (like pxa2xx_udc),
++ * and accordingly can't correctly implement interface altsettings.
++ */
++static inline int
++usb_ep_clear_halt (struct usb_ep *ep)
++{
++ return ep->ops->set_halt (ep, 0);
++}
++
++/**
++ * usb_ep_fifo_status - returns number of bytes in fifo, or error
++ * @ep: the endpoint whose fifo status is being checked.
++ *
++ * FIFO endpoints may have "unclaimed data" in them in certain cases,
++ * such as after aborted transfers. Hosts may not have collected all
++ * the IN data written by the gadget driver (and reported by a request
++ * completion). The gadget driver may not have collected all the data
++ * written OUT to it by the host. Drivers that need precise handling for
++ * fault reporting or recovery may need to use this call.
++ *
++ * This returns the number of such bytes in the fifo, or a negative
++ * errno if the endpoint doesn't use a FIFO or doesn't support such
++ * precise handling.
++ */
++static inline int
++usb_ep_fifo_status (struct usb_ep *ep)
++{
++ if (ep->ops->fifo_status)
++ return ep->ops->fifo_status (ep);
++ else
++ return -EOPNOTSUPP;
++}
++
++/**
++ * usb_ep_fifo_flush - flushes contents of a fifo
++ * @ep: the endpoint whose fifo is being flushed.
++ *
++ * This call may be used to flush the "unclaimed data" that may exist in
++ * an endpoint fifo after abnormal transaction terminations. The call
++ * must never be used except when endpoint is not being used for any
++ * protocol translation.
++ */
++static inline void
++usb_ep_fifo_flush (struct usb_ep *ep)
++{
++ if (ep->ops->fifo_flush)
++ ep->ops->fifo_flush (ep);
++}
++
++
++/*-------------------------------------------------------------------------*/
++
++struct usb_gadget;
++
++/* the rest of the api to the controller hardware: device operations,
++ * which don't involve endpoints (or i/o).
++ */
++struct usb_gadget_ops {
++ int (*get_frame)(struct usb_gadget *);
++ int (*wakeup)(struct usb_gadget *);
++ int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
++ int (*vbus_session) (struct usb_gadget *, int is_active);
++ int (*vbus_draw) (struct usb_gadget *, unsigned mA);
++ int (*pullup) (struct usb_gadget *, int is_on);
++ int (*ioctl)(struct usb_gadget *,
++ unsigned code, unsigned long param);
++};
++
++/**
++ * struct usb_gadget - represents a usb slave device
++ * @ops: Function pointers used to access hardware-specific operations.
++ * @ep0: Endpoint zero, used when reading or writing responses to
++ * driver setup() requests
++ * @ep_list: List of other endpoints supported by the device.
++ * @speed: Speed of current connection to USB host.
++ * @is_dualspeed: True if the controller supports both high and full speed
++ * operation. If it does, the gadget driver must also support both.
++ * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
++ * gadget driver must provide a USB OTG descriptor.
++ * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
++ * is in the Mini-AB jack, and HNP has been used to switch roles
++ * so that the "A" device currently acts as A-Peripheral, not A-Host.
++ * @a_hnp_support: OTG device feature flag, indicating that the A-Host
++ * supports HNP at this port.
++ * @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host
++ * only supports HNP on a different root port.
++ * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
++ * enabled HNP support.
++ * @name: Identifies the controller hardware type. Used in diagnostics
++ * and sometimes configuration.
++ * @dev: Driver model state for this abstract device.
++ *
++ * Gadgets have a mostly-portable "gadget driver" implementing device
++ * functions, handling all usb configurations and interfaces. Gadget
++ * drivers talk to hardware-specific code indirectly, through ops vectors.
++ * That insulates the gadget driver from hardware details, and packages
++ * the hardware endpoints through generic i/o queues. The "usb_gadget"
++ * and "usb_ep" interfaces provide that insulation from the hardware.
++ *
++ * Except for the driver data, all fields in this structure are
++ * read-only to the gadget driver. That driver data is part of the
++ * "driver model" infrastructure in 2.6 (and later) kernels, and for
++ * earlier systems is grouped in a similar structure that's not known
++ * to the rest of the kernel.
++ *
++ * Values of the three OTG device feature flags are updated before the
++ * setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before
++ * driver suspend() calls. They are valid only when is_otg, and when the
++ * device is acting as a B-Peripheral (so is_a_peripheral is false).
++ */
++struct usb_gadget {
++ /* readonly to gadget driver */
++ const struct usb_gadget_ops *ops;
++ struct usb_ep *ep0;
++ struct list_head ep_list; /* of usb_ep */
++ enum usb_device_speed speed;
++ unsigned is_dualspeed:1;
++ unsigned is_otg:1;
++ unsigned is_a_peripheral:1;
++ unsigned b_hnp_enable:1;
++ unsigned a_hnp_support:1;
++ unsigned a_alt_hnp_support:1;
++ const char *name;
++ struct device dev;
++};
++
++static inline void set_gadget_data (struct usb_gadget *gadget, void *data)
++ { dev_set_drvdata (&gadget->dev, data); }
++static inline void *get_gadget_data (struct usb_gadget *gadget)
++ { return dev_get_drvdata (&gadget->dev); }
++
++/* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */
++#define gadget_for_each_ep(tmp,gadget) \
++ list_for_each_entry(tmp, &(gadget)->ep_list, ep_list)
++
++
++/**
++ * usb_gadget_frame_number - returns the current frame number
++ * @gadget: controller that reports the frame number
++ *
++ * Returns the usb frame number, normally eleven bits from a SOF packet,
++ * or negative errno if this device doesn't support this capability.
++ */
++static inline int usb_gadget_frame_number (struct usb_gadget *gadget)
++{
++ return gadget->ops->get_frame (gadget);
++}
++
++/**
++ * usb_gadget_wakeup - tries to wake up the host connected to this gadget
++ * @gadget: controller used to wake up the host
++ *
++ * Returns zero on success, else negative error code if the hardware
++ * doesn't support such attempts, or its support has not been enabled
++ * by the usb host. Drivers must return device descriptors that report
++ * their ability to support this, or hosts won't enable it.
++ *
++ * This may also try to use SRP to wake the host and start enumeration,
++ * even if OTG isn't otherwise in use. OTG devices may also start
++ * remote wakeup even when hosts don't explicitly enable it.
++ */
++static inline int usb_gadget_wakeup (struct usb_gadget *gadget)
++{
++ if (!gadget->ops->wakeup)
++ return -EOPNOTSUPP;
++ return gadget->ops->wakeup (gadget);
++}
++
++/**
++ * usb_gadget_set_selfpowered - sets the device selfpowered feature.
++ * @gadget:the device being declared as self-powered
++ *
++ * this affects the device status reported by the hardware driver
++ * to reflect that it now has a local power supply.
++ *
++ * returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_set_selfpowered (struct usb_gadget *gadget)
++{
++ if (!gadget->ops->set_selfpowered)
++ return -EOPNOTSUPP;
++ return gadget->ops->set_selfpowered (gadget, 1);
++}
++
++/**
++ * usb_gadget_clear_selfpowered - clear the device selfpowered feature.
++ * @gadget:the device being declared as bus-powered
++ *
++ * this affects the device status reported by the hardware driver.
++ * some hardware may not support bus-powered operation, in which
++ * case this feature's value can never change.
++ *
++ * returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_clear_selfpowered (struct usb_gadget *gadget)
++{
++ if (!gadget->ops->set_selfpowered)
++ return -EOPNOTSUPP;
++ return gadget->ops->set_selfpowered (gadget, 0);
++}
++
++/**
++ * usb_gadget_vbus_connect - Notify controller that VBUS is powered
++ * @gadget:The device which now has VBUS power.
++ *
++ * This call is used by a driver for an external transceiver (or GPIO)
++ * that detects a VBUS power session starting. Common responses include
++ * resuming the controller, activating the D+ (or D-) pullup to let the
++ * host detect that a USB device is attached, and starting to draw power
++ * (8mA or possibly more, especially after SET_CONFIGURATION).
++ *
++ * Returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_vbus_connect(struct usb_gadget *gadget)
++{
++ if (!gadget->ops->vbus_session)
++ return -EOPNOTSUPP;
++ return gadget->ops->vbus_session (gadget, 1);
++}
++
++/**
++ * usb_gadget_vbus_draw - constrain controller's VBUS power usage
++ * @gadget:The device whose VBUS usage is being described
++ * @mA:How much current to draw, in milliAmperes. This should be twice
++ * the value listed in the configuration descriptor bMaxPower field.
++ *
++ * This call is used by gadget drivers during SET_CONFIGURATION calls,
++ * reporting how much power the device may consume. For example, this
++ * could affect how quickly batteries are recharged.
++ *
++ * Returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
++{
++ if (!gadget->ops->vbus_draw)
++ return -EOPNOTSUPP;
++ return gadget->ops->vbus_draw (gadget, mA);
++}
++
++/**
++ * usb_gadget_vbus_disconnect - notify controller about VBUS session end
++ * @gadget:the device whose VBUS supply is being described
++ *
++ * This call is used by a driver for an external transceiver (or GPIO)
++ * that detects a VBUS power session ending. Common responses include
++ * reversing everything done in usb_gadget_vbus_connect().
++ *
++ * Returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
++{
++ if (!gadget->ops->vbus_session)
++ return -EOPNOTSUPP;
++ return gadget->ops->vbus_session (gadget, 0);
++}
++
++/**
++ * usb_gadget_connect - software-controlled connect to USB host
++ * @gadget:the peripheral being connected
++ *
++ * Enables the D+ (or potentially D-) pullup. The host will start
++ * enumerating this gadget when the pullup is active and a VBUS session
++ * is active (the link is powered). This pullup is always enabled unless
++ * usb_gadget_disconnect() has been used to disable it.
++ *
++ * Returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_connect (struct usb_gadget *gadget)
++{
++ if (!gadget->ops->pullup)
++ return -EOPNOTSUPP;
++ return gadget->ops->pullup (gadget, 1);
++}
++
++/**
++ * usb_gadget_disconnect - software-controlled disconnect from USB host
++ * @gadget:the peripheral being disconnected
++ *
++ * Disables the D+ (or potentially D-) pullup, which the host may see
++ * as a disconnect (when a VBUS session is active). Not all systems
++ * support software pullup controls.
++ *
++ * This routine may be used during the gadget driver bind() call to prevent
++ * the peripheral from ever being visible to the USB host, unless later
++ * usb_gadget_connect() is called. For example, user mode components may
++ * need to be activated before the system can talk to hosts.
++ *
++ * Returns zero on success, else negative errno.
++ */
++static inline int
++usb_gadget_disconnect (struct usb_gadget *gadget)
++{
++ if (!gadget->ops->pullup)
++ return -EOPNOTSUPP;
++ return gadget->ops->pullup (gadget, 0);
++}
++
++
++
++/*-------------------------------------------------------------------------*/
++
++/**
++ * struct usb_gadget_driver - driver for usb 'slave' devices
++ * @function: String describing the gadget's function
++ * @speed: Highest speed the driver handles.
++ * @bind: Invoked when the driver is bound to a gadget, usually
++ * after registering the driver.
++ * At that point, ep0 is fully initialized, and ep_list holds
++ * the currently-available endpoints.
++ * Called in a context that permits sleeping.
++ * @setup: Invoked for ep0 control requests that aren't handled by
++ * the hardware level driver. Most calls must be handled by
++ * the gadget driver, including descriptor and configuration
++ * management. The 16 bit members of the setup data are in
++ * USB byte order. Called in_interrupt; this may not sleep. Driver
++ * queues a response to ep0, or returns negative to stall.
++ * @disconnect: Invoked after all transfers have been stopped,
++ * when the host is disconnected. May be called in_interrupt; this
++ * may not sleep. Some devices can't detect disconnect, so this might
++ * not be called except as part of controller shutdown.
++ * @unbind: Invoked when the driver is unbound from a gadget,
++ * usually from rmmod (after a disconnect is reported).
++ * Called in a context that permits sleeping.
++ * @suspend: Invoked on USB suspend. May be called in_interrupt.
++ * @resume: Invoked on USB resume. May be called in_interrupt.
++ * @driver: Driver model state for this driver.
++ *
++ * Devices are disabled till a gadget driver successfully bind()s, which
++ * means the driver will handle setup() requests needed to enumerate (and
++ * meet "chapter 9" requirements) then do some useful work.
++ *
++ * If gadget->is_otg is true, the gadget driver must provide an OTG
++ * descriptor during enumeration, or else fail the bind() call. In such
++ * cases, no USB traffic may flow until both bind() returns without
++ * having called usb_gadget_disconnect(), and the USB host stack has
++ * initialized.
++ *
++ * Drivers use hardware-specific knowledge to configure the usb hardware.
++ * endpoint addressing is only one of several hardware characteristics that
++ * are in descriptors the ep0 implementation returns from setup() calls.
++ *
++ * Except for ep0 implementation, most driver code shouldn't need change to
++ * run on top of different usb controllers. It'll use endpoints set up by
++ * that ep0 implementation.
++ *
++ * The usb controller driver handles a few standard usb requests. Those
++ * include set_address, and feature flags for devices, interfaces, and
++ * endpoints (the get_status, set_feature, and clear_feature requests).
++ *
++ * Accordingly, the driver's setup() callback must always implement all
++ * get_descriptor requests, returning at least a device descriptor and
++ * a configuration descriptor. Drivers must make sure the endpoint
++ * descriptors match any hardware constraints. Some hardware also constrains
++ * other descriptors. (The pxa250 allows only configurations 1, 2, or 3).
++ *
++ * The driver's setup() callback must also implement set_configuration,
++ * and should also implement set_interface, get_configuration, and
++ * get_interface. Setting a configuration (or interface) is where
++ * endpoints should be activated or (config 0) shut down.
++ *
++ * (Note that only the default control endpoint is supported. Neither
++ * hosts nor devices generally support control traffic except to ep0.)
++ *
++ * Most devices will ignore USB suspend/resume operations, and so will
++ * not provide those callbacks. However, some may need to change modes
++ * when the host is not longer directing those activities. For example,
++ * local controls (buttons, dials, etc) may need to be re-enabled since
++ * the (remote) host can't do that any longer; or an error state might
++ * be cleared, to make the device behave identically whether or not
++ * power is maintained.
++ */
++struct usb_gadget_driver {
++ char *function;
++ enum usb_device_speed speed;
++ int (*bind)(struct usb_gadget *);
++ void (*unbind)(struct usb_gadget *);
++ int (*setup)(struct usb_gadget *,
++ const struct usb_ctrlrequest *);
++ void (*disconnect)(struct usb_gadget *);
++ void (*suspend)(struct usb_gadget *);
++ void (*resume)(struct usb_gadget *);
++
++ // FIXME support safe rmmod
++ struct device_driver driver;
++};
++
++
++
++/*-------------------------------------------------------------------------*/
++
++/* driver modules register and unregister, as usual.
++ * these calls must be made in a context that can sleep.
++ *
++ * these will usually be implemented directly by the hardware-dependent
++ * usb bus interface driver, which will only support a single driver.
++ */
++
++/**
++ * usb_gadget_register_driver - register a gadget driver
++ * @driver:the driver being registered
++ *
++ * Call this in your gadget driver's module initialization function,
++ * to tell the underlying usb controller driver about your driver.
++ * The driver's bind() function will be called to bind it to a
++ * gadget before this registration call returns. It's expected that
++ * the bind() functions will be in init sections.
++ * This function must be called in a context that can sleep.
++ */
++int usb_gadget_register_driver (struct usb_gadget_driver *driver);
++
++/**
++ * usb_gadget_unregister_driver - unregister a gadget driver
++ * @driver:the driver being unregistered
++ *
++ * Call this in your gadget driver's module cleanup function,
++ * to tell the underlying usb controller that your driver is
++ * going away. If the controller is connected to a USB host,
++ * it will first disconnect(). The driver is also requested
++ * to unbind() and clean up any device state, before this procedure
++ * finally returns. It's expected that the unbind() functions
++ * will in in exit sections, so may not be linked in some kernels.
++ * This function must be called in a context that can sleep.
++ */
++int usb_gadget_unregister_driver (struct usb_gadget_driver *driver);
++
++/*-------------------------------------------------------------------------*/
++
++/* utility to simplify dealing with string descriptors */
++
++/**
++ * struct usb_string - wraps a C string and its USB id
++ * @id:the (nonzero) ID for this string
++ * @s:the string, in UTF-8 encoding
++ *
++ * If you're using usb_gadget_get_string(), use this to wrap a string
++ * together with its ID.
++ */
++struct usb_string {
++ u8 id;
++ const char *s;
++};
++
++/**
++ * struct usb_gadget_strings - a set of USB strings in a given language
++ * @language:identifies the strings' language (0x0409 for en-us)
++ * @strings:array of strings with their ids
++ *
++ * If you're using usb_gadget_get_string(), use this to wrap all the
++ * strings for a given language.
++ */
++struct usb_gadget_strings {
++ u16 language; /* 0x0409 for en-us */
++ struct usb_string *strings;
++};
++
++/* put descriptor for string with that id into buf (buflen >= 256) */
++int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf);
++
++/*-------------------------------------------------------------------------*/
++
++/* utility to simplify managing config descriptors */
++
++/* write vector of descriptors into buffer */
++int usb_descriptor_fillbuf(void *, unsigned,
++ const struct usb_descriptor_header **);
++
++/* build config descriptor from single descriptor vector */
++int usb_gadget_config_buf(const struct usb_config_descriptor *config,
++ void *buf, unsigned buflen, const struct usb_descriptor_header **desc);
++
++/*-------------------------------------------------------------------------*/
++
++/* utility wrapping a simple endpoint selection policy */
++
++extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *,
++ struct usb_endpoint_descriptor *) __devinit;
++
++extern void usb_ep_autoconfig_reset (struct usb_gadget *) __devinit;
++
++#endif /* __KERNEL__ */
++
++#endif /* __LINUX_USB_GADGET_H */
+diff -Naur linux-2.6.25_original/kernel/kgdb.c linux-2.6.25/kernel/kgdb.c
+--- linux-2.6.25_original/kernel/kgdb.c 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/kernel/kgdb.c 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,1970 @@
++/*
++ * kernel/kgdb.c
++ *
++ * Maintainer: Tom Rini <trini@kernel.crashing.org>
++ *
++ * Copyright (C) 2000-2001 VERITAS Software Corporation.
++ * Copyright (C) 2002-2004 Timesys Corporation
++ * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com>
++ * Copyright (C) 2004 Pavel Machek <pavel@suse.cz>
++ * Copyright (C) 2004-2005 Tom Rini <trini@kernel.crashing.org>
++ * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd.
++ * Copyright (C) 2005 Wind River Systems, Inc.
++ *
++ * Contributors at various stages not listed above:
++ * Jason Wessel ( jason.wessel@windriver.com )
++ * George Anzinger <george@mvista.com>
++ * Anurekh Saxena (anurekh.saxena@timesys.com)
++ * Lake Stevens Instrument Division (Glenn Engel)
++ * Jim Kingdon, Cygnus Support.
++ *
++ * Original KGDB stub: David Grothe <dave@gcom.com>,
++ * Tigran Aivazian <tigran@sco.com>
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++#include <linux/config.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/spinlock.h>
++#include <linux/delay.h>
++#include <linux/mm.h>
++#include <linux/threads.h>
++#include <linux/reboot.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>
++#include <asm/uaccess.h>
++#include <linux/kgdb.h>
++#include <asm/atomic.h>
++#include <linux/notifier.h>
++#include <linux/module.h>
++#include <asm/cacheflush.h>
++#include <linux/init.h>
++#include <linux/sysrq.h>
++#include <linux/console.h>
++#include <asm/byteorder.h>
++
++extern int pid_max;
++extern int pidhash_init_done;
++
++/* How many times to count all of the waiting CPUs */
++#define ROUNDUP_WAIT 640000 /* Arbitrary, increase if needed. */
++#define BUF_THREAD_ID_SIZE 16
++
++/*
++ * kgdb_initialized with a value of 1 indicates that kgdb is setup and is
++ * all ready to serve breakpoints and other kernel exceptions. A value of
++ * -1 indicates that we have tried to initialize early, and need to try
++ * again later.
++ */
++int kgdb_initialized;
++/* Is a host GDB connected to us? */
++int kgdb_connected;
++/* Could we be about to try and access a bad memory location? If so we
++ * also need to flag this has happend. */
++int kgdb_may_fault;
++/* All the KGDB handlers are installed */
++int kgdb_from_module_registered = 0;
++
++/* We provide a kgdb_io_ops structure that may be overriden. */
++struct kgdb_io __attribute__ ((weak)) kgdb_io_ops;
++
++static struct kgdb_io kgdb_io_ops_prev[MAX_KGDB_IO_HANDLERS];
++static int kgdb_io_handler_cnt = 0;
++
++/* Export the following symbols for use with kernel modules */
++EXPORT_SYMBOL(kgdb_io_ops);
++EXPORT_SYMBOL(kgdb_tasklet_breakpoint);
++EXPORT_SYMBOL(kgdb_connected);
++EXPORT_SYMBOL(kgdb_register_io_module);
++EXPORT_SYMBOL(kgdb_unregister_io_module);
++EXPORT_SYMBOL(debugger_active);
++
++/*
++ * Holds information about breakpoints in a kernel. These breakpoints are
++ * added and removed by gdb.
++ */
++struct kgdb_bkpt kgdb_break[MAX_BREAKPOINTS];
++
++struct kgdb_arch *kgdb_ops = &arch_kgdb_ops;
++
++static const char hexchars[] = "0123456789abcdef";
++
++static spinlock_t slavecpulocks[NR_CPUS];
++static atomic_t procindebug[NR_CPUS];
++atomic_t kgdb_setting_breakpoint;
++EXPORT_SYMBOL(kgdb_setting_breakpoint);
++struct task_struct *kgdb_usethread, *kgdb_contthread;
++
++int debugger_step;
++atomic_t debugger_active;
++
++/* Our I/O buffers. */
++static char remcom_in_buffer[BUFMAX];
++static char remcom_out_buffer[BUFMAX];
++/* Storage for the registers, in GDB format. */
++static unsigned long gdb_regs[(NUMREGBYTES + sizeof(unsigned long) - 1) /
++ sizeof(unsigned long)];
++/* Storage of registers for handling a fault. */
++unsigned long kgdb_fault_jmp_regs[NUMCRITREGBYTES / sizeof(unsigned long)]
++ JMP_REGS_ALIGNMENT;
++static int kgdb_notify_reboot(struct notifier_block *this,
++ unsigned long code ,void *x);
++struct debuggerinfo_struct {
++ void *debuggerinfo;
++ struct task_struct *task;
++} kgdb_info[NR_CPUS];
++
++/* to keep track of the CPU which is doing the single stepping*/
++atomic_t cpu_doing_single_step = ATOMIC_INIT(-1);
++
++atomic_t kgdb_sync_softlockup[NR_CPUS] = {ATOMIC_INIT(0)};
++
++/* reboot notifier block */
++static struct notifier_block kgdb_reboot_notifier = {
++ .notifier_call = kgdb_notify_reboot,
++ .next = NULL,
++ .priority = INT_MAX,
++};
++
++/**
++ * kgdb_arch_init - Perform any architecture specific initalization.
++ *
++ * RETURN:
++ * The return value is ignored.
++ *
++ * This function will handle the initalization of any architecture
++ * specific hooks.
++ */
++int __attribute__ ((weak))
++ kgdb_arch_init(void)
++{
++ return 0;
++}
++
++/**
++ * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb.
++ * @regs: Current &struct pt_regs.
++ *
++ * This function will be called if the particular architecture must
++ * disable hardware debugging while it is processing gdb packets or
++ * handling exception.
++ */
++void __attribute__ ((weak))
++ kgdb_disable_hw_debug(struct pt_regs *regs)
++{
++}
++
++/*
++ * Skip an int3 exception when it occurs after a breakpoint has been
++ * removed. Backtrack eip by 1 since the int3 would have caused it to
++ * increment by 1.
++ */
++int __attribute__ ((weak))
++ kgdb_skipexception(int exception, struct pt_regs *regs)
++{
++ return 0;
++}
++
++/**
++ * kgdb_set_hw_break - Set a hardware breakpoint at @addr.
++ * @addr: The address to set a hardware breakpoint at.
++ */
++int __attribute__ ((weak))
++ kgdb_set_hw_break(unsigned long addr)
++{
++ return 0;
++}
++
++/**
++ * kgdb_remove_hw_break - Remove a hardware breakpoint at @addr.
++ * @addr: The address to remove a hardware breakpoint from.
++ */
++int __attribute__ ((weak))
++ kgdb_remove_hw_break(unsigned long addr)
++{
++ return 0;
++}
++
++/**
++ * kgdb_remove_all_hw_break - Clear all hardware breakpoints.
++ */
++void __attribute__ ((weak))
++ kgdb_remove_all_hw_break(void)
++{
++}
++
++/**
++ * kgdb_correct_hw_break - Correct hardware breakpoints.
++ *
++ * A hook to allow for changes to the hardware breakpoint, called
++ * after a single step (s) or continue (c) packet, and once we're about
++ * to let the kernel continue running.
++ *
++ * This is used to set the hardware breakpoint registers for all the
++ * slave cpus on an SMP configuration. This must be called after any
++ * changes are made to the hardware breakpoints (such as by a single
++ * step (s) or continue (c) packet. This is only required on
++ * architectures that support SMP and every processor has its own set
++ * of breakpoint registers.
++ */
++void __attribute__ ((weak))
++ kgdb_correct_hw_break(void)
++{
++}
++
++/**
++ * kgdb_post_master_code - Save error vector/code numbers.
++ * @regs: Original pt_regs.
++ * @e_vector: Original error vector.
++ * @err_code: Original error code.
++ *
++ * This is needed on architectures which support SMP and KGDB.
++ * This function is called after all the slave cpus have been put
++ * to a know spin state and the master CPU has control over KGDB.
++ */
++
++void __attribute__ ((weak))
++ kgdb_post_master_code(struct pt_regs *regs, int e_vector, int err_code)
++{
++}
++
++/**
++ * kgdb_roundup_cpus - Get other CPUs into a holding pattern
++ * @flags: Current IRQ state
++ *
++ * On SMP systems, we need to get the attention of the other CPUs
++ * and get them be in a known state. This should do what is needed
++ * to get the other CPUs to call kgdb_wait(). Note that on some arches,
++ * the NMI approach is not used for rounding up all the CPUs. For example,
++ * in case of MIPS, smp_call_function() is used to roundup CPUs. In
++ * this case, we have to make sure that interrupts are enabled before
++ * calling smp_call_function(). The argument to this function is
++ * the flags that will be used when restoring the interrupts. There is
++ * local_irq_save() call before kgdb_roundup_cpus().
++ */
++void __attribute__ ((weak))
++ kgdb_roundup_cpus(unsigned long flags)
++{
++}
++
++/**
++ * kgdb_shadowinfo - Get shadowed information on @threadid.
++ * @regs: The &struct pt_regs of the current process.
++ * @buffer: A buffer of %BUFMAX size.
++ * @threadid: The thread id of the shadowed process to get information on.
++ */
++void __attribute__ ((weak))
++ kgdb_shadowinfo(struct pt_regs *regs, char *buffer, unsigned threadid)
++{
++}
++
++
++/**
++ * kgdb_get_shadow_thread - Get the shadowed &task_struct of @threadid.
++ * @regs: The &struct pt_regs of the current thread.
++ * @threadid: The thread id of the shadowed process to get information on.
++ *
++ * RETURN:
++ * This returns a pointer to the &struct task_struct of the shadowed
++ * thread, @threadid.
++ */
++struct task_struct __attribute__ ((weak))
++ * kgdb_get_shadow_thread(struct pt_regs *regs, int threadid)
++{
++
++ return NULL;
++}
++
++/**
++ * kgdb_shadow_regs - Return the shadowed registers of @threadid.
++ * @regs: The &struct pt_regs of the current thread.
++ * @threadid: The thread id we want the &struct pt_regs for.
++ *
++ * RETURN:
++ * The a pointer to the &struct pt_regs of the shadowed thread @threadid.
++ */
++struct pt_regs __attribute__ ((weak))
++ * kgdb_shadow_regs(struct pt_regs *regs, int threadid)
++{
++
++ return NULL;
++}
++
++int __attribute__ ((weak))
++ kgdb_validate_break_address(unsigned long addr)
++{
++ int error = 0;
++ char tmp_variable[BREAK_INSTR_SIZE];
++ error = kgdb_get_mem((char *)addr, tmp_variable, BREAK_INSTR_SIZE);
++ return error;
++}
++
++int __attribute__ ((weak))
++ kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
++{
++ int error = 0;
++ if ((error = kgdb_get_mem((char *)addr,
++ saved_instr, BREAK_INSTR_SIZE)) < 0)
++ return error;
++
++ if ((error = kgdb_set_mem((char *)addr, kgdb_ops->gdb_bpt_instr,
++ BREAK_INSTR_SIZE)) < 0)
++ return error;
++ return 0;
++}
++
++int __attribute__ ((weak))
++ kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
++{
++
++ int error = 0;
++ if ((error =kgdb_set_mem((char *)addr, (char *)bundle,
++ BREAK_INSTR_SIZE)) < 0)
++ return error;
++ return 0;
++}
++
++static int hex(char ch)
++{
++ if ((ch >= 'a') && (ch <= 'f'))
++ return (ch - 'a' + 10);
++ if ((ch >= '0') && (ch <= '9'))
++ return (ch - '0');
++ if ((ch >= 'A') && (ch <= 'F'))
++ return (ch - 'A' + 10);
++ return (-1);
++}
++
++/* scan for the sequence $<data>#<checksum> */
++static void get_packet(char *buffer)
++{
++ unsigned char checksum;
++ unsigned char xmitcsum;
++ int count;
++ char ch;
++ if (!kgdb_io_ops.read_char)
++ return;
++ do {
++ /* Spin and wait around for the start character, ignore all
++ * other characters */
++ while ((ch = (kgdb_io_ops.read_char())) != '$') ;
++ kgdb_connected = 1;
++ checksum = 0;
++ xmitcsum = -1;
++
++ count = 0;
++
++ /* now, read until a # or end of buffer is found */
++ while (count < (BUFMAX - 1)) {
++ ch = kgdb_io_ops.read_char();
++ if (ch == '#')
++ break;
++ checksum = checksum + ch;
++ buffer[count] = ch;
++ count = count + 1;
++ }
++ buffer[count] = 0;
++
++ if (ch == '#') {
++ xmitcsum = hex(kgdb_io_ops.read_char()) << 4;
++ xmitcsum += hex(kgdb_io_ops.read_char());
++
++ if (checksum != xmitcsum)
++ /* failed checksum */
++ kgdb_io_ops.write_char('-');
++ else
++ /* successful transfer */
++ kgdb_io_ops.write_char('+');
++ if (kgdb_io_ops.flush)
++ kgdb_io_ops.flush();
++ }
++ } while (checksum != xmitcsum);
++}
++
++/*
++ * Send the packet in buffer.
++ * Check for gdb connection if asked for.
++ */
++static void put_packet(char *buffer)
++{
++ unsigned char checksum;
++ int count;
++ char ch;
++
++ if (!kgdb_io_ops.write_char)
++ return;
++ /* $<packet info>#<checksum>. */
++ while (1) {
++ kgdb_io_ops.write_char('$');
++ checksum = 0;
++ count = 0;
++
++ while ((ch = buffer[count])) {
++ kgdb_io_ops.write_char(ch);
++ checksum += ch;
++ count++;
++ }
++
++ kgdb_io_ops.write_char('#');
++ kgdb_io_ops.write_char(hexchars[checksum >> 4]);
++ kgdb_io_ops.write_char(hexchars[checksum % 16]);
++ if (kgdb_io_ops.flush)
++ kgdb_io_ops.flush();
++
++ /* Now see what we get in reply. */
++ ch = kgdb_io_ops.read_char();
++
++ if (ch == 3)
++ ch = kgdb_io_ops.read_char();
++
++ /* If we get an ACK, we are done. */
++ if (ch == '+')
++ return;
++
++ /* If we get the start of another packet, this means
++ * that GDB is attempting to reconnect. We will NAK
++ * the packet being sent, and stop trying to send this
++ * packet. */
++ if (ch == '$') {
++ kgdb_io_ops.write_char('-');
++ if (kgdb_io_ops.flush)
++ kgdb_io_ops.flush();
++ return;
++ }
++ }
++}
++
++/*
++ * convert the memory pointed to by mem into hex, placing result in buf
++ * return a pointer to the last char put in buf (null). May return an error.
++ */
++char *kgdb_mem2hex(char *mem, char *buf, int count)
++{
++ kgdb_may_fault = 1;
++ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {
++ kgdb_may_fault = 0;
++ return ERR_PTR(-EINVAL);
++ }
++ /* Accessing some registers in a single load instruction is
++ * required to avoid bad side effects for some I/O registers.
++ */
++ if ((count == 2) && (((long)mem & 1) == 0)) {
++ unsigned short tmp_s = *(unsigned short *)mem;
++ mem += 2;
++#ifdef __BIG_ENDIAN
++ *buf++ = hexchars[(tmp_s >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_s >> 8) & 0xf];
++ *buf++ = hexchars[(tmp_s >> 4) & 0xf];
++ *buf++ = hexchars[tmp_s & 0xf];
++#else
++ *buf++ = hexchars[(tmp_s >> 4) & 0xf];
++ *buf++ = hexchars[tmp_s & 0xf];
++ *buf++ = hexchars[(tmp_s >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_s >> 8) & 0xf];
++#endif
++ } else if ((count == 4) && (((long)mem & 3) == 0)) {
++ unsigned long tmp_l = *(unsigned int *)mem;
++ mem += 4;
++#ifdef __BIG_ENDIAN
++ *buf++ = hexchars[(tmp_l >> 28) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 24) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 20) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 16) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 8) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 4) & 0xf];
++ *buf++ = hexchars[tmp_l & 0xf];
++#else
++ *buf++ = hexchars[(tmp_l >> 4) & 0xf];
++ *buf++ = hexchars[tmp_l & 0xf];
++ *buf++ = hexchars[(tmp_l >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 8) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 20) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 16) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 28) & 0xf];
++ *buf++ = hexchars[(tmp_l >> 24) & 0xf];
++#endif
++#ifdef CONFIG_64BIT
++ } else if ((count == 8) && (((long)mem & 7) == 0)) {
++ unsigned long long tmp_ll = *(unsigned long long *)mem;
++ mem += 8;
++#ifdef __BIG_ENDIAN
++ *buf++ = hexchars[(tmp_ll >> 60) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 56) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 52) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 48) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 44) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 40) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 36) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 32) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 28) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 24) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 20) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 16) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 8) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 4) & 0xf];
++ *buf++ = hexchars[tmp_ll & 0xf];
++#else
++ *buf++ = hexchars[(tmp_ll >> 4) & 0xf];
++ *buf++ = hexchars[tmp_ll & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 12) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 8) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 20) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 16) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 28) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 24) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 36) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 32) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 44) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 40) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 52) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 48) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 60) & 0xf];
++ *buf++ = hexchars[(tmp_ll >> 56) & 0xf];
++#endif
++#endif
++ } else {
++ while (count-- > 0) {
++ unsigned char ch = *mem++;
++ *buf++ = hexchars[ch >> 4];
++ *buf++ = hexchars[ch & 0xf];
++ }
++ }
++ kgdb_may_fault = 0;
++ *buf = 0;
++ return (buf);
++}
++
++/*
++ * Copy the binary array pointed to by buf into mem. Fix $, #, and
++ * 0x7d escaped with 0x7d. Return a pointer to the character after
++ * the last byte written.
++ */
++static char *kgdb_ebin2mem(char *buf, char *mem, int count)
++{
++ kgdb_may_fault = 1;
++ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {
++ kgdb_may_fault = 0;
++ return ERR_PTR(-EINVAL);
++ }
++ for (; count > 0; count--, buf++) {
++ if (*buf == 0x7d)
++ *mem++ = *(++buf) ^ 0x20;
++ else
++ *mem++ = *buf;
++ }
++ kgdb_may_fault = 0;
++ return mem;
++}
++
++/*
++ * convert the hex array pointed to by buf into binary to be placed in mem
++ * return a pointer to the character AFTER the last byte written
++ * May return an error.
++ */
++char *kgdb_hex2mem(char *buf, char *mem, int count)
++{
++ kgdb_may_fault = 1;
++ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {
++ kgdb_may_fault = 0;
++ return ERR_PTR(-EINVAL);
++ }
++ if ((count == 2) && (((long)mem & 1) == 0)) {
++ unsigned short tmp_s = 0;
++#ifdef __BIG_ENDIAN
++ tmp_s |= hex(*buf++) << 12;
++ tmp_s |= hex(*buf++) << 8;
++ tmp_s |= hex(*buf++) << 4;
++ tmp_s |= hex(*buf++);
++#else
++ tmp_s |= hex(*buf++) << 4;
++ tmp_s |= hex(*buf++);
++ tmp_s |= hex(*buf++) << 12;
++ tmp_s |= hex(*buf++) << 8;
++#endif
++ *(unsigned short *)mem = tmp_s;
++ mem += 2;
++ } else if ((count == 4) && (((long)mem & 3) == 0)) {
++ unsigned long tmp_l = 0;
++#ifdef __BIG_ENDIAN
++ tmp_l |= hex(*buf++) << 28;
++ tmp_l |= hex(*buf++) << 24;
++ tmp_l |= hex(*buf++) << 20;
++ tmp_l |= hex(*buf++) << 16;
++ tmp_l |= hex(*buf++) << 12;
++ tmp_l |= hex(*buf++) << 8;
++ tmp_l |= hex(*buf++) << 4;
++ tmp_l |= hex(*buf++);
++#else
++ tmp_l |= hex(*buf++) << 4;
++ tmp_l |= hex(*buf++);
++ tmp_l |= hex(*buf++) << 12;
++ tmp_l |= hex(*buf++) << 8;
++ tmp_l |= hex(*buf++) << 20;
++ tmp_l |= hex(*buf++) << 16;
++ tmp_l |= hex(*buf++) << 28;
++ tmp_l |= hex(*buf++) << 24;
++#endif
++ *(unsigned long *)mem = tmp_l;
++ mem += 4;
++ } else {
++ int i;
++ for (i = 0; i < count; i++) {
++ unsigned char ch = hex(*buf++) << 4;
++ ch |= hex(*buf++);
++ *mem++ = ch;
++ }
++ }
++ kgdb_may_fault = 0;
++ return (mem);
++}
++
++/*
++ * While we find nice hex chars, build a long_val.
++ * Return number of chars processed.
++ */
++int kgdb_hex2long(char **ptr, long *long_val)
++{
++ int hex_val, num = 0;
++
++ *long_val = 0;
++
++ while (**ptr) {
++ hex_val = hex(**ptr);
++ if (hex_val >= 0) {
++ *long_val = (*long_val << 4) | hex_val;
++ num++;
++ } else
++ break;
++
++ (*ptr)++;
++ }
++
++ return (num);
++}
++
++/* Write memory due to an 'M' or 'X' packet. */
++static char *write_mem_msg(int binary)
++{
++ char *ptr = &remcom_in_buffer[1];
++ unsigned long addr, length;
++
++ if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' &&
++ kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') {
++ if (binary)
++ ptr = kgdb_ebin2mem(ptr, (char *)addr, length);
++ else
++ ptr = kgdb_hex2mem(ptr, (char *)addr, length);
++ if (CACHE_FLUSH_IS_SAFE)
++ flush_icache_range(addr, addr + length + 1);
++ if (IS_ERR(ptr))
++ return ptr;
++ return NULL;
++ }
++
++ return ERR_PTR(-EINVAL);
++}
++
++static inline char *pack_hex_byte(char *pkt, int byte)
++{
++ *pkt++ = hexchars[(byte >> 4) & 0xf];
++ *pkt++ = hexchars[(byte & 0xf)];
++ return pkt;
++}
++
++static inline void error_packet(char *pkt, int error)
++{
++ error = -error;
++ pkt[0] = 'E';
++ pkt[1] = hexchars[(error / 10)];
++ pkt[2] = hexchars[(error % 10)];
++ pkt[3] = '\0';
++}
++
++static char *pack_threadid(char *pkt, threadref * id)
++{
++ char *limit;
++ unsigned char *altid;
++
++ altid = (unsigned char *)id;
++ limit = pkt + BUF_THREAD_ID_SIZE;
++ while (pkt < limit)
++ pkt = pack_hex_byte(pkt, *altid++);
++
++ return pkt;
++}
++
++void int_to_threadref(threadref * id, int value)
++{
++ unsigned char *scan;
++ int i = 4;
++
++ scan = (unsigned char *)id;
++ while (i--)
++ *scan++ = 0;
++ *scan++ = (value >> 24) & 0xff;
++ *scan++ = (value >> 16) & 0xff;
++ *scan++ = (value >> 8) & 0xff;
++ *scan++ = (value & 0xff);
++}
++
++static struct task_struct *getthread(struct pt_regs *regs, int tid)
++{
++ if (!pidhash_init_done)
++ return current;
++
++ if (num_online_cpus() &&
++ (tid >= pid_max + num_online_cpus() + kgdb_ops->shadowth))
++ return NULL;
++
++ if (kgdb_ops->shadowth && (tid >= pid_max + num_online_cpus()))
++ return kgdb_get_shadow_thread(regs, tid - pid_max -
++ num_online_cpus());
++
++ if (tid >= pid_max)
++ return idle_task(tid - pid_max);
++
++ if (!tid)
++ return NULL;
++
++ return find_task_by_pid(tid);
++}
++
++#ifdef CONFIG_SMP
++static void kgdb_wait(struct pt_regs *regs)
++{
++ unsigned long flags;
++ int processor;
++
++ local_irq_save(flags);
++ processor = smp_processor_id();
++ kgdb_info[processor].debuggerinfo = regs;
++ kgdb_info[processor].task = current;
++ atomic_set(&procindebug[processor], 1);
++
++ /* Wait till master processor goes completely into the debugger.
++ * FIXME: this looks racy */
++ while (!atomic_read(&procindebug[atomic_read(&debugger_active) - 1])) {
++ int i = 10; /* an arbitrary number */
++
++ while (--i)
++ cpu_relax();
++ }
++
++ /* Wait till master processor is done with debugging */
++ spin_lock(&slavecpulocks[processor]);
++
++ /* This has been taken from x86 kgdb implementation and
++ * will be needed by architectures that have SMP support
++ */
++ kgdb_correct_hw_break();
++
++ kgdb_info[processor].debuggerinfo = NULL;
++ kgdb_info[processor].task = NULL;
++
++ /* Signal the master processor that we are done */
++ atomic_set(&procindebug[processor], 0);
++ spin_unlock(&slavecpulocks[processor]);
++ local_irq_restore(flags);
++}
++#endif
++
++int kgdb_get_mem(char *addr, unsigned char *buf, int count)
++{
++ kgdb_may_fault = 1;
++ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {
++ kgdb_may_fault = 0;
++ return -EINVAL;
++ }
++ while (count) {
++ if ((unsigned long)addr < TASK_SIZE)
++ return -EINVAL;
++ *buf++ = *addr++;
++ count--;
++ }
++ kgdb_may_fault = 0;
++ return 0;
++}
++
++int kgdb_set_mem(char *addr, unsigned char *buf, int count)
++{
++ kgdb_may_fault = 1;
++ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {
++ kgdb_may_fault = 0;
++ return -EINVAL;
++ }
++ while (count) {
++ if ((unsigned long)addr < TASK_SIZE)
++ return -EINVAL;
++ *addr++ = *buf++;
++ count--;
++ }
++ kgdb_may_fault = 0;
++ return 0;
++}
++int kgdb_activate_sw_breakpoints(void)
++{
++ int i;
++ int error = 0;
++ unsigned long addr;
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if (kgdb_break[i].state != bp_set)
++ continue;
++ addr = kgdb_break[i].bpt_addr;
++ if ((error = kgdb_arch_set_breakpoint(addr,
++ kgdb_break[i].saved_instr)))
++ return error;
++
++ if (CACHE_FLUSH_IS_SAFE) {
++ if (current->mm && addr < TASK_SIZE)
++ flush_cache_range(current->mm->mmap_cache,
++ addr, addr + BREAK_INSTR_SIZE);
++ else
++ flush_icache_range(addr, addr +
++ BREAK_INSTR_SIZE);
++ }
++
++ kgdb_break[i].state = bp_active;
++ }
++ return 0;
++}
++
++static int kgdb_set_sw_break(unsigned long addr)
++{
++ int i, breakno = -1;
++ int error = 0;
++ if ((error = kgdb_validate_break_address(addr)) < 0)
++ return error;
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if ((kgdb_break[i].state == bp_set) &&
++ (kgdb_break[i].bpt_addr == addr))
++ return -EEXIST;
++ }
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if (kgdb_break[i].state == bp_removed &&
++ kgdb_break[i].bpt_addr == addr) {
++ breakno = i;
++ break;
++ }
++ }
++
++ if (breakno == -1) {
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if (kgdb_break[i].state == bp_none) {
++ breakno = i;
++ break;
++ }
++ }
++ }
++ if (breakno == -1)
++ return -E2BIG;
++
++ kgdb_break[breakno].state = bp_set;
++ kgdb_break[breakno].type = bp_breakpoint;
++ kgdb_break[breakno].bpt_addr = addr;
++
++ return 0;
++}
++
++int kgdb_deactivate_sw_breakpoints(void)
++{
++ int i;
++ int error = 0;
++ unsigned long addr;
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if (kgdb_break[i].state != bp_active)
++ continue;
++ addr = kgdb_break[i].bpt_addr;
++ if ((error = kgdb_arch_remove_breakpoint(addr,
++ kgdb_break[i].saved_instr)))
++ return error;
++
++ if (CACHE_FLUSH_IS_SAFE && current->mm &&
++ addr < TASK_SIZE)
++ flush_cache_range(current->mm->mmap_cache,
++ addr, addr + BREAK_INSTR_SIZE);
++ else if (CACHE_FLUSH_IS_SAFE)
++ flush_icache_range(addr,
++ addr + BREAK_INSTR_SIZE);
++ kgdb_break[i].state = bp_set;
++ }
++ return 0;
++}
++
++static int kgdb_remove_sw_break(unsigned long addr)
++{
++ int i;
++
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if ((kgdb_break[i].state == bp_set) &&
++ (kgdb_break[i].bpt_addr == addr)) {
++ kgdb_break[i].state = bp_removed;
++ return 0;
++ }
++ }
++ return -ENOENT;
++}
++
++int kgdb_isremovedbreak(unsigned long addr)
++{
++ int i;
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if ((kgdb_break[i].state == bp_removed) &&
++ (kgdb_break[i].bpt_addr == addr)) {
++ return 1;
++ }
++ }
++ return 0;
++}
++
++int remove_all_break(void)
++{
++ int i;
++ int error;
++ unsigned long addr;
++
++ /* Clear memory breakpoints. */
++ for (i = 0; i < MAX_BREAKPOINTS; i++) {
++ if (kgdb_break[i].state != bp_set)
++ continue;
++ addr = kgdb_break[i].bpt_addr;
++ if ((error = kgdb_arch_remove_breakpoint(addr,
++ kgdb_break[i].saved_instr)))
++ return error;
++ kgdb_break[i].state = bp_removed;
++ }
++
++ /* Clear hardware breakpoints. */
++ kgdb_remove_all_hw_break();
++
++ return 0;
++}
++
++static inline int shadow_pid(int realpid)
++{
++ if (realpid) {
++ return realpid;
++ }
++ return pid_max + smp_processor_id();
++}
++
++static char gdbmsgbuf[BUFMAX + 1];
++static void kgdb_msg_write(const char *s, int len)
++{
++ int i;
++ int wcount;
++ char *bufptr;
++
++ /* 'O'utput */
++ gdbmsgbuf[0] = 'O';
++
++ /* Fill and send buffers... */
++ while (len > 0) {
++ bufptr = gdbmsgbuf + 1;
++
++ /* Calculate how many this time */
++ if ((len << 1) > (BUFMAX - 2))
++ wcount = (BUFMAX - 2) >> 1;
++ else
++ wcount = len;
++
++ /* Pack in hex chars */
++ for (i = 0; i < wcount; i++)
++ bufptr = pack_hex_byte(bufptr, s[i]);
++ *bufptr = '\0';
++
++ /* Move up */
++ s += wcount;
++ len -= wcount;
++
++ /* Write packet */
++ put_packet(gdbmsgbuf);
++ }
++}
++
++/*
++ * This function does all command procesing for interfacing to gdb.
++ *
++ * Locking hierarchy:
++ * interface locks, if any (begin_session)
++ * kgdb lock (debugger_active)
++ *
++ * Note that since we can be in here prior to our cpumask being filled
++ * out, we err on the side of caution and loop over NR_CPUS instead
++ * of a for_each_online_cpu.
++ *
++ */
++int kgdb_handle_exception(int ex_vector, int signo, int err_code,
++ struct pt_regs *linux_regs)
++{
++ unsigned long length, addr;
++ char *ptr;
++ unsigned long flags;
++ unsigned i;
++ long threadid;
++ threadref thref;
++ struct task_struct *thread = NULL;
++ unsigned procid;
++ int numshadowth = num_online_cpus() + kgdb_ops->shadowth;
++ long kgdb_usethreadid = 0;
++ int error = 0, all_cpus_synced = 0;
++ struct pt_regs *shadowregs;
++ int processor = smp_processor_id();
++ void *local_debuggerinfo;
++
++ /* Panic on recursive debugger calls. */
++ if (atomic_read(&debugger_active) == smp_processor_id() + 1)
++ return 0;
++
++ acquirelock:
++
++ /* Call the I/O drivers pre_exception routine if the I/O
++ * driver defined one
++ */
++ if (kgdb_io_ops.pre_exception)
++ kgdb_io_ops.pre_exception();
++
++ /*
++ * Interrupts will be restored by the 'trap return' code, except when
++ * single stepping.
++ */
++ local_irq_save(flags);
++
++ /* Hold debugger_active */
++ procid = smp_processor_id();
++
++ while (cmpxchg(&atomic_read(&debugger_active), 0, (procid + 1)) != 0) {
++ int i = 25; /* an arbitrary number */
++
++ while (--i)
++ cpu_relax();
++
++ if (atomic_read(&cpu_doing_single_step) != -1 &&
++ atomic_read(&cpu_doing_single_step) != procid)
++ udelay(1);
++ }
++
++ /*
++ * Don't enter if the last instance of the exception handler wanted to
++ * come into the debugger again.
++ */
++ if (atomic_read(&cpu_doing_single_step) != -1 &&
++ atomic_read(&cpu_doing_single_step) != procid) {
++ atomic_set(&debugger_active, 0);
++ local_irq_restore(flags);
++ goto acquirelock;
++ }
++
++ atomic_set(&kgdb_sync_softlockup[smp_processor_id()], 1);
++
++ /*
++ * Don't enter if we have hit a removed breakpoint.
++ */
++ if (kgdb_skipexception(ex_vector, linux_regs))
++ goto kgdb_restore;
++
++ kgdb_info[processor].debuggerinfo = linux_regs;
++ kgdb_info[processor].task = current;
++
++ kgdb_disable_hw_debug(linux_regs);
++
++ if (!debugger_step || !kgdb_contthread)
++ for (i = 0; i < NR_CPUS; i++)
++ spin_lock(&slavecpulocks[i]);
++
++ /* Make sure we get the other CPUs */
++ if (!debugger_step || !kgdb_contthread)
++ kgdb_roundup_cpus(flags);
++
++ /* spin_lock code is good enough as a barrier so we don't
++ * need one here */
++ atomic_set(&procindebug[processor], 1);
++
++ /* Wait a reasonable time for the other CPUs to be notified and
++ * be waiting for us. Very early on this could be imperfect
++ * as num_online_cpus() could be 0.*/
++ for (i = 0; i < ROUNDUP_WAIT; i++) {
++ int cpu, num = 0;
++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
++ if (atomic_read(&procindebug[cpu]))
++ num++;
++ }
++ if (num >= num_online_cpus()) {
++ all_cpus_synced = 1;
++ break;
++ }
++ }
++
++ /* Clear the out buffer. */
++ memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
++
++ /* Master processor is completely in the debugger */
++ kgdb_post_master_code(linux_regs, ex_vector, err_code);
++ kgdb_deactivate_sw_breakpoints();
++ debugger_step = 0;
++ kgdb_contthread = NULL;
++
++ if (kgdb_connected) {
++ /* If we're still unable to roundup all of the CPUs,
++ * send an 'O' packet informing the user again. */
++ if (!all_cpus_synced)
++ kgdb_msg_write("Not all CPUs have been synced for "
++ "KGDB\n", 39);
++ /* Reply to host that an exception has occurred */
++ ptr = remcom_out_buffer;
++ *ptr++ = 'T';
++ *ptr++ = hexchars[(signo >> 4) % 16];
++ *ptr++ = hexchars[signo % 16];
++ ptr += strlen(strcpy(ptr, "thread:"));
++ int_to_threadref(&thref, shadow_pid(current->pid));
++ ptr = pack_threadid(ptr, &thref);
++ *ptr++ = ';';
++
++ put_packet(remcom_out_buffer);
++ }
++
++ kgdb_usethread = kgdb_info[processor].task;
++ kgdb_usethreadid = shadow_pid(kgdb_info[processor].task->pid);
++
++ while (kgdb_io_ops.read_char) {
++ char *bpt_type;
++ error = 0;
++
++ /* Clear the out buffer. */
++ memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
++
++ get_packet(remcom_in_buffer);
++
++ switch (remcom_in_buffer[0]) {
++ case '?':
++ /* We know that this packet is only sent
++ * during initial connect. So to be safe,
++ * we clear out our breakpoints now incase
++ * GDB is reconnecting. */
++ remove_all_break();
++ /* Also, if we haven't been able to roundup all
++ * CPUs, send an 'O' packet informing the user
++ * as much. Only need to do this once. */
++ if (!all_cpus_synced)
++ kgdb_msg_write("Not all CPUs have been "
++ "synced for KGDB\n", 39);
++ remcom_out_buffer[0] = 'S';
++ remcom_out_buffer[1] = hexchars[signo >> 4];
++ remcom_out_buffer[2] = hexchars[signo % 16];
++ break;
++
++ case 'g': /* return the value of the CPU registers */
++ thread = kgdb_usethread;
++
++ if (!thread) {
++ thread = kgdb_info[processor].task;
++ local_debuggerinfo =
++ kgdb_info[processor].debuggerinfo;
++ } else {
++ local_debuggerinfo = NULL;
++ for (i = 0; i < NR_CPUS; i++) {
++ /* Try to find the task on some other
++ * or possibly this node if we do not
++ * find the matching task then we try
++ * to approximate the results.
++ */
++ if (thread == kgdb_info[i].task)
++ local_debuggerinfo =
++ kgdb_info[i].debuggerinfo;
++ }
++ }
++
++ /* All threads that don't have debuggerinfo should be
++ * in __schedule() sleeping, since all other CPUs
++ * are in kgdb_wait, and thus have debuggerinfo. */
++ if (kgdb_ops->shadowth &&
++ kgdb_usethreadid >= pid_max + num_online_cpus()) {
++ shadowregs = kgdb_shadow_regs(linux_regs,
++ kgdb_usethreadid -
++ pid_max -
++ num_online_cpus
++ ());
++ if (!shadowregs) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ regs_to_gdb_regs(gdb_regs, shadowregs);
++ } else if (local_debuggerinfo)
++ regs_to_gdb_regs(gdb_regs, local_debuggerinfo);
++ else {
++ /* Pull stuff saved during
++ * switch_to; nothing else is
++ * accessible (or even particularly relevant).
++ * This should be enough for a stack trace. */
++ sleeping_thread_to_gdb_regs(gdb_regs, thread);
++ }
++ kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer,
++ NUMREGBYTES);
++ break;
++
++ /* set the value of the CPU registers - return OK */
++ case 'G':
++ kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs,
++ NUMREGBYTES);
++
++ if (kgdb_usethread && kgdb_usethread != current)
++ error_packet(remcom_out_buffer, -EINVAL);
++ else {
++ gdb_regs_to_regs(gdb_regs, linux_regs);
++ strcpy(remcom_out_buffer, "OK");
++ }
++ break;
++
++ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
++ case 'm':
++ ptr = &remcom_in_buffer[1];
++ if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
++ kgdb_hex2long(&ptr, &length) > 0) {
++ if (IS_ERR(ptr = kgdb_mem2hex((char *)addr,
++ remcom_out_buffer,
++ length)))
++ error_packet(remcom_out_buffer,
++ PTR_ERR(ptr));
++ } else
++ error_packet(remcom_out_buffer, -EINVAL);
++ break;
++
++ /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */
++ case 'M':
++ if (IS_ERR(ptr = write_mem_msg(0)))
++ error_packet(remcom_out_buffer, PTR_ERR(ptr));
++ else
++ strcpy(remcom_out_buffer, "OK");
++ break;
++ /* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */
++ case 'X':
++ if (IS_ERR(ptr = write_mem_msg(1)))
++ error_packet(remcom_out_buffer, PTR_ERR(ptr));
++ else
++ strcpy(remcom_out_buffer, "OK");
++ break;
++
++ /* kill or detach. KGDB should treat this like a
++ * continue.
++ */
++ case 'D':
++ if ((error = remove_all_break()) < 0) {
++ error_packet(remcom_out_buffer, error);
++ } else {
++ strcpy(remcom_out_buffer, "OK");
++ kgdb_connected = 0;
++ }
++ put_packet(remcom_out_buffer);
++ goto default_handle;
++
++ case 'k':
++ /* Don't care about error from remove_all_break */
++ remove_all_break();
++ kgdb_connected = 0;
++ goto default_handle;
++
++ /* Reboot */
++ case 'R':
++ /* For now, only honor R0 */
++ if (strcmp(remcom_in_buffer, "R0") == 0) {
++ printk(KERN_CRIT "Executing reboot\n");
++ strcpy(remcom_out_buffer, "OK");
++ put_packet(remcom_out_buffer);
++ emergency_sync();
++ /* Execution should not return from
++ * machine_restart()
++ */
++ machine_restart(NULL);
++ kgdb_connected = 0;
++ goto default_handle;
++ }
++
++ /* query */
++ case 'q':
++ switch (remcom_in_buffer[1]) {
++ case 's':
++ case 'f':
++ if (memcmp(remcom_in_buffer + 2, "ThreadInfo",
++ 10)) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++
++ /*
++ * If we have not yet completed in
++ * pidhash_init() there isn't much we
++ * can give back.
++ */
++ if (!pidhash_init_done) {
++ if (remcom_in_buffer[1] == 'f')
++ strcpy(remcom_out_buffer,
++ "m0000000000000001");
++ break;
++ }
++
++ if (remcom_in_buffer[1] == 'f') {
++ threadid = 1;
++ }
++ remcom_out_buffer[0] = 'm';
++ ptr = remcom_out_buffer + 1;
++ for (i = 0; i < 17 && threadid < pid_max +
++ numshadowth; threadid++) {
++ thread = getthread(linux_regs,
++ threadid);
++ if (thread) {
++ int_to_threadref(&thref,
++ threadid);
++ pack_threadid(ptr, &thref);
++ ptr += 16;
++ *(ptr++) = ',';
++ i++;
++ }
++ }
++ *(--ptr) = '\0';
++ break;
++
++ case 'C':
++ /* Current thread id */
++ strcpy(remcom_out_buffer, "QC");
++
++ threadid = shadow_pid(current->pid);
++
++ int_to_threadref(&thref, threadid);
++ pack_threadid(remcom_out_buffer + 2, &thref);
++ break;
++ case 'T':
++ if (memcmp(remcom_in_buffer + 1,
++ "ThreadExtraInfo,", 16)) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ threadid = 0;
++ ptr = remcom_in_buffer + 17;
++ kgdb_hex2long(&ptr, &threadid);
++ if (!getthread(linux_regs, threadid)) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ if (threadid < pid_max) {
++ kgdb_mem2hex(getthread(linux_regs,
++ threadid)->comm,
++ remcom_out_buffer, 16);
++ } else if (threadid >= pid_max +
++ num_online_cpus()) {
++ kgdb_shadowinfo(linux_regs,
++ remcom_out_buffer,
++ threadid - pid_max -
++ num_online_cpus());
++ } else {
++ static char tmpstr[23 +
++ BUF_THREAD_ID_SIZE];
++ sprintf(tmpstr, "Shadow task %d"
++ " for pid 0",
++ (int)(threadid - pid_max));
++ kgdb_mem2hex(tmpstr, remcom_out_buffer,
++ strlen(tmpstr));
++ }
++ break;
++ }
++ break;
++
++ /* task related */
++ case 'H':
++ switch (remcom_in_buffer[1]) {
++ case 'g':
++ ptr = &remcom_in_buffer[2];
++ kgdb_hex2long(&ptr, &threadid);
++ thread = getthread(linux_regs, threadid);
++ if (!thread && threadid > 0) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ kgdb_usethread = thread;
++ kgdb_usethreadid = threadid;
++ strcpy(remcom_out_buffer, "OK");
++ break;
++
++ case 'c':
++ ptr = &remcom_in_buffer[2];
++ kgdb_hex2long(&ptr, &threadid);
++ if (!threadid) {
++ kgdb_contthread = NULL;
++ } else {
++ thread = getthread(linux_regs,
++ threadid);
++ if (!thread && threadid > 0) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ kgdb_contthread = thread;
++ }
++ strcpy(remcom_out_buffer, "OK");
++ break;
++ }
++ break;
++
++ /* Query thread status */
++ case 'T':
++ ptr = &remcom_in_buffer[1];
++ kgdb_hex2long(&ptr, &threadid);
++ thread = getthread(linux_regs, threadid);
++ if (thread)
++ strcpy(remcom_out_buffer, "OK");
++ else
++ error_packet(remcom_out_buffer, -EINVAL);
++ break;
++ /* Since GDB-5.3, it's been drafted that '0' is a software
++ * breakpoint, '1' is a hardware breakpoint, so let's do
++ * that.
++ */
++ case 'z':
++ case 'Z':
++ bpt_type = &remcom_in_buffer[1];
++ ptr = &remcom_in_buffer[2];
++
++ if (kgdb_ops->set_hw_breakpoint && *bpt_type >= '1') {
++ /* Unsupported */
++ if (*bpt_type > '4')
++ break;
++ } else if (*bpt_type != '0' && *bpt_type != '1')
++ /* Unsupported. */
++ break;
++ /* Test if this is a hardware breakpoint, and
++ * if we support it. */
++ if (*bpt_type == '1' &&
++ !kgdb_ops->flags & KGDB_HW_BREAKPOINT)
++ /* Unsupported. */
++ break;
++
++ if (*(ptr++) != ',') {
++ error_packet(remcom_out_buffer, -EINVAL);
++ break;
++ } else if (kgdb_hex2long(&ptr, &addr)) {
++ if (*(ptr++) != ',' ||
++ !kgdb_hex2long(&ptr, &length)) {
++ error_packet(remcom_out_buffer,
++ -EINVAL);
++ break;
++ }
++ } else {
++ error_packet(remcom_out_buffer, -EINVAL);
++ break;
++ }
++
++ if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')
++ error = kgdb_set_sw_break(addr);
++ else if (remcom_in_buffer[0] == 'Z' && *bpt_type == '1')
++ error = kgdb_set_hw_break(addr);
++ else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')
++ error = kgdb_remove_sw_break(addr);
++ else if (remcom_in_buffer[0] == 'z' && *bpt_type == '1')
++ error = kgdb_remove_hw_break(addr);
++ else if (remcom_in_buffer[0] == 'Z')
++ error = kgdb_ops->set_hw_breakpoint(addr,
++ (int)length,
++ *bpt_type);
++ else if (remcom_in_buffer[0] == 'z')
++ error = kgdb_ops->remove_hw_breakpoint(addr,
++ (int)
++ length,
++ *bpt_type);
++
++ if (error == 0)
++ strcpy(remcom_out_buffer, "OK");
++ else
++ error_packet(remcom_out_buffer, error);
++
++ break;
++ case 'c':
++ case 's':
++ if (kgdb_contthread && kgdb_contthread != current) {
++ /* Can't switch threads in kgdb */
++ error_packet(remcom_out_buffer, -EINVAL);
++ break;
++ }
++ kgdb_activate_sw_breakpoints();
++ /* Followthrough to default processing */
++ default:
++ default_handle:
++ error = kgdb_arch_handle_exception(ex_vector, signo,
++ err_code,
++ remcom_in_buffer,
++ remcom_out_buffer,
++ linux_regs);
++
++ if (error >= 0 || remcom_in_buffer[0] == 'D' ||
++ remcom_in_buffer[0] == 'k')
++ goto kgdb_exit;
++
++ } /* switch */
++
++ /* reply to the request */
++ put_packet(remcom_out_buffer);
++ }
++
++ kgdb_exit:
++ /* Call the I/O driver's post_exception routine if the I/O
++ * driver defined one.
++ */
++ if (kgdb_io_ops.post_exception)
++ kgdb_io_ops.post_exception();
++
++ kgdb_info[processor].debuggerinfo = NULL;
++ kgdb_info[processor].task = NULL;
++ atomic_set(&procindebug[processor], 0);
++
++ if (!debugger_step || !kgdb_contthread) {
++ for (i = 0; i < NR_CPUS; i++)
++ spin_unlock(&slavecpulocks[i]);
++ /* Wait till all the processors have quit
++ * from the debugger. */
++ for (i = 0; i < NR_CPUS; i++) {
++ while (atomic_read(&procindebug[i])) {
++ int j = 10; /* an arbitrary number */
++
++ while (--j)
++ cpu_relax();
++ }
++ }
++ }
++
++#ifdef CONFIG_SMP
++ /* This delay has a real purpose. The problem is that if you
++ * are single-stepping, you are sending an NMI to all the
++ * other processors to stop them. Interrupts come in, but
++ * don't get handled. Then you let them go just long enough
++ * to get into their interrupt routines and use up some stack.
++ * You stop them again, and then do the same thing. After a
++ * while you blow the stack on the other processors. This
++ * delay gives some time for interrupts to be cleared out on
++ * the other processors.
++ */
++ if (debugger_step)
++ mdelay(2);
++#endif
++kgdb_restore:
++ /* Free debugger_active */
++ atomic_set(&debugger_active, 0);
++ local_irq_restore(flags);
++
++ return error;
++}
++
++/*
++ * GDB places a breakpoint at this function to know dynamically
++ * loaded objects. It's not defined static so that only one instance with this
++ * name exists in the kernel.
++ */
++
++int module_event(struct notifier_block *self, unsigned long val, void *data)
++{
++ return 0;
++}
++
++static struct notifier_block kgdb_module_load_nb = {
++ .notifier_call = module_event,
++};
++
++void kgdb_nmihook(int cpu, void *regs)
++{
++#ifdef CONFIG_SMP
++ if (!atomic_read(&procindebug[cpu]) && atomic_read(&debugger_active) != (cpu + 1))
++ kgdb_wait((struct pt_regs *)regs);
++#endif
++}
++
++/*
++ * This is called when a panic happens. All we need to do is
++ * breakpoint().
++ */
++static int kgdb_panic_notify(struct notifier_block *self, unsigned long cmd,
++ void *ptr)
++{
++ breakpoint();
++
++ return 0;
++}
++
++static struct notifier_block kgdb_panic_notifier = {
++ .notifier_call = kgdb_panic_notify,
++};
++
++/*
++ * Initialization that needs to be done in either of our entry points.
++ */
++static void __init kgdb_internal_init(void)
++{
++ int i;
++
++ /* Initialize our spinlocks. */
++ for (i = 0; i < NR_CPUS; i++)
++ spin_lock_init(&slavecpulocks[i]);
++
++ for (i = 0; i < MAX_BREAKPOINTS; i++)
++ kgdb_break[i].state = bp_none;
++
++ /* Initialize the I/O handles */
++ memset(&kgdb_io_ops_prev, 0, sizeof(kgdb_io_ops_prev));
++
++ /* We can't do much if this fails */
++ register_module_notifier(&kgdb_module_load_nb);
++
++ kgdb_initialized = 1;
++}
++int notifier_chain_register(struct notifier_block **nl,
++ struct notifier_block *n);
++int notifier_chain_unregister(struct notifier_block **nl,
++ struct notifier_block *n);
++
++static void kgdb_register_for_panic(void)
++{
++ /* Register for panics(). */
++ /* The registration is done in the kgdb_register_for_panic
++ * routine because KGDB should not try to handle a panic when
++ * there are no kgdb_io_ops setup. It is assumed that the
++ * kgdb_io_ops are setup at the time this method is called.
++ */
++ if (!kgdb_from_module_registered) {
++ notifier_chain_register(&panic_notifier_list,
++ &kgdb_panic_notifier);
++ kgdb_from_module_registered = 1;
++ }
++}
++
++static void kgdb_unregister_for_panic(void)
++{
++ /* When this routine is called KGDB should unregister from the
++ * panic handler and clean up, making sure it is not handling any
++ * break exceptions at the time.
++ */
++ if (kgdb_from_module_registered) {
++ kgdb_from_module_registered = 0;
++ notifier_chain_unregister(&panic_notifier_list,
++ &kgdb_panic_notifier);
++ }
++}
++
++int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops)
++{
++
++ if (kgdb_connected) {
++ printk(KERN_ERR "kgdb: Cannot load I/O module while KGDB "
++ "connected.\n");
++ return -EINVAL;
++ }
++
++ /* Save the old values so they can be restored */
++ if (kgdb_io_handler_cnt >= MAX_KGDB_IO_HANDLERS) {
++ printk(KERN_ERR "kgdb: No more I/O handles available.\n");
++ return -EINVAL;
++ }
++
++ /* Check to see if there is an existing driver and if so save its
++ * values. Also check to make sure the same driver was not trying
++ * to re-register.
++ */
++ if (kgdb_io_ops.read_char != NULL &&
++ kgdb_io_ops.read_char != local_kgdb_io_ops->read_char) {
++ memcpy(&kgdb_io_ops_prev[kgdb_io_handler_cnt],
++ &kgdb_io_ops, sizeof(struct kgdb_io));
++ kgdb_io_handler_cnt++;
++ }
++
++ /* Initialize the io values for this module */
++ memcpy(&kgdb_io_ops, local_kgdb_io_ops, sizeof(struct kgdb_io));
++
++ /* Make the call to register kgdb if is not initialized */
++ kgdb_register_for_panic();
++
++ return 0;
++}
++
++void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops)
++{
++ int i;
++
++ /* Unregister KGDB if there were no other prior io hooks, else
++ * restore the io hooks.
++ */
++ if (kgdb_io_handler_cnt > 0 && kgdb_io_ops_prev[0].read_char != NULL) {
++ /* First check if the hook that is in use is the one being
++ * removed */
++ if (kgdb_io_ops.read_char == local_kgdb_io_ops->read_char) {
++ /* Set 'i' to the value of where the list should be
++ * shifed */
++ i = kgdb_io_handler_cnt - 1;
++ memcpy(&kgdb_io_ops, &kgdb_io_ops_prev[i],
++ sizeof(struct kgdb_io));
++ } else {
++ /* Simple case to remove an entry for an I/O handler
++ * that is not in use */
++ for (i = 0; i < kgdb_io_handler_cnt; i++) {
++ if (kgdb_io_ops_prev[i].read_char ==
++ local_kgdb_io_ops->read_char)
++ break;
++ }
++ }
++
++ /* Shift all the entries in the handler array so it is
++ * ordered from oldest to newest.
++ */
++ kgdb_io_handler_cnt--;
++ for (; i < kgdb_io_handler_cnt; i++) {
++ memcpy(&kgdb_io_ops_prev[i], &kgdb_io_ops_prev[i + 1],
++ sizeof(struct kgdb_io));
++ }
++ /* Handle the case if we are on the last element and set it
++ * to NULL; */
++ memset(&kgdb_io_ops_prev[kgdb_io_handler_cnt], 0,
++ sizeof(struct kgdb_io));
++
++ if (kgdb_connected)
++ printk(KERN_ERR "kgdb: WARNING: I/O method changed "
++ "while kgdb was connected state.\n");
++ } else {
++ /* KGDB is no longer able to communicate out, so
++ * unregister our hooks and reset state. */
++ kgdb_unregister_for_panic();
++ if (kgdb_connected) {
++ printk(KERN_CRIT "kgdb: I/O module was unloaded while "
++ "a debugging session was running. "
++ "KGDB will be reset.\n");
++ if (remove_all_break() < 0)
++ printk(KERN_CRIT "kgdb: Reset failed.\n");
++ kgdb_connected = 0;
++ }
++ memset(&kgdb_io_ops, 0, sizeof(struct kgdb_io));
++ }
++}
++
++/*
++ * There are times we need to call a tasklet to cause a breakpoint
++ * as calling breakpoint() at that point might be fatal. We have to
++ * check that the exception stack is setup, as tasklets may be scheduled
++ * prior to this. When that happens, it is up to the architecture to
++ * schedule this when it is safe to run.
++ */
++static void kgdb_tasklet_bpt(unsigned long ing)
++{
++ breakpoint();
++}
++
++DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0);
++
++/*
++ * This function can be called very early, either via early_param() or
++ * an explicit breakpoint() early on.
++ */
++static void __init kgdb_early_entry(void)
++{
++ /* Let the architecture do any setup that it needs to. */
++ kgdb_arch_init();
++
++ /* Now try the I/O. */
++ /* For early entry kgdb_io_ops.init must be defined */
++ if (!kgdb_io_ops.init || kgdb_io_ops.init()) {
++ /* Try again later. */
++ kgdb_initialized = -1;
++ return;
++ }
++
++ /* Finish up. */
++ kgdb_internal_init();
++
++ /* KGDB can assume that if kgdb_io_ops.init was defined that the
++ * panic registion should be performed at this time. This means
++ * kgdb_io_ops.init did not come from a kernel module and was
++ * initialized statically by a built in.
++ */
++ if (kgdb_io_ops.init)
++ kgdb_register_for_panic();
++}
++
++/*
++ * This function will always be invoked to make sure that KGDB will grab
++ * what it needs to so that if something happens while the system is
++ * running, KGDB will get involved. If kgdb_early_entry() has already
++ * been invoked, there is little we need to do.
++ */
++static int __init kgdb_late_entry(void)
++{
++ int need_break = 0;
++
++ /* If kgdb_initialized is -1 then we were passed kgdbwait. */
++ if (kgdb_initialized == -1)
++ need_break = 1;
++
++ /*
++ * If we haven't tried to initialize KGDB yet, we need to call
++ * kgdb_arch_init before moving onto the I/O.
++ */
++ if (!kgdb_initialized)
++ kgdb_arch_init();
++
++ if (kgdb_initialized != 1) {
++ if (kgdb_io_ops.init && kgdb_io_ops.init()) {
++ /* When KGDB allows I/O via modules and the core
++ * I/O init fails KGDB must default to defering the
++ * I/O setup, and appropriately print an error about
++ * it.
++ */
++ printk(KERN_ERR "kgdb: Could not setup core I/O "
++ "for KGDB.\n");
++ printk(KERN_INFO "kgdb: Defering I/O setup to kernel "
++ "module.\n");
++ memset(&kgdb_io_ops, 0, sizeof(struct kgdb_io));
++ }
++
++ kgdb_internal_init();
++
++ /* KGDB can assume that if kgdb_io_ops.init was defined that
++ * panic registion should be performed at this time. This means
++ * kgdb_io_ops.init did not come from a kernel module and was
++ * initialized statically by a built in.
++ */
++ if (kgdb_io_ops.init)
++ kgdb_register_for_panic();
++ }
++
++ /* Registering to reboot notifier list*/
++ register_reboot_notifier(&kgdb_reboot_notifier);
++
++ /* Now do any late init of the I/O. */
++ if (kgdb_io_ops.late_init)
++ kgdb_io_ops.late_init();
++
++ if (need_break) {
++ printk(KERN_CRIT "kgdb: Waiting for connection from remote"
++ " gdb...\n");
++ breakpoint();
++ }
++
++ return 0;
++}
++
++late_initcall(kgdb_late_entry);
++
++/*
++ * This function will generate a breakpoint exception. It is used at the
++ * beginning of a program to sync up with a debugger and can be used
++ * otherwise as a quick means to stop program execution and "break" into
++ * the debugger.
++ */
++void breakpoint(void)
++{
++ if (kgdb_initialized != 1) {
++ kgdb_early_entry();
++ if (kgdb_initialized == 1)
++ printk(KERN_CRIT "Waiting for connection from remote "
++ "gdb...\n");
++ else {
++ printk(KERN_CRIT "KGDB cannot initialize I/O yet.\n");
++ return;
++ }
++ }
++
++ atomic_set(&kgdb_setting_breakpoint, 1);
++ wmb();
++ BREAKPOINT();
++ wmb();
++ atomic_set(&kgdb_setting_breakpoint, 0);
++}
++
++EXPORT_SYMBOL(breakpoint);
++
++#ifdef CONFIG_MAGIC_SYSRQ
++static void sysrq_handle_gdb(int key, struct pt_regs *pt_regs,
++ struct tty_struct *tty)
++{
++ printk("Entering GDB stub\n");
++ breakpoint();
++}
++static struct sysrq_key_op sysrq_gdb_op = {
++ .handler = sysrq_handle_gdb,
++ .help_msg = "Gdb",
++ .action_msg = "GDB",
++};
++
++static int gdb_register_sysrq(void)
++{
++ printk("Registering GDB sysrq handler\n");
++ register_sysrq_key('g', &sysrq_gdb_op);
++ return 0;
++}
++
++module_init(gdb_register_sysrq);
++#endif
++
++static int kgdb_notify_reboot(struct notifier_block *this,
++ unsigned long code, void *x)
++{
++
++ unsigned long flags;
++
++ /* If we're debugging, or KGDB has not connected, don't try
++ * and print. */
++ if (!kgdb_connected || atomic_read(&debugger_active) != 0)
++ return 0;
++ if ((code == SYS_RESTART) || (code == SYS_HALT) || (code == SYS_POWER_OFF)){
++ local_irq_save(flags);
++ put_packet("X00");
++ local_irq_restore(flags);
++ }
++ return NOTIFY_DONE;
++}
++
++#ifdef CONFIG_KGDB_CONSOLE
++void kgdb_console_write(struct console *co, const char *s, unsigned count)
++{
++ unsigned long flags;
++
++ /* If we're debugging, or KGDB has not connected, don't try
++ * and print. */
++ if (!kgdb_connected || atomic_read(&debugger_active) != 0)
++ return;
++
++ local_irq_save(flags);
++ kgdb_msg_write(s, count);
++ local_irq_restore(flags);
++}
++
++static struct console kgdbcons = {
++ .name = "kgdb",
++ .write = kgdb_console_write,
++ .flags = CON_PRINTBUFFER | CON_ENABLED,
++};
++static int __init kgdb_console_init(void)
++{
++ register_console(&kgdbcons);
++ return 0;
++}
++
++console_initcall(kgdb_console_init);
++#endif
++
++static int __init opt_kgdb_enter(char *str)
++{
++ /* We've already done this by an explicit breakpoint() call. */
++ if (kgdb_initialized)
++ return 0;
++
++ /* Call breakpoint() which will take care of init. */
++ breakpoint();
++
++ return 0;
++}
++
++early_param("kgdbwait", opt_kgdb_enter);
+diff -Naur linux-2.6.25_original/kernel/Makefile linux-2.6.25/kernel/Makefile
+--- linux-2.6.25_original/kernel/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -53,6 +53,7 @@
+ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+ obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
+ obj-$(CONFIG_KPROBES) += kprobes.o
++obj-$(CONFIG_KGDB) += kgdb.o
+ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
+ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
+ obj-$(CONFIG_SECCOMP) += seccomp.o
+diff -Naur linux-2.6.25_original/kernel/module.c linux-2.6.25/kernel/module.c
+--- linux-2.6.25_original/kernel/module.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/module.c 2009-05-16 18:43:58.000000000 +0530
+@@ -47,6 +47,7 @@
+ #include <asm/cacheflush.h>
+ #include <linux/license.h>
+ #include <asm/sections.h>
++#include <linux/kprobes.h>
+
+ #if 0
+ #define DEBUGP printk
+@@ -65,7 +66,11 @@
+ * (add/delete uses stop_machine). */
+ static DEFINE_MUTEX(module_mutex);
+ static LIST_HEAD(modules);
+-
++static DECLARE_MUTEX(notify_mutex);
++/*extern static int __kprobes notifier_call_chain(struct notifier_block **nl,
++ unsigned long val, void *v,
++ int nr_to_call, int *nr_calls);
++*/
+ /* Waiting for a module to finish initializing? */
+ static DECLARE_WAIT_QUEUE_HEAD(module_wq);
+
+@@ -733,6 +738,11 @@
+ if (ret != 0)
+ goto out;
+
++ down(¬ify_mutex);
++ blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING,
++ mod);
++ up(¬ify_mutex);
++
+ /* Never wait if forced. */
+ if (!forced && module_refcount(mod) != 0)
+ wait_for_zero_refcount(mod);
+@@ -746,6 +756,11 @@
+ /* Store the name of the last unloaded module for diagnostic purposes */
+ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
+ free_module(mod);
++
++ down(¬ify_mutex);
++ blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GONE,
++ NULL);
++ up(¬ify_mutex);
+
+ out:
+ mutex_unlock(&module_mutex);
+@@ -1343,6 +1358,11 @@
+ /* Arch-specific cleanup. */
+ module_arch_cleanup(mod);
+
++#ifdef CONFIG_KGDB
++ /* kgdb info */
++ vfree(mod->mod_sections);
++#endif
++
+ /* Module unload stuff */
+ module_unload_free(mod);
+
+@@ -1606,6 +1626,31 @@
+ }
+ }
+
++#ifdef CONFIG_KGDB
++int add_modsects (struct module *mod, Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const
++ char *secstrings)
++{
++ int i;
++
++ mod->num_sections = hdr->e_shnum - 1;
++ mod->mod_sections = vmalloc((hdr->e_shnum - 1)*
++ sizeof (struct mod_section));
++
++ if (mod->mod_sections == NULL) {
++ return -ENOMEM;
++ }
++
++ for (i = 1; i < hdr->e_shnum; i++) {
++ mod->mod_sections[i - 1].address = (void *)sechdrs[i].sh_addr;
++ strncpy(mod->mod_sections[i - 1].name, secstrings +
++ sechdrs[i].sh_name, MAX_SECTNAME);
++ mod->mod_sections[i - 1].name[MAX_SECTNAME] = '\0';
++ }
++
++ return 0;
++}
++#endif
++
+ #ifdef CONFIG_KALLSYMS
+ static int is_exported(const char *name, const struct module *mod)
+ {
+@@ -2039,6 +2084,11 @@
+
+ add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
+
++#ifdef CONFIG_KGDB
++ if ((err = add_modsects(mod, hdr, sechdrs, secstrings)) < 0) {
++ goto nomodsectinfo;
++ }
++#endif
+ #ifdef CONFIG_MARKERS
+ if (!mod->taints)
+ marker_update_probe_range(mod->markers,
+@@ -2113,6 +2163,10 @@
+ cleanup:
+ kobject_del(&mod->mkobj.kobj);
+ kobject_put(&mod->mkobj.kobj);
++#ifdef CONFIG_KGDB
++nomodsectinfo:
++ vfree(mod->mod_sections);
++#endif
+ free_unload:
+ module_unload_free(mod);
+ module_free(mod, mod->module_init);
+@@ -2170,6 +2224,10 @@
+ /* Init routine failed: abort. Try to protect us from
+ buggy refcounters. */
+ mod->state = MODULE_STATE_GOING;
++ down(¬ify_mutex);
++ blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING,
++ mod);
++ up(¬ify_mutex);
+ synchronize_sched();
+ module_put(mod);
+ mutex_lock(&module_mutex);
+diff -Naur linux-2.6.25_original/kernel/notifier.c linux-2.6.25/kernel/notifier.c
+--- linux-2.6.25_original/kernel/notifier.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/notifier.c 2009-05-16 18:43:58.000000000 +0530
+@@ -18,7 +18,7 @@
+ * are layered on top of these, with appropriate locking added.
+ */
+
+-static int notifier_chain_register(struct notifier_block **nl,
++int notifier_chain_register(struct notifier_block **nl,
+ struct notifier_block *n)
+ {
+ while ((*nl) != NULL) {
+@@ -31,7 +31,7 @@
+ return 0;
+ }
+
+-static int notifier_chain_unregister(struct notifier_block **nl,
++int notifier_chain_unregister(struct notifier_block **nl,
+ struct notifier_block *n)
+ {
+ while ((*nl) != NULL) {
+diff -Naur linux-2.6.25_original/kernel/pid.c linux-2.6.25/kernel/pid.c
+--- linux-2.6.25_original/kernel/pid.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/pid.c 2009-05-16 18:43:58.000000000 +0530
+@@ -496,8 +496,13 @@
+ /*
+ * The pid hash table is scaled according to the amount of memory in the
+ * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
+- * more.
++ * more. KGDB needs to know if this function has been called already,
++ * since we might have entered KGDB very early.
+ */
++#ifdef CONFIG_KGDB
++int pidhash_init_done;
++#endif
++
+ void __init pidhash_init(void)
+ {
+ int i, pidhash_size;
+@@ -516,6 +521,10 @@
+ panic("Could not alloc pidhash!\n");
+ for (i = 0; i < pidhash_size; i++)
+ INIT_HLIST_HEAD(&pid_hash[i]);
++
++#ifdef CONFIG_KGDB
++ pidhash_init_done = 1;
++#endif
+ }
+
+ void __init pidmap_init(void)
+diff -Naur linux-2.6.25_original/kernel/sched.c linux-2.6.25/kernel/sched.c
+--- linux-2.6.25_original/kernel/sched.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/sched.c 2009-05-16 18:43:58.000000000 +0530
+@@ -66,6 +66,7 @@
+ #include <linux/unistd.h>
+ #include <linux/pagemap.h>
+ #include <linux/hrtimer.h>
++#include <linux/kgdb.h>
+
+ #include <asm/tlb.h>
+ #include <asm/irq_regs.h>
+@@ -7295,6 +7296,9 @@
+ #ifdef in_atomic
+ static unsigned long prev_jiffy; /* ratelimiting */
+
++ if (atomic_read(&debugger_active))
++ return;
++
+ if ((in_atomic() || irqs_disabled()) &&
+ system_state == SYSTEM_RUNNING && !oops_in_progress) {
+ if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
+diff -Naur linux-2.6.25_original/kernel/softlockup.c linux-2.6.25/kernel/softlockup.c
+--- linux-2.6.25_original/kernel/softlockup.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/softlockup.c 2009-05-16 18:43:58.000000000 +0530
+@@ -15,6 +15,7 @@
+ #include <linux/kthread.h>
+ #include <linux/notifier.h>
+ #include <linux/module.h>
++#include <linux/kgdb.h>
+
+ #include <asm/irq_regs.h>
+
+@@ -52,7 +53,9 @@
+ void touch_softlockup_watchdog(void)
+ {
+ int this_cpu = raw_smp_processor_id();
+-
++#ifdef CONFIG_KGDB
++ atomic_set(&kgdb_sync_softlockup[raw_smp_processor_id()], 0);
++#endif
+ __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu);
+ }
+ EXPORT_SYMBOL(touch_softlockup_watchdog);
+diff -Naur linux-2.6.25_original/kernel/timer.c linux-2.6.25/kernel/timer.c
+--- linux-2.6.25_original/kernel/timer.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/kernel/timer.c 2009-05-16 18:43:58.000000000 +0530
+@@ -34,6 +34,7 @@
+ #include <linux/posix-timers.h>
+ #include <linux/cpu.h>
+ #include <linux/syscalls.h>
++#include <linux/kgdb.h>
+ #include <linux/delay.h>
+ #include <linux/tick.h>
+ #include <linux/kallsyms.h>
+@@ -938,8 +939,14 @@
+
+ void do_timer(unsigned long ticks)
+ {
++ int this_cpu = smp_processor_id();
+ jiffies_64 += ticks;
+ update_times(ticks);
++
++#ifdef CONFIG_KGDB
++ if(!atomic_read(&kgdb_sync_softlockup[this_cpu]))
++#endif
++ softlockup_tick();
+ }
+
+ #ifdef __ARCH_WANT_SYS_ALARM
+diff -Naur linux-2.6.25_original/lib/Kconfig.debug linux-2.6.25/lib/Kconfig.debug
+--- linux-2.6.25_original/lib/Kconfig.debug 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/lib/Kconfig.debug 2009-05-16 18:43:58.000000000 +0530
+@@ -499,6 +499,120 @@
+ Say M if you want the RCU torture tests to build as a module.
+ Say N if you are unsure.
+
++config WANT_EXTRA_DEBUG_INFORMATION
++ bool
++ select DEBUG_INFO
++ select FRAME_POINTER if X86
++ default n
++
++config KGDB
++ bool "KGDB: kernel debugging with remote gdb"
++ select WANT_EXTRA_DEBUG_INFORMATION
++ depends on DEBUG_KERNEL && (ARM || X86 || MIPS || (SUPERH && !SUPERH64) || IA64 || X86_64 || PPC)
++ help
++ If you say Y here, it will be possible to remotely debug the
++ kernel using gdb. It is strongly suggested that you enable
++ DEBUG_INFO, and if available on your platform, FRAME_POINTER.
++ Documentation of kernel debugger available at
++ http://kgdb.sourceforge.net as well as in DocBook form
++ in Documentation/DocBook/. If unsure, say N.
++
++config KGDB_CONSOLE
++ bool "KGDB: Console messages through gdb"
++ depends on KGDB
++ help
++ If you say Y here, console messages will appear through gdb.
++ Other consoles such as tty or ttyS will continue to work as usual.
++ Note, that if you use this in conjunction with KGDB_ETH, if the
++ ethernet driver runs into an error condition during use with KGDB
++ it is possible to hit an infinite recusrion, causing the kernel
++ to crash, and typically reboot. For this reason, it is preferable
++ to use NETCONSOLE in conjunction with KGDB_ETH instead of
++ KGDB_CONSOLE.
++
++choice
++ prompt "Method for KGDB communication"
++ depends on KGDB
++ default KGDB_8250_NOMODULE
++ help
++ There are a number of different ways in which you can communicate
++ with KGDB. The most common is via serial, with the 8250 driver
++ (should your hardware have an 8250, or ns1655x style uart).
++ Another option is to use the NETPOLL framework and UDP, should
++ your ethernet card support this. Other options may exist.
++ You can elect to have one core I/O driver that is built into the
++ kernel for debugging as the kernel is booting, or using only
++ kernel modules.
++
++config KGDB_ONLY_MODULES
++ bool "KGDB: Use only kernel modules for I/O"
++ depends on MODULES
++ help
++ Use only kernel modules to configure KGDB I/O after the
++ kernel is booted.
++
++
++
++config KGDB_8250_NOMODULE
++ bool "KGDB: On generic serial port (8250)"
++ select KGDB_8250
++ help
++ Uses generic serial port (8250) to communicate with the host
++ GDB. This is independent of the normal (SERIAL_8250) driver
++ for this chipset.
++
++
++endchoice
++
++config KGDB_8250
++ tristate "KGDB: On generic serial port (8250)" if !KGDB_8250_NOMODULE
++ depends on m && KGDB_ONLY_MODULES
++ help
++ Uses generic serial port (8250) to communicate with the host
++ GDB. This is independent of the normal (SERIAL_8250) driver
++ for this chipset.
++
++config KGDB_SIMPLE_SERIAL
++ bool "Simple selection of KGDB serial port"
++ depends on KGDB_8250_NOMODULE
++ default y
++ help
++ If you say Y here, you will only have to pick the baud rate
++ and port number that you wish to use for KGDB. Note that this
++ only works on architectures that register known serial ports
++ early on. If you say N, you will have to provide, either here
++ or on the command line, the type (I/O or MMIO), IRQ and
++ address to use. If in doubt, say Y.
++
++config KGDB_BAUDRATE
++ int "Debug serial port baud rate"
++ depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL)
++ default "115200"
++ help
++ gdb and the kernel stub need to agree on the baud rate to be
++ used. Standard rates from 9600 to 115200 are allowed, and this
++ may be overridden via the commandline.
++
++config KGDB_PORT_NUM
++ int "Serial port number for KGDB"
++ range 0 1 if KGDB_MPSC
++ range 0 3
++ depends on (KGDB_8250 && KGDB_SIMPLE_SERIAL) || KGDB_MPSC
++ default "1"
++ help
++ Pick the port number (0 based) for KGDB to use.
++
++config KGDB_8250_CONF_STRING
++ string "Configuration string for KGDB"
++ depends on KGDB_8250_NOMODULE && !KGDB_SIMPLE_SERIAL
++ default "io,2f8,115200,3" if X86
++ help
++ The format of this string should be <io or
++ mmio>,<address>,<baud rate>,<irq>. For example, to use the
++ serial port on an i386 box located at 0x2f8 and 115200 baud
++ on IRQ 3 at use:
++ io,2f8,115200,3
++
+ config KPROBES_SANITY_TEST
+ bool "Kprobes sanity tests"
+ depends on DEBUG_KERNEL
+diff -Naur linux-2.6.25_original/Makefile linux-2.6.25/Makefile
+--- linux-2.6.25_original/Makefile 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/Makefile 2009-05-16 18:43:58.000000000 +0530
+@@ -192,7 +192,8 @@
+ export KBUILD_BUILDHOST := $(SUBARCH)
+ ARCH ?= $(SUBARCH)
+ CROSS_COMPILE ?=
+-
++ARCH=arm
++#CROSS_COMPILE=/usr/local/arm/4.0.0/usr/bin/arm-linux-
+ # Architecture as present in compile.h
+ UTS_MACHINE := $(ARCH)
+ SRCARCH := $(ARCH)
+@@ -1578,7 +1579,11 @@
+ endif # skip-makefile
+
+ PHONY += FORCE
+-FORCE:
++include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk
++ mkdir -p include/linux/
++ awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h
++
++FORCE: include/linux/dwarf2-defs.h
+
+ # Declare the contents of the .PHONY variable as phony. We keep that
+ # information in a variable se we can use it in if_changed and friends.
+diff -Naur linux-2.6.25_original/net/Kconfig linux-2.6.25/net/Kconfig
+--- linux-2.6.25_original/net/Kconfig 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/net/Kconfig 2009-05-16 18:43:58.000000000 +0530
+@@ -29,7 +29,7 @@
+
+ config NET_NS
+ bool "Network namespace support"
+- default n
++ default y
+ depends on EXPERIMENTAL && !SYSFS && NAMESPACES
+ help
+ Allow user space to create what appear to be multiple instances
+diff -Naur linux-2.6.25_original/scripts/dwarfh.awk linux-2.6.25/scripts/dwarfh.awk
+--- linux-2.6.25_original/scripts/dwarfh.awk 1970-01-01 05:30:00.000000000 +0530
++++ linux-2.6.25/scripts/dwarfh.awk 2009-05-16 18:43:58.000000000 +0530
+@@ -0,0 +1,20 @@
++BEGIN {
++ print "#ifndef _ELF_DWARF_H"
++ print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */"
++}
++$2 == "=" {
++ gsub(/,/, "", $3)
++ print "#define " $1 "\t " $3
++}
++$1 == "#define" {
++ print $0
++ while( index($0,"\\") == length($0)){
++ getline
++ print $0
++ }
++}
++/.*/ {}
++END {
++ print "#endif"
++}
++
+diff -Naur linux-2.6.25_original/sound/arm/pxa2xx-ac97.c linux-2.6.25/sound/arm/pxa2xx-ac97.c
+--- linux-2.6.25_original/sound/arm/pxa2xx-ac97.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/arm/pxa2xx-ac97.c 2009-05-16 18:43:58.000000000 +0530
+@@ -124,8 +124,10 @@
+ #endif
+
+ if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
++#if !CONFIG_MACH_REGULUS
+ printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
+ __FUNCTION__, gsr_bits);
++#endif
+
+ /* let's try warm reset */
+ gsr_bits = 0;
+@@ -331,7 +333,12 @@
+ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
++#ifndef CONFIG_MACH_REGULUS
++#warning "CONFIG_MACH_REGULUS is not defined"
+ pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
++#else
++#warning "CONFIG_MACH_REGULUS is defined"
++#endif
+ #ifdef CONFIG_PXA27x
+ /* Use GPIO 113 as AC97 Reset on Bulverde */
+ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
+diff -Naur linux-2.6.25_original/sound/core/info.c linux-2.6.25/sound/core/info.c
+--- linux-2.6.25_original/sound/core/info.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/core/info.c 2009-05-16 18:43:58.000000000 +0530
+@@ -976,10 +976,14 @@
+
+ static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+ {
++#if !CONFIG_MACH_REGULUS
+ snd_iprintf(buffer,
+ "Advanced Linux Sound Architecture Driver Version "
+ CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
+ );
++#else
++ snd_iprintf(buffer,"");
++#endif
+ }
+
+ static int __init snd_info_version_init(void)
+diff -Naur linux-2.6.25_original/sound/core/sound.c linux-2.6.25/sound/core/sound.c
+--- linux-2.6.25_original/sound/core/sound.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/core/sound.c 2009-05-16 18:43:58.000000000 +0530
+@@ -439,9 +439,11 @@
+ return -ENOMEM;
+ }
+ snd_info_minor_register();
++#if !CONFIG_MACH_REGULUS
+ #ifndef MODULE
+ printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
+ #endif
++#endif
+ return 0;
+ }
+
+diff -Naur linux-2.6.25_original/sound/last.c linux-2.6.25/sound/last.c
+--- linux-2.6.25_original/sound/last.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/last.c 2009-05-16 18:43:58.000000000 +0530
+@@ -26,7 +26,8 @@
+ static int __init alsa_sound_last_init(void)
+ {
+ int idx, ok = 0;
+-
++
++#if !CONFIG_MACH_REGULUS
+ printk(KERN_INFO "ALSA device list:\n");
+ for (idx = 0; idx < SNDRV_CARDS; idx++)
+ if (snd_cards[idx] != NULL) {
+@@ -35,6 +36,7 @@
+ }
+ if (ok == 0)
+ printk(KERN_INFO " No soundcards found.\n");
++#endif
+ return 0;
+ }
+
+diff -Naur linux-2.6.25_original/sound/pci/ac97/ac97_codec.c linux-2.6.25/sound/pci/ac97/ac97_codec.c
+--- linux-2.6.25_original/sound/pci/ac97/ac97_codec.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/pci/ac97/ac97_codec.c 2009-06-04 11:01:30.000000000 +0530
+@@ -1316,6 +1316,9 @@
+ else
+ err = snd_ac97_cmix_new(card, "Master Playback",
+ AC97_MASTER, 0, ac97);
++ snd_ac97_write_cache (ac97, AC97_MASTER, 0x0707); // added by to remove default mute
++ snd_ac97_write_cache (ac97, AC97_MIC, 0x0040); // MIC volume 20db boost is enabled
++
+ if (err < 0)
+ return err;
+ }
+@@ -1516,6 +1519,7 @@
+ set_tlv_db_scale(kctl, db_scale_rec_gain);
+ snd_ac97_write_cache(ac97, AC97_REC_SEL, 0x0000);
+ snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x0000);
++ snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x0808); // Optimized record gain value
+ }
+ /* build MIC Capture controls */
+ if (snd_ac97_try_volume_mix(ac97, AC97_REC_GAIN_MIC)) {
+diff -Naur linux-2.6.25_original/sound/soc/pxa/pxa2xx-ac97.c linux-2.6.25/sound/soc/pxa/pxa2xx-ac97.c
+--- linux-2.6.25_original/sound/soc/pxa/pxa2xx-ac97.c 2008-04-17 08:19:44.000000000 +0530
++++ linux-2.6.25/sound/soc/pxa/pxa2xx-ac97.c 2009-05-16 18:43:58.000000000 +0530
+@@ -171,8 +171,12 @@
+ #endif
+
+ if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
++ {
++#if !CONFIG_MACH_REGULUS
+ printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
+ __FUNCTION__, gsr_bits);
++#endif
++ }
+
+ GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
+ GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
diff --git a/recipes/linux/linux_2.6.25.bb b/recipes/linux/linux_2.6.25.bb
index 38e651b..a9fc8c1 100644
--- a/recipes/linux/linux_2.6.25.bb
+++ b/recipes/linux/linux_2.6.25.bb
@@ -15,6 +15,7 @@ DEFAULT_PREFERENCE_at91-l9260 = "1"
DEFAULT_PREFERENCE_m8050 = "1"
DEFAULT_PREFERENCE_ronetix-pm9263 = "1"
DEFAULT_PREFERENCE_ronetix-pm9261 = "1"
+DEFAULT_PREFERENCE_regulus = "1"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.25.tar.bz2 \
${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/patch-${PV}.20.bz2;patch=1 \
@@ -58,6 +59,10 @@ SRC_URI_append_ronetix-pm9261 = " \
SRC_URI_append_m8050 = " file://m8050.diff;patch=1 file://update-mach-types.diff;patch=1"
+SRC_URI_append_regulus = "\
+ file://regulus_linux-2.6.25.patch;patch=1 \
+"
+
CMDLINE_cm-x270 = "console=${CMX270_CONSOLE_SERIAL_PORT},38400 monitor=1 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2"
FILES_kernel-image_cm-x270 = ""
--
1.6.0.4
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-u-boot_2008.10-Regulus-support-added.patch --]
[-- Type: text/x-patch; name="0003-u-boot_2008.10-Regulus-support-added.patch"; charset="UTF-8", Size: 1537730 bytes --]
From 96a13842cec2b3f7c9ec07ab74a016312edaf9c7 Mon Sep 17 00:00:00 2001
From: balakrishnan <balakrishnan@e-consystems.com>
Date: Wed, 17 Mar 2010 19:15:37 +0530
Subject: [PATCH] u-boot_2008.10: Regulus support added
* Regulus patch will be applied to the u-boot-2008.10 version
Signed-off-by: balakrishnan <balakrishnan@e-consystems.com>
---
.../regulus/regulus_u-boot-2008.10.patch |30484 ++++++++++++++++++++
recipes/u-boot/u-boot_2008.10.bb | 16 +
2 files changed, 30500 insertions(+), 0 deletions(-)
create mode 100644 recipes/u-boot/u-boot-2008.10/regulus/regulus_u-boot-2008.10.patch
create mode 100644 recipes/u-boot/u-boot_2008.10.bb
diff --git a/recipes/u-boot/u-boot-2008.10/regulus/regulus_u-boot-2008.10.patch b/recipes/u-boot/u-boot-2008.10/regulus/regulus_u-boot-2008.10.patch
new file mode 100644
index 0000000..51aa66e
--- /dev/null
+++ b/recipes/u-boot/u-boot-2008.10/regulus/regulus_u-boot-2008.10.patch
@@ -0,0 +1,30484 @@
+diff -Naur u-boot-2008.10_original/board/regulus/config.mk u-boot-2008.10/board/regulus/config.mk
+--- u-boot-2008.10_original/board/regulus/config.mk 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/config.mk 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,4 @@
++#TEXT_BASE =0xa1f00000
++TEXT_BASE =0xa7700000
++# 0xa1700000
++#TEXT_BASE = 0
+diff -Naur u-boot-2008.10_original/board/regulus/eeprom.c u-boot-2008.10/board/regulus/eeprom.c
+--- u-boot-2008.10_original/board/regulus/eeprom.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/eeprom.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,84 @@
++/*
++ * (C) Copyright 2007
++ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <command.h>
++
++extern u16 read_srom_word(int);
++extern void write_srom_word(int offset, u16 val);
++
++static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
++ int i;
++
++ for (i=0; i < 0x40; i++) {
++ if (!(i % 0x10))
++ printf("\n%08lx:", i);
++ printf(" %04x", read_srom_word(i));
++ }
++ printf ("\n");
++ return (0);
++}
++
++static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
++ int offset,value;
++
++ if (argc < 4) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ offset=simple_strtoul(argv[2],NULL,16);
++ value=simple_strtoul(argv[3],NULL,16);
++ if (offset > 0x40) {
++ printf("Wrong offset : 0x%x\n",offset);
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++ write_srom_word(offset, value);
++ return (0);
++}
++
++int do_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {
++ if (argc < 2) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ if (strcmp (argv[1],"read") == 0) {
++ return (do_read_dm9000_eeprom(cmdtp,flag,argc,argv));
++ } else if (strcmp (argv[1],"write") == 0) {
++ return (do_write_dm9000_eeprom(cmdtp,flag,argc,argv));
++ } else {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++}
++
++U_BOOT_CMD(
++ dm9000ee,4,1,do_dm9000_eeprom,
++ "dm9000ee- Read/Write eeprom connected to Ethernet Controller\n",
++ "\ndm9000ee write <word offset> <value> \n"
++ "\tdm9000ee read \n"
++ "\tword:\t\t00-02 : MAC Address\n"
++ "\t\t\t03-07 : DM9000 Configuration\n"
++ "\t\t\t08-63 : User data\n");
+diff -Naur u-boot-2008.10_original/board/regulus/lowlevel_init.S u-boot-2008.10/board/regulus/lowlevel_init.S
+--- u-boot-2008.10_original/board/regulus/lowlevel_init.S 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/lowlevel_init.S 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,999 @@
++/*
++ * This was originally from the Lubbock u-boot port.
++ *
++ * Most of this taken from Redboot hal_platform_setup.h with cleanup
++ *
++ * NOTE: I haven't clean this up considerably, just enough to get it
++ * running. See hal_platform_setup.h for the source. See
++ * board/cradle/lowlevel_init.S for another PXA250 setup that is
++ * much cleaner.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/arch/pxa-regs.h>
++#include </usr/include/linux/linkage.h>
++
++#define ASENTRY(x_) ENTRY(x_)
++#define _C_FUNC(x_) /**/x_/**/
++#define _C_LABEL(x_) /**/x_/**/
++#define DEBUG
++
++
++#if 0
++@#define CORE_104MHz
++@#define CORE_208MHz
++#define CORE_312MHz
++@#define CORE_416MHz
++@#define CORE_520MHz
++@#define RUN_MODE
++#define TURBO_MODE
++
++/* Clock Manager Registers */
++#ifdef CFG_CPUSPEED
++CC_BASE: .word 0x41300000
++#define CCCR 0x00
++@cpuspeed: .word CFG_CPUSPEED @tharma
++
++#ifdef CORE_104MHz
++cpuspeed: .word 0x02000108 @ L = 8, 2N = 2, A = 1
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x0000000a @ B = 1, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++
++#ifdef CORE_208MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000110 @ L = 16, 2N = 2, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000110 @ L = 16, 2N = 2, A = 1
++#endif
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x00000002 @ B = 0, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x00000003 @ B = 0, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++#ifdef CORE_312MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000190 @ L = 16, 2N = 3, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000190 @ L = 16, 2N = 3, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_416MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000210 @ L= 16, 2N = 4, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000210 @ L= 16, 2N = 4, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_520MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++
++@#error "You have to define CFG_CPUSPEED!!"
++#endif
++#endif
++
++
++MDCNFG_ADDR: .word 0x48000000
++MDMRS_ADDR: .word 0x48000040
++MDMRSLP_ADDR: .word 0x48000058
++MDREFR_ADDR: .word 0x48000004
++MDMRS_VALUE: .word 0x00000032
++
++
++
++#ifdef SDRAM32
++ MDCNFG_VAL_DIS: .word 0x0ba80ba8
++ MDCNFG_VAL_EN: .word 0x0ba80bab
++
++ #warning "SDRAM SIZE is 32MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26030 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x030 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6030
++ MDREFR_VAL_NOCLK: .word 0x208f6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe030
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c26060 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x060 for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6060
++ MDREFR_VAL_NOCLK: .word 0x208f6060
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe060
++ #endif
++
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06030 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x030 for memclk = 104Mhz. The DRI is 0x20 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6030
++ MDREFR_VAL_NOCLK: .word 0x208d6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de030
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06028 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x028 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6028
++ MDREFR_VAL_NOCLK: .word 0x208d6028
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de028
++ #endif
++ #endif
++#elif defined (SDRAM64)
++ MDCNFG_VAL_DIS: .word 0x0ba80bc8
++ MDCNFG_VAL_EN: .word 0x0ba80bcb
++ #warning "SDRAM SIZE is 64MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif define(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++#elif defined (SDRAM128)
++ MDCNFG_VAL_DIS: .word 0x8ba80bd0
++ MDCNFG_VAL_EN: .word 0x8ba80bd3
++ #warning "SDRAM SIZE is 128MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++
++ #elif defined(MEMCLK91)
++ #warning "MEMCLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c26013 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6013
++ MDREFR_VAL_NOCLK: .word 0x208f6013
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe013
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++
++
++
++
++
++
++/* wait for coprocessor write complete */
++ .macro CPWAIT reg
++ mrc p15,0,\reg,c2,c0,0
++ mov \reg,\reg
++ sub pc,pc,#4
++ .endm
++
++
++/*
++ * Memory setup
++ */
++
++.globl lowlevel_init
++lowlevel_init:
++
++
++ /* Set up GPIO pins first ----------------------------------------- */
++
++#if 0
++ ldr r0, =GPSR0
++ ldr r1, =CFG_GPSR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR1
++ ldr r1, =CFG_GPSR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR2
++ ldr r1, =CFG_GPSR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR3
++ ldr r1, =CFG_GPSR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR0
++ ldr r1, =CFG_GPCR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR1
++ ldr r1, =CFG_GPCR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR2
++ ldr r1, =CFG_GPCR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR3
++ ldr r1, =CFG_GPCR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER0
++ ldr r1, =CFG_GRER0_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER1
++ ldr r1, =CFG_GRER1_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER2
++ ldr r1, =CFG_GRER2_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER3
++ ldr r1, =CFG_GRER3_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER0
++ ldr r1, =CFG_GFER0_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER1
++ ldr r1, =CFG_GFER1_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER2
++ ldr r1, =CFG_GFER2_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER3
++ ldr r1, =CFG_GFER3_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR0
++ ldr r1, =CFG_GPDR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR1
++ ldr r1, =CFG_GPDR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR2
++ ldr r1, =CFG_GPDR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR3
++ ldr r1, =CFG_GPDR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR0_L
++ ldr r1, =CFG_GAFR0_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR0_U
++ ldr r1, =CFG_GAFR0_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR1_L
++ ldr r1, =CFG_GAFR1_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR1_U
++ ldr r1, =CFG_GAFR1_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR2_L
++ ldr r1, =CFG_GAFR2_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR2_U
++ ldr r1, =CFG_GAFR2_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR3_L
++ ldr r1, =CFG_GAFR3_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR3_U
++ ldr r1, =CFG_GAFR3_U_VAL
++ str r1, [r0]
++
++ ldr r0, =PSSR /* enable GPIO pins */
++ ldr r1, =CFG_PSSR_VAL
++ str r1, [r0]
++#endif
++
++ /* ---------------------------------------------------------------- */
++ /* Enable memory interface */
++ /* */
++ /* The sequence below is based on the recommended init steps */
++ /* detailed in the Intel PXA250 Operating Systems Developers Guide, */
++ /* Chapter 10. */
++ /* ---------------------------------------------------------------- */
++
++ /* ---------------------------------------------------------------- */
++ /* Step 1: Wait for at least 200 microsedonds to allow internal */
++ /* clocks to settle. Only necessary after hard reset... */
++ /* FIXME: can be optimized later */
++ /* ---------------------------------------------------------------- */
++
++ ldr r3, =OSCR /* reset the OS Timer Count to zero */
++ mov r2, #0
++ str r2, [r3]
++ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
++ /* so 0x300 should be plenty */
++1:
++ ldr r2, [r3]
++ cmp r4, r2
++ bgt 1b
++
++mem_init:
++
++ ldr r1, =MEMC_BASE /* get memory controller base addr. */
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2a: Initialize Asynchronous static memory controller */
++ /* ---------------------------------------------------------------- */
++
++ /* MSC registers: timing, bus width, mem type */
++
++ /* MSC0: nCS(0,1) */
++ ldr r2, =CFG_MSC0_VAL
++ str r2, [r1, #MSC0_OFFSET]
++ ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
++ /* that data latches */
++ /* MSC1: nCS(2,3) */
++ ldr r2, =CFG_MSC1_VAL
++ str r2, [r1, #MSC1_OFFSET]
++ ldr r2, [r1, #MSC1_OFFSET]
++
++ /* MSC2: nCS(4,5) */
++ ldr r2, =CFG_MSC2_VAL
++ str r2, [r1, #MSC2_OFFSET]
++ ldr r2, [r1, #MSC2_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2b: Initialize Card Interface */
++ /* ---------------------------------------------------------------- */
++
++ /* MECR: Memory Expansion Card Register */
++ ldr r2, =CFG_MECR_VAL
++ str r2, [r1, #MECR_OFFSET]
++ ldr r2, [r1, #MECR_OFFSET]
++
++ /* MCMEM0: Card Interface slot 0 timing */
++ ldr r2, =CFG_MCMEM0_VAL
++ str r2, [r1, #MCMEM0_OFFSET]
++ ldr r2, [r1, #MCMEM0_OFFSET]
++
++ /* MCMEM1: Card Interface slot 1 timing */
++ ldr r2, =CFG_MCMEM1_VAL
++ str r2, [r1, #MCMEM1_OFFSET]
++ ldr r2, [r1, #MCMEM1_OFFSET]
++
++ /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
++ ldr r2, =CFG_MCATT0_VAL
++ str r2, [r1, #MCATT0_OFFSET]
++ ldr r2, [r1, #MCATT0_OFFSET]
++
++ /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
++ ldr r2, =CFG_MCATT1_VAL
++ str r2, [r1, #MCATT1_OFFSET]
++ ldr r2, [r1, #MCATT1_OFFSET]
++
++ /* MCIO0: Card Interface I/O Space Timing, slot 0 */
++ ldr r2, =CFG_MCIO0_VAL
++ str r2, [r1, #MCIO0_OFFSET]
++ ldr r2, [r1, #MCIO0_OFFSET]
++
++ /* MCIO1: Card Interface I/O Space Timing, slot 1 */
++ ldr r2, =CFG_MCIO1_VAL
++ str r2, [r1, #MCIO1_OFFSET]
++ ldr r2, [r1, #MCIO1_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2c: Write FLYCNFG FIXME: what's that??? */
++ /* ---------------------------------------------------------------- */
++ ldr r2, =CFG_FLYCNFG_VAL
++ str r2, [r1, #FLYCNFG_OFFSET]
++ str r2, [r1, #FLYCNFG_OFFSET]
++
++
++#if 0
++ /* ---------------------------------------------------------------- */
++ /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
++ /* ---------------------------------------------------------------- */
++
++ /* Before accessing MDREFR we need a valid DRI field, so we set */
++ /* this to power on defaults + DRI field. */
++
++ ldr r4, [r1, #MDREFR_OFFSET]
++ ldr r2, =0xFFF
++ bic r4, r4, r2
++
++ ldr r3, =CFG_MDREFR_VAL
++ and r3, r3, r2
++
++ orr r4, r4, r3
++ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
++
++ orr r4, r4, #MDREFR_K0RUN
++ orr r4, r4, #MDREFR_K0DB4
++ orr r4, r4, #MDREFR_K0FREE
++ orr r4, r4, #MDREFR_K0DB2
++ orr r4, r4, #MDREFR_K1DB2
++ bic r4, r4, #MDREFR_K1FREE
++ bic r4, r4, #MDREFR_K2FREE
++
++ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ /* Note: preserve the mdrefr value in r4 */
++
++
++ /* ---------------------------------------------------------------- */
++ /* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
++ /* ---------------------------------------------------------------- */
++
++ /* Initialize SXCNFG register. Assert the enable bits */
++
++ /* Write SXMRS to cause an MRS command to all enabled banks of */
++ /* synchronous static memory. Note that SXLCR need not be written */
++ /* at this time. */
++
++ ldr r2, =CFG_SXCNFG_VAL
++ str r2, [r1, #SXCNFG_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 4: Initialize SDRAM */
++ /* ---------------------------------------------------------------- */
++
++ bic r4, r4, #(MDREFR_K2FREE |MDREFR_K1FREE | MDREFR_K0FREE)
++
++ orr r4, r4, #MDREFR_K1RUN
++ bic r4, r4, #MDREFR_K2DB2
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ bic r4, r4, #MDREFR_SLFRSH
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ orr r4, r4, #MDREFR_E1PIN
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ nop
++ nop
++
++
++ /* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
++ /* configure but not enable each SDRAM partition pair. */
++
++ ldr r4, =CFG_MDCNFG_VAL
++ bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
++ bic r4, r4, #(MDCNFG_DE2|MDCNFG_DE3)
++
++ str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
++ ldr r4, [r1, #MDCNFG_OFFSET]
++
++
++ /* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
++ /* 100..200 µsec. */
++
++ ldr r3, =OSCR /* reset the OS Timer Count to zero */
++ mov r2, #0
++ str r2, [r3]
++ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
++ /* so 0x300 should be plenty */
++1:
++ ldr r2, [r3]
++ cmp r4, r2
++ bgt 1b
++
++
++ /* Step 4f: Trigger a number (usually 8) refresh cycles by */
++ /* attempting non-burst read or write accesses to disabled */
++ /* SDRAM, as commonly specified in the power up sequence */
++ /* documented in SDRAM data sheets. The address(es) used */
++ /* for this purpose must not be cacheable. */
++
++ ldr r3, =CFG_DRAM_BASE
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++
++
++ /* Step 4g: Write MDCNFG with enable bits asserted */
++ /* (MDCNFG:DEx set to 1). */
++
++ ldr r3, [r1, #MDCNFG_OFFSET]
++ mov r4, r3
++ orr r3, r3, #MDCNFG_DE0
++ str r3, [r1, #MDCNFG_OFFSET]
++ mov r0, r3
++
++ /* Step 4h: Write MDMRS. */
++
++ ldr r2, =CFG_MDMRS_VAL
++ str r2, [r1, #MDMRS_OFFSET]
++
++ /* enable APD */
++ ldr r3, [r1, #MDREFR_OFFSET]
++ orr r3, r3, #MDREFR_APD
++ str r3, [r1, #MDREFR_OFFSET]
++
++ /* We are finished with Intel's memory controller initialisation */
++#endif
++
++
++@-------------------------------------------@
++@ Serial Port Initialization @
++@-------------------------------------------@
++
++serial_port_init:
++#ifdef CONFIG_STUART
++#warning "DEBUG UART IS STUART"
++
++/* Setting the GPIO46 and GPIO47 as input pin (STD_RXD) and output pin (STD_TXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E00010 @Addr of GPDR1
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x8000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ str r1, [r0]
++
++/* Setting the GPIO46 and GPIO47 for alter.func af2 and af1 respectively */
++ ldr r0, =0x40E0005C @Addr of GAFR1_L
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ orr r1, r1, #0x60000000 @AF47 = 0b01 , AF46 = 0b10
++ str r1, [r0]
++
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x700000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++#elif defined(CONFIG_FFUART)
++#warning "DEBUG UART IS FFUART"
++
++/* Setting the GPIO96 and GPIO16 as input pin (FFRXD) and output pin (FFTXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E0000C @Addr of GPDR0
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x10000 @ GPIO16 = 1 o/p
++ str r1, [r0]
++
++ ldr r0, =0x40E0010C @Addr of GPDR3
++ ldr r1, [r0] @Get the value present in GPDR1
++ bic r1, r1, #0x0001 @ GPIO96 = 0 i/p
++ str r1, [r0]
++
++/* Setting the GPIO16 and GPIO96 for alter.func af3 and af3 respectively */
++ ldr r0, =0x40E00058
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x40E0006c
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000040 /* FFUART CLK ENABLE CKEN6 in CLK Enable Register */
++ str r1, [r0]
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x100000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++
++#elif defined(CONFIG_BTUART)
++#warning " ADDITION UART IS BTUART"
++
++/* Setting the GPIO42 and GPIO43 as input pin (BT_RXD) and output pin (BT_TXD) respectively */
++@--------------------------------------------------------------@
++config_btuart:
++
++ ldr r0, =0x40e00010
++ ldr r1, [r0]
++ orr r1, r1, #0x0002800
++ str r1, [r0]
++
++ ldr r0, =0x40e00014
++ ldr r1, [r0]
++ orr r1, r1, #0x00300000
++ str r1, [r0]
++
++ ldr r0, =0x40e0005c
++ ldr r1, [r0]
++ orr r1, r1, #0x09900000
++ str r1, [r0]
++
++bt_uart_start:
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000080 /* STUART CLK ENABLE CKEN7 in CLK Enable Register */
++ str r1, [r0]
++
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x200000 @ BTUART register start addr
++
++ /* disable the UART */
++bt_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++bt_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++bt_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++bt_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++#endif
++
++
++
++sdram_config:
++ /*Now initalize the SP before calling putstr or print_byte */
++ mov r0, #0x5c000000
++ add r0, r0, #0x8000
++ mov sp, r0
++
++ ldr r0, MDCNFG_ADDR
++ ldr r1, [r0]
++ ldr r2, =0xfffcfffc
++ and r1, r1, r2 @disable all banks
++ str r1, [r0]
++
++ @Config K0DB2, K0DB4 and DRI. SLFRSH=1, APD=0, K0RUN=1
++ ldr r0, MDREFR_ADDR
++ ldr r1, MDREFR_VAL_START
++ str r1, [r0]
++
++ @Enter Selfresfresh with ClkStop. K1RUN = 1, K2RUN=1, K1DB2=1 (MEMCLK/2), K2DB2 = 1
++ ldr r1, MDREFR_VAL_SR_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go out of self-refresh SLFRSH = 0 (Goes to PWRDWN)
++ ldr r1, MDREFR_VAL_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go to PWRDWNX (powerdown exit)
++ @E1PIN = 1, K1RUN =1 (already set to 1)
++ ldr r1, MDREFR_VAL_PWRDWNEXIT
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Now the SDRAM is in NOP mode
++
++ @configure the SDRAM with partitions disabled
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_DIS
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++
++ @Dummy Write and Read from SDRAM banks
++ mov r0, #0xa0000000
++ mov r1, #0xa0000000
++ str r1, [r0]
++ mov r2, #0x10
++loop:
++ add r1, r1, #0x04
++ str r1, [r0, #0x04]
++ sub r2, r2, #0x01
++ cmp r2, #0x00
++ bne loop
++
++ @enable sdram partion
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_EN
++ str r1, [r0]
++
++ @Configure MRS
++ ldr r0, MDMRS_ADDR
++ ldr r1, MDMRS_VALUE
++ str r1, [r0]
++
++
++
++
++
++setvoltage:
++
++ mov r10, lr
++ bl initPXAvoltage /* In case the board is rebooting with a */
++ mov lr, r10 /* low voltage raise it up to a good one. */
++
++#if 1
++ b initirqs
++#endif
++
++wakeup:
++ /* Are we waking from sleep? */
++ ldr r0, =RCSR
++ ldr r1, [r0]
++ and r1, r1, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR)
++ str r1, [r0]
++ teq r1, #RCSR_SMR
++
++ bne initirqs
++
++ ldr r0, =PSSR
++ mov r1, #PSSR_PH
++ str r1, [r0]
++
++ /* if so, resume at PSPR */
++ ldr r0, =PSPR
++ ldr r1, [r0]
++ mov pc, r1
++
++ /* ---------------------------------------------------------------- */
++ /* Disable (mask) all interrupts at interrupt controller */
++ /* ---------------------------------------------------------------- */
++
++initirqs:
++
++ mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
++ ldr r2, =ICLR
++ str r1, [r2]
++
++ ldr r2, =ICMR /* mask all interrupts at the controller */
++ str r1, [r2]
++
++ /* ---------------------------------------------------------------- */
++ /* Clock initialisation */
++ /* ---------------------------------------------------------------- */
++
++initclks:
++
++ /* Disable the peripheral clocks, and set the core clock frequency */
++
++ /* Turn Off on-chip peripheral clocks (except for memory) */
++ /* for re-configuration. */
++ ldr r1, =CKEN
++ ldr r2, =CFG_CKEN
++ str r2, [r1]
++
++ /* ... and write the core clock config register */
++ ldr r2, =CFG_CCCR
++ ldr r1, =CCCR
++ str r2, [r1]
++
++ /* Turn on turbo mode */
++ mrc p14, 0, r2, c6, c0, 0
++ orr r2, r2, #0xB /* Turbo, Fast-Bus, Freq change**/
++ mcr p14, 0, r2, c6, c0, 0
++
++ /* Re-write MDREFR */
++ ldr r1, =MEMC_BASE
++ ldr r2, [r1, #MDREFR_OFFSET]
++ str r2, [r1, #MDREFR_OFFSET]
++#ifdef RTC
++ /* enable the 32Khz oscillator for RTC and PowerManager */
++ ldr r1, =OSCC
++ mov r2, #OSCC_OON
++ str r2, [r1]
++
++ /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
++ /* has settled. */
++60:
++ ldr r2, [r1]
++ ands r2, r2, #1
++ beq 60b
++#else
++#error "RTC not defined"
++#endif
++
++ /* Interrupt init: Mask all interrupts */
++ ldr r0, =ICMR /* enable no sources */
++ mov r1, #0
++ str r1, [r0]
++ /* FIXME */
++
++#ifdef NODEBUG
++ /*Disable software and data breakpoints */
++ mov r0,#0
++ mcr p15,0,r0,c14,c8,0 /* ibcr0 */
++ mcr p15,0,r0,c14,c9,0 /* ibcr1 */
++ mcr p15,0,r0,c14,c4,0 /* dbcon */
++
++ /*Enable all debug functionality */
++ mov r0,#0x80000000
++ mcr p14,0,r0,c10,c0,0 /* dcsr */
++#endif
++
++ /* ---------------------------------------------------------------- */
++ /* End lowlevel_init */
++ /* ---------------------------------------------------------------- */
++
++endlowlevel_init:
++
++ mov pc, lr
++
++
++
++/* Delay Routine */
++@------------------------------------------------------@
++@ time delay subroutine @
++@ uses r9 and r10 registers @
++@------------------------------------------------------@
++
++
++bdelay:
++ mov r9, #0x0 @ zero out r4
++outloop:
++ mov r10, #0x0
++inloop:
++ add r10, r10, #1 @ increment it
++ cmp r10, #0x0001000 @ compare against constant
++ bne inloop @ if not equal, loop
++ add r9, r9, #1
++ cmp r9, #0x2000
++ bne outloop
++ mov pc, r14 @ return from subroutine
++
++
++
+diff -Naur u-boot-2008.10_original/board/regulus/lowlevel_init.S_modified u-boot-2008.10/board/regulus/lowlevel_init.S_modified
+--- u-boot-2008.10_original/board/regulus/lowlevel_init.S_modified 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/lowlevel_init.S_modified 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,999 @@
++/*
++ * This was originally from the Lubbock u-boot port.
++ *
++ * Most of this taken from Redboot hal_platform_setup.h with cleanup
++ *
++ * NOTE: I haven't clean this up considerably, just enough to get it
++ * running. See hal_platform_setup.h for the source. See
++ * board/cradle/lowlevel_init.S for another PXA250 setup that is
++ * much cleaner.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/arch/pxa-regs.h>
++#include </usr/include/linux/linkage.h>
++
++#define ASENTRY(x_) ENTRY(x_)
++#define _C_FUNC(x_) /**/x_/**/
++#define _C_LABEL(x_) /**/x_/**/
++#define DEBUG
++
++
++#if 0
++@#define CORE_104MHz
++@#define CORE_208MHz
++#define CORE_312MHz
++@#define CORE_416MHz
++@#define CORE_520MHz
++@#define RUN_MODE
++#define TURBO_MODE
++
++/* Clock Manager Registers */
++#ifdef CFG_CPUSPEED
++CC_BASE: .word 0x41300000
++#define CCCR 0x00
++@cpuspeed: .word CFG_CPUSPEED @tharma
++
++#ifdef CORE_104MHz
++cpuspeed: .word 0x02000108 @ L = 8, 2N = 2, A = 1
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x0000000a @ B = 1, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++
++#ifdef CORE_208MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000110 @ L = 16, 2N = 2, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000110 @ L = 16, 2N = 2, A = 1
++#endif
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x00000002 @ B = 0, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x00000003 @ B = 0, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++#ifdef CORE_312MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000190 @ L = 16, 2N = 3, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000190 @ L = 16, 2N = 3, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_416MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000210 @ L= 16, 2N = 4, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000210 @ L= 16, 2N = 4, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_520MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++
++@#error "You have to define CFG_CPUSPEED!!"
++#endif
++#endif
++
++
++MDCNFG_ADDR: .word 0x48000000
++MDMRS_ADDR: .word 0x48000040
++MDMRSLP_ADDR: .word 0x48000058
++MDREFR_ADDR: .word 0x48000004
++MDMRS_VALUE: .word 0x00000032
++
++
++
++#ifdef SDRAM32
++ MDCNFG_VAL_DIS: .word 0x0ba80ba8
++ MDCNFG_VAL_EN: .word 0x0ba80bab
++
++ #warning "SDRAM SIZE is 32MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26030 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x030 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6030
++ MDREFR_VAL_NOCLK: .word 0x208f6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe030
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c26060 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x060 for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6060
++ MDREFR_VAL_NOCLK: .word 0x208f6060
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe060
++ #endif
++
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06030 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x030 for memclk = 104Mhz. The DRI is 0x20 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6030
++ MDREFR_VAL_NOCLK: .word 0x208d6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de030
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06028 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x028 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6028
++ MDREFR_VAL_NOCLK: .word 0x208d6028
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de028
++ #endif
++ #endif
++#elif defined (SDRAM64)
++ MDCNFG_VAL_DIS: .word 0x0ba80bc8
++ MDCNFG_VAL_EN: .word 0x0ba80bcb
++ #warning "SDRAM SIZE is 64MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif define(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++#elif defined (SDRAM128)
++ MDCNFG_VAL_DIS: .word 0x8ba80bd0
++ MDCNFG_VAL_EN: .word 0x8ba80bd3
++ #warning "SDRAM SIZE is 128MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++
++ #elif defined(MEMCLK91)
++ #warning "MEMCLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c26013 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6013
++ MDREFR_VAL_NOCLK: .word 0x208f6013
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe013
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++
++
++
++
++
++
++/* wait for coprocessor write complete */
++ .macro CPWAIT reg
++ mrc p15,0,\reg,c2,c0,0
++ mov \reg,\reg
++ sub pc,pc,#4
++ .endm
++
++
++/*
++ * Memory setup
++ */
++
++.globl lowlevel_init
++lowlevel_init:
++
++
++ /* Set up GPIO pins first ----------------------------------------- */
++
++#if 0
++ ldr r0, =GPSR0
++ ldr r1, =CFG_GPSR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR1
++ ldr r1, =CFG_GPSR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR2
++ ldr r1, =CFG_GPSR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPSR3
++ ldr r1, =CFG_GPSR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR0
++ ldr r1, =CFG_GPCR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR1
++ ldr r1, =CFG_GPCR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR2
++ ldr r1, =CFG_GPCR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPCR3
++ ldr r1, =CFG_GPCR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER0
++ ldr r1, =CFG_GRER0_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER1
++ ldr r1, =CFG_GRER1_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER2
++ ldr r1, =CFG_GRER2_VAL
++ str r1, [r0]
++
++ ldr r0, =GRER3
++ ldr r1, =CFG_GRER3_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER0
++ ldr r1, =CFG_GFER0_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER1
++ ldr r1, =CFG_GFER1_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER2
++ ldr r1, =CFG_GFER2_VAL
++ str r1, [r0]
++
++ ldr r0, =GFER3
++ ldr r1, =CFG_GFER3_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR0
++ ldr r1, =CFG_GPDR0_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR1
++ ldr r1, =CFG_GPDR1_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR2
++ ldr r1, =CFG_GPDR2_VAL
++ str r1, [r0]
++
++ ldr r0, =GPDR3
++ ldr r1, =CFG_GPDR3_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR0_L
++ ldr r1, =CFG_GAFR0_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR0_U
++ ldr r1, =CFG_GAFR0_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR1_L
++ ldr r1, =CFG_GAFR1_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR1_U
++ ldr r1, =CFG_GAFR1_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR2_L
++ ldr r1, =CFG_GAFR2_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR2_U
++ ldr r1, =CFG_GAFR2_U_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR3_L
++ ldr r1, =CFG_GAFR3_L_VAL
++ str r1, [r0]
++
++ ldr r0, =GAFR3_U
++ ldr r1, =CFG_GAFR3_U_VAL
++ str r1, [r0]
++
++ ldr r0, =PSSR /* enable GPIO pins */
++ ldr r1, =CFG_PSSR_VAL
++ str r1, [r0]
++#endif
++
++ /* ---------------------------------------------------------------- */
++ /* Enable memory interface */
++ /* */
++ /* The sequence below is based on the recommended init steps */
++ /* detailed in the Intel PXA250 Operating Systems Developers Guide, */
++ /* Chapter 10. */
++ /* ---------------------------------------------------------------- */
++
++ /* ---------------------------------------------------------------- */
++ /* Step 1: Wait for at least 200 microsedonds to allow internal */
++ /* clocks to settle. Only necessary after hard reset... */
++ /* FIXME: can be optimized later */
++ /* ---------------------------------------------------------------- */
++
++ ldr r3, =OSCR /* reset the OS Timer Count to zero */
++ mov r2, #0
++ str r2, [r3]
++ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
++ /* so 0x300 should be plenty */
++1:
++ ldr r2, [r3]
++ cmp r4, r2
++ bgt 1b
++
++mem_init:
++
++ ldr r1, =MEMC_BASE /* get memory controller base addr. */
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2a: Initialize Asynchronous static memory controller */
++ /* ---------------------------------------------------------------- */
++
++ /* MSC registers: timing, bus width, mem type */
++
++ /* MSC0: nCS(0,1) */
++ ldr r2, =CFG_MSC0_VAL
++ str r2, [r1, #MSC0_OFFSET]
++ ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */
++ /* that data latches */
++ /* MSC1: nCS(2,3) */
++ ldr r2, =CFG_MSC1_VAL
++ str r2, [r1, #MSC1_OFFSET]
++ ldr r2, [r1, #MSC1_OFFSET]
++
++ /* MSC2: nCS(4,5) */
++ ldr r2, =CFG_MSC2_VAL
++ str r2, [r1, #MSC2_OFFSET]
++ ldr r2, [r1, #MSC2_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2b: Initialize Card Interface */
++ /* ---------------------------------------------------------------- */
++
++ /* MECR: Memory Expansion Card Register */
++ ldr r2, =CFG_MECR_VAL
++ str r2, [r1, #MECR_OFFSET]
++ ldr r2, [r1, #MECR_OFFSET]
++
++ /* MCMEM0: Card Interface slot 0 timing */
++ ldr r2, =CFG_MCMEM0_VAL
++ str r2, [r1, #MCMEM0_OFFSET]
++ ldr r2, [r1, #MCMEM0_OFFSET]
++
++ /* MCMEM1: Card Interface slot 1 timing */
++ ldr r2, =CFG_MCMEM1_VAL
++ str r2, [r1, #MCMEM1_OFFSET]
++ ldr r2, [r1, #MCMEM1_OFFSET]
++
++ /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
++ ldr r2, =CFG_MCATT0_VAL
++ str r2, [r1, #MCATT0_OFFSET]
++ ldr r2, [r1, #MCATT0_OFFSET]
++
++ /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
++ ldr r2, =CFG_MCATT1_VAL
++ str r2, [r1, #MCATT1_OFFSET]
++ ldr r2, [r1, #MCATT1_OFFSET]
++
++ /* MCIO0: Card Interface I/O Space Timing, slot 0 */
++ ldr r2, =CFG_MCIO0_VAL
++ str r2, [r1, #MCIO0_OFFSET]
++ ldr r2, [r1, #MCIO0_OFFSET]
++
++ /* MCIO1: Card Interface I/O Space Timing, slot 1 */
++ ldr r2, =CFG_MCIO1_VAL
++ str r2, [r1, #MCIO1_OFFSET]
++ ldr r2, [r1, #MCIO1_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 2c: Write FLYCNFG FIXME: what's that??? */
++ /* ---------------------------------------------------------------- */
++ ldr r2, =CFG_FLYCNFG_VAL
++ str r2, [r1, #FLYCNFG_OFFSET]
++ str r2, [r1, #FLYCNFG_OFFSET]
++
++
++#if 0
++ /* ---------------------------------------------------------------- */
++ /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
++ /* ---------------------------------------------------------------- */
++
++ /* Before accessing MDREFR we need a valid DRI field, so we set */
++ /* this to power on defaults + DRI field. */
++
++ ldr r4, [r1, #MDREFR_OFFSET]
++ ldr r2, =0xFFF
++ bic r4, r4, r2
++
++ ldr r3, =CFG_MDREFR_VAL
++ and r3, r3, r2
++
++ orr r4, r4, r3
++ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
++
++ orr r4, r4, #MDREFR_K0RUN
++ orr r4, r4, #MDREFR_K0DB4
++ orr r4, r4, #MDREFR_K0FREE
++ orr r4, r4, #MDREFR_K0DB2
++ orr r4, r4, #MDREFR_K1DB2
++ bic r4, r4, #MDREFR_K1FREE
++ bic r4, r4, #MDREFR_K2FREE
++
++ str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ /* Note: preserve the mdrefr value in r4 */
++
++
++ /* ---------------------------------------------------------------- */
++ /* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */
++ /* ---------------------------------------------------------------- */
++
++ /* Initialize SXCNFG register. Assert the enable bits */
++
++ /* Write SXMRS to cause an MRS command to all enabled banks of */
++ /* synchronous static memory. Note that SXLCR need not be written */
++ /* at this time. */
++
++ ldr r2, =CFG_SXCNFG_VAL
++ str r2, [r1, #SXCNFG_OFFSET]
++
++ /* ---------------------------------------------------------------- */
++ /* Step 4: Initialize SDRAM */
++ /* ---------------------------------------------------------------- */
++
++ bic r4, r4, #(MDREFR_K2FREE |MDREFR_K1FREE | MDREFR_K0FREE)
++
++ orr r4, r4, #MDREFR_K1RUN
++ bic r4, r4, #MDREFR_K2DB2
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ bic r4, r4, #MDREFR_SLFRSH
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ orr r4, r4, #MDREFR_E1PIN
++ str r4, [r1, #MDREFR_OFFSET]
++ ldr r4, [r1, #MDREFR_OFFSET]
++
++ nop
++ nop
++
++
++ /* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */
++ /* configure but not enable each SDRAM partition pair. */
++
++ ldr r4, =CFG_MDCNFG_VAL
++ bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1)
++ bic r4, r4, #(MDCNFG_DE2|MDCNFG_DE3)
++
++ str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */
++ ldr r4, [r1, #MDCNFG_OFFSET]
++
++
++ /* Step 4e: Wait for the clock to the SDRAMs to stabilize, */
++ /* 100..200 µsec. */
++
++ ldr r3, =OSCR /* reset the OS Timer Count to zero */
++ mov r2, #0
++ str r2, [r3]
++ ldr r4, =0x300 /* really 0x2E1 is about 200usec, */
++ /* so 0x300 should be plenty */
++1:
++ ldr r2, [r3]
++ cmp r4, r2
++ bgt 1b
++
++
++ /* Step 4f: Trigger a number (usually 8) refresh cycles by */
++ /* attempting non-burst read or write accesses to disabled */
++ /* SDRAM, as commonly specified in the power up sequence */
++ /* documented in SDRAM data sheets. The address(es) used */
++ /* for this purpose must not be cacheable. */
++
++ ldr r3, =CFG_DRAM_BASE
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++ str r2, [r3]
++
++
++ /* Step 4g: Write MDCNFG with enable bits asserted */
++ /* (MDCNFG:DEx set to 1). */
++
++ ldr r3, [r1, #MDCNFG_OFFSET]
++ mov r4, r3
++ orr r3, r3, #MDCNFG_DE0
++ str r3, [r1, #MDCNFG_OFFSET]
++ mov r0, r3
++
++ /* Step 4h: Write MDMRS. */
++
++ ldr r2, =CFG_MDMRS_VAL
++ str r2, [r1, #MDMRS_OFFSET]
++
++ /* enable APD */
++ ldr r3, [r1, #MDREFR_OFFSET]
++ orr r3, r3, #MDREFR_APD
++ str r3, [r1, #MDREFR_OFFSET]
++
++ /* We are finished with Intel's memory controller initialisation */
++#endif
++
++
++@-------------------------------------------@
++@ Serial Port Initialization @
++@-------------------------------------------@
++
++serial_port_init:
++#ifdef CONFIG_STUART
++#warning "DEBUG UART IS STUART"
++
++/* Setting the GPIO46 and GPIO47 as input pin (STD_RXD) and output pin (STD_TXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E00010 @Addr of GPDR1
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x8000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ str r1, [r0]
++
++/* Setting the GPIO46 and GPIO47 for alter.func af2 and af1 respectively */
++ ldr r0, =0x40E0005C @Addr of GAFR1_L
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ orr r1, r1, #0x60000000 @AF47 = 0b01 , AF46 = 0b10
++ str r1, [r0]
++
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x700000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++#elif defined(CONFIG_FFUART)
++#warning "DEBUG UART IS FFUART"
++
++/* Setting the GPIO96 and GPIO16 as input pin (FFRXD) and output pin (FFTXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E0000C @Addr of GPDR0
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x10000 @ GPIO16 = 1 o/p
++ str r1, [r0]
++
++ ldr r0, =0x40E0010C @Addr of GPDR3
++ ldr r1, [r0] @Get the value present in GPDR1
++ bic r1, r1, #0x0001 @ GPIO96 = 0 i/p
++ str r1, [r0]
++
++/* Setting the GPIO16 and GPIO96 for alter.func af3 and af3 respectively */
++ ldr r0, =0x40E00058
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x40E0006c
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000040 /* FFUART CLK ENABLE CKEN6 in CLK Enable Register */
++ str r1, [r0]
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x100000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++
++#elif defined(CONFIG_BTUART)
++#warning " ADDITION UART IS BTUART"
++
++/* Setting the GPIO42 and GPIO43 as input pin (BT_RXD) and output pin (BT_TXD) respectively */
++@--------------------------------------------------------------@
++config_btuart:
++
++ ldr r0, =0x40e00010
++ ldr r1, [r0]
++ orr r1, r1, #0x0002800
++ str r1, [r0]
++
++ ldr r0, =0x40e00014
++ ldr r1, [r0]
++ orr r1, r1, #0x00300000
++ str r1, [r0]
++
++ ldr r0, =0x40e0005c
++ ldr r1, [r0]
++ orr r1, r1, #0x09900000
++ str r1, [r0]
++
++bt_uart_start:
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000080 /* STUART CLK ENABLE CKEN7 in CLK Enable Register */
++ str r1, [r0]
++
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x200000 @ BTUART register start addr
++
++ /* disable the UART */
++bt_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++bt_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++bt_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++bt_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++#endif
++
++
++
++sdram_config:
++ /*Now initalize the SP before calling putstr or print_byte */
++ mov r0, #0x5c000000
++ add r0, r0, #0x8000
++ mov sp, r0
++
++ ldr r0, MDCNFG_ADDR
++ ldr r1, [r0]
++ ldr r2, =0xfffcfffc
++ and r1, r1, r2 @disable all banks
++ str r1, [r0]
++
++ @Config K0DB2, K0DB4 and DRI. SLFRSH=1, APD=0, K0RUN=1
++ ldr r0, MDREFR_ADDR
++ ldr r1, MDREFR_VAL_START
++ str r1, [r0]
++
++ @Enter Selfresfresh with ClkStop. K1RUN = 1, K2RUN=1, K1DB2=1 (MEMCLK/2), K2DB2 = 1
++ ldr r1, MDREFR_VAL_SR_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go out of self-refresh SLFRSH = 0 (Goes to PWRDWN)
++ ldr r1, MDREFR_VAL_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go to PWRDWNX (powerdown exit)
++ @E1PIN = 1, K1RUN =1 (already set to 1)
++ ldr r1, MDREFR_VAL_PWRDWNEXIT
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Now the SDRAM is in NOP mode
++
++ @configure the SDRAM with partitions disabled
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_DIS
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++
++ @Dummy Write and Read from SDRAM banks
++ mov r0, #0xa0000000
++ mov r1, #0xa0000000
++ str r1, [r0]
++ mov r2, #0x10
++loop:
++ add r1, r1, #0x04
++ str r1, [r0, #0x04]
++ sub r2, r2, #0x01
++ cmp r2, #0x00
++ bne loop
++
++ @enable sdram partion
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_EN
++ str r1, [r0]
++
++ @Configure MRS
++ ldr r0, MDMRS_ADDR
++ ldr r1, MDMRS_VALUE
++ str r1, [r0]
++
++
++
++
++
++setvoltage:
++
++ mov r10, lr
++ bl initPXAvoltage /* In case the board is rebooting with a */
++ mov lr, r10 /* low voltage raise it up to a good one. */
++
++#if 1
++ b initirqs
++#endif
++
++wakeup:
++ /* Are we waking from sleep? */
++ ldr r0, =RCSR
++ ldr r1, [r0]
++ and r1, r1, #(RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR)
++ str r1, [r0]
++ teq r1, #RCSR_SMR
++
++ bne initirqs
++
++ ldr r0, =PSSR
++ mov r1, #PSSR_PH
++ str r1, [r0]
++
++ /* if so, resume at PSPR */
++ ldr r0, =PSPR
++ ldr r1, [r0]
++ mov pc, r1
++
++ /* ---------------------------------------------------------------- */
++ /* Disable (mask) all interrupts at interrupt controller */
++ /* ---------------------------------------------------------------- */
++
++initirqs:
++
++ mov r1, #0 /* clear int. level register (IRQ, not FIQ) */
++ ldr r2, =ICLR
++ str r1, [r2]
++
++ ldr r2, =ICMR /* mask all interrupts at the controller */
++ str r1, [r2]
++
++ /* ---------------------------------------------------------------- */
++ /* Clock initialisation */
++ /* ---------------------------------------------------------------- */
++
++initclks:
++
++ /* Disable the peripheral clocks, and set the core clock frequency */
++
++ /* Turn Off on-chip peripheral clocks (except for memory) */
++ /* for re-configuration. */
++ ldr r1, =CKEN
++ ldr r2, =CFG_CKEN
++ str r2, [r1]
++
++ /* ... and write the core clock config register */
++ ldr r2, =CFG_CCCR
++ ldr r1, =CCCR
++ str r2, [r1]
++
++ /* Turn on turbo mode */
++ mrc p14, 0, r2, c6, c0, 0
++ orr r2, r2, #0xB /* Turbo, Fast-Bus, Freq change**/
++ mcr p14, 0, r2, c6, c0, 0
++
++ /* Re-write MDREFR */
++ ldr r1, =MEMC_BASE
++ ldr r2, [r1, #MDREFR_OFFSET]
++ str r2, [r1, #MDREFR_OFFSET]
++#ifdef RTC
++ /* enable the 32Khz oscillator for RTC and PowerManager */
++ ldr r1, =OSCC
++ mov r2, #OSCC_OON
++ str r2, [r1]
++
++ /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
++ /* has settled. */
++60:
++ ldr r2, [r1]
++ ands r2, r2, #1
++ beq 60b
++#else
++#error "RTC not defined"
++#endif
++
++ /* Interrupt init: Mask all interrupts */
++ ldr r0, =ICMR /* enable no sources */
++ mov r1, #0
++ str r1, [r0]
++ /* FIXME */
++
++#ifdef NODEBUG
++ /*Disable software and data breakpoints */
++ mov r0,#0
++ mcr p15,0,r0,c14,c8,0 /* ibcr0 */
++ mcr p15,0,r0,c14,c9,0 /* ibcr1 */
++ mcr p15,0,r0,c14,c4,0 /* dbcon */
++
++ /*Enable all debug functionality */
++ mov r0,#0x80000000
++ mcr p14,0,r0,c10,c0,0 /* dcsr */
++#endif
++
++ /* ---------------------------------------------------------------- */
++ /* End lowlevel_init */
++ /* ---------------------------------------------------------------- */
++
++endlowlevel_init:
++
++ mov pc, lr
++
++
++
++/* Delay Routine */
++@------------------------------------------------------@
++@ time delay subroutine @
++@ uses r9 and r10 registers @
++@------------------------------------------------------@
++
++
++bdelay:
++ mov r9, #0x0 @ zero out r4
++outloop:
++ mov r10, #0x0
++inloop:
++ add r10, r10, #1 @ increment it
++ cmp r10, #0x0001000 @ compare against constant
++ bne inloop @ if not equal, loop
++ add r9, r9, #1
++ cmp r9, #0x2000
++ bne outloop
++ mov pc, r14 @ return from subroutine
++
++
++
+diff -Naur u-boot-2008.10_original/board/regulus/Makefile u-boot-2008.10/board/regulus/Makefile
+--- u-boot-2008.10_original/board/regulus/Makefile 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,51 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation; either version 2 of
++# the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++# MA 02111-1307 USA
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).a
++
++COBJS := regulus.o regulus_nand.o #eeprom.o
++SOBJS := lowlevel_init.o pxavoltage.o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++clean:
++ rm -f $(SOBJS) $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+diff -Naur u-boot-2008.10_original/board/regulus/pxavoltage.S u-boot-2008.10/board/regulus/pxavoltage.S
+--- u-boot-2008.10_original/board/regulus/pxavoltage.S 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/pxavoltage.S 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,29 @@
++/*
++ * (C) Copyright 2007
++ * Stefano Babic, DENX Gmbh, sbabic@denx.de
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <asm/arch/pxa-regs.h>
++
++ .global initPXAvoltage
++
++initPXAvoltage:
++ mov pc, lr
+diff -Naur u-boot-2008.10_original/board/regulus/regulus.c u-boot-2008.10/board/regulus/regulus.c
+--- u-boot-2008.10_original/board/regulus/regulus.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/regulus.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,340 @@
++/*
++ * (C) Copyright 2007
++ * Stefano Babic, DENX Gmbh, sbabic@denx.de
++ *
++ * (C) Copyright 2004
++ * Robert Whaley, Applied Data Systems, Inc. rwhaley@applieddata.net
++ *
++ * (C) Copyright 2002
++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/arch/pxa-regs.h>
++#define PXA_LAST_GPIO 127
++#define GPIO_IN 0x000
++#define GPIO_OUT 0x080
++#define GPIO_ALT_FN_1_IN 0x100
++#define GPIO_ALT_FN_1_OUT 0x180
++#define GPIO_ALT_FN_2_IN 0x200
++#define GPIO_ALT_FN_2_OUT 0x280
++#define GPIO_ALT_FN_3_IN 0x300
++#define GPIO_ALT_FN_3_OUT 0x380
++#define GPIO_MD_MASK_NR 0x07f
++#define GPIO_MD_MASK_DIR 0x080
++#define GPIO_MD_MASK_FN 0x300
++#define GPIO_DFLT_LOW 0x400
++#define GPIO_DFLT_HIGH 0x800
++
++#define UP2OCR __REG(0x40600020)
++DECLARE_GLOBAL_DATA_PTR;
++
++#define RH_A_PSM (1 << 8) /* power switching mode */
++#define RH_A_NPS (1 << 9) /* no power switching */
++
++extern struct serial_device serial_ffuart_device;
++extern struct serial_device serial_btuart_device;
++extern struct serial_device serial_stuart_device;
++void lcd_init_board(void);
++
++/* ------------------------------------------------------------------------- */
++
++/*
++ * Miscelaneous platform dependent initialisations
++ */
++
++void usb_board_init(void)
++{
++ UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
++ ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
++
++ UHCHR |= UHCHR_FSBIR;
++
++ while (UHCHR & UHCHR_FSBIR);
++
++ UHCHR &= ~UHCHR_SSE;
++ UHCHIE = (UHCHIE_UPRIE | UHCHIE_RWIE);
++
++ /* Clear any OTG Pin Hold */
++ if (PSSR & PSSR_OTGPH)
++ PSSR |= PSSR_OTGPH;
++
++ UHCRHDA &= ~(RH_A_NPS);
++ UHCRHDA |= RH_A_PSM;
++
++ /* Set port power control mask bits, only 3 ports. */
++ UHCRHDB |= (0x7<<17);
++}
++
++void usb_board_init_fail(void)
++{
++ return;
++}
++
++void usb_board_stop(void)
++{
++ UHCHR |= UHCHR_FHR;
++ udelay(11);
++ UHCHR &= ~UHCHR_FHR;
++
++ UHCCOMS |= 1;
++ udelay(10);
++
++ CKEN &= ~CKEN10_USBHOST;
++
++ puts("Called USB STOP\n");
++ return;
++}
++
++int board_init (void)
++{
++ /* memory and cpu-speed are setup before relocation */
++ /* so we do _nothing_ here */
++ //printf("FUNC %s(): memory and cpu-speed are setup before relocation \n",__FUNCTION__);
++
++ /* arch number of ConXS Board */
++ //gd->bd->bi_arch_number = 776;
++ gd->bd->bi_arch_number = 900;
++
++ /* adress of boot parameters */
++ gd->bd->bi_boot_params = 0xa000003c;
++
++
++ mmc_init_board();
++ lcd_init_board();
++ usb_init_board();
++ return 0;
++}
++
++int board_late_init(void)
++{
++#if defined(CONFIG_SERIAL_MULTI)
++ char *console=getenv("boot_console");
++
++ if ((strcmp(console,"serial_btuart") == 0) ||
++ (strcmp(console,"serial_stuart") == 0) ||
++ (strcmp(console,"serial_ffuart") == 0)) {
++ setenv("stdout",console);
++ setenv("stdin", console);
++ setenv("stderr",console);
++ } else {
++ setenv("stdout", "serial");
++ setenv("stdin", "serial");
++ setenv("stderr", "serial");
++ }
++#endif
++ return 0;
++}
++
++struct serial_device *default_serial_console (void)
++{
++#if defined (CONFIG_FFUART)
++ return &serial_ffuart_device;
++#elif defined (CONFIG_BTUART)
++ return &serial_btuart_device;
++#elif defined (CONFIG_STUART)
++ return &serial_stuart_device;
++#endif
++
++}
++
++int dram_init (void)
++{
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
++ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
++ gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
++ gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
++ gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
++ gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
++
++ return 0;
++}
++
++
++void i2c_init_board()
++{
++ /* Enable I2C Unit Clock */
++ CKEN |= (CKEN14_I2C);
++
++ /* setup I2C GPIO's */
++ pxa_gpio_mode(GPIO117_SCL);
++ pxa_gpio_mode(GPIO118_SDA);
++}
++
++
++void mmc_init_board()
++{
++#define GPIO98_MMC_SD_WP 98
++#define GPIO101_MMC_SD_CD 101
++#define GPIO98_MMC_SD_WP_MD (GPIO98_MMC_SD_WP | GPIO_IN)
++#define GPIO101_MMC_SD_CD_MD (GPIO101_MMC_SD_CD | GPIO_IN)
++
++#define GPIO32_GPIO_OUT (32 | GPIO_OUT)
++#define GPIO112_GPIO_OUT (112 | GPIO_OUT)
++
++#define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT)
++#define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT)
++#define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT)
++#define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT)
++#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT)
++#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT)
++
++ //printf("FUNC %s(): MMC Initialization \n",__FUNCTION__);
++
++ GPSR(32)=GPIO_bit(32);
++ GPSR(112)=GPIO_bit(112);
++
++ pxa_gpio_mode(GPIO32_MMCCLK_MD);
++ pxa_gpio_mode(GPIO92_MMCDAT0_MD);
++ pxa_gpio_mode(GPIO109_MMCDAT1_MD);
++ pxa_gpio_mode(GPIO110_MMCDAT2_MD);
++ pxa_gpio_mode(GPIO111_MMCDAT3_MD);
++ pxa_gpio_mode(GPIO112_MMCCMD_MD);
++ pxa_gpio_mode(GPIO98_MMC_SD_WP_MD);
++ pxa_gpio_mode(GPIO101_MMC_SD_CD_MD);
++ CKEN |= (CKEN12_MMC);
++
++}
++
++void lcd_init_board(void)
++{
++#define GPIO50_LCD_BACKLIGHT_MD (50 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define GPIO53_PSAVE_MD (53 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define PWM_CTRL3 __REG(0x40C00010) /* PWM 3Control Register */
++#define PWM_PWDUTY3 __REG(0x40C00014) /* PWM 3 Duty Cycle Register */
++#define PWM_PERVAL3 __REG(0x40C00018) /* PWM 3 Period Control Register */
++#define PWM_CONTROL3_VALUE (0x00000013)
++#define PWMDCR3_VALUE (0x00000006)
++#define PWMPCR3_VALUE (0x0000001F)
++#define GPIO12_PWM3 (12 | GPIO_ALT_FN_2_OUT)
++
++ //printf("FUNC %s(): LCD Initialization \n",__FUNCTION__);
++ pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
++ pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD);
++ pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
++ pxa_gpio_mode(GPIO73_LDD_15_MD);
++ pxa_gpio_mode(GPIO72_LDD_14_MD);
++ pxa_gpio_mode(GPIO70_LDD_12_MD);
++ pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
++ pxa_gpio_mode(GPIO69_LDD_11_MD);
++ pxa_gpio_mode(GPIO64_LDD_6_MD);
++ pxa_gpio_mode(GPIO62_LDD_4_MD);
++ pxa_gpio_mode(GPIO61_LDD_3_MD);
++ pxa_gpio_mode(GPIO68_LDD_10_MD);
++ pxa_gpio_mode(GPIO60_LDD_2_MD);
++ pxa_gpio_mode(GPIO58_LDD_0_MD);
++ pxa_gpio_mode(GPIO59_LDD_1_MD);
++ pxa_gpio_mode(GPIO63_LDD_5_MD);
++ pxa_gpio_mode(GPIO66_LDD_8_MD);
++ pxa_gpio_mode(GPIO65_LDD_7_MD);
++ pxa_gpio_mode(GPIO67_LDD_9_MD);
++ pxa_gpio_mode(GPIO71_LDD_13_MD);
++ pxa_gpio_mode(GPIO50_LCD_BACKLIGHT_MD);
++ pxa_gpio_mode(GPIO53_PSAVE_MD);
++ CKEN |= CKEN16_LCD;
++ // Configure PWM Registers for Supporting 5.7 inch and 6.5 inch LCD displays in REGULUS Board
++ pxa_gpio_mode(GPIO12_PWM3);
++ PWM_CTRL3 = PWM_CONTROL3_VALUE;
++ PWM_PWDUTY3 = PWMDCR3_VALUE;
++ PWM_PERVAL3 = PWMPCR3_VALUE;
++ CKEN |= CKEN0_PWM0;
++ CKEN |= CKEN1_PWM1;
++
++}
++
++void usb_init_board(void)
++{
++#if 1
++ //printf("FUNC %s(): USB Initialization \n",__FUNCTION__);
++#define USBCLIENT_ENABLE_GPIO 107
++#define USBCLIENT_ENABLE_GPIO_MD (USBCLIENT_ENABLE_GPIO | GPIO_OUT)
++ pxa_gpio_mode(USBCLIENT_ENABLE_GPIO_MD);
++ // Set the USBCLIENT_ENABLE GPIO for Enabling the USBCLIENT
++ GPSR(USBCLIENT_ENABLE_GPIO) = GPIO_bit(USBCLIENT_ENABLE_GPIO);
++#endif
++ /* setup Port1 GPIO pin. */
++ pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
++ pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
++ usb_port2_conf();
++}
++
++void usb_port2_conf(void)
++{
++// Macros for USB OHCI Driver for USB Host Port 2
++#define GPIO21_FOR_USBHPEN2 21
++#define GPIO16_FOR_USBHPWR2 16
++#define GPIO119_FOR_USBHPWR2 119
++#define GPIO120_FOR_USBHPEN2 120
++#define GPIO35_USB_P2_1 (35 | GPIO_ALT_FN_2_IN)
++#define GPIO34_USB_P2_2 (34 | GPIO_ALT_FN_1_OUT)
++#define GPIO38_USB_P2_3 (38 | GPIO_ALT_FN_3_IN)
++#define GPIO36_USB_P2_4 (36 | GPIO_ALT_FN_1_OUT)
++#define GPIO40_USB_P2_5 (40 | GPIO_ALT_FN_3_IN)
++#define GPIO39_USB_P2_6 (39 | GPIO_ALT_FN_1_OUT)
++#define GPIO41_USB_P2_7 (41 | GPIO_ALT_FN_2_IN)
++#define GPIO21_USBHPEN2_MD (21 | GPIO_OUT)
++#define GPIO16_USBHPWR2_MD (16 | GPIO_IN)
++#define GPIO55_USB_PORT2_SUSPEND_MD (55 | GPIO_OUT | GPIO_DFLT_LOW)
++#define GPIO119_USBHPWR2_MD ( GPIO119_FOR_USBHPWR2 | GPIO_ALT_FN_1_IN )
++#define GPIO120_USBHPEN2_MD ( GPIO120_FOR_USBHPEN2 | GPIO_ALT_FN_2_OUT )
++
++#define UP2OCR_VALUE 0x03020300 //Differential port- OFF Single-Ended port2-Externel Non-OTG Tran Host
++
++#define UHCINTE_ADDR 0xf8000010 //OHCI interrupt enable register
++#define UHCINTE_VALUE 0x80000040
++
++
++ pxa_gpio_mode(GPIO35_USB_P2_1);
++ pxa_gpio_mode(GPIO34_USB_P2_2);
++ pxa_gpio_mode(GPIO38_USB_P2_3);
++ pxa_gpio_mode(GPIO36_USB_P2_4);
++ pxa_gpio_mode(GPIO40_USB_P2_5);
++ pxa_gpio_mode(GPIO39_USB_P2_6);
++ pxa_gpio_mode(GPIO41_USB_P2_7);
++
++#if 1
++ // Reconfigure the USB_P2_7 GPIO as General GPIO, Direction Output, Default Drive value as High
++ pxa_gpio_mode(41 | GPIO_OUT | GPIO_DFLT_HIGH);
++ // Configure the GPIO55 as General GPIO, Direction Output, Default Drive value as High
++ pxa_gpio_mode(GPIO55_USB_PORT2_SUSPEND_MD);
++#endif
++
++
++ /* setup Port2 GPIO pin. */
++ pxa_gpio_mode(GPIO119_USBHPWR2_MD) ; /* USBHPWR2 */
++ pxa_gpio_mode(GPIO120_USBHPEN2_MD); /* USBHPEN2 */
++ pxa_gpio_mode(GPIO16_USBHPWR2_MD) ; /* USBHPWR2 */
++ pxa_gpio_mode(GPIO21_USBHPEN2_MD); /* USBHPEN2 */
++ GPCR(GPIO21_FOR_USBHPEN2) = GPIO_bit(GPIO21_FOR_USBHPEN2);
++
++ UP2OCR=UP2OCR_VALUE;
++
++ /* enable the ohci interrupt in UHCINTE Reg */
++ UHCINTE |= UHCINTE_VALUE;
++
++}
++
+diff -Naur u-boot-2008.10_original/board/regulus/regulus_nand.c u-boot-2008.10/board/regulus/regulus_nand.c
+--- u-boot-2008.10_original/board/regulus/regulus_nand.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/regulus_nand.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,192 @@
++/*
++ * (C) Copyright 2006 Aubrey.Li, aubrey.li@analog.com
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++#if defined(CONFIG_CMD_NAND)
++//#include <nand.h>
++#ifdef CONFIG_NAND_LEGACY
++#include <linux/mtd/nand_legacy.h>
++#else /* !CONFIG_NAND_LEGACY */
++#include <linux/mtd/nand.h>
++#include <nand.h>
++#endif /* !CONFIG_NAND_LEGACY */
++
++#define GPIO97_FOR_NAND_CHIP_READY 97
++#define GPIO97_NAND_READYnBUSY ( GPIO97_FOR_NAND_CHIP_READY | GPIO_IN )
++// GPIO & Mem Ctrl,Pwr Man. Gen. Register Config Definitions
++#define PCFR_ADDR 0x40F0001C
++#define MCMEM0_SET (0x0 << 0)
++#define MCMEM0_ASST (0x2 << 7)
++#define MCMEM0_HOLD (0x2 << 14)
++#define MCMEM0_VALUE (MCMEM0_ASST | MCMEM0_SET | MCMEM0_HOLD) //0x000FFFFF //0x00078CA2 // 0x000FFFFF
++//#define MCMEM0_VALUE 0x00078CA2 // 0x000FFFFF
++#define MECR_VALUE 0x00000002
++#define PCFR_FP_BIT 0x00000002
++#define MCMEM0 *((volatile unsigned int *)(0x48000028))
++#define MECR *((volatile unsigned int *)(0x48000014))
++#define GPIO_PCMCIA 79
++#define GPIO_PCMCIA_MD (GPIO_PCMCIA | GPIO_ALT_FN_1_OUT)
++
++#define GPIO_nPOE 48
++#define GPIO_nPOE_MD (GPIO_nPOE | GPIO_ALT_FN_2_OUT)
++
++#define GPIO_nWE 49
++#define GPIO_nWE_MD (GPIO_nWE | GPIO_ALT_FN_2_OUT)
++
++#define GPIO_nPWAIT 56
++#define GPIO_nPWAIT_MD (GPIO_nPWAIT | GPIO_ALT_FN_1_IN)
++
++#define GPIO_nIOIS16 57
++#define GPIO_nIOIS16_MD (GPIO_nIOIS16 | GPIO_ALT_FN_1_IN)
++
++
++#define PHY_NAND_BASE 0x2C000000
++#define CLE_SHIFT_BITS 21
++#define ALE_SHIFT_BITS 22
++
++#define AWA (PHY_NAND_BASE | (1<<ALE_SHIFT_BITS))
++#define CWA (PHY_NAND_BASE | (1<<CLE_SHIFT_BITS))
++#define DWA (PHY_NAND_BASE)
++#define DSRA (PHY_NAND_BASE)
++
++
++
++extern int pxa_gpio_mode(int gpio_mode);
++
++/*
++ * hardware specific access to control-lines
++ */
++static void regulus_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ register struct nand_chip *this = mtd->priv;
++ u32 IO_ADDR_W = (u32) this->IO_ADDR_W;
++
++
++
++
++ if (ctrl & NAND_CTRL_CHANGE)
++ {
++ if( ctrl & NAND_CLE )
++ {
++ IO_ADDR_W = (CFG_NAND_BASE | REGULUS_NAND_CLE);
++ }
++ else if( ctrl & NAND_ALE )
++ {
++ IO_ADDR_W = (CFG_NAND_BASE | REGULUS_NAND_ALE);
++ }
++ else
++ {
++ IO_ADDR_W = CFG_NAND_BASE;
++ }
++
++ this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
++ }
++
++ this->IO_ADDR_R = this->IO_ADDR_W;
++
++ /* Drain the writebuffer */
++ if (cmd != NAND_CMD_NONE)
++ {
++ //printk("cmd is 0x%02X . this->IO_ADDR_W is 0x%08X . this->IO_ADDR_R is 0x%08X \n",cmd,this->IO_ADDR_W,this->IO_ADDR_R);
++ writeb(cmd, this->IO_ADDR_W);
++ }
++ else
++ {
++ //printk("cmd is NAND_CMD_NONE . this->IO_ADDR_W is 0x%08X . this->IO_ADDR_R is 0x%08X \n",this->IO_ADDR_W,this->IO_ADDR_R);
++ }
++
++}
++
++int regulus_device_ready(struct mtd_info *mtd)
++{
++ int ret = (((GPLR(GPIO97_FOR_NAND_CHIP_READY)&GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))==GPIO_bit(GPIO97_FOR_NAND_CHIP_READY))?1:0);
++ return ret;
++}
++
++/*
++ * Board-specific NAND initialization. The following members of the
++ * argument are board-specific (per include/linux/mtd/nand.h):
++ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
++ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
++ * - cmd_ctrl: hardwarespecific function for accesing control-lines
++ * - dev_ready: hardwarespecific function for accesing device ready/busy line
++ * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
++ * only be provided if a hardware ECC is available
++ * - ecc.mode: mode of ecc, see defines
++ * - chip_delay: chip dependent delay for transfering data from array to
++ * read regs (tR)
++ * - options: various chip options. They can partly be set to inform
++ * nand_scan about special functionality. See the defines for further
++ * explanation
++ * Members with a "?" were not set in the merged testing-NAND branch,
++ * so they are not set here either.
++ */
++int board_nand_init(struct nand_chip *nand)
++{
++
++ unsigned char nand_mid=0,nand_did=0;
++
++ //Initialize GPIO for NAND flash interface
++
++
++ pxa_gpio_mode(GPIO_PCMCIA_MD);
++ pxa_gpio_mode(GPIO_nPOE_MD);
++ pxa_gpio_mode(GPIO_nWE_MD);
++ pxa_gpio_mode(GPIO_nPWAIT_MD);
++ pxa_gpio_mode(GPIO_nIOIS16_MD);
++ pxa_gpio_mode(GPIO97_NAND_READYnBUSY);
++
++ MCMEM0 = MCMEM0_VALUE;
++ MECR |= MECR_VALUE;
++
++ PCFR &= (~PCFR_FP_BIT);
++
++
++ //printk("CFG_NAND_BASE is 0x%08X \n",CFG_NAND_BASE);
++ //printk("REGULUS_NAND_CLE is 0x%08X \n",REGULUS_NAND_CLE);
++ //printk("REGULUS_NAND_ALE is 0x%08X \n",REGULUS_NAND_ALE);
++
++ //printk("Reset the NAND flash chip \n");
++ writeb(0xFF, (CFG_NAND_BASE |REGULUS_NAND_CLE));
++ udelay(100000);
++#if 0
++ printk("Read ID from NAND flash chip \n");
++ writeb(0x90, (CFG_NAND_BASE |REGULUS_NAND_CLE));
++ writeb(0x00, (CFG_NAND_BASE |REGULUS_NAND_ALE));
++
++ printk("manufacture id is 0x%02X \n",readb(CFG_NAND_BASE));
++ printk("device id is 0x%02X \n",readb(CFG_NAND_BASE));
++
++ printk("Reset the NAND flash chip \n");
++ writeb(0xFF, (CFG_NAND_BASE |REGULUS_NAND_CLE));
++#endif
++ nand->cmd_ctrl = regulus_hwcontrol;
++ nand->ecc.mode = NAND_ECC_SOFT;
++// nand->dev_ready = regulus_device_ready;
++ nand->dev_ready = NULL;
++ nand->chip_delay = 10;
++
++ return 0;
++}
++#endif
+diff -Naur u-boot-2008.10_original/board/regulus/u-boot.lds u-boot-2008.10/board/regulus/u-boot.lds
+--- u-boot-2008.10_original/board/regulus/u-boot.lds 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/board/regulus/u-boot.lds 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2000
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/pxa/start.o (.text)
++ *(.text)
++ }
++
++ . = ALIGN(4);
++ .rodata : { *(.rodata) }
++
++ . = ALIGN(4);
++ .data : { *(.data) }
++
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ . = .;
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss (NOLOAD) : { *(.bss) }
++ _end = .;
++}
+diff -Naur u-boot-2008.10_original/bulbcx_16 u-boot-2008.10/bulbcx_16
+--- u-boot-2008.10_original/bulbcx_16 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/bulbcx_16 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,1031 @@
++/* BulvBCx_16.dat version 1.00.001
++****************************************************************************
++
++ This data file contains the JTAG and board configuration data required
++ for multi-mode JFlash. This data file is a text file with specific
++ format requirements.
++
++ Comment blocks can be defined using the old-style C comment blocks.
++ The difference is that the delimiter characters must have whitespace
++ on both sides.
++
++ Data may be string data, or numeric. String data is only allowed
++ at specific positions within this file. Numeric data can be decimal,
++ hexadecimal, or octal.
++ Decimal data is assumed, and HEX data may be denoted by a
++ preceding 'X' character.
++
++ Valid HEX data:
++ xA0000000
++ XA4090000
++ Xff
++
++ Valid OCTAL data:
++ o765
++ O123545
++
++ The data required to fill in this table comes from knowledge of the
++ BSDL file for the processor, the development board user's guide,
++ and specifications for the flash components.
++
++ Data is position dependent in terms of order. Whitespace is the
++ delimiter for the data and may be used as necessary to keep the
++ data in reasonably readable format.
++
++ There are checkpoints within this file that are used as validation
++ that the data alignment is correct. DO NOT MODIFY THE CHECKPOINT DATA.
++
++ The filename of this file is used as the parameter for JFlash.
++*/
++
++/*
++****************************************************************************
++Release Information
++****************************************************************************
++
++ 1. This data file will identify the A0 and A1 silicon, but the scan data is not
++ compatible with these older revisions.
++
++ 2. 2.0 release: adds identification for the C2 silicon.
++
++ END RELEASE INFORMATION
++*/
++
++
++/*
++****************************************************************************
++File Identification strings to display from JFlash
++****************************************************************************
++*/
++ PXA27x /* Position 0 - Supported Processor Code Name or Number */
++ Mainstone /* Supported Development platform name or number */
++ 1.00.001 /* Version number of this data file */
++ VL00000001 /* Version lock code for compatibility to JTAG engine */
++
++/*
++****************************************************************************
++Basic JTAG setup required by JFlash
++****************************************************************************
++*/
++ 504 /* The number of bits in the Boundary Scan chain */
++ 7 /* The number of bits in the instruction register */
++ X0 /* EXTEST instruction in HEX */
++ X7E /* IDCODE instruction in HEX */
++ X7F /* BYPASS instruction */
++/*
++****************************************************************************
++Chip select offsets: 6 total, beginning with chip select 0 and in order.
++****************************************************************************
++*/
++ 61 303 240 239 238 285
++/*
++****************************************************************************
++Control Bits required for bus transactions
++****************************************************************************
++*/
++ 60 /* Output enable: nOE_OUT */
++ 59 /* Write Enable: nWE_OUT */
++ 72 /* Memory data upper bit control: mdupper_ctrl */
++ 71 /* Memory data lower bit control: mdlower_ctrl */
++ 68 /* Read/Write direction: RD_nWR_OUT */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 1 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 1111 /* position 20 */
++/*
++****************************************************************************
++Address bit offsets beginning with A0
++****************************************************************************
++*/
++ 25 24 23 22 21 20 19 18 /* A0 - A7 */
++ 17 16 15 14 13 12 11 10 /* A8 - A15 */
++ 9 8 7 6 5 4 3 2 /* A16 - A23 */
++ 1 0 /* A24, A25 */
++/*
++****************************************************************************
++Input data bit offsets beginning with D0
++****************************************************************************
++*/
++ 491 490 489 488 487 486 485 484 /* D0 - D7 */
++ 483 482 481 480 479 478 477 476 /* D8 - D15 */
++ 475 474 473 472 471 470 469 468 /* D16 - D23 */
++ 467 466 465 464 463 462 461 460 /* D24 - D31 */
++/*
++****************************************************************************
++Output data bit offsets beginning with D0
++****************************************************************************
++*/
++ 57 56 55 54 53 52 51 50 /* D0 - D7 */
++ 49 48 47 46 45 44 43 42 /* D8 - D15 */
++ 41 40 39 38 37 36 35 34 /* D16 - D23 */
++ 33 32 31 30 29 28 27 26 /* D24 - D31 */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 2 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 2222 /* position 111 */
++/*
++****************************************************************************
++Width of data bus. Only 16 or 32 are allowed as values
++****************************************************************************
++*/
++ 16
++/*
++****************************************************************************
++Memory Space Definition for chip selects. The memory addresses are defined
++by a lower and upper limit and the chip select that is used to access this
++address. The chip selects are identified by an integer.
++Only 6 regions are allowed. If there are fewer regions on the platform,
++then specify the unused regions with XFFFFFFFF as the lower and upper
++region limits and specify the highest chip select for these regions.
++****************************************************************************
++*/
++/* Lower Address Upper Address Chip Select */
++ X00000000 X04000000 0
++ X04000000 X08000000 1
++ X08000000 X0C000000 2
++ X0C000000 X10000000 3
++ X10000000 X14000000 4
++ X14000000 X18000000 5
++/*
++****************************************************************************
++Processor JTAG ID string. The upper 4 bits that define the stepping are not
++required here, but must be defined afterward to equate the value to the
++named stepping.
++****************************************************************************
++*/
++ 1001001001100101 /* Processor ID */
++ 00000001001 /* Intel Manufacturer Code */
++ 1 /* required by JTAG Standards */
++/*
++****************************************************************************
++Stepping labels relative to the top 4 bits of the chip ID.
++16 values required.
++****************************************************************************
++*/
++ A0 /* id = 0 , data position 131 */
++ A1 /* id = 1 */
++ B0 /* id = 2 */
++ B1 /* id = 3 */
++ C0 /* id = 4 */
++ C2 /* id = 5 */
++ ?? /* id = 6 */
++ ?? /* id = 7 */
++ ?? /* id = 8 */
++ ?? /* id = 9 */
++ ?? /* id = 10 */
++ ?? /* id = 11 */
++ ?? /* id = 12 */
++ ?? /* id = 13 */
++ ?? /* id = 14 */
++ ?? /* id = 15 */
++/*
++****************************************************************************
++Default High bits. These are pins on the chain that are required to be set
++high by default. This list contains some usual pins, and allows for 20
++arbitrary additional pins to be set. This list as with all lists is required
++to have a fixed number of entries. All entries that are not used should be
++set to 9999
++****************************************************************************
++*/
++ /* Normally high */
++
++ 61 /* nCS0_OUT */
++ 303 /* nCS1_OUT */ 182 /* nCS1 control pin */
++ 240 /* nCS2_OUT */ 119 /* nCS2 control pin */
++ 239 /* nCS3_OUT */ 118 /* nCS3 control pin */
++ 238 /* nCS4_OUT */ 117 /* nCS4 control pin */
++ 285 /* nCS5_OUT */ 164 /* nCS5 control pin */
++ 9999 /* additional */
++ 59 /* nWE_OUT */
++ 60 /* nOE_OUT */
++ 69 /* ma_ctrl - address lines enable */
++ 70 /* dqm_ctrl - DQM Control */
++ 71 /* mdlower_ctrl - memory data lower 16 bits */
++ 72 /* mdupper_ctrl - memory data upper 16 bits */
++ 73 /* nwe_ctrl */
++ 74 /* noe_ctrl */
++ 75 /* sdclk_ctrl */
++ 319 /* nsdcs_0 */
++ 318 /* nsdcs_1 */
++ 321 /* nsdras */
++ 325 /* clk_req_ctrl */
++ 492 /* nbatt_fault */
++ 494 /* nvdd_fault */
++
++ /* Arbitrary Additional Pins */
++
++ 316 /* GPIO 2 required for sys enable */
++ 195 /* GPIO 2 Control */
++ 269 /* GPIO 49 nPWE */
++ 148 /* GPIO 49 control */
++ 228 /* GPIO 90 nURST */
++ 107 /* GPIO 90 control */
++ 313 /* additional */
++ 192 /* additional */
++ 312 /* additional */
++ 191 /* additional */
++ 311 /* additional */
++ 190 /* additional */
++ 310 /* additional */
++ 189 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++/*
++****************************************************************************
++JTAG Chain description: This section defines the position of components
++on the chain so that these components can be accounted for and bypassed
++during the programming operation. There are up to 5 devices that can be
++handled, and at least one must be the main processor. Specify that a
++device is present with the string 'Enabled' or not present with the string
++'Disabled'. Each device that is enabled requires a specification for the
++number of bits in the JTAG instruction register. The controlling entity,
++usually the main processor is identified by the string 'Controller'.
++The order of the components is from TDI to TDO. The procedure needs to
++know if the device is the last
++****************************************************************************
++*/
++/* TDI --------> */ Enabled 7 Controller Last
++ Disabled 0 Other More
++ Disabled 0 Other More
++ Disabled 0 Other More
++ Disabled 0 Other More /* TDO ---------> */
++/*
++****************************************************************************
++Additional flash component UNLOCK controls: 4 addition pins can be defined
++that would be controlled to UNLOCK a flash memory device that has external
++locking pins. Any unused pins should be set to 9999. Specify the signal level
++required to UNLOCK the flash. These signals will be reversed to re-lock the
++flash after programming.
++****************************************************************************
++*/
++ 9999 1 /* gpio22_ctrl */
++ 9999 1 /* gpio12_ctrl */
++ 9999 1 /* gpio22_out */
++ 9999 1 /* gpio12_out */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 3 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 3333
++
++/*
++****************************************************************************
++number of flash devices in parallel on the bus
++****************************************************************************
++*/
++ 1
++/*
++****************************************************************************
++position of nsdcas signal - toggled in parallel with any chip select
++****************************************************************************
++*/
++ 58 /* nsdcas */
++/*
++****************************************************************************
++Flash programming Mode: WORD or BUFFER
++WORD programming is useful for doing things like smoothly crossing device
++boundaries but is a little slower.
++****************************************************************************
++*/
++ BUFFER /* WORD or BUFFER is the allowed entry */
++/*
++****************************************************************************
++E N D O F D A T A
++****************************************************************************
++*/
++
++/*
++BSDL File Used
++
++--------------------------------------------------------------------------
++-- File Type : BSDL Description Bulverde B0 v1_0 13x13 VFBGA
++-- Author : jboyer
++--------------------------------------------------------------------------
++
++entity bulverde_b0_13x13 is
++
++generic(PHYSICAL_PIN_MAP : string := "VFBGA");
++
++port(
++ boot_sel_0 : in bit;
++ rdnwr : out bit;
++ clk_req : inout bit;
++ gpio : inout bit_vector(118 downto 0);
++ dqm_0 : out bit;
++ dqm_1 : out bit;
++ dqm_2 : out bit;
++ dqm_3 : out bit;
++ ma : out bit_vector(25 downto 0);
++ md : inout bit_vector(31 downto 0);
++ ncs_0 : out bit;
++ noe : out bit;
++ nsdcas : out bit;
++ nsdcs_0 : out bit;
++ nsdcs_1 : out bit;
++ nsdras : out bit;
++ nwe : out bit;
++ sdcke_1 : out bit;
++ sdclk_0 : out bit;
++ sdclk_1 : out bit;
++ sdclk_2 : out bit;
++ nbatt_fault : in bit;
++ nreset : in bit;
++ nreset_out : linkage bit;
++ nvdd_fault : in bit;
++ pwr_en : linkage bit;
++ pxtal_in : linkage bit;
++ pxtal_out : linkage bit;
++ test : in bit;
++ testclk : in bit;
++ txtal_in : linkage bit;
++ txtal_out : linkage bit;
++ uio : inout bit;
++ usbc_n : inout bit;
++ usbc_p : inout bit;
++ usbh_n_0 : inout bit;
++ usbh_p_0 : inout bit;
++ vcc_batt : linkage bit;
++ vcc_bb : linkage bit;
++ vcc_core : linkage bit_vector(13 downto 0);
++ vcc_io : linkage bit_vector(2 downto 0);
++ vcc_usb : linkage bit_vector(3 downto 0);
++ vcc_lcd : linkage bit_vector(1 downto 0);
++ vcc_mem : linkage bit_vector(18 downto 0);
++ pwr_out : linkage bit;
++ vcc_pll : linkage bit;
++ vcc_ram : linkage bit_vector(3 downto 0);
++ vcc_usim : linkage bit;
++ vss_bb : linkage bit;
++ vss_core : linkage bit_vector(19 downto 0);
++ vss_io : linkage bit_vector(7 downto 0);
++ vss_mem : linkage bit_vector(16 downto 0);
++ vss_pad : linkage bit_vector(5 downto 0);
++ vss_pll : linkage bit;
++ tdi : in bit;
++ tms : in bit;
++ tck : in bit;
++ tdo : out bit;
++ ntrst : in bit
++ );
++
++use STD_1149_1_1994.all;
++
++attribute COMPONENT_CONFORMANCE of bulverde_b0_13x13 : entity is "STD_1149_1_1993";
++
++attribute PIN_MAP of bulverde_b0_13x13 : entity is PHYSICAL_PIN_MAP;
++
++constant VFBGA : PIN_MAP_STRING :=
++ "boot_sel_0: ab23," &
++ "rdnwr: c9," &
++ "clk_req: w24," &
++ "gpio: (a22,d20,c24,e21,d24,a13,b18,c17,b17," &
++ "d17,ad14,ac15,ab15,ab16,ad15,ac16,ab17,ac17,ac18," &
++ "ab18,ad18,aa17,ac19,aa18,ad19,ab19,a19,f23,f22," &
++ "d22,c23,n23,n22,ac12,aa11,ad10,ad9,ab12,c7," &
++ "c8,b7,r21,p22,p23,r23,m22,n24,l22,m24," &
++ "l23,l21,k23,k22,k24,j22,h23,h22,h24,g23," &
++ "g22,g24,ac11,ab11,aa10,aa14,ab14,ac14,ad13,ab13," &
++ "a10,ac13,a11,b11,c19,b20,c22,c21,c18,d14," &
++ "d19,b14,a15,c14,b19,a21,b6,a20,c12,c13," &
++ "b13,a14,c15,b15,d16,a17,b16,d13,ad5,ab6," &
++ "r22,b9,c16,a18,a3,t24,c10,b10,c11,v23," &
++ "u22,aa20,ac22,ad22,ab21,w23,w21,aa24,y24,v22)," &
++ "dqm_0: ab9," &
++ "dqm_1: ab10," &
++ "dqm_2: ac9," &
++ "dqm_3: ac10," &
++ "ma: (d6,c4,d4,c2,d2,e4,e3,c1,d1,f3," &
++ "g4,f2,e1,g3,g2,h3,h2,g1,j3,j2,k3,k2,j1,k4,a6,c6)," &
++ "md: (l2,m2,m3,n2,n1,p3,r3,r1,t1,v2,v1,w1,y1,aa1,ab3,aa4," &
++ "k1,l1,m4,n3,p2,p4,r4,t3,u1,v3,u4,y2,y3,aa3,ab1,ab4)," &
++ "ncs_0: b3," &
++ "noe: ac5," &
++ "nsdcas: aa6," &
++ "nsdcs_0: ab7," &
++ "nsdcs_1: ab8," &
++ "nsdras: ac7," &
++ "nwe: ab5," &
++ "sdcke_1: ad6," &
++ "sdclk_0: ac4," &
++ "sdclk_1: ad7," &
++ "sdclk_2: ad3," &
++ "nbatt_fault: ab24," &
++ "nreset: y22," &
++ "nreset_out: y21," &
++ "nvdd_fault: w22," &
++ "pwr_en: y23," &
++ "pxtal_in: ac21," &
++ "pxtal_out: ad21," &
++ "test: u24," &
++ "testclk: t23," &
++ "txtal_in: aa22," &
++ "txtal_out: aa23," &
++ "uio: e23," &
++ "usbc_n: c20," &
++ "usbc_p: b22," &
++ "usbh_n_0: d23," &
++ "usbh_p_0: e22," &
++ "vcc_batt: ab20," &
++ "vcc_bb: ad12," &
++ "vcc_core: (ad11,t2,ad4,w3,b21,m23,r24,ad16,f24,l24,j23,d3," &
++ "a7,b12)," &
++ "vcc_io: (ad17,a12,a16)," &
++ "vcc_usb: (a23,a24,b23,b24)," &
++ "vcc_lcd: (j24,p24)," &
++ "vcc_mem: (w2,ac6,a4,b8,ac8,aa2,u2,ad8,f1,h1,m1,ad1,ac1," &
++ "ac2,ad2,l3,e2,c3,p1)," &
++ "pwr_out: ab22," &
++ "vcc_pll: ac20," &
++ "vcc_ram: (b4,a5,a8,a9)," &
++ "vcc_usim: e24," &
++ "vss_bb: aa13," &
++ "vss_core: (aa12,w4,d8,d12,d21,g21,k21,p21,aa7,u3,m21,aa15," &
++ "d10,j21,a1,b1,a2,b2,d7,b5)," &
++ "vss_io: (d11,d15,d18,f21,h21,n21,aa19,aa16)," &
++ "vss_mem: (y4,c5,r2,n4,d9,aa9,aa8,aa5,v4,t4,l4,ab2,ac3,j4," &
++ "h4,f4,d5)," &
++ "vss_pad: (v21,ad23,ac23,ad24,ac24,aa21)," &
++ "vss_pll: ad20," &
++ "tdi: u23," &
++ "tms: t21," &
++ "tck: t22," &
++ "tdo: v24," &
++ "ntrst: u21";
++
++
++attribute TAP_SCAN_IN of TDI : signal is true;
++attribute TAP_SCAN_MODE of TMS : signal is true;
++attribute TAP_SCAN_OUT of TDO : signal is true;
++attribute TAP_SCAN_CLOCK of TCK : signal is (20.0e6, BOTH);
++attribute TAP_SCAN_RESET of NTRST : signal is true;
++
++attribute INSTRUCTION_LENGTH of bulverde_b0_13x13 : entity is 7;
++attribute INSTRUCTION_OPCODE of bulverde_b0_13x13 : entity is
++ "extest (0000000)," &
++ "bypass (1111111)," &
++ "sample (0000001)," &
++ "clamp (0000100)," &
++ "highz (0001000)," &
++ "flashload (0110110)," &
++ "flashprgm (0110111)," &
++ "idcode (1111110)";
++
++attribute INSTRUCTION_CAPTURE of bulverde_b0_13x13 : entity is "0000001";
++attribute IDCODE_REGISTER of bulverde_b0_13x13 : entity is
++ "0010" & -- Version Number
++ "1001001001100101" & -- Part Number
++ "00000001001" & -- Manufacturer ID
++ "1"; -- Required by IEEE Std. 1149.1-1990
++
++attribute REGISTER_ACCESS of bulverde_b0_13x13 : entity is
++ "BOUNDARY (extest, sample)," &
++ "DEVICE_ID (idcode)," &
++ "BYPASS (bypass, clamp, highz)," &
++ "flash_reg[76] (flashload, flashprgm)";
++
++attribute BOUNDARY_LENGTH of bulverde_b0_13x13 : entity is 504;
++attribute BOUNDARY_REGISTER of bulverde_b0_13x13 : entity is
++ -- num cell port function safe [ccell disval rslt]
++ "0 ( bc_1, ma(25), output3, X, 69, 0, Z)," &
++ "1 ( bc_1, ma(24), output3, X, 69, 0, Z)," &
++ "2 ( bc_1, ma(23), output3, X, 69, 0, Z)," &
++ "3 ( bc_1, ma(22), output3, X, 69, 0, Z)," &
++ "4 ( bc_1, ma(21), output3, X, 69, 0, Z)," &
++ "5 ( bc_1, ma(20), output3, X, 69, 0, Z)," &
++ "6 ( bc_1, ma(19), output3, X, 69, 0, Z)," &
++ "7 ( bc_1, ma(18), output3, X, 69, 0, Z)," &
++ "8 ( bc_1, ma(17), output3, X, 69, 0, Z)," &
++ "9 ( bc_1, ma(16), output3, X, 69, 0, Z)," &
++ "10 ( bc_1, ma(15), output3, X, 69, 0, Z)," &
++ "11 ( bc_1, ma(14), output3, X, 69, 0, Z)," &
++ "12 ( bc_1, ma(13), output3, X, 69, 0, Z)," &
++ "13 ( bc_1, ma(12), output3, X, 69, 0, Z)," &
++ "14 ( bc_1, ma(11), output3, X, 69, 0, Z)," &
++ "15 ( bc_1, ma(10), output3, X, 69, 0, Z)," &
++ "16 ( bc_1, ma(9), output3, X, 69, 0, Z)," &
++ "17 ( bc_1, ma(8), output3, X, 69, 0, Z)," &
++ "18 ( bc_1, ma(7), output3, X, 69, 0, Z)," &
++ "19 ( bc_1, ma(6), output3, X, 69, 0, Z)," &
++ "20 ( bc_1, ma(5), output3, X, 69, 0, Z)," &
++ "21 ( bc_1, ma(4), output3, X, 69, 0, Z)," &
++ "22 ( bc_1, ma(3), output3, X, 69, 0, Z)," &
++ "23 ( bc_1, ma(2), output3, X, 69, 0, Z)," &
++ "24 ( bc_1, ma(1), output3, X, 69, 0, Z)," &
++ "25 ( bc_1, ma(0), output3, X, 69, 0, Z)," &
++ "26 ( bc_1, md(31), output3, X, 72, 0, Z)," &
++ "27 ( bc_1, md(30), output3, X, 72, 0, Z)," &
++ "28 ( bc_1, md(29), output3, X, 72, 0, Z)," &
++ "29 ( bc_1, md(28), output3, X, 72, 0, Z)," &
++ "30 ( bc_1, md(27), output3, X, 72, 0, Z)," &
++ "31 ( bc_1, md(26), output3, X, 72, 0, Z)," &
++ "32 ( bc_1, md(25), output3, X, 72, 0, Z)," &
++ "33 ( bc_1, md(24), output3, X, 72, 0, Z)," &
++ "34 ( bc_1, md(23), output3, X, 72, 0, Z)," &
++ "35 ( bc_1, md(22), output3, X, 72, 0, Z)," &
++ "36 ( bc_1, md(21), output3, X, 72, 0, Z)," &
++ "37 ( bc_1, md(20), output3, X, 72, 0, Z)," &
++ "38 ( bc_1, md(19), output3, X, 72, 0, Z)," &
++ "39 ( bc_1, md(18), output3, X, 72, 0, Z)," &
++ "40 ( bc_1, md(17), output3, X, 72, 0, Z)," &
++ "41 ( bc_1, md(16), output3, X, 72, 0, Z)," &
++ "42 ( bc_1, md(15), output3, X, 71, 0, Z)," &
++ "43 ( bc_1, md(14), output3, X, 71, 0, Z)," &
++ "44 ( bc_1, md(13), output3, X, 71, 0, Z)," &
++ "45 ( bc_1, md(12), output3, X, 71, 0, Z)," &
++ "46 ( bc_1, md(11), output3, X, 71, 0, Z)," &
++ "47 ( bc_1, md(10), output3, X, 71, 0, Z)," &
++ "48 ( bc_1, md(9), output3, X, 71, 0, Z)," &
++ "49 ( bc_1, md(8), output3, X, 71, 0, Z)," &
++ "50 ( bc_1, md(7), output3, X, 71, 0, Z)," &
++ "51 ( bc_1, md(6), output3, X, 71, 0, Z)," &
++ "52 ( bc_1, md(5), output3, X, 71, 0, Z)," &
++ "53 ( bc_1, md(4), output3, X, 71, 0, Z)," &
++ "54 ( bc_1, md(3), output3, X, 71, 0, Z)," &
++ "55 ( bc_1, md(2), output3, X, 71, 0, Z)," &
++ "56 ( bc_1, md(1), output3, X, 71, 0, Z)," &
++ "57 ( bc_1, md(0), output3, X, 71, 0, Z)," &
++ "58 ( bc_1, nsdcas, output3, X, 69, 0, Z)," &
++ "59 ( bc_1, nwe, output3, X, 73, 0, Z)," &
++ "60 ( bc_1, noe, output3, X, 74, 0, Z)," &
++ "61 ( bc_1, ncs_0, output3, X, 74, 0, Z)," &
++ "62 ( bc_1, sdclk_0, output3, X, 75, 0, Z)," &
++ "63 ( bc_1, *, internal, 0)," &
++ "64 ( bc_1, dqm_3, output3, X, 70, 0, Z)," &
++ "65 ( bc_1, dqm_2, output3, X, 70, 0, Z)," &
++ "66 ( bc_1, dqm_1, output3, X, 69, 0, Z)," &
++ "67 ( bc_1, dqm_0, output3, X, 69, 0, Z)," &
++ "68 ( bc_1, rdnwr, output3, X, 69, 0, Z)," &
++ "69 ( bc_1, *, control, 0)," &
++ "70 ( bc_1, *, control, 0)," &
++ "71 ( bc_1, *, control, 0)," &
++ "72 ( bc_1, *, control, 0)," &
++ "73 ( bc_1, *, control, 0)," &
++ "74 ( bc_1, *, control, 0)," &
++ "75 ( bc_1, *, control, 0)," &
++ "76 ( bc_1, clk_req, output3, X, 325, 0, Z)," &
++ "77 ( bc_1, *, internal, 0)," &
++ "78 ( bc_1, *, internal, 0)," &
++ "79 ( bc_1, *, control, 0)," &
++ "80 ( bc_1, *, control, 0)," &
++ "81 ( bc_1, *, control, 0)," &
++ "82 ( bc_1, *, control, 0)," &
++ "83 ( bc_1, *, control, 0)," &
++ "84 ( bc_1, *, control, 0)," &
++ "85 ( bc_1, *, control, 0)," &
++ "86 ( bc_1, *, control, 0)," &
++ "87 ( bc_1, *, control, 0)," &
++ "88 ( bc_1, *, control, 0)," &
++ "89 ( bc_1, *, control, 0)," &
++ "90 ( bc_1, *, control, 0)," &
++ "91 ( bc_1, *, control, 0)," &
++ "92 ( bc_1, *, control, 0)," &
++ "93 ( bc_1, *, control, 0)," &
++ "94 ( bc_1, *, control, 0)," &
++ "95 ( bc_1, *, control, 0)," &
++ "96 ( bc_1, *, control, 0)," &
++ "97 ( bc_1, *, control, 0)," &
++ "98 ( bc_1, *, control, 0)," &
++ "99 ( bc_1, *, control, 0)," &
++ "100 ( bc_1, *, control, 0)," &
++ "101 ( bc_1, *, control, 0)," &
++ "102 ( bc_1, *, control, 0)," &
++ "103 ( bc_1, *, control, 0)," &
++ "104 ( bc_1, *, control, 0)," &
++ "105 ( bc_1, *, control, 0)," &
++ "106 ( bc_1, *, control, 0)," &
++ "107 ( bc_1, *, control, 0)," &
++ "108 ( bc_1, *, control, 0)," &
++ "109 ( bc_1, *, control, 0)," &
++ "110 ( bc_1, *, control, 0)," &
++ "111 ( bc_1, *, control, 0)," &
++ "112 ( bc_1, *, control, 0)," &
++ "113 ( bc_1, *, control, 0)," &
++ "114 ( bc_1, *, control, 0)," &
++ "115 ( bc_1, *, control, 0)," &
++ "116 ( bc_1, *, control, 0)," &
++ "117 ( bc_1, *, control, 0)," &
++ "118 ( bc_1, *, control, 0)," &
++ "119 ( bc_1, *, control, 0)," &
++ "120 ( bc_1, *, control, 0)," &
++ "121 ( bc_1, *, control, 0)," &
++ "122 ( bc_1, *, control, 0)," &
++ "123 ( bc_1, *, control, 0)," &
++ "124 ( bc_1, *, control, 0)," &
++ "125 ( bc_1, *, control, 0)," &
++ "126 ( bc_1, *, control, 0)," &
++ "127 ( bc_1, *, control, 0)," &
++ "128 ( bc_1, *, control, 0)," &
++ "129 ( bc_1, *, control, 0)," &
++ "130 ( bc_1, *, control, 0)," &
++ "131 ( bc_1, *, control, 0)," &
++ "132 ( bc_1, *, control, 0)," &
++ "133 ( bc_1, *, control, 0)," &
++ "134 ( bc_1, *, control, 0)," &
++ "135 ( bc_1, *, control, 0)," &
++ "136 ( bc_1, *, control, 0)," &
++ "137 ( bc_1, *, control, 0)," &
++ "138 ( bc_1, *, control, 0)," &
++ "139 ( bc_1, *, control, 0)," &
++ "140 ( bc_1, *, control, 0)," &
++ "141 ( bc_1, *, control, 0)," &
++ "142 ( bc_1, *, control, 0)," &
++ "143 ( bc_1, *, control, 0)," &
++ "144 ( bc_1, *, control, 0)," &
++ "145 ( bc_1, *, control, 0)," &
++ "146 ( bc_1, *, control, 0)," &
++ "147 ( bc_1, *, control, 0)," &
++ "148 ( bc_1, *, control, 0)," &
++ "149 ( bc_1, *, control, 0)," &
++ "150 ( bc_1, *, control, 0)," &
++ "151 ( bc_1, *, control, 0)," &
++ "152 ( bc_1, *, control, 0)," &
++ "153 ( bc_1, *, control, 0)," &
++ "154 ( bc_1, *, control, 0)," &
++ "155 ( bc_1, *, control, 0)," &
++ "156 ( bc_1, *, control, 0)," &
++ "157 ( bc_1, *, control, 0)," &
++ "158 ( bc_1, *, control, 0)," &
++ "159 ( bc_1, *, control, 0)," &
++ "160 ( bc_1, *, control, 0)," &
++ "161 ( bc_1, *, control, 0)," &
++ "162 ( bc_1, *, control, 0)," &
++ "163 ( bc_1, *, control, 0)," &
++ "164 ( bc_1, *, control, 0)," &
++ "165 ( bc_1, *, control, 0)," &
++ "166 ( bc_1, *, control, 0)," &
++ "167 ( bc_1, *, control, 0)," &
++ "168 ( bc_1, *, control, 0)," &
++ "169 ( bc_1, *, control, 0)," &
++ "170 ( bc_1, *, control, 0)," &
++ "171 ( bc_1, *, control, 0)," &
++ "172 ( bc_1, *, control, 0)," &
++ "173 ( bc_1, *, control, 0)," &
++ "174 ( bc_1, *, control, 0)," &
++ "175 ( bc_1, *, control, 0)," &
++ "176 ( bc_1, *, control, 0)," &
++ "177 ( bc_1, *, control, 0)," &
++ "178 ( bc_1, *, control, 0)," &
++ "179 ( bc_1, *, control, 0)," &
++ "180 ( bc_1, *, control, 0)," &
++ "181 ( bc_1, *, control, 0)," &
++ "182 ( bc_1, *, control, 0)," &
++ "183 ( bc_1, *, control, 0)," &
++ "184 ( bc_1, *, control, 0)," &
++ "185 ( bc_1, *, control, 0)," &
++ "186 ( bc_1, *, control, 0)," &
++ "187 ( bc_1, *, control, 0)," &
++ "188 ( bc_1, *, control, 0)," &
++ "189 ( bc_1, *, control, 0)," &
++ "190 ( bc_1, *, control, 0)," &
++ "191 ( bc_1, *, control, 0)," &
++ "192 ( bc_1, *, control, 0)," &
++ "193 ( bc_1, *, control, 0)," &
++ "194 ( bc_1, *, control, 0)," &
++ "195 ( bc_1, *, control, 0)," &
++ "196 ( bc_1, *, control, 0)," &
++ "197 ( bc_1, *, control, 0)," &
++ "198 ( bc_1, *, internal, 0)," &
++ "199 ( bc_1, *, internal, 0)," &
++ "200 ( bc_1, gpio(118), output3, X, 79, 0, Z)," &
++ "201 ( bc_1, gpio(117), output3, X, 80, 0, Z)," &
++ "202 ( bc_1, gpio(116), output3, X, 81, 0, Z)," &
++ "203 ( bc_1, gpio(115), output3, X, 82, 0, Z)," &
++ "204 ( bc_1, gpio(114), output3, X, 83, 0, Z)," &
++ "205 ( bc_1, gpio(113), output3, X, 84, 0, Z)," &
++ "206 ( bc_1, gpio(112), output3, X, 85, 0, Z)," &
++ "207 ( bc_1, gpio(111), output3, X, 86, 0, Z)," &
++ "208 ( bc_1, gpio(110), output3, X, 87, 0, Z)," &
++ "209 ( bc_1, gpio(109), output3, X, 88, 0, Z)," &
++ "210 ( bc_1, gpio(108), output3, X, 89, 0, Z)," &
++ "211 ( bc_1, gpio(107), output3, X, 90, 0, Z)," &
++ "212 ( bc_1, gpio(106), output3, X, 91, 0, Z)," &
++ "213 ( bc_1, gpio(105), output3, X, 92, 0, Z)," &
++ "214 ( bc_1, gpio(104), output3, X, 93, 0, Z)," &
++ "215 ( bc_1, gpio(103), output3, X, 94, 0, Z)," &
++ "216 ( bc_1, gpio(102), output3, X, 95, 0, Z)," &
++ "217 ( bc_1, gpio(101), output3, X, 96, 0, Z)," &
++ "218 ( bc_1, gpio(100), output3, X, 97, 0, Z)," &
++ "219 ( bc_1, gpio(99), output3, X, 98, 0, Z)," &
++ "220 ( bc_1, gpio(98), output3, X, 99, 0, Z)," &
++ "221 ( bc_1, gpio(97), output3, X, 100, 0, Z)," &
++ "222 ( bc_1, gpio(96), output3, X, 101, 0, Z)," &
++ "223 ( bc_1, gpio(95), output3, X, 102, 0, Z)," &
++ "224 ( bc_1, gpio(94), output3, X, 103, 0, Z)," &
++ "225 ( bc_1, gpio(93), output3, X, 104, 0, Z)," &
++ "226 ( bc_1, gpio(92), output3, X, 105, 0, Z)," &
++ "227 ( bc_1, gpio(91), output3, X, 106, 0, Z)," &
++ "228 ( bc_1, gpio(90), output3, X, 107, 0, Z)," &
++ "229 ( bc_1, gpio(89), output3, X, 108, 0, Z)," &
++ "230 ( bc_1, gpio(88), output3, X, 109, 0, Z)," &
++ "231 ( bc_1, gpio(87), output3, X, 110, 0, Z)," &
++ "232 ( bc_1, gpio(86), output3, X, 111, 0, Z)," &
++ "233 ( bc_1, gpio(85), output3, X, 112, 0, Z)," &
++ "234 ( bc_1, gpio(84), output3, X, 113, 0, Z)," &
++ "235 ( bc_1, gpio(83), output3, X, 114, 0, Z)," &
++ "236 ( bc_1, gpio(82), output3, X, 115, 0, Z)," &
++ "237 ( bc_1, gpio(81), output3, X, 116, 0, Z)," &
++ "238 ( bc_1, gpio(80), output3, X, 117, 0, Z)," &
++ "239 ( bc_1, gpio(79), output3, X, 118, 0, Z)," &
++ "240 ( bc_1, gpio(78), output3, X, 119, 0, Z)," &
++ "241 ( bc_1, gpio(77), output3, X, 120, 0, Z)," &
++ "242 ( bc_1, gpio(76), output3, X, 121, 0, Z)," &
++ "243 ( bc_1, gpio(75), output3, X, 122, 0, Z)," &
++ "244 ( bc_1, gpio(74), output3, X, 123, 0, Z)," &
++ "245 ( bc_1, gpio(73), output3, X, 124, 0, Z)," &
++ "246 ( bc_1, gpio(72), output3, X, 125, 0, Z)," &
++ "247 ( bc_1, gpio(71), output3, X, 126, 0, Z)," &
++ "248 ( bc_1, gpio(70), output3, X, 127, 0, Z)," &
++ "249 ( bc_1, gpio(69), output3, X, 128, 0, Z)," &
++ "250 ( bc_1, gpio(68), output3, X, 129, 0, Z)," &
++ "251 ( bc_1, gpio(67), output3, X, 130, 0, Z)," &
++ "252 ( bc_1, gpio(66), output3, X, 131, 0, Z)," &
++ "253 ( bc_1, gpio(65), output3, X, 132, 0, Z)," &
++ "254 ( bc_1, gpio(64), output3, X, 133, 0, Z)," &
++ "255 ( bc_1, gpio(63), output3, X, 134, 0, Z)," &
++ "256 ( bc_1, gpio(62), output3, X, 135, 0, Z)," &
++ "257 ( bc_1, gpio(61), output3, X, 136, 0, Z)," &
++ "258 ( bc_1, gpio(60), output3, X, 137, 0, Z)," &
++ "259 ( bc_1, gpio(59), output3, X, 138, 0, Z)," &
++ "260 ( bc_1, gpio(58), output3, X, 139, 0, Z)," &
++ "261 ( bc_1, gpio(57), output3, X, 140, 0, Z)," &
++ "262 ( bc_1, gpio(56), output3, X, 141, 0, Z)," &
++ "263 ( bc_1, gpio(55), output3, X, 142, 0, Z)," &
++ "264 ( bc_1, gpio(54), output3, X, 143, 0, Z)," &
++ "265 ( bc_1, gpio(53), output3, X, 144, 0, Z)," &
++ "266 ( bc_1, gpio(52), output3, X, 145, 0, Z)," &
++ "267 ( bc_1, gpio(51), output3, X, 146, 0, Z)," &
++ "268 ( bc_1, gpio(50), output3, X, 147, 0, Z)," &
++ "269 ( bc_1, gpio(49), output3, X, 148, 0, Z)," &
++ "270 ( bc_1, gpio(48), output3, X, 149, 0, Z)," &
++ "271 ( bc_1, gpio(47), output3, X, 150, 0, Z)," &
++ "272 ( bc_1, gpio(46), output3, X, 151, 0, Z)," &
++ "273 ( bc_1, gpio(45), output3, X, 152, 0, Z)," &
++ "274 ( bc_1, gpio(44), output3, X, 153, 0, Z)," &
++ "275 ( bc_1, gpio(43), output3, X, 154, 0, Z)," &
++ "276 ( bc_1, gpio(42), output3, X, 155, 0, Z)," &
++ "277 ( bc_1, gpio(41), output3, X, 156, 0, Z)," &
++ "278 ( bc_1, gpio(40), output3, X, 157, 0, Z)," &
++ "279 ( bc_1, gpio(39), output3, X, 158, 0, Z)," &
++ "280 ( bc_1, gpio(38), output3, X, 159, 0, Z)," &
++ "281 ( bc_1, gpio(37), output3, X, 160, 0, Z)," &
++ "282 ( bc_1, gpio(36), output3, X, 161, 0, Z)," &
++ "283 ( bc_1, gpio(35), output3, X, 162, 0, Z)," &
++ "284 ( bc_1, gpio(34), output3, X, 163, 0, Z)," &
++ "285 ( bc_1, gpio(33), output3, X, 164, 0, Z)," &
++ "286 ( bc_1, gpio(32), output3, X, 165, 0, Z)," &
++ "287 ( bc_1, gpio(31), output3, X, 166, 0, Z)," &
++ "288 ( bc_1, gpio(30), output3, X, 167, 0, Z)," &
++ "289 ( bc_1, gpio(29), output3, X, 168, 0, Z)," &
++ "290 ( bc_1, gpio(28), output3, X, 169, 0, Z)," &
++ "291 ( bc_1, gpio(27), output3, X, 170, 0, Z)," &
++ "292 ( bc_1, gpio(26), output3, X, 171, 0, Z)," &
++ "293 ( bc_1, gpio(25), output3, X, 172, 0, Z)," &
++ "294 ( bc_1, gpio(24), output3, X, 173, 0, Z)," &
++ "295 ( bc_1, gpio(23), output3, X, 174, 0, Z)," &
++ "296 ( bc_1, gpio(22), output3, X, 175, 0, Z)," &
++ "297 ( bc_1, gpio(21), output3, X, 176, 0, Z)," &
++ "298 ( bc_1, gpio(20), output3, X, 177, 0, Z)," &
++ "299 ( bc_1, gpio(19), output3, X, 178, 0, Z)," &
++ "300 ( bc_1, gpio(18), output3, X, 179, 0, Z)," &
++ "301 ( bc_1, gpio(17), output3, X, 180, 0, Z)," &
++ "302 ( bc_1, gpio(16), output3, X, 181, 0, Z)," &
++ "303 ( bc_1, gpio(15), output3, X, 182, 0, Z)," &
++ "304 ( bc_1, gpio(14), output3, X, 183, 0, Z)," &
++ "305 ( bc_1, gpio(13), output3, X, 184, 0, Z)," &
++ "306 ( bc_1, gpio(12), output3, X, 185, 0, Z)," &
++ "307 ( bc_1, gpio(11), output3, X, 186, 0, Z)," &
++ "308 ( bc_1, gpio(10), output3, X, 187, 0, Z)," &
++ "309 ( bc_1, gpio(9), output3, X, 188, 0, Z)," &
++ "310 ( bc_1, gpio(8), output3, X, 189, 0, Z)," &
++ "311 ( bc_1, gpio(7), output3, X, 190, 0, Z)," &
++ "312 ( bc_1, gpio(6), output3, X, 191, 0, Z)," &
++ "313 ( bc_1, gpio(5), output3, X, 192, 0, Z)," &
++ "314 ( bc_1, gpio(4), output3, X, 193, 0, Z)," &
++ "315 ( bc_1, gpio(3), output3, X, 194, 0, Z)," &
++ "316 ( bc_1, gpio(2), output3, X, 195, 0, Z)," &
++ "317 ( bc_1, gpio(1), output3, X, 196, 0, Z)," &
++ "318 ( bc_1, gpio(0), output3, X, 197, 0, Z)," &
++ "319 ( bc_1, nsdcs_0, output3, X, 69, 0, Z)," &
++ "320 ( bc_1, nsdcs_1, output3, X, 75, 0, Z)," &
++ "321 ( bc_1, nsdras, output3, X, 69, 0, Z)," &
++ "322 ( bc_1, sdcke_1, output3, X, 75, 0, Z)," &
++ "323 ( bc_1, sdclk_1, output3, X, 69, 0, Z)," &
++ "324 ( bc_1, sdclk_2, output3, X, 75, 0, Z)," &
++ "325 ( bc_1, *, control, 0)," &
++ "326 ( bc_1, uio, output3, X, 327, 0, Z)," &
++ "327 ( bc_1, *, control, 0)," &
++ "328 ( bc_1, *, control, 0)," &
++ "329 ( bc_1, usbc_n, output3, X, 328, 0, Z)," &
++ "330 ( bc_1, usbc_p, output3, X, 328, 0, Z)," &
++ "331 ( bc_1, *, control, 1)," &
++ "332 ( bc_1, *, internal, 1)," &
++ "333 ( bc_1, usbh_n_0, output3, X, 331, 1, Z)," &
++ "334 ( bc_1, *, internal, 0)," &
++ "335 ( bc_1, usbh_p_0, output3, X, 331, 1, Z)," &
++ "336 ( bc_1, *, internal, 0)," &
++ "337 ( bc_1, boot_sel_0, input, X)," &
++ "338 ( bc_1, clk_req, input, X)," &
++ "339 ( bc_1, *, internal, 0)," &
++ "340 ( bc_1, *, internal, 0)," &
++ "341 ( bc_1, gpio(118), input, X)," &
++ "342 ( bc_1, gpio(117), input, X)," &
++ "343 ( bc_1, gpio(116), input, X)," &
++ "344 ( bc_1, gpio(115), input, X)," &
++ "345 ( bc_1, gpio(114), input, X)," &
++ "346 ( bc_1, gpio(113), input, X)," &
++ "347 ( bc_1, gpio(112), input, X)," &
++ "348 ( bc_1, gpio(111), input, X)," &
++ "349 ( bc_1, gpio(110), input, X)," &
++ "350 ( bc_1, gpio(109), input, X)," &
++ "351 ( bc_1, gpio(108), input, X)," &
++ "352 ( bc_1, gpio(107), input, X)," &
++ "353 ( bc_1, gpio(106), input, X)," &
++ "354 ( bc_1, gpio(105), input, X)," &
++ "355 ( bc_1, gpio(104), input, X)," &
++ "356 ( bc_1, gpio(103), input, X)," &
++ "357 ( bc_1, gpio(102), input, X)," &
++ "358 ( bc_1, gpio(101), input, X)," &
++ "359 ( bc_1, gpio(100), input, X)," &
++ "360 ( bc_1, gpio(99), input, X)," &
++ "361 ( bc_1, gpio(98), input, X)," &
++ "362 ( bc_1, gpio(97), input, X)," &
++ "363 ( bc_1, gpio(96), input, X)," &
++ "364 ( bc_1, gpio(95), input, X)," &
++ "365 ( bc_1, gpio(94), input, X)," &
++ "366 ( bc_1, gpio(93), input, X)," &
++ "367 ( bc_1, gpio(92), input, X)," &
++ "368 ( bc_1, gpio(91), input, X)," &
++ "369 ( bc_1, gpio(90), input, X)," &
++ "370 ( bc_1, gpio(89), input, X)," &
++ "371 ( bc_1, gpio(88), input, X)," &
++ "372 ( bc_1, gpio(87), input, X)," &
++ "373 ( bc_1, gpio(86), input, X)," &
++ "374 ( bc_1, gpio(85), input, X)," &
++ "375 ( bc_1, gpio(84), input, X)," &
++ "376 ( bc_1, gpio(83), input, X)," &
++ "377 ( bc_1, gpio(82), input, X)," &
++ "378 ( bc_1, gpio(81), input, X)," &
++ "379 ( bc_1, gpio(80), input, X)," &
++ "380 ( bc_1, gpio(79), input, X)," &
++ "381 ( bc_1, gpio(78), input, X)," &
++ "382 ( bc_1, gpio(77), input, X)," &
++ "383 ( bc_1, gpio(76), input, X)," &
++ "384 ( bc_1, gpio(75), input, X)," &
++ "385 ( bc_1, gpio(74), input, X)," &
++ "386 ( bc_1, gpio(73), input, X)," &
++ "387 ( bc_1, gpio(72), input, X)," &
++ "388 ( bc_1, gpio(71), input, X)," &
++ "389 ( bc_1, gpio(70), input, X)," &
++ "390 ( bc_1, gpio(69), input, X)," &
++ "391 ( bc_1, gpio(68), input, X)," &
++ "392 ( bc_1, gpio(67), input, X)," &
++ "393 ( bc_1, gpio(66), input, X)," &
++ "394 ( bc_1, gpio(65), input, X)," &
++ "395 ( bc_1, gpio(64), input, X)," &
++ "396 ( bc_1, gpio(63), input, X)," &
++ "397 ( bc_1, gpio(62), input, X)," &
++ "398 ( bc_1, gpio(61), input, X)," &
++ "399 ( bc_1, gpio(60), input, X)," &
++ "400 ( bc_1, gpio(59), input, X)," &
++ "401 ( bc_1, gpio(58), input, X)," &
++ "402 ( bc_1, gpio(57), input, X)," &
++ "403 ( bc_1, gpio(56), input, X)," &
++ "404 ( bc_1, gpio(55), input, X)," &
++ "405 ( bc_1, gpio(54), input, X)," &
++ "406 ( bc_1, gpio(53), input, X)," &
++ "407 ( bc_1, gpio(52), input, X)," &
++ "408 ( bc_1, gpio(51), input, X)," &
++ "409 ( bc_1, gpio(50), input, X)," &
++ "410 ( bc_1, gpio(49), input, X)," &
++ "411 ( bc_1, gpio(48), input, X)," &
++ "412 ( bc_1, gpio(47), input, X)," &
++ "413 ( bc_1, gpio(46), input, X)," &
++ "414 ( bc_1, gpio(45), input, X)," &
++ "415 ( bc_1, gpio(44), input, X)," &
++ "416 ( bc_1, gpio(43), input, X)," &
++ "417 ( bc_1, gpio(42), input, X)," &
++ "418 ( bc_1, gpio(41), input, X)," &
++ "419 ( bc_1, gpio(40), input, X)," &
++ "420 ( bc_1, gpio(39), input, X)," &
++ "421 ( bc_1, gpio(38), input, X)," &
++ "422 ( bc_1, gpio(37), input, X)," &
++ "423 ( bc_1, gpio(36), input, X)," &
++ "424 ( bc_1, gpio(35), input, X)," &
++ "425 ( bc_1, gpio(34), input, X)," &
++ "426 ( bc_1, gpio(33), input, X)," &
++ "427 ( bc_1, gpio(32), input, X)," &
++ "428 ( bc_1, gpio(31), input, X)," &
++ "429 ( bc_1, gpio(30), input, X)," &
++ "430 ( bc_1, gpio(29), input, X)," &
++ "431 ( bc_1, gpio(28), input, X)," &
++ "432 ( bc_1, gpio(27), input, X)," &
++ "433 ( bc_1, gpio(26), input, X)," &
++ "434 ( bc_1, gpio(25), input, X)," &
++ "435 ( bc_1, gpio(24), input, X)," &
++ "436 ( bc_1, gpio(23), input, X)," &
++ "437 ( bc_1, gpio(22), input, X)," &
++ "438 ( bc_1, gpio(21), input, X)," &
++ "439 ( bc_1, gpio(20), input, X)," &
++ "440 ( bc_1, gpio(19), input, X)," &
++ "441 ( bc_1, gpio(18), input, X)," &
++ "442 ( bc_1, gpio(17), input, X)," &
++ "443 ( bc_1, gpio(16), input, X)," &
++ "444 ( bc_1, gpio(15), input, X)," &
++ "445 ( bc_1, gpio(14), input, X)," &
++ "446 ( bc_1, gpio(13), input, X)," &
++ "447 ( bc_1, gpio(12), input, X)," &
++ "448 ( bc_1, gpio(11), input, X)," &
++ "449 ( bc_1, gpio(10), input, X)," &
++ "450 ( bc_1, gpio(9), input, X)," &
++ "451 ( bc_1, gpio(8), input, X)," &
++ "452 ( bc_1, gpio(7), input, X)," &
++ "453 ( bc_1, gpio(6), input, X)," &
++ "454 ( bc_1, gpio(5), input, X)," &
++ "455 ( bc_1, gpio(4), input, X)," &
++ "456 ( bc_1, gpio(3), input, X)," &
++ "457 ( bc_1, gpio(2), input, X)," &
++ "458 ( bc_1, gpio(1), input, X)," &
++ "459 ( bc_1, gpio(0), input, X)," &
++ "460 ( bc_1, md(31), input, X)," &
++ "461 ( bc_1, md(30), input, X)," &
++ "462 ( bc_1, md(29), input, X)," &
++ "463 ( bc_1, md(28), input, X)," &
++ "464 ( bc_1, md(27), input, X)," &
++ "465 ( bc_1, md(26), input, X)," &
++ "466 ( bc_1, md(25), input, X)," &
++ "467 ( bc_1, md(24), input, X)," &
++ "468 ( bc_1, md(23), input, X)," &
++ "469 ( bc_1, md(22), input, X)," &
++ "470 ( bc_1, md(21), input, X)," &
++ "471 ( bc_1, md(20), input, X)," &
++ "472 ( bc_1, md(19), input, X)," &
++ "473 ( bc_1, md(18), input, X)," &
++ "474 ( bc_1, md(17), input, X)," &
++ "475 ( bc_1, md(16), input, X)," &
++ "476 ( bc_1, md(15), input, X)," &
++ "477 ( bc_1, md(14), input, X)," &
++ "478 ( bc_1, md(13), input, X)," &
++ "479 ( bc_1, md(12), input, X)," &
++ "480 ( bc_1, md(11), input, X)," &
++ "481 ( bc_1, md(10), input, X)," &
++ "482 ( bc_1, md(9), input, X)," &
++ "483 ( bc_1, md(8), input, X)," &
++ "484 ( bc_1, md(7), input, X)," &
++ "485 ( bc_1, md(6), input, X)," &
++ "486 ( bc_1, md(5), input, X)," &
++ "487 ( bc_1, md(4), input, X)," &
++ "488 ( bc_1, md(3), input, X)," &
++ "489 ( bc_1, md(2), input, X)," &
++ "490 ( bc_1, md(1), input, X)," &
++ "491 ( bc_1, md(0), input, X)," &
++ "492 ( bc_1, nbatt_fault, input, 1)," &
++ "493 ( bc_1, nreset, input, 1)," &
++ "494 ( bc_1, nvdd_fault, input, 1)," &
++ "495 ( bc_1, test, input, X)," &
++ "496 ( bc_1, testclk, input, X)," &
++ "497 ( bc_1, uio, input, X)," &
++ "498 ( bc_1, usbc_n, input, X)," &
++ "499 ( bc_1, usbc_p, input, X)," &
++ "500 ( bc_1, usbh_n_0, input, X)," &
++ "501 ( bc_1, *, internal, 0)," &
++ "502 ( bc_1, usbh_p_0, input, X)," &
++ "503 ( bc_1, *, internal, 0)";
++
++attribute DESIGN_WARNING of bulverde_b0_13x13 : entity is
++ " 1. The following ports are not part of the boundary scan register: " &
++ " pxtal_in, txtal_in, pextal_out, textal_out, tdi, tms, ntrst, " &
++ " tck, tdo " &
++ " " &
++ " 2. ntrst must be driven from low to high either before or at the " &
++ " same time as nreset at power-up. Only after nreset_out has " &
++ " been deasserted is power applied to the BSR logic. " &
++ " " &
++ " 3. The nbatt_fault, nvdd_fault, and nreset input ports must be " &
++ " driven to a logic 1 at all times. Not doing so puts the part " &
++ " into sleep which disables power to all BSR logic. " &
++ " " &
++ " 4. gpio[2]=sys_en, gpio[20]=nsdcs2, gpio[21]=nsdcs3 " &
++ " " &
++ " 5. The following BSR cells are internal, i.e. not bounded out: " &
++ " 63,77,78,198,199,332,334,336,339,340,501,503 " &
++ " As such they will capture indeterminate values. ";
++
++end bulverde_b0_13x13;
++
++*/
++
++/* End of reference information */
++
++
++
++
++
+diff -Naur u-boot-2008.10_original/bulbcx_16.dat u-boot-2008.10/bulbcx_16.dat
+--- u-boot-2008.10_original/bulbcx_16.dat 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/bulbcx_16.dat 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,1031 @@
++/* BulvBCx_16.dat version 1.00.001
++****************************************************************************
++
++ This data file contains the JTAG and board configuration data required
++ for multi-mode JFlash. This data file is a text file with specific
++ format requirements.
++
++ Comment blocks can be defined using the old-style C comment blocks.
++ The difference is that the delimiter characters must have whitespace
++ on both sides.
++
++ Data may be string data, or numeric. String data is only allowed
++ at specific positions within this file. Numeric data can be decimal,
++ hexadecimal, or octal.
++ Decimal data is assumed, and HEX data may be denoted by a
++ preceding 'X' character.
++
++ Valid HEX data:
++ xA0000000
++ XA4090000
++ Xff
++
++ Valid OCTAL data:
++ o765
++ O123545
++
++ The data required to fill in this table comes from knowledge of the
++ BSDL file for the processor, the development board user's guide,
++ and specifications for the flash components.
++
++ Data is position dependent in terms of order. Whitespace is the
++ delimiter for the data and may be used as necessary to keep the
++ data in reasonably readable format.
++
++ There are checkpoints within this file that are used as validation
++ that the data alignment is correct. DO NOT MODIFY THE CHECKPOINT DATA.
++
++ The filename of this file is used as the parameter for JFlash.
++*/
++
++/*
++****************************************************************************
++Release Information
++****************************************************************************
++
++ 1. This data file will identify the A0 and A1 silicon, but the scan data is not
++ compatible with these older revisions.
++
++ 2. 2.0 release: adds identification for the C2 silicon.
++
++ END RELEASE INFORMATION
++*/
++
++
++/*
++****************************************************************************
++File Identification strings to display from JFlash
++****************************************************************************
++*/
++ PXA27x /* Position 0 - Supported Processor Code Name or Number */
++ Mainstone /* Supported Development platform name or number */
++ 1.00.001 /* Version number of this data file */
++ VL00000001 /* Version lock code for compatibility to JTAG engine */
++
++/*
++****************************************************************************
++Basic JTAG setup required by JFlash
++****************************************************************************
++*/
++ 504 /* The number of bits in the Boundary Scan chain */
++ 7 /* The number of bits in the instruction register */
++ X0 /* EXTEST instruction in HEX */
++ X7E /* IDCODE instruction in HEX */
++ X7F /* BYPASS instruction */
++/*
++****************************************************************************
++Chip select offsets: 6 total, beginning with chip select 0 and in order.
++****************************************************************************
++*/
++ 61 303 240 239 238 285
++/*
++****************************************************************************
++Control Bits required for bus transactions
++****************************************************************************
++*/
++ 60 /* Output enable: nOE_OUT */
++ 59 /* Write Enable: nWE_OUT */
++ 72 /* Memory data upper bit control: mdupper_ctrl */
++ 71 /* Memory data lower bit control: mdlower_ctrl */
++ 68 /* Read/Write direction: RD_nWR_OUT */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 1 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 1111 /* position 20 */
++/*
++****************************************************************************
++Address bit offsets beginning with A0
++****************************************************************************
++*/
++ 25 24 23 22 21 20 19 18 /* A0 - A7 */
++ 17 16 15 14 13 12 11 10 /* A8 - A15 */
++ 9 8 7 6 5 4 3 2 /* A16 - A23 */
++ 1 0 /* A24, A25 */
++/*
++****************************************************************************
++Input data bit offsets beginning with D0
++****************************************************************************
++*/
++ 491 490 489 488 487 486 485 484 /* D0 - D7 */
++ 483 482 481 480 479 478 477 476 /* D8 - D15 */
++ 475 474 473 472 471 470 469 468 /* D16 - D23 */
++ 467 466 465 464 463 462 461 460 /* D24 - D31 */
++/*
++****************************************************************************
++Output data bit offsets beginning with D0
++****************************************************************************
++*/
++ 57 56 55 54 53 52 51 50 /* D0 - D7 */
++ 49 48 47 46 45 44 43 42 /* D8 - D15 */
++ 41 40 39 38 37 36 35 34 /* D16 - D23 */
++ 33 32 31 30 29 28 27 26 /* D24 - D31 */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 2 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 2222 /* position 111 */
++/*
++****************************************************************************
++Width of data bus. Only 16 or 32 are allowed as values
++****************************************************************************
++*/
++ 16
++/*
++****************************************************************************
++Memory Space Definition for chip selects. The memory addresses are defined
++by a lower and upper limit and the chip select that is used to access this
++address. The chip selects are identified by an integer.
++Only 6 regions are allowed. If there are fewer regions on the platform,
++then specify the unused regions with XFFFFFFFF as the lower and upper
++region limits and specify the highest chip select for these regions.
++****************************************************************************
++*/
++/* Lower Address Upper Address Chip Select */
++ X00000000 X04000000 0
++ X04000000 X08000000 1
++ X08000000 X0C000000 2
++ X0C000000 X10000000 3
++ X10000000 X14000000 4
++ X14000000 X18000000 5
++/*
++****************************************************************************
++Processor JTAG ID string. The upper 4 bits that define the stepping are not
++required here, but must be defined afterward to equate the value to the
++named stepping.
++****************************************************************************
++*/
++ 1001001001100101 /* Processor ID */
++ 00000001001 /* Intel Manufacturer Code */
++ 1 /* required by JTAG Standards */
++/*
++****************************************************************************
++Stepping labels relative to the top 4 bits of the chip ID.
++16 values required.
++****************************************************************************
++*/
++ A0 /* id = 0 , data position 131 */
++ A1 /* id = 1 */
++ B0 /* id = 2 */
++ B1 /* id = 3 */
++ C0 /* id = 4 */
++ C2 /* id = 5 */
++ ?? /* id = 6 */
++ ?? /* id = 7 */
++ ?? /* id = 8 */
++ ?? /* id = 9 */
++ ?? /* id = 10 */
++ ?? /* id = 11 */
++ ?? /* id = 12 */
++ ?? /* id = 13 */
++ ?? /* id = 14 */
++ ?? /* id = 15 */
++/*
++****************************************************************************
++Default High bits. These are pins on the chain that are required to be set
++high by default. This list contains some usual pins, and allows for 20
++arbitrary additional pins to be set. This list as with all lists is required
++to have a fixed number of entries. All entries that are not used should be
++set to 9999
++****************************************************************************
++*/
++ /* Normally high */
++
++ 61 /* nCS0_OUT */
++ 303 /* nCS1_OUT */ 182 /* nCS1 control pin */
++ 240 /* nCS2_OUT */ 119 /* nCS2 control pin */
++ 239 /* nCS3_OUT */ 118 /* nCS3 control pin */
++ 238 /* nCS4_OUT */ 117 /* nCS4 control pin */
++ 285 /* nCS5_OUT */ 164 /* nCS5 control pin */
++ 9999 /* additional */
++ 59 /* nWE_OUT */
++ 60 /* nOE_OUT */
++ 69 /* ma_ctrl - address lines enable */
++ 70 /* dqm_ctrl - DQM Control */
++ 71 /* mdlower_ctrl - memory data lower 16 bits */
++ 72 /* mdupper_ctrl - memory data upper 16 bits */
++ 73 /* nwe_ctrl */
++ 74 /* noe_ctrl */
++ 75 /* sdclk_ctrl */
++ 319 /* nsdcs_0 */
++ 318 /* nsdcs_1 */
++ 321 /* nsdras */
++ 325 /* clk_req_ctrl */
++ 492 /* nbatt_fault */
++ 494 /* nvdd_fault */
++
++ /* Arbitrary Additional Pins */
++
++ 316 /* GPIO 2 required for sys enable */
++ 195 /* GPIO 2 Control */
++ 269 /* GPIO 49 nPWE */
++ 148 /* GPIO 49 control */
++ 228 /* GPIO 90 nURST */
++ 107 /* GPIO 90 control */
++ 313 /* additional */
++ 192 /* additional */
++ 312 /* additional */
++ 191 /* additional */
++ 311 /* additional */
++ 190 /* additional */
++ 310 /* additional */
++ 189 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++ 9999 /* additional */
++/*
++****************************************************************************
++JTAG Chain description: This section defines the position of components
++on the chain so that these components can be accounted for and bypassed
++during the programming operation. There are up to 5 devices that can be
++handled, and at least one must be the main processor. Specify that a
++device is present with the string 'Enabled' or not present with the string
++'Disabled'. Each device that is enabled requires a specification for the
++number of bits in the JTAG instruction register. The controlling entity,
++usually the main processor is identified by the string 'Controller'.
++The order of the components is from TDI to TDO. The procedure needs to
++know if the device is the last
++****************************************************************************
++*/
++/* TDI --------> */ Enabled 7 Controller Last
++ Disabled 0 Other More
++ Disabled 0 Other More
++ Disabled 0 Other More
++ Disabled 0 Other More /* TDO ---------> */
++/*
++****************************************************************************
++Additional flash component UNLOCK controls: 4 addition pins can be defined
++that would be controlled to UNLOCK a flash memory device that has external
++locking pins. Any unused pins should be set to 9999. Specify the signal level
++required to UNLOCK the flash. These signals will be reversed to re-lock the
++flash after programming.
++****************************************************************************
++*/
++ 9999 1 /* gpio22_ctrl */
++ 9999 1 /* gpio12_ctrl */
++ 9999 1 /* gpio22_out */
++ 9999 1 /* gpio12_out */
++/*
++****************************************************************************
++ALIGNMENT CHECKPOINT # 3 - DO NOT MODIFY THIS DATA
++****************************************************************************
++*/
++ 3333
++
++/*
++****************************************************************************
++number of flash devices in parallel on the bus
++****************************************************************************
++*/
++ 1
++/*
++****************************************************************************
++position of nsdcas signal - toggled in parallel with any chip select
++****************************************************************************
++*/
++ 58 /* nsdcas */
++/*
++****************************************************************************
++Flash programming Mode: WORD or BUFFER
++WORD programming is useful for doing things like smoothly crossing device
++boundaries but is a little slower.
++****************************************************************************
++*/
++ BUFFER /* WORD or BUFFER is the allowed entry */
++/*
++****************************************************************************
++E N D O F D A T A
++****************************************************************************
++*/
++
++/*
++BSDL File Used
++
++--------------------------------------------------------------------------
++-- File Type : BSDL Description Bulverde B0 v1_0 13x13 VFBGA
++-- Author : jboyer
++--------------------------------------------------------------------------
++
++entity bulverde_b0_13x13 is
++
++generic(PHYSICAL_PIN_MAP : string := "VFBGA");
++
++port(
++ boot_sel_0 : in bit;
++ rdnwr : out bit;
++ clk_req : inout bit;
++ gpio : inout bit_vector(118 downto 0);
++ dqm_0 : out bit;
++ dqm_1 : out bit;
++ dqm_2 : out bit;
++ dqm_3 : out bit;
++ ma : out bit_vector(25 downto 0);
++ md : inout bit_vector(31 downto 0);
++ ncs_0 : out bit;
++ noe : out bit;
++ nsdcas : out bit;
++ nsdcs_0 : out bit;
++ nsdcs_1 : out bit;
++ nsdras : out bit;
++ nwe : out bit;
++ sdcke_1 : out bit;
++ sdclk_0 : out bit;
++ sdclk_1 : out bit;
++ sdclk_2 : out bit;
++ nbatt_fault : in bit;
++ nreset : in bit;
++ nreset_out : linkage bit;
++ nvdd_fault : in bit;
++ pwr_en : linkage bit;
++ pxtal_in : linkage bit;
++ pxtal_out : linkage bit;
++ test : in bit;
++ testclk : in bit;
++ txtal_in : linkage bit;
++ txtal_out : linkage bit;
++ uio : inout bit;
++ usbc_n : inout bit;
++ usbc_p : inout bit;
++ usbh_n_0 : inout bit;
++ usbh_p_0 : inout bit;
++ vcc_batt : linkage bit;
++ vcc_bb : linkage bit;
++ vcc_core : linkage bit_vector(13 downto 0);
++ vcc_io : linkage bit_vector(2 downto 0);
++ vcc_usb : linkage bit_vector(3 downto 0);
++ vcc_lcd : linkage bit_vector(1 downto 0);
++ vcc_mem : linkage bit_vector(18 downto 0);
++ pwr_out : linkage bit;
++ vcc_pll : linkage bit;
++ vcc_ram : linkage bit_vector(3 downto 0);
++ vcc_usim : linkage bit;
++ vss_bb : linkage bit;
++ vss_core : linkage bit_vector(19 downto 0);
++ vss_io : linkage bit_vector(7 downto 0);
++ vss_mem : linkage bit_vector(16 downto 0);
++ vss_pad : linkage bit_vector(5 downto 0);
++ vss_pll : linkage bit;
++ tdi : in bit;
++ tms : in bit;
++ tck : in bit;
++ tdo : out bit;
++ ntrst : in bit
++ );
++
++use STD_1149_1_1994.all;
++
++attribute COMPONENT_CONFORMANCE of bulverde_b0_13x13 : entity is "STD_1149_1_1993";
++
++attribute PIN_MAP of bulverde_b0_13x13 : entity is PHYSICAL_PIN_MAP;
++
++constant VFBGA : PIN_MAP_STRING :=
++ "boot_sel_0: ab23," &
++ "rdnwr: c9," &
++ "clk_req: w24," &
++ "gpio: (a22,d20,c24,e21,d24,a13,b18,c17,b17," &
++ "d17,ad14,ac15,ab15,ab16,ad15,ac16,ab17,ac17,ac18," &
++ "ab18,ad18,aa17,ac19,aa18,ad19,ab19,a19,f23,f22," &
++ "d22,c23,n23,n22,ac12,aa11,ad10,ad9,ab12,c7," &
++ "c8,b7,r21,p22,p23,r23,m22,n24,l22,m24," &
++ "l23,l21,k23,k22,k24,j22,h23,h22,h24,g23," &
++ "g22,g24,ac11,ab11,aa10,aa14,ab14,ac14,ad13,ab13," &
++ "a10,ac13,a11,b11,c19,b20,c22,c21,c18,d14," &
++ "d19,b14,a15,c14,b19,a21,b6,a20,c12,c13," &
++ "b13,a14,c15,b15,d16,a17,b16,d13,ad5,ab6," &
++ "r22,b9,c16,a18,a3,t24,c10,b10,c11,v23," &
++ "u22,aa20,ac22,ad22,ab21,w23,w21,aa24,y24,v22)," &
++ "dqm_0: ab9," &
++ "dqm_1: ab10," &
++ "dqm_2: ac9," &
++ "dqm_3: ac10," &
++ "ma: (d6,c4,d4,c2,d2,e4,e3,c1,d1,f3," &
++ "g4,f2,e1,g3,g2,h3,h2,g1,j3,j2,k3,k2,j1,k4,a6,c6)," &
++ "md: (l2,m2,m3,n2,n1,p3,r3,r1,t1,v2,v1,w1,y1,aa1,ab3,aa4," &
++ "k1,l1,m4,n3,p2,p4,r4,t3,u1,v3,u4,y2,y3,aa3,ab1,ab4)," &
++ "ncs_0: b3," &
++ "noe: ac5," &
++ "nsdcas: aa6," &
++ "nsdcs_0: ab7," &
++ "nsdcs_1: ab8," &
++ "nsdras: ac7," &
++ "nwe: ab5," &
++ "sdcke_1: ad6," &
++ "sdclk_0: ac4," &
++ "sdclk_1: ad7," &
++ "sdclk_2: ad3," &
++ "nbatt_fault: ab24," &
++ "nreset: y22," &
++ "nreset_out: y21," &
++ "nvdd_fault: w22," &
++ "pwr_en: y23," &
++ "pxtal_in: ac21," &
++ "pxtal_out: ad21," &
++ "test: u24," &
++ "testclk: t23," &
++ "txtal_in: aa22," &
++ "txtal_out: aa23," &
++ "uio: e23," &
++ "usbc_n: c20," &
++ "usbc_p: b22," &
++ "usbh_n_0: d23," &
++ "usbh_p_0: e22," &
++ "vcc_batt: ab20," &
++ "vcc_bb: ad12," &
++ "vcc_core: (ad11,t2,ad4,w3,b21,m23,r24,ad16,f24,l24,j23,d3," &
++ "a7,b12)," &
++ "vcc_io: (ad17,a12,a16)," &
++ "vcc_usb: (a23,a24,b23,b24)," &
++ "vcc_lcd: (j24,p24)," &
++ "vcc_mem: (w2,ac6,a4,b8,ac8,aa2,u2,ad8,f1,h1,m1,ad1,ac1," &
++ "ac2,ad2,l3,e2,c3,p1)," &
++ "pwr_out: ab22," &
++ "vcc_pll: ac20," &
++ "vcc_ram: (b4,a5,a8,a9)," &
++ "vcc_usim: e24," &
++ "vss_bb: aa13," &
++ "vss_core: (aa12,w4,d8,d12,d21,g21,k21,p21,aa7,u3,m21,aa15," &
++ "d10,j21,a1,b1,a2,b2,d7,b5)," &
++ "vss_io: (d11,d15,d18,f21,h21,n21,aa19,aa16)," &
++ "vss_mem: (y4,c5,r2,n4,d9,aa9,aa8,aa5,v4,t4,l4,ab2,ac3,j4," &
++ "h4,f4,d5)," &
++ "vss_pad: (v21,ad23,ac23,ad24,ac24,aa21)," &
++ "vss_pll: ad20," &
++ "tdi: u23," &
++ "tms: t21," &
++ "tck: t22," &
++ "tdo: v24," &
++ "ntrst: u21";
++
++
++attribute TAP_SCAN_IN of TDI : signal is true;
++attribute TAP_SCAN_MODE of TMS : signal is true;
++attribute TAP_SCAN_OUT of TDO : signal is true;
++attribute TAP_SCAN_CLOCK of TCK : signal is (20.0e6, BOTH);
++attribute TAP_SCAN_RESET of NTRST : signal is true;
++
++attribute INSTRUCTION_LENGTH of bulverde_b0_13x13 : entity is 7;
++attribute INSTRUCTION_OPCODE of bulverde_b0_13x13 : entity is
++ "extest (0000000)," &
++ "bypass (1111111)," &
++ "sample (0000001)," &
++ "clamp (0000100)," &
++ "highz (0001000)," &
++ "flashload (0110110)," &
++ "flashprgm (0110111)," &
++ "idcode (1111110)";
++
++attribute INSTRUCTION_CAPTURE of bulverde_b0_13x13 : entity is "0000001";
++attribute IDCODE_REGISTER of bulverde_b0_13x13 : entity is
++ "0010" & -- Version Number
++ "1001001001100101" & -- Part Number
++ "00000001001" & -- Manufacturer ID
++ "1"; -- Required by IEEE Std. 1149.1-1990
++
++attribute REGISTER_ACCESS of bulverde_b0_13x13 : entity is
++ "BOUNDARY (extest, sample)," &
++ "DEVICE_ID (idcode)," &
++ "BYPASS (bypass, clamp, highz)," &
++ "flash_reg[76] (flashload, flashprgm)";
++
++attribute BOUNDARY_LENGTH of bulverde_b0_13x13 : entity is 504;
++attribute BOUNDARY_REGISTER of bulverde_b0_13x13 : entity is
++ -- num cell port function safe [ccell disval rslt]
++ "0 ( bc_1, ma(25), output3, X, 69, 0, Z)," &
++ "1 ( bc_1, ma(24), output3, X, 69, 0, Z)," &
++ "2 ( bc_1, ma(23), output3, X, 69, 0, Z)," &
++ "3 ( bc_1, ma(22), output3, X, 69, 0, Z)," &
++ "4 ( bc_1, ma(21), output3, X, 69, 0, Z)," &
++ "5 ( bc_1, ma(20), output3, X, 69, 0, Z)," &
++ "6 ( bc_1, ma(19), output3, X, 69, 0, Z)," &
++ "7 ( bc_1, ma(18), output3, X, 69, 0, Z)," &
++ "8 ( bc_1, ma(17), output3, X, 69, 0, Z)," &
++ "9 ( bc_1, ma(16), output3, X, 69, 0, Z)," &
++ "10 ( bc_1, ma(15), output3, X, 69, 0, Z)," &
++ "11 ( bc_1, ma(14), output3, X, 69, 0, Z)," &
++ "12 ( bc_1, ma(13), output3, X, 69, 0, Z)," &
++ "13 ( bc_1, ma(12), output3, X, 69, 0, Z)," &
++ "14 ( bc_1, ma(11), output3, X, 69, 0, Z)," &
++ "15 ( bc_1, ma(10), output3, X, 69, 0, Z)," &
++ "16 ( bc_1, ma(9), output3, X, 69, 0, Z)," &
++ "17 ( bc_1, ma(8), output3, X, 69, 0, Z)," &
++ "18 ( bc_1, ma(7), output3, X, 69, 0, Z)," &
++ "19 ( bc_1, ma(6), output3, X, 69, 0, Z)," &
++ "20 ( bc_1, ma(5), output3, X, 69, 0, Z)," &
++ "21 ( bc_1, ma(4), output3, X, 69, 0, Z)," &
++ "22 ( bc_1, ma(3), output3, X, 69, 0, Z)," &
++ "23 ( bc_1, ma(2), output3, X, 69, 0, Z)," &
++ "24 ( bc_1, ma(1), output3, X, 69, 0, Z)," &
++ "25 ( bc_1, ma(0), output3, X, 69, 0, Z)," &
++ "26 ( bc_1, md(31), output3, X, 72, 0, Z)," &
++ "27 ( bc_1, md(30), output3, X, 72, 0, Z)," &
++ "28 ( bc_1, md(29), output3, X, 72, 0, Z)," &
++ "29 ( bc_1, md(28), output3, X, 72, 0, Z)," &
++ "30 ( bc_1, md(27), output3, X, 72, 0, Z)," &
++ "31 ( bc_1, md(26), output3, X, 72, 0, Z)," &
++ "32 ( bc_1, md(25), output3, X, 72, 0, Z)," &
++ "33 ( bc_1, md(24), output3, X, 72, 0, Z)," &
++ "34 ( bc_1, md(23), output3, X, 72, 0, Z)," &
++ "35 ( bc_1, md(22), output3, X, 72, 0, Z)," &
++ "36 ( bc_1, md(21), output3, X, 72, 0, Z)," &
++ "37 ( bc_1, md(20), output3, X, 72, 0, Z)," &
++ "38 ( bc_1, md(19), output3, X, 72, 0, Z)," &
++ "39 ( bc_1, md(18), output3, X, 72, 0, Z)," &
++ "40 ( bc_1, md(17), output3, X, 72, 0, Z)," &
++ "41 ( bc_1, md(16), output3, X, 72, 0, Z)," &
++ "42 ( bc_1, md(15), output3, X, 71, 0, Z)," &
++ "43 ( bc_1, md(14), output3, X, 71, 0, Z)," &
++ "44 ( bc_1, md(13), output3, X, 71, 0, Z)," &
++ "45 ( bc_1, md(12), output3, X, 71, 0, Z)," &
++ "46 ( bc_1, md(11), output3, X, 71, 0, Z)," &
++ "47 ( bc_1, md(10), output3, X, 71, 0, Z)," &
++ "48 ( bc_1, md(9), output3, X, 71, 0, Z)," &
++ "49 ( bc_1, md(8), output3, X, 71, 0, Z)," &
++ "50 ( bc_1, md(7), output3, X, 71, 0, Z)," &
++ "51 ( bc_1, md(6), output3, X, 71, 0, Z)," &
++ "52 ( bc_1, md(5), output3, X, 71, 0, Z)," &
++ "53 ( bc_1, md(4), output3, X, 71, 0, Z)," &
++ "54 ( bc_1, md(3), output3, X, 71, 0, Z)," &
++ "55 ( bc_1, md(2), output3, X, 71, 0, Z)," &
++ "56 ( bc_1, md(1), output3, X, 71, 0, Z)," &
++ "57 ( bc_1, md(0), output3, X, 71, 0, Z)," &
++ "58 ( bc_1, nsdcas, output3, X, 69, 0, Z)," &
++ "59 ( bc_1, nwe, output3, X, 73, 0, Z)," &
++ "60 ( bc_1, noe, output3, X, 74, 0, Z)," &
++ "61 ( bc_1, ncs_0, output3, X, 74, 0, Z)," &
++ "62 ( bc_1, sdclk_0, output3, X, 75, 0, Z)," &
++ "63 ( bc_1, *, internal, 0)," &
++ "64 ( bc_1, dqm_3, output3, X, 70, 0, Z)," &
++ "65 ( bc_1, dqm_2, output3, X, 70, 0, Z)," &
++ "66 ( bc_1, dqm_1, output3, X, 69, 0, Z)," &
++ "67 ( bc_1, dqm_0, output3, X, 69, 0, Z)," &
++ "68 ( bc_1, rdnwr, output3, X, 69, 0, Z)," &
++ "69 ( bc_1, *, control, 0)," &
++ "70 ( bc_1, *, control, 0)," &
++ "71 ( bc_1, *, control, 0)," &
++ "72 ( bc_1, *, control, 0)," &
++ "73 ( bc_1, *, control, 0)," &
++ "74 ( bc_1, *, control, 0)," &
++ "75 ( bc_1, *, control, 0)," &
++ "76 ( bc_1, clk_req, output3, X, 325, 0, Z)," &
++ "77 ( bc_1, *, internal, 0)," &
++ "78 ( bc_1, *, internal, 0)," &
++ "79 ( bc_1, *, control, 0)," &
++ "80 ( bc_1, *, control, 0)," &
++ "81 ( bc_1, *, control, 0)," &
++ "82 ( bc_1, *, control, 0)," &
++ "83 ( bc_1, *, control, 0)," &
++ "84 ( bc_1, *, control, 0)," &
++ "85 ( bc_1, *, control, 0)," &
++ "86 ( bc_1, *, control, 0)," &
++ "87 ( bc_1, *, control, 0)," &
++ "88 ( bc_1, *, control, 0)," &
++ "89 ( bc_1, *, control, 0)," &
++ "90 ( bc_1, *, control, 0)," &
++ "91 ( bc_1, *, control, 0)," &
++ "92 ( bc_1, *, control, 0)," &
++ "93 ( bc_1, *, control, 0)," &
++ "94 ( bc_1, *, control, 0)," &
++ "95 ( bc_1, *, control, 0)," &
++ "96 ( bc_1, *, control, 0)," &
++ "97 ( bc_1, *, control, 0)," &
++ "98 ( bc_1, *, control, 0)," &
++ "99 ( bc_1, *, control, 0)," &
++ "100 ( bc_1, *, control, 0)," &
++ "101 ( bc_1, *, control, 0)," &
++ "102 ( bc_1, *, control, 0)," &
++ "103 ( bc_1, *, control, 0)," &
++ "104 ( bc_1, *, control, 0)," &
++ "105 ( bc_1, *, control, 0)," &
++ "106 ( bc_1, *, control, 0)," &
++ "107 ( bc_1, *, control, 0)," &
++ "108 ( bc_1, *, control, 0)," &
++ "109 ( bc_1, *, control, 0)," &
++ "110 ( bc_1, *, control, 0)," &
++ "111 ( bc_1, *, control, 0)," &
++ "112 ( bc_1, *, control, 0)," &
++ "113 ( bc_1, *, control, 0)," &
++ "114 ( bc_1, *, control, 0)," &
++ "115 ( bc_1, *, control, 0)," &
++ "116 ( bc_1, *, control, 0)," &
++ "117 ( bc_1, *, control, 0)," &
++ "118 ( bc_1, *, control, 0)," &
++ "119 ( bc_1, *, control, 0)," &
++ "120 ( bc_1, *, control, 0)," &
++ "121 ( bc_1, *, control, 0)," &
++ "122 ( bc_1, *, control, 0)," &
++ "123 ( bc_1, *, control, 0)," &
++ "124 ( bc_1, *, control, 0)," &
++ "125 ( bc_1, *, control, 0)," &
++ "126 ( bc_1, *, control, 0)," &
++ "127 ( bc_1, *, control, 0)," &
++ "128 ( bc_1, *, control, 0)," &
++ "129 ( bc_1, *, control, 0)," &
++ "130 ( bc_1, *, control, 0)," &
++ "131 ( bc_1, *, control, 0)," &
++ "132 ( bc_1, *, control, 0)," &
++ "133 ( bc_1, *, control, 0)," &
++ "134 ( bc_1, *, control, 0)," &
++ "135 ( bc_1, *, control, 0)," &
++ "136 ( bc_1, *, control, 0)," &
++ "137 ( bc_1, *, control, 0)," &
++ "138 ( bc_1, *, control, 0)," &
++ "139 ( bc_1, *, control, 0)," &
++ "140 ( bc_1, *, control, 0)," &
++ "141 ( bc_1, *, control, 0)," &
++ "142 ( bc_1, *, control, 0)," &
++ "143 ( bc_1, *, control, 0)," &
++ "144 ( bc_1, *, control, 0)," &
++ "145 ( bc_1, *, control, 0)," &
++ "146 ( bc_1, *, control, 0)," &
++ "147 ( bc_1, *, control, 0)," &
++ "148 ( bc_1, *, control, 0)," &
++ "149 ( bc_1, *, control, 0)," &
++ "150 ( bc_1, *, control, 0)," &
++ "151 ( bc_1, *, control, 0)," &
++ "152 ( bc_1, *, control, 0)," &
++ "153 ( bc_1, *, control, 0)," &
++ "154 ( bc_1, *, control, 0)," &
++ "155 ( bc_1, *, control, 0)," &
++ "156 ( bc_1, *, control, 0)," &
++ "157 ( bc_1, *, control, 0)," &
++ "158 ( bc_1, *, control, 0)," &
++ "159 ( bc_1, *, control, 0)," &
++ "160 ( bc_1, *, control, 0)," &
++ "161 ( bc_1, *, control, 0)," &
++ "162 ( bc_1, *, control, 0)," &
++ "163 ( bc_1, *, control, 0)," &
++ "164 ( bc_1, *, control, 0)," &
++ "165 ( bc_1, *, control, 0)," &
++ "166 ( bc_1, *, control, 0)," &
++ "167 ( bc_1, *, control, 0)," &
++ "168 ( bc_1, *, control, 0)," &
++ "169 ( bc_1, *, control, 0)," &
++ "170 ( bc_1, *, control, 0)," &
++ "171 ( bc_1, *, control, 0)," &
++ "172 ( bc_1, *, control, 0)," &
++ "173 ( bc_1, *, control, 0)," &
++ "174 ( bc_1, *, control, 0)," &
++ "175 ( bc_1, *, control, 0)," &
++ "176 ( bc_1, *, control, 0)," &
++ "177 ( bc_1, *, control, 0)," &
++ "178 ( bc_1, *, control, 0)," &
++ "179 ( bc_1, *, control, 0)," &
++ "180 ( bc_1, *, control, 0)," &
++ "181 ( bc_1, *, control, 0)," &
++ "182 ( bc_1, *, control, 0)," &
++ "183 ( bc_1, *, control, 0)," &
++ "184 ( bc_1, *, control, 0)," &
++ "185 ( bc_1, *, control, 0)," &
++ "186 ( bc_1, *, control, 0)," &
++ "187 ( bc_1, *, control, 0)," &
++ "188 ( bc_1, *, control, 0)," &
++ "189 ( bc_1, *, control, 0)," &
++ "190 ( bc_1, *, control, 0)," &
++ "191 ( bc_1, *, control, 0)," &
++ "192 ( bc_1, *, control, 0)," &
++ "193 ( bc_1, *, control, 0)," &
++ "194 ( bc_1, *, control, 0)," &
++ "195 ( bc_1, *, control, 0)," &
++ "196 ( bc_1, *, control, 0)," &
++ "197 ( bc_1, *, control, 0)," &
++ "198 ( bc_1, *, internal, 0)," &
++ "199 ( bc_1, *, internal, 0)," &
++ "200 ( bc_1, gpio(118), output3, X, 79, 0, Z)," &
++ "201 ( bc_1, gpio(117), output3, X, 80, 0, Z)," &
++ "202 ( bc_1, gpio(116), output3, X, 81, 0, Z)," &
++ "203 ( bc_1, gpio(115), output3, X, 82, 0, Z)," &
++ "204 ( bc_1, gpio(114), output3, X, 83, 0, Z)," &
++ "205 ( bc_1, gpio(113), output3, X, 84, 0, Z)," &
++ "206 ( bc_1, gpio(112), output3, X, 85, 0, Z)," &
++ "207 ( bc_1, gpio(111), output3, X, 86, 0, Z)," &
++ "208 ( bc_1, gpio(110), output3, X, 87, 0, Z)," &
++ "209 ( bc_1, gpio(109), output3, X, 88, 0, Z)," &
++ "210 ( bc_1, gpio(108), output3, X, 89, 0, Z)," &
++ "211 ( bc_1, gpio(107), output3, X, 90, 0, Z)," &
++ "212 ( bc_1, gpio(106), output3, X, 91, 0, Z)," &
++ "213 ( bc_1, gpio(105), output3, X, 92, 0, Z)," &
++ "214 ( bc_1, gpio(104), output3, X, 93, 0, Z)," &
++ "215 ( bc_1, gpio(103), output3, X, 94, 0, Z)," &
++ "216 ( bc_1, gpio(102), output3, X, 95, 0, Z)," &
++ "217 ( bc_1, gpio(101), output3, X, 96, 0, Z)," &
++ "218 ( bc_1, gpio(100), output3, X, 97, 0, Z)," &
++ "219 ( bc_1, gpio(99), output3, X, 98, 0, Z)," &
++ "220 ( bc_1, gpio(98), output3, X, 99, 0, Z)," &
++ "221 ( bc_1, gpio(97), output3, X, 100, 0, Z)," &
++ "222 ( bc_1, gpio(96), output3, X, 101, 0, Z)," &
++ "223 ( bc_1, gpio(95), output3, X, 102, 0, Z)," &
++ "224 ( bc_1, gpio(94), output3, X, 103, 0, Z)," &
++ "225 ( bc_1, gpio(93), output3, X, 104, 0, Z)," &
++ "226 ( bc_1, gpio(92), output3, X, 105, 0, Z)," &
++ "227 ( bc_1, gpio(91), output3, X, 106, 0, Z)," &
++ "228 ( bc_1, gpio(90), output3, X, 107, 0, Z)," &
++ "229 ( bc_1, gpio(89), output3, X, 108, 0, Z)," &
++ "230 ( bc_1, gpio(88), output3, X, 109, 0, Z)," &
++ "231 ( bc_1, gpio(87), output3, X, 110, 0, Z)," &
++ "232 ( bc_1, gpio(86), output3, X, 111, 0, Z)," &
++ "233 ( bc_1, gpio(85), output3, X, 112, 0, Z)," &
++ "234 ( bc_1, gpio(84), output3, X, 113, 0, Z)," &
++ "235 ( bc_1, gpio(83), output3, X, 114, 0, Z)," &
++ "236 ( bc_1, gpio(82), output3, X, 115, 0, Z)," &
++ "237 ( bc_1, gpio(81), output3, X, 116, 0, Z)," &
++ "238 ( bc_1, gpio(80), output3, X, 117, 0, Z)," &
++ "239 ( bc_1, gpio(79), output3, X, 118, 0, Z)," &
++ "240 ( bc_1, gpio(78), output3, X, 119, 0, Z)," &
++ "241 ( bc_1, gpio(77), output3, X, 120, 0, Z)," &
++ "242 ( bc_1, gpio(76), output3, X, 121, 0, Z)," &
++ "243 ( bc_1, gpio(75), output3, X, 122, 0, Z)," &
++ "244 ( bc_1, gpio(74), output3, X, 123, 0, Z)," &
++ "245 ( bc_1, gpio(73), output3, X, 124, 0, Z)," &
++ "246 ( bc_1, gpio(72), output3, X, 125, 0, Z)," &
++ "247 ( bc_1, gpio(71), output3, X, 126, 0, Z)," &
++ "248 ( bc_1, gpio(70), output3, X, 127, 0, Z)," &
++ "249 ( bc_1, gpio(69), output3, X, 128, 0, Z)," &
++ "250 ( bc_1, gpio(68), output3, X, 129, 0, Z)," &
++ "251 ( bc_1, gpio(67), output3, X, 130, 0, Z)," &
++ "252 ( bc_1, gpio(66), output3, X, 131, 0, Z)," &
++ "253 ( bc_1, gpio(65), output3, X, 132, 0, Z)," &
++ "254 ( bc_1, gpio(64), output3, X, 133, 0, Z)," &
++ "255 ( bc_1, gpio(63), output3, X, 134, 0, Z)," &
++ "256 ( bc_1, gpio(62), output3, X, 135, 0, Z)," &
++ "257 ( bc_1, gpio(61), output3, X, 136, 0, Z)," &
++ "258 ( bc_1, gpio(60), output3, X, 137, 0, Z)," &
++ "259 ( bc_1, gpio(59), output3, X, 138, 0, Z)," &
++ "260 ( bc_1, gpio(58), output3, X, 139, 0, Z)," &
++ "261 ( bc_1, gpio(57), output3, X, 140, 0, Z)," &
++ "262 ( bc_1, gpio(56), output3, X, 141, 0, Z)," &
++ "263 ( bc_1, gpio(55), output3, X, 142, 0, Z)," &
++ "264 ( bc_1, gpio(54), output3, X, 143, 0, Z)," &
++ "265 ( bc_1, gpio(53), output3, X, 144, 0, Z)," &
++ "266 ( bc_1, gpio(52), output3, X, 145, 0, Z)," &
++ "267 ( bc_1, gpio(51), output3, X, 146, 0, Z)," &
++ "268 ( bc_1, gpio(50), output3, X, 147, 0, Z)," &
++ "269 ( bc_1, gpio(49), output3, X, 148, 0, Z)," &
++ "270 ( bc_1, gpio(48), output3, X, 149, 0, Z)," &
++ "271 ( bc_1, gpio(47), output3, X, 150, 0, Z)," &
++ "272 ( bc_1, gpio(46), output3, X, 151, 0, Z)," &
++ "273 ( bc_1, gpio(45), output3, X, 152, 0, Z)," &
++ "274 ( bc_1, gpio(44), output3, X, 153, 0, Z)," &
++ "275 ( bc_1, gpio(43), output3, X, 154, 0, Z)," &
++ "276 ( bc_1, gpio(42), output3, X, 155, 0, Z)," &
++ "277 ( bc_1, gpio(41), output3, X, 156, 0, Z)," &
++ "278 ( bc_1, gpio(40), output3, X, 157, 0, Z)," &
++ "279 ( bc_1, gpio(39), output3, X, 158, 0, Z)," &
++ "280 ( bc_1, gpio(38), output3, X, 159, 0, Z)," &
++ "281 ( bc_1, gpio(37), output3, X, 160, 0, Z)," &
++ "282 ( bc_1, gpio(36), output3, X, 161, 0, Z)," &
++ "283 ( bc_1, gpio(35), output3, X, 162, 0, Z)," &
++ "284 ( bc_1, gpio(34), output3, X, 163, 0, Z)," &
++ "285 ( bc_1, gpio(33), output3, X, 164, 0, Z)," &
++ "286 ( bc_1, gpio(32), output3, X, 165, 0, Z)," &
++ "287 ( bc_1, gpio(31), output3, X, 166, 0, Z)," &
++ "288 ( bc_1, gpio(30), output3, X, 167, 0, Z)," &
++ "289 ( bc_1, gpio(29), output3, X, 168, 0, Z)," &
++ "290 ( bc_1, gpio(28), output3, X, 169, 0, Z)," &
++ "291 ( bc_1, gpio(27), output3, X, 170, 0, Z)," &
++ "292 ( bc_1, gpio(26), output3, X, 171, 0, Z)," &
++ "293 ( bc_1, gpio(25), output3, X, 172, 0, Z)," &
++ "294 ( bc_1, gpio(24), output3, X, 173, 0, Z)," &
++ "295 ( bc_1, gpio(23), output3, X, 174, 0, Z)," &
++ "296 ( bc_1, gpio(22), output3, X, 175, 0, Z)," &
++ "297 ( bc_1, gpio(21), output3, X, 176, 0, Z)," &
++ "298 ( bc_1, gpio(20), output3, X, 177, 0, Z)," &
++ "299 ( bc_1, gpio(19), output3, X, 178, 0, Z)," &
++ "300 ( bc_1, gpio(18), output3, X, 179, 0, Z)," &
++ "301 ( bc_1, gpio(17), output3, X, 180, 0, Z)," &
++ "302 ( bc_1, gpio(16), output3, X, 181, 0, Z)," &
++ "303 ( bc_1, gpio(15), output3, X, 182, 0, Z)," &
++ "304 ( bc_1, gpio(14), output3, X, 183, 0, Z)," &
++ "305 ( bc_1, gpio(13), output3, X, 184, 0, Z)," &
++ "306 ( bc_1, gpio(12), output3, X, 185, 0, Z)," &
++ "307 ( bc_1, gpio(11), output3, X, 186, 0, Z)," &
++ "308 ( bc_1, gpio(10), output3, X, 187, 0, Z)," &
++ "309 ( bc_1, gpio(9), output3, X, 188, 0, Z)," &
++ "310 ( bc_1, gpio(8), output3, X, 189, 0, Z)," &
++ "311 ( bc_1, gpio(7), output3, X, 190, 0, Z)," &
++ "312 ( bc_1, gpio(6), output3, X, 191, 0, Z)," &
++ "313 ( bc_1, gpio(5), output3, X, 192, 0, Z)," &
++ "314 ( bc_1, gpio(4), output3, X, 193, 0, Z)," &
++ "315 ( bc_1, gpio(3), output3, X, 194, 0, Z)," &
++ "316 ( bc_1, gpio(2), output3, X, 195, 0, Z)," &
++ "317 ( bc_1, gpio(1), output3, X, 196, 0, Z)," &
++ "318 ( bc_1, gpio(0), output3, X, 197, 0, Z)," &
++ "319 ( bc_1, nsdcs_0, output3, X, 69, 0, Z)," &
++ "320 ( bc_1, nsdcs_1, output3, X, 75, 0, Z)," &
++ "321 ( bc_1, nsdras, output3, X, 69, 0, Z)," &
++ "322 ( bc_1, sdcke_1, output3, X, 75, 0, Z)," &
++ "323 ( bc_1, sdclk_1, output3, X, 69, 0, Z)," &
++ "324 ( bc_1, sdclk_2, output3, X, 75, 0, Z)," &
++ "325 ( bc_1, *, control, 0)," &
++ "326 ( bc_1, uio, output3, X, 327, 0, Z)," &
++ "327 ( bc_1, *, control, 0)," &
++ "328 ( bc_1, *, control, 0)," &
++ "329 ( bc_1, usbc_n, output3, X, 328, 0, Z)," &
++ "330 ( bc_1, usbc_p, output3, X, 328, 0, Z)," &
++ "331 ( bc_1, *, control, 1)," &
++ "332 ( bc_1, *, internal, 1)," &
++ "333 ( bc_1, usbh_n_0, output3, X, 331, 1, Z)," &
++ "334 ( bc_1, *, internal, 0)," &
++ "335 ( bc_1, usbh_p_0, output3, X, 331, 1, Z)," &
++ "336 ( bc_1, *, internal, 0)," &
++ "337 ( bc_1, boot_sel_0, input, X)," &
++ "338 ( bc_1, clk_req, input, X)," &
++ "339 ( bc_1, *, internal, 0)," &
++ "340 ( bc_1, *, internal, 0)," &
++ "341 ( bc_1, gpio(118), input, X)," &
++ "342 ( bc_1, gpio(117), input, X)," &
++ "343 ( bc_1, gpio(116), input, X)," &
++ "344 ( bc_1, gpio(115), input, X)," &
++ "345 ( bc_1, gpio(114), input, X)," &
++ "346 ( bc_1, gpio(113), input, X)," &
++ "347 ( bc_1, gpio(112), input, X)," &
++ "348 ( bc_1, gpio(111), input, X)," &
++ "349 ( bc_1, gpio(110), input, X)," &
++ "350 ( bc_1, gpio(109), input, X)," &
++ "351 ( bc_1, gpio(108), input, X)," &
++ "352 ( bc_1, gpio(107), input, X)," &
++ "353 ( bc_1, gpio(106), input, X)," &
++ "354 ( bc_1, gpio(105), input, X)," &
++ "355 ( bc_1, gpio(104), input, X)," &
++ "356 ( bc_1, gpio(103), input, X)," &
++ "357 ( bc_1, gpio(102), input, X)," &
++ "358 ( bc_1, gpio(101), input, X)," &
++ "359 ( bc_1, gpio(100), input, X)," &
++ "360 ( bc_1, gpio(99), input, X)," &
++ "361 ( bc_1, gpio(98), input, X)," &
++ "362 ( bc_1, gpio(97), input, X)," &
++ "363 ( bc_1, gpio(96), input, X)," &
++ "364 ( bc_1, gpio(95), input, X)," &
++ "365 ( bc_1, gpio(94), input, X)," &
++ "366 ( bc_1, gpio(93), input, X)," &
++ "367 ( bc_1, gpio(92), input, X)," &
++ "368 ( bc_1, gpio(91), input, X)," &
++ "369 ( bc_1, gpio(90), input, X)," &
++ "370 ( bc_1, gpio(89), input, X)," &
++ "371 ( bc_1, gpio(88), input, X)," &
++ "372 ( bc_1, gpio(87), input, X)," &
++ "373 ( bc_1, gpio(86), input, X)," &
++ "374 ( bc_1, gpio(85), input, X)," &
++ "375 ( bc_1, gpio(84), input, X)," &
++ "376 ( bc_1, gpio(83), input, X)," &
++ "377 ( bc_1, gpio(82), input, X)," &
++ "378 ( bc_1, gpio(81), input, X)," &
++ "379 ( bc_1, gpio(80), input, X)," &
++ "380 ( bc_1, gpio(79), input, X)," &
++ "381 ( bc_1, gpio(78), input, X)," &
++ "382 ( bc_1, gpio(77), input, X)," &
++ "383 ( bc_1, gpio(76), input, X)," &
++ "384 ( bc_1, gpio(75), input, X)," &
++ "385 ( bc_1, gpio(74), input, X)," &
++ "386 ( bc_1, gpio(73), input, X)," &
++ "387 ( bc_1, gpio(72), input, X)," &
++ "388 ( bc_1, gpio(71), input, X)," &
++ "389 ( bc_1, gpio(70), input, X)," &
++ "390 ( bc_1, gpio(69), input, X)," &
++ "391 ( bc_1, gpio(68), input, X)," &
++ "392 ( bc_1, gpio(67), input, X)," &
++ "393 ( bc_1, gpio(66), input, X)," &
++ "394 ( bc_1, gpio(65), input, X)," &
++ "395 ( bc_1, gpio(64), input, X)," &
++ "396 ( bc_1, gpio(63), input, X)," &
++ "397 ( bc_1, gpio(62), input, X)," &
++ "398 ( bc_1, gpio(61), input, X)," &
++ "399 ( bc_1, gpio(60), input, X)," &
++ "400 ( bc_1, gpio(59), input, X)," &
++ "401 ( bc_1, gpio(58), input, X)," &
++ "402 ( bc_1, gpio(57), input, X)," &
++ "403 ( bc_1, gpio(56), input, X)," &
++ "404 ( bc_1, gpio(55), input, X)," &
++ "405 ( bc_1, gpio(54), input, X)," &
++ "406 ( bc_1, gpio(53), input, X)," &
++ "407 ( bc_1, gpio(52), input, X)," &
++ "408 ( bc_1, gpio(51), input, X)," &
++ "409 ( bc_1, gpio(50), input, X)," &
++ "410 ( bc_1, gpio(49), input, X)," &
++ "411 ( bc_1, gpio(48), input, X)," &
++ "412 ( bc_1, gpio(47), input, X)," &
++ "413 ( bc_1, gpio(46), input, X)," &
++ "414 ( bc_1, gpio(45), input, X)," &
++ "415 ( bc_1, gpio(44), input, X)," &
++ "416 ( bc_1, gpio(43), input, X)," &
++ "417 ( bc_1, gpio(42), input, X)," &
++ "418 ( bc_1, gpio(41), input, X)," &
++ "419 ( bc_1, gpio(40), input, X)," &
++ "420 ( bc_1, gpio(39), input, X)," &
++ "421 ( bc_1, gpio(38), input, X)," &
++ "422 ( bc_1, gpio(37), input, X)," &
++ "423 ( bc_1, gpio(36), input, X)," &
++ "424 ( bc_1, gpio(35), input, X)," &
++ "425 ( bc_1, gpio(34), input, X)," &
++ "426 ( bc_1, gpio(33), input, X)," &
++ "427 ( bc_1, gpio(32), input, X)," &
++ "428 ( bc_1, gpio(31), input, X)," &
++ "429 ( bc_1, gpio(30), input, X)," &
++ "430 ( bc_1, gpio(29), input, X)," &
++ "431 ( bc_1, gpio(28), input, X)," &
++ "432 ( bc_1, gpio(27), input, X)," &
++ "433 ( bc_1, gpio(26), input, X)," &
++ "434 ( bc_1, gpio(25), input, X)," &
++ "435 ( bc_1, gpio(24), input, X)," &
++ "436 ( bc_1, gpio(23), input, X)," &
++ "437 ( bc_1, gpio(22), input, X)," &
++ "438 ( bc_1, gpio(21), input, X)," &
++ "439 ( bc_1, gpio(20), input, X)," &
++ "440 ( bc_1, gpio(19), input, X)," &
++ "441 ( bc_1, gpio(18), input, X)," &
++ "442 ( bc_1, gpio(17), input, X)," &
++ "443 ( bc_1, gpio(16), input, X)," &
++ "444 ( bc_1, gpio(15), input, X)," &
++ "445 ( bc_1, gpio(14), input, X)," &
++ "446 ( bc_1, gpio(13), input, X)," &
++ "447 ( bc_1, gpio(12), input, X)," &
++ "448 ( bc_1, gpio(11), input, X)," &
++ "449 ( bc_1, gpio(10), input, X)," &
++ "450 ( bc_1, gpio(9), input, X)," &
++ "451 ( bc_1, gpio(8), input, X)," &
++ "452 ( bc_1, gpio(7), input, X)," &
++ "453 ( bc_1, gpio(6), input, X)," &
++ "454 ( bc_1, gpio(5), input, X)," &
++ "455 ( bc_1, gpio(4), input, X)," &
++ "456 ( bc_1, gpio(3), input, X)," &
++ "457 ( bc_1, gpio(2), input, X)," &
++ "458 ( bc_1, gpio(1), input, X)," &
++ "459 ( bc_1, gpio(0), input, X)," &
++ "460 ( bc_1, md(31), input, X)," &
++ "461 ( bc_1, md(30), input, X)," &
++ "462 ( bc_1, md(29), input, X)," &
++ "463 ( bc_1, md(28), input, X)," &
++ "464 ( bc_1, md(27), input, X)," &
++ "465 ( bc_1, md(26), input, X)," &
++ "466 ( bc_1, md(25), input, X)," &
++ "467 ( bc_1, md(24), input, X)," &
++ "468 ( bc_1, md(23), input, X)," &
++ "469 ( bc_1, md(22), input, X)," &
++ "470 ( bc_1, md(21), input, X)," &
++ "471 ( bc_1, md(20), input, X)," &
++ "472 ( bc_1, md(19), input, X)," &
++ "473 ( bc_1, md(18), input, X)," &
++ "474 ( bc_1, md(17), input, X)," &
++ "475 ( bc_1, md(16), input, X)," &
++ "476 ( bc_1, md(15), input, X)," &
++ "477 ( bc_1, md(14), input, X)," &
++ "478 ( bc_1, md(13), input, X)," &
++ "479 ( bc_1, md(12), input, X)," &
++ "480 ( bc_1, md(11), input, X)," &
++ "481 ( bc_1, md(10), input, X)," &
++ "482 ( bc_1, md(9), input, X)," &
++ "483 ( bc_1, md(8), input, X)," &
++ "484 ( bc_1, md(7), input, X)," &
++ "485 ( bc_1, md(6), input, X)," &
++ "486 ( bc_1, md(5), input, X)," &
++ "487 ( bc_1, md(4), input, X)," &
++ "488 ( bc_1, md(3), input, X)," &
++ "489 ( bc_1, md(2), input, X)," &
++ "490 ( bc_1, md(1), input, X)," &
++ "491 ( bc_1, md(0), input, X)," &
++ "492 ( bc_1, nbatt_fault, input, 1)," &
++ "493 ( bc_1, nreset, input, 1)," &
++ "494 ( bc_1, nvdd_fault, input, 1)," &
++ "495 ( bc_1, test, input, X)," &
++ "496 ( bc_1, testclk, input, X)," &
++ "497 ( bc_1, uio, input, X)," &
++ "498 ( bc_1, usbc_n, input, X)," &
++ "499 ( bc_1, usbc_p, input, X)," &
++ "500 ( bc_1, usbh_n_0, input, X)," &
++ "501 ( bc_1, *, internal, 0)," &
++ "502 ( bc_1, usbh_p_0, input, X)," &
++ "503 ( bc_1, *, internal, 0)";
++
++attribute DESIGN_WARNING of bulverde_b0_13x13 : entity is
++ " 1. The following ports are not part of the boundary scan register: " &
++ " pxtal_in, txtal_in, pextal_out, textal_out, tdi, tms, ntrst, " &
++ " tck, tdo " &
++ " " &
++ " 2. ntrst must be driven from low to high either before or at the " &
++ " same time as nreset at power-up. Only after nreset_out has " &
++ " been deasserted is power applied to the BSR logic. " &
++ " " &
++ " 3. The nbatt_fault, nvdd_fault, and nreset input ports must be " &
++ " driven to a logic 1 at all times. Not doing so puts the part " &
++ " into sleep which disables power to all BSR logic. " &
++ " " &
++ " 4. gpio[2]=sys_en, gpio[20]=nsdcs2, gpio[21]=nsdcs3 " &
++ " " &
++ " 5. The following BSR cells are internal, i.e. not bounded out: " &
++ " 63,77,78,198,199,332,334,336,339,340,501,503 " &
++ " As such they will capture indeterminate values. ";
++
++end bulverde_b0_13x13;
++
++*/
++
++/* End of reference information */
++
++
++
++
++
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ctl.c u-boot-2008.10/common/bvd_usb_ctl.c
+--- u-boot-2008.10_original/common/bvd_usb_ctl.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ctl.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,585 @@
++/*
++ * Copyright (C) Compaq Computer Corporation, 1998, 1999
++ * Copyright (C) Extenex Corporation, 2001
++ * Copyright (C) Intrinsyc, Inc., 2002
++ *
++ * PXA USB controller core driver.
++ *
++ * This file provides interrupt routing and overall coordination
++ * of the endpoints.
++ *
++ * Please see:
++ * linux/Documentation/arm/SA1100/SA1100_USB
++ * for more info.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.c
++ *
++ */
++#include "pxa_usb.h"
++#include "bvd_usb_ctl.h"
++#include <asm/errno.h>
++#define CKEN __REG(0x41300004) /* Clock Enable Register */ //Added by Tharma
++#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */ //Added by Tharma
++
++
++
++//#undef DEBUG
++#define DEBUG 1
++#if DEBUG
++static unsigned int usb_debug = DEBUG;
++#else
++#define usb_debug 0 /* gcc will remove all the debug code for us */
++#endif
++
++//////////////////////////////////////////////////////////////////////////////
++// Prototypes
++//////////////////////////////////////////////////////////////////////////////
++
++int usbctl_next_state_on_event( int event );
++void udc_int_hndlr(int, void *);
++static void initialize_descriptors( void );
++static void soft_connect_hook( int enable );
++static void udc_disable(void);
++static void udc_enable(void);
++
++#if CONFIG_PROC_FS
++#define PROC_NODE_NAME "driver/pxausb"
++static int usbctl_read_proc(char *page, char **start, off_t off,
++ int count, int *eof, void *data);
++#endif
++
++/////////////////////////////////////////////////////////////////////////////
++int usb_connected = 0;
++
++
++//////////////////////////////////////////////////////////////////////////////
++// Globals
++//////////////////////////////////////////////////////////////////////////////
++static const char pszMe[] = "usbctl: ";
++struct usb_info_t usbd_info; /* global to ep0, usb_recv, usb_send */
++
++/* device descriptors */
++static desc_t desc;
++
++#define MAX_STRING_DESC 64
++static string_desc_t * string_desc_array[ MAX_STRING_DESC ];
++static string_desc_t sd_zero; /* special sd_zero holds language codes */
++
++// called when configured
++static usb_notify_t configured_callback = NULL;
++
++enum {
++ kStateZombie = 0,
++ kStateZombieSuspend = 1,
++ kStateDefault = 2,
++ kStateDefaultSuspend = 3,
++ kStateAddr = 4,
++ kStateAddrSuspend = 5,
++ kStateConfig = 6,
++ kStateConfigSuspend = 7
++};
++
++/*
++ * FIXME: The PXA UDC handles several host device requests without user
++ * notification/intervention. The table could be collapsed quite a bit...
++ */
++static int device_state_machine[8][6] = {
++// suspend reset resume adddr config deconfig
++/* zombie */ { kStateZombieSuspend , kStateDefault, kStateZombie , kError , kError , kError },
++/* zom sus */ { kStateZombieSuspend , kStateDefault, kStateZombie , kError , kError , kError },
++/* default */ { kStateDefaultSuspend, kStateDefault, kStateDefault, kStateAddr, kStateConfig, kError },
++/* def sus */ { kStateDefaultSuspend, kStateDefault, kStateDefault, kError , kError , kError },
++/* addr */ { kStateAddrSuspend , kStateDefault, kStateAddr , kError , kStateConfig, kError },
++/* addr sus */{ kStateAddrSuspend , kStateDefault, kStateAddr , kError , kError , kError },
++/* config */ { kStateConfigSuspend , kStateDefault, kStateConfig , kError , kError , kStateDefault },
++/* cfg sus */ { kStateConfigSuspend , kStateDefault, kStateConfig , kError , kError , kError }
++};
++
++/* "device state" is the usb device framework state, as opposed to the
++ "state machine state" which is whatever the driver needs and is much
++ more fine grained
++*/
++static int sm_state_to_device_state[8] = {
++// zombie zom suspend
++USB_STATE_POWERED, USB_STATE_SUSPENDED,
++// default default sus
++USB_STATE_DEFAULT, USB_STATE_SUSPENDED,
++// addr addr sus
++USB_STATE_ADDRESS, USB_STATE_SUSPENDED,
++// config config sus
++USB_STATE_CONFIGURED, USB_STATE_SUSPENDED
++};
++
++static char * state_names[8] =
++{ "zombie", "zombie suspended",
++ "default", "default suspended",
++ "address", "address suspended",
++ "configured", "config suspended"
++};
++
++static char * event_names[6] =
++{ "suspend", "reset", "resume",
++ "address assigned", "configure", "de-configure"
++};
++
++static char * device_state_names[] =
++{ "not attached", "attached", "powered", "default",
++ "address", "configured", "suspended" };
++
++static int sm_state = kStateZombie;
++
++//////////////////////////////////////////////////////////////////////////////
++// Async
++//////////////////////////////////////////////////////////////////////////////
++
++/* The UDCCR reg contains mask and interrupt status bits,
++ * so using '|=' isn't safe as it may ack an interrupt.
++ */
++
++void udc_set_mask_UDCCR( int mask )
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
++}
++
++void udc_clear_mask_UDCCR( int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
++}
++
++void udc_ack_int_UDCCR( int mask)
++{
++ /* udccr contains the bits we dont want to change */
++ UINT32 udccr = UDCCR & UDCCR_MASK_BITS;
++
++ UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);
++}
++
++void
++udc_int_hndlr(int irq, void *dev_id)
++{
++ UINT32 isr0 = UDCISR0;
++ UINT32 isr1 = UDCISR1;
++ UINT32 icr0 = UDCICR0;
++ UINT32 icr1 = UDCICR1;
++
++ if (usb_debug) printf("%s UDCISR0=%08x, UDCISR1=%08x, UDCICR0=%08x, UDCICR1=%08x\n",
++ pszMe, isr0, isr1, icr0, icr1);
++
++ if ( (!isr0) && (!isr1)) return;
++
++ UDCICR0 = 0x0;
++ UDCICR1 = 0x0;
++
++ /* InterRupt SUSpend */
++ if ( isr1 & UDCISR1_IRSU )
++ {
++ /* FIXME */
++ /* udc_ack_int_UDCCR( UDCCR_SUSIR); */
++ UDCISR1 = UDCISR1_IRSU;
++ if (usb_debug) printf("%sSuspend...\n", pszMe);
++ usbctl_next_state_on_event( kEvSuspend );
++ }
++
++ /* InterRupt ResUme */
++ if ( isr1 & UDCISR1_IRRU )
++ {
++ /* FIXME */
++ /* udc_ack_int_UDCCR( UDCCR_RESIR); */
++ UDCISR1 = UDCISR1_IRRU;
++ if( usb_debug) printf("%sResume...\n", pszMe);
++ usbctl_next_state_on_event( kEvResume );
++ usb_connected = 0;
++ }
++
++ /* InterRupt Configuration Changed */
++ if (isr1 & UDCISR1_IRCC) {
++ if (usb_debug) printf("Configuration Changed\n");
++
++ UDCISR1 = UDCISR1_IRCC;
++ UDCCR |= UDCCR_SMAC;
++
++ /* Reset usb driver here */
++ if ( usbctl_next_state_on_event(kEvReset) != kError ) {
++ ep0_reset();
++ ep1_reset();
++ ep2_reset();
++
++ usbctl_next_state_on_event(kEvConfig);
++
++ usb_driver_reset();
++ }
++
++ usb_connected = 1;
++ }
++
++ /* ReSeT Interrupt Request - UDC has been reset */
++ if (isr1 & UDCISR1_IRRS) {
++ if(usb_debug) printf("%sReset...\n", pszMe);
++ UDCISR1 = UDCISR1_IRRS;
++
++ usb_connected = 0;
++ }
++ else
++ {
++ if ( isr0 & 0x2 ) UDCISR0 = 0x2;
++ /* ep0 int */
++ if ( isr0 & UDCISR0_IR0 ) {
++ if (usb_debug) printf("%sEP0...\n", pszMe);
++
++ UDCISR0 = 0x1;
++ ep0_int_hndlr();
++ }
++
++ if ( isr0 & 0x8 ) UDCISR0 = 0x8;
++ /* transmit bulk */
++ if ( isr0 & UDCISR0_IRA ) {
++ if (usb_debug) printf("%sEP1...\n", pszMe);
++
++ UDCISR0 = 0x4;
++ ep1_int_hndlr(isr0);
++ }
++
++ if ( isr0 & 0x20 ) UDCISR0 = 0x20;
++ /* receive bulk */
++ if (isr0 & UDCISR0_IRB) {
++ if (usb_debug) printf("%sEP2...\n", pszMe);
++
++ UDCISR0 = 0x10;
++ ep2_int_hndlr(isr0);
++ }
++
++ while (UDCCSRB & UDCCSR_BNE) {
++ ep2_int_hndlr(isr0);
++ }
++ }
++
++ UDCICR0 = icr0;
++ UDCICR1 = icr1;
++}
++
++//////////////////////////////////////////////////////////////////////////////
++// Public Interface
++//////////////////////////////////////////////////////////////////////////////
++
++/* Open PXA usb core on behalf of a client, but don't start running */
++
++int pxa_usb_open(void)
++{
++ memset(&usbd_info.stats, 0, sizeof(struct usb_stats_t));
++ memset(string_desc_array, 0, sizeof(string_desc_array));
++
++ /* hack to start in zombie suspended state */
++ sm_state = kStateZombieSuspend;
++ usbd_info.state = USB_STATE_SUSPENDED;
++
++ /* create descriptors for enumeration */
++ initialize_descriptors();
++
++ if (usb_debug) printf("%s registered.\n", pszMe);
++ return 0;
++}
++
++/* Start running. Must have called usb_open (above) first */
++int
++pxa_usb_start( void )
++{
++
++
++ /* start UDC internal machinery running */
++ udc_enable();
++ msleep(1);
++
++ if (usb_debug) printf("%sStarted %s\n", pszMe, usbd_info.client_name );
++ return 0;
++}
++
++/* Stop USB core from running */
++int
++pxa_usb_stop( void )
++{
++ if ( usbd_info.client_name == NULL ) {
++ printf("%s%s - no client registered\n",pszMe, __FUNCTION__ );
++ return -EPERM;
++ }
++
++ ep1_reset();
++ ep2_reset();
++
++ udc_disable();
++ if( usb_debug) printf("%sStopped %s\n", pszMe, usbd_info.client_name );
++ return 0;
++}
++
++/* Tell PXA core client is through using it */
++int
++pxa_usb_close( void )
++{
++ if ( usbd_info.client_name == NULL ) {
++ printf("%s%s - no client registered\n",pszMe, __FUNCTION__ );
++ return -EPERM;
++ }
++ printf("%s%s closed.\n", pszMe, (char*)usbd_info.client_name );
++ usbd_info.client_name = NULL;
++ return 0;
++}
++
++/* set a proc to be called when device is configured */
++usb_notify_t pxa_set_configured_callback( usb_notify_t func )
++{
++ usb_notify_t retval = configured_callback;
++ configured_callback = func;
++ return retval;
++}
++
++/*====================================================
++ * Descriptor Manipulation.
++ * Use these between open() and start() above to setup
++ * the descriptors for your device.
++ *
++ */
++
++/* get pointer to static default descriptor */
++desc_t *
++pxa_usb_get_descriptor_ptr( void ) { return &desc; }
++
++/* optional: set a string descriptor */
++int
++pxa_usb_set_string_descriptor( int i, string_desc_t * p )
++{
++ int retval;
++ if ( i < MAX_STRING_DESC ) {
++ string_desc_array[i] = p;
++ retval = 0;
++ } else {
++ retval = -EINVAL;
++ }
++ return retval;
++}
++
++/* optional: get a previously set string descriptor */
++string_desc_t *
++pxa_usb_get_string_descriptor( int i )
++{
++ return ( i < MAX_STRING_DESC )
++ ? string_desc_array[i]
++ : NULL;
++}
++
++config_desc_t *
++pxa_usb_get_config(int cfgval)
++{
++ int i;
++ desc_t * pdesc = pxa_usb_get_descriptor_ptr();
++ config_desc_t *cfg = (config_desc_t*) (pdesc->cdb);
++
++ for( i=0; i<pdesc->dev.bNumConfigurations; i++) {
++ if( cfg->bConfigurationValue == cfgval ) return cfg;
++ cfg = (config_desc_t*) ((unsigned char*)cfg + cfg->wTotalLength);
++ }
++
++ return NULL;
++}
++
++intf_desc_t *
++pxa_usb_get_interface( config_desc_t *cfg, int idx)
++{
++ int i;
++ intf_desc_t *intf = (intf_desc_t*) (cfg + 1);
++
++ for( i=0; i < cfg->bNumInterfaces; i++) {
++ if( idx == intf->bInterfaceNumber) return intf;
++ intf++;
++ }
++
++ return NULL;
++}
++
++
++ep_desc_t *
++pxa_usb_get_endpoint( intf_desc_t *intf, int idx)
++{
++ int i;
++ ep_desc_t *ep = (ep_desc_t *) (intf+1);
++
++
++ for( i=0; i< intf->bNumEndpoints; i++) {
++ if( idx == (ep->bEndpointAddress & 0xF) ) return ep;
++ ep++;
++ }
++ return NULL;
++}
++
++//////////////////////////////////////////////////////////////////////////////
++// Exports to rest of driver
++//////////////////////////////////////////////////////////////////////////////
++
++/* called by the int handler here and the two endpoint files when interesting
++ .."events" happen */
++
++int
++usbctl_next_state_on_event( int event )
++{
++ int next_state = device_state_machine[ sm_state ][ event ];
++ if ( next_state != kError )
++ {
++ int next_device_state = sm_state_to_device_state[ next_state ];
++ if (usb_debug) printf("%s%s --> [%s] --> %s. Device in %s state.\n",
++ pszMe, state_names[ sm_state ], event_names[ event ],
++ state_names[ next_state ], device_state_names[ next_device_state ] );
++
++ sm_state = next_state;
++ if ( usbd_info.state != next_device_state )
++ {
++ if ( configured_callback != NULL
++ &&
++ next_device_state == USB_STATE_CONFIGURED
++ &&
++ usbd_info.state != USB_STATE_SUSPENDED
++ ) {
++ configured_callback();
++ }
++ usbd_info.state = next_device_state;
++
++ ep1_state_change_notify( next_device_state );
++ ep2_state_change_notify( next_device_state );
++ }
++ }
++ else
++ printf("%s%s --> [%s] --> ??? is an error.\n",
++ pszMe, state_names[ sm_state ], event_names[ event ] );
++ return next_state;
++}
++
++//////////////////////////////////////////////////////////////////////////////
++// Private Helpers
++//////////////////////////////////////////////////////////////////////////////
++
++/* setup default descriptors */
++
++static void
++initialize_descriptors(void)
++{
++
++ desc.dev.bLength = sizeof( device_desc_t );
++ desc.dev.bDescriptorType = USB_DESC_DEVICE;
++ desc.dev.bcdUSB = 0x100; /* 1.0 */
++ desc.dev.bDeviceClass = 0x00; /* vendor specific */
++ desc.dev.bDeviceSubClass = 0;
++ desc.dev.bDeviceProtocol = 0;
++ desc.dev.bMaxPacketSize0 = 16; /* ep0 max fifo size */
++ desc.dev.idVendor = 0; /* vendor ID undefined */
++ desc.dev.idProduct = 0; /* product */
++ desc.dev.bcdDevice = 0; /* vendor assigned device release num */
++ desc.dev.iManufacturer = 0; /* index of manufacturer string */
++ desc.dev.iProduct = 0; /* index of product description string */
++ desc.dev.iSerialNumber = 0; /* index of string holding product s/n */
++ desc.dev.bNumConfigurations = 1; /* configurations we have */
++
++
++ usb_driver_reset();
++
++ /* set language */
++ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
++ sd_zero.bDescriptorType = USB_DESC_STRING;
++ sd_zero.bLength = sizeof( string_desc_t );
++ sd_zero.bString[0] = 'e';
++ sd_zero.bString[1] = '-';
++ sd_zero.bString[2] = 'c';
++ sd_zero.bString[3] = 'o';
++ sd_zero.bString[4] = 'n';
++ sd_zero.bString[5] = ' ';
++ sd_zero.bString[6] = 'D';
++ sd_zero.bString[7] = 'F';
++ sd_zero.bString[8] = 'U';
++ sd_zero.bString[9] = 0;
++ pxa_usb_set_string_descriptor( 0, &sd_zero );
++}
++
++/* soft_connect_hook()
++ * Some devices have platform-specific circuitry to make USB
++ * not seem to be plugged in, even when it is. This allows
++ * software to control when a device 'appears' on the USB bus
++ * (after Linux has booted and this driver has loaded, for
++ * example). If you have such a circuit, control it here.
++ */
++static void
++soft_connect_hook( int enable )
++{
++}
++
++/* configure udc endpoints */
++static void
++udc_configure(void)
++{
++ /* endpoint A ~ BULK, IN, MPS: 64bytes, Double-buffering, configuration 1, interface 0,
++ * altsetting 0, endpoint 1
++ */
++ UDCCRA = 0x0200d103;
++
++ /* endpoint B ~ BULK, OUT,MPS: 64bytes, Double-buffering, configuration 1, interface 0,
++ * altsetting 0, endpoint 2
++ */
++ UDCCRB = 0x02014103;
++
++ printf("\r\nUDCCRA = 0x%x UDCCRB = 0x%x\r\n",UDCCRA,UDCCRB);
++}
++
++
++/* disable the UDC at the source */
++static void
++udc_disable(void)
++{
++ soft_connect_hook( 0 );
++ /* clear UDC-enable */
++ udc_clear_mask_UDCCR( UDCCR_UDE);
++
++ /* Disable clock for USB device */
++ CKEN &= ~CKEN11_USB;
++}
++
++
++/* enable the udc at the source */
++static void
++udc_enable(void)
++{
++ /* Enable clock for USB device */
++ CKEN |= CKEN11_USB;
++
++ /* UDC Endpoints */
++// udc_configure();
++
++ /* NOTE: special fix for Bulverde-B0 MCP
++ * clear bit 20, set HXOE, clear HXS, and do some housekeeping
++ * these two operations are required for USB to work
++ */
++ UP2OCR = 0x00020000;
++// UDCWAKEUP |= 0x00008000;
++
++ /* enable endpoint 0, A, B's Packet Complete Interrupt. */
++ UDCICR0 = 0x0000003f;
++ UDCICR1 = 0xa8000000;
++
++ /* clear the interrupt status/control registers */
++ UDCISR0 = 0xffffffff;
++ UDCISR1 = 0xffffffff;
++
++ /* set UDC-enable */
++ udc_set_mask_UDCCR( UDCCR_UDE);
++
++ if (UDCCR & UDCCR_EMCE) {
++ printf("%s:Endpoint Memory Config Error\n", __FUNCTION__);
++ }
++
++ if( (UDCCR & UDCCR_UDA) == 0) {
++ /* There's a reset on the bus,
++ * clear the interrupt bit and keep going
++ */
++ //if (usb_debug)
++ printf("\r\nreset on bus\r\n");
++ /* udc_ack_int_UDCCR( UDCCR_RSTIR); */
++ }
++ printf("UDCCR=0x%x\r\n",UDCCR);
++
++}
++
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ctl.h u-boot-2008.10/common/bvd_usb_ctl.h
+--- u-boot-2008.10_original/common/bvd_usb_ctl.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ctl.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,189 @@
++/*
++ * Copyright (C) Compaq Computer Corporation, 1998, 1999
++ * Copyright (C) Extenex Corporation 2001
++ * Copyright (C) Intrinsyc, Inc., 2002
++ *
++ * usb_ctl.h
++ *
++ * PRIVATE interface used to share info among components of the PXA USB
++ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
++ * should use pxa_usb.h.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.h
++ *
++ */
++
++#ifndef _USB_CTL_H
++#define _USB_CTL_H
++
++//#define io_p2v(x) (OALPAtoVA(x,FALSE))
++#define __REG(x) (*((volatile UINT32 *)io_p2v(x))) //Added by Tharma
++
++/* Interrupt mask bits and UDC enable bit */
++//#define UDCCR_MASK_BITS (UDCCR_REM | UDCCR_SRM | UDCCR_UDE)
++#define UDCCR_MASK_BITS UDCCR_UDE //Modified
++
++/*
++ * These states correspond to those in the USB specification v1.0
++ * in chapter 8, Device Framework.
++ */
++enum {
++ USB_STATE_NOTATTACHED =0,
++ USB_STATE_ATTACHED =1,
++ USB_STATE_POWERED =2,
++ USB_STATE_DEFAULT =3,
++ USB_STATE_ADDRESS =4,
++ USB_STATE_CONFIGURED =5,
++ USB_STATE_SUSPENDED =6
++};
++
++struct usb_stats_t {
++ unsigned long ep0_fifo_write_failures;
++ unsigned long ep0_bytes_written;
++ unsigned long ep0_fifo_read_failures;
++ unsigned long ep0_bytes_read;
++};
++
++struct usb_info_t
++{
++ char * client_name;
++ int state;
++ unsigned char address;
++ struct usb_stats_t stats;
++};
++
++/* in usb_ctl.c */
++extern struct usb_info_t usbd_info;
++
++/*
++ * Function Prototypes
++ */
++enum {
++ kError =-1,
++ kEvSuspend =0,
++ kEvReset =1,
++ kEvResume =2,
++ kEvAddress =3,
++ kEvConfig =4,
++ kEvDeConfig =5
++};
++int usbctl_next_state_on_event( int event );
++
++/* endpoint zero */
++void ep0_reset(void);
++void ep0_int_hndlr(void);
++
++/* receiver */
++void ep2_state_change_notify( int new_state );
++int ep2_recv(char *buf, int len, usb_callback_t callback);
++int ep2_init(int chn);
++void ep2_int_hndlr(int status);
++void ep2_reset(void);
++void ep2_stall(void);
++
++/* xmitter */
++void ep1_state_change_notify( int new_state );
++int ep1_send(char *buf, int len, usb_callback_t callback);
++void ep1_reset(void);
++int ep1_init(int chn);
++void ep1_int_hndlr(int status);
++void ep1_stall(void);
++
++/* Bulverde USB register's definition */
++#define UDCCR __REG(0x40600000)
++#define UDCICR0 __REG(0x40600004)
++#define UDCICR1 __REG(0x40600008)
++#define UDCISR0 __REG(0x4060000c)
++#define UDCISR1 __REG(0x40600010)
++#define UDCFNR __REG(0x40600014)
++#define UP2OCR __REG(0x40600020)
++
++#define UDCCSR0 __REG(0x40600100)
++#define UDCCSRA __REG(0x40600104)
++#define UDCCSRB __REG(0x40600108)
++/* Omit endpoint C~X */
++
++#define UDCBCR0 __REG(0x40600200)
++#define UDCBCRA __REG(0x40600204)
++#define UDCBCRB __REG(0x40600208)
++/* Omit endpoint C~X */
++
++#define UDCDR0 __REG(0x40600300)
++#define UDCDRA __REG(0x40600304)
++#define UDCDRB __REG(0x40600308)
++#define UDCWAKEUP __REG(0x40F00044)
++
++/* Omit endpiont C~X */
++
++#define UDCCRA __REG(0x40600404)
++#define UDCCRB __REG(0x40600408)
++/* Omit endpoint C~X */
++
++/* USB register bit definitions */
++
++#define UDCCR_UDE (1 << 0)
++#define UDCCR_UDA (1 << 1)
++#define UDCCR_UDR (1 << 2)
++#define UDCCR_EMCE (1 << 3)
++#define UDCCR_SMAC (1 << 4)
++#define UDCCR_AAISN (1 << 5)
++#define UDCCR_AIN (1 << 8)
++#define UDCCR_ACN (1 << 11)
++#define UDCCR_DWRE (1 << 16)
++
++#define UDCICR0_IE0 (1 << 0)
++#define UDCICR0_IEA (1 << 2)
++#define UDCICR0_IEB (1 << 4)
++/* Omit endpoint C~X */
++
++#define UDCICR1_IERS (1 << 27)
++#define UDCICR1_IESU (1 << 28)
++#define UDCICR1_IERU (1 << 29)
++#define UDCICR1_IESOF (1 << 30)
++#define UDCICR1_IECC (1 << 31)
++
++#define UDCISR0_IR0 (1 << 0)
++#define UDCISR0_IRA (1 << 2)
++#define UDCISR0_IRB (1 << 4)
++/* Omit endpiont C~X */
++
++#define UDCISR1_IRRS (1 << 27)
++#define UDCISR1_IRSU (1 << 28)
++#define UDCISR1_IRRU (1 << 29)
++#define UDCISR1_IRSOF (1 << 30)
++#define UDCISR1_IRCC (1 << 31)
++
++#define UDCCSR0_OPC (1 << 0)
++#define UDCCSR0_IPR (1 << 1)
++#define UDCCSR0_FTF (1 << 2)
++#define UDCCSR0_DME (1 << 3)
++#define UDCCSR0_SST (1 << 4)
++#define UDCCSR0_FST (1 << 5)
++#define UDCCSR0_RNE (1 << 6)
++#define UDCCSR0_SA (1 << 7)
++#define UDCCSR0_ARE (1 << 8)
++
++#define UDCCSR_FS (1 << 0)
++#define UDCCSR_PC (1 << 1)
++#define UDCCSR_TRN (1 << 2)
++#define UDCCSR_DME (1 << 3)
++#define UDCCSR_SST (1 << 4)
++#define UDCCSR_FST (1 << 5)
++#define UDCCSR_BNE (1 << 6)
++#define UDCCSR_BNF (1 << 6)
++#define UDCCSR_SP (1 << 7)
++#define UDCCSR_FEF (1 << 8)
++#define UDCCSR_DPE (1 << 9)
++
++#define UDCCRB_EE (1 << 0)
++#define UDCCRB_DE (1 << 1)
++#define UDCCRB_MPS (1 << 2)
++#define UDCCRB_ED (1 << 12)
++#define UDCCRB_ET (1 << 13)
++#define UDCCRB_EN (1 << 15)
++#define UDCCRB_AISN (1 << 19)
++#define UDCCRB_IN (1 << 22)
++#define UDCCRB_CN (1 << 25)
++
++#endif /* _USB_CTL_H */
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ep0.c u-boot-2008.10/common/bvd_usb_ep0.c
+--- u-boot-2008.10_original/common/bvd_usb_ep0.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ep0.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,925 @@
++/*
++ * Copyright (C) Extenex Corporation 2001
++ * Copyright (C) Compaq Computer Corporation, 1998, 1999
++ * Copyright (C) Intrinsyc, Inc., 2002
++ *
++ * PXA USB controller driver - Endpoint zero management
++ *
++ * Please see:
++ * linux/Documentation/arm/SA1100/SA1100_USB
++ * for more info.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.c
++ *
++ */
++
++#include "pxa_usb.h" /* public interface */
++#include "bvd_usb_ctl.h" /* private stuff */
++#include "bvd_usb_ep0.h"
++struct start_setup_pkt Setup_Pkt;
++struct status_pkt Status_Pkt;
++struct send_pkt Send_Pkt;
++
++#undef DEBUG
++//#define DEBUG 3
++#if DEBUG
++#define USB_DEBUG 1
++#else
++#define USB_DEBUG 0 /* gcc will remove all the debug code for us */
++#endif
++
++enum { true = 1, false = 0 };
++typedef int bool;
++#ifndef MIN
++#define MIN( a, b ) ((a)<(b)?(a):(b))
++#endif
++
++#define LOAD_ADDR ((unsigned int)0xa0060000)
++
++#define DATA_PACKET_SIZE (1024*2)
++
++extern void ep2_int_hndlr(int udcsr);
++static EP0_state ep0_state = EP0_IDLE;
++char Pkt_Data[DATA_PACKET_SIZE+10];
++static int current_cfg_index = 0;
++
++
++static void IntrHandlr(void); /* setup begin (idle) */
++void DFU_Intr_Handlr(usb_dev_request_t req);
++static void sh_write( void ); /* writing data */
++static int read_fifo( usb_dev_request_t * p );
++static void write_fifo( void );
++static void get_descriptor( usb_dev_request_t * pReq );
++static void queue_and_start_write( void * p, int req, int act );
++
++static int read_fifo_and_print( );
++
++static int GetFifoData(char *data,UINT32 length);
++
++char *fstartaddr=NULL;
++
++
++void SendStatus();
++void SendState();
++void SendZeroLengthPkt();
++void SendStall();
++int DownloadFirmware(char *fstartaddr,int length);
++/***************************************************************************
++ Inline Helpers
++ ***************************************************************************/
++
++int type_code_from_request(UINT8 by)
++{
++ return (( by >> 4 ) & 3);
++}
++
++
++
++#if VERBOSITY
++
++static inline void pcs( void )
++{
++ UINT32 foo = UDCCSR0;
++ printf("%08x: %s %s %s %s %s %s\n",
++ foo,
++ foo & UDCCSR0_SA ? "SA" : "",
++ foo & UDCCSR0_OPC ? "OPC" : "",
++ foo & UDCCSR0_RNE ? "RNE" : "",
++ foo & UDCCSR0_SST ? "SST" : "",
++ foo & UDCCSR0_FST ? "FST" : "",
++ foo & UDCCSR0_DRWF ? "DRWF" : ""
++ );
++}
++static inline void preq( usb_dev_request_t * pReq )
++{
++ static char * tnames[] = { "dev", "intf", "ep", "oth" };
++ static char * rnames[] = { "std", "class", "vendor", "???" };
++ char * psz;
++ switch( pReq->bRequest ) {
++ case GET_STATUS: psz = "get stat"; break;
++ case CLEAR_FEATURE: psz = "clr feat"; break;
++ case SET_FEATURE: psz = "set feat"; break;
++ case SET_ADDRESS: psz = "set addr"; break;
++ case GET_DESCRIPTOR: psz = "get desc"; break;
++ case SET_DESCRIPTOR: psz = "set desc"; break;
++ case GET_CONFIGURATION: psz = "get cfg"; break;
++ case SET_CONFIGURATION: psz = "set cfg"; break;
++ case GET_INTERFACE: psz = "get intf"; break;
++ case SET_INTERFACE: psz = "set intf"; break;
++ case SYNCH_FRAME: psz = "synch frame"; break;
++ default: psz = "unknown"; break;
++ }
++ printf( "- [%s: %s req to %s. dir=%s]\n", psz,
++ rnames[ (pReq->bmRequestType >> 5) & 3 ],
++ tnames[ pReq->bmRequestType & 3 ],
++ ( pReq->bmRequestType & 0x80 ) ? "in" : "out" );
++}
++
++#else
++static void pcs( void ){}
++static void preq( usb_dev_request_t *x){}
++#endif
++
++/***************************************************************************
++ Globals
++ ***************************************************************************/
++static const char pszMe0[] = "usbep0: ";
++
++/* pointer to current setup handler */
++static void (*current_handler)(void) = IntrHandlr;
++
++/* global write struct to keep write
++ ..state around across interrupts */
++static struct {
++ unsigned char *p;
++ int bytes_left;
++} wr;
++
++/***************************************************************************
++ Public Interface
++ ***************************************************************************/
++
++/* reset received from HUB (or controller just went nuts and reset by itself!)
++ so udc core has been reset, track this state here */
++void ep0_reset(void)
++{
++ if (USB_DEBUG) printf("%sep0_reset\n", pszMe0);
++ /* reset state machine */
++ current_handler = IntrHandlr;
++ wr.p = 0;
++ wr.bytes_left = 0;
++ usbd_info.address=0;
++}
++
++/* handle interrupt for endpoint zero */
++void ep0_int_hndlr( void )
++{
++ if (USB_DEBUG) printf("%sep0_int_hndlr\n", pszMe0);
++ (*current_handler)();
++}
++
++
++/***************************************************************************
++ Setup Handlers
++ ***************************************************************************/
++/*
++ * IntrHandlr()
++ * This setup handler is the "idle" state of endpoint zero. It looks for OPC
++ * (OUT packet ready) to see if a setup request has been been received from the
++ * host.
++ *
++ */
++static void IntrHandlr( void )
++{
++ usb_dev_request_t req;
++ int request_type;
++ int n;
++ UINT32 cs_reg_in = UDCCSR0;
++
++
++ if (USB_DEBUG) printf("%ssh_setup_begin\n", pszMe0);
++
++ /* Be sure out packet ready, otherwise something is wrong */
++ if ( (cs_reg_in & UDCCSR0_OPC) == 0 ) {
++ /* we can get here early...if so, we'll int again in a moment */
++ if (USB_DEBUG) printf("%ssetup begin: no OUT packet available. Exiting\n", pszMe0 );
++ goto sh_sb_end;
++ }
++
++ if( ((cs_reg_in & UDCCSR0_SA) == 0) && (ep0_state == EP0_IN_DATA_PHASE))
++ {
++ if (USB_DEBUG) printf("%ssetup begin: premature status\n", pszMe0 );
++
++ /* premature status, reset tx fifo and go back to idle state*/
++ UDCCSR0 = UDCCSR0_OPC | UDCCSR0_FTF;
++
++ ep0_state = EP0_IDLE;
++ return;
++ }
++
++ if( (UDCCSR0 & UDCCSR0_RNE) == 0)
++ {
++ /* zero-length OUT? This is ACK for control message ack*/
++ // printf("%ssetup begin: zero-length OUT?\n", pszMe0 );
++ goto sh_sb_end;
++ }
++
++ /* read the setup request */
++ n = read_fifo( &req );
++ if ( n != sizeof( req ) ) {
++ printf("%ssetup begin: fifo READ ERROR wanted %d bytes got %d. Stalling out...\n",
++ pszMe0, sizeof( req ), n );
++ /* force stall, serviced out */
++ UDCCSR0 = UDCCSR0_FST;
++ goto sh_sb_end;
++ }
++
++ /* Is it a standard request? (not vendor or class request) */
++ request_type = type_code_from_request( req.bmRequestType );
++ if ( request_type != 0 ) {
++
++ DFU_Intr_Handlr(req);
++ //printf("\r\n%ssetup begin: unsupported bmRequestType: %d ignored\r\nbRequest = 0x%x\n",
++ // pszMe0, request_type, req.bRequest );
++ UDCCSR0=UDCCSR0_IPR;
++ goto sh_sb_end;
++ }
++
++
++
++ /* Handle it */
++ switch( req.bRequest ) {
++
++ case SET_ADDRESS:
++ //if (USB_DEBUG)
++ printf("%sSET_ADDRESS handled by UDC\n", pszMe0);
++ break;
++#if 0 /* NOT_NEEDED */
++
++ case SET_FEATURE:
++ if (USB_DEBUG) printf("%sSET_FEATURE handled by UDC\n", pszMe0);
++ break;
++
++ case CLEAR_FEATURE:
++ if (USB_DEBUG) printf("%sCLEAR_FEATURE handled by UDC\n", pszMe0);
++ break;
++
++ case GET_CONFIGURATION:
++ if (USB_DEBUG) printf("%sGET_CONFIGURATION handled by UDC\n", pszMe0 );
++ break;
++
++ case GET_STATUS:
++ if (USB_DEBUG) printf("%s%sGET_STATUS handled by UDC\n", pszMe0 );
++ break;
++
++ case GET_INTERFACE:
++ if (USB_DEBUG) printf("%sGET_INTERFACE handled by UDC\n", pszMe0);
++ break;
++
++ case SYNCH_FRAME:
++ if (USB_DEBUG) printf("%sSYNCH_FRAME handled by UDC\n", pszMe0 );
++ break;
++#endif
++
++ case GET_DESCRIPTOR:
++ if (USB_DEBUG) printf("%sGET_DESCRIPTOR\n", pszMe0 );
++ get_descriptor( &req );
++ break;
++
++ case SET_INTERFACE:
++ // if (USB_DEBUG)
++ printf("%sSET_INTERFACE TODO...\n", pszMe0);
++ break;
++
++ case SET_DESCRIPTOR:
++ // if (USB_DEBUG)
++ printf("%sSET_DESCRIPTOR TODO...\n", pszMe0 );
++ break;
++
++ case SET_CONFIGURATION:
++ // if (USB_DEBUG)
++ printf("%sSET_CONFIGURATION %d\n", pszMe0, req.wValue);
++/*
++ * FIXME: Something is not quite right here... I only ever get a
++ * de-configure from the host. Ignoring it for now, since usb
++ * ethernet won't do anything unless usb is 'configured'.
++ *
++ */ break;
++ default :
++ printf("%sunknown request 0x%x\n", pszMe0, req.bRequest);
++ break;
++ } /* switch( bRequest ) */
++
++sh_sb_end:
++// printf("sh_end\n" );
++ return;
++}
++void DFU_Intr_Handlr(usb_dev_request_t req)
++{
++ int ret;
++ switch (curr_dfu_state)
++ {
++ case DFU_STATE_appIDLE:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ case USB_REQ_DFU_DETACH:
++ Bytes_Written=0;
++ pudccsr0 = 0x40600100;
++ pudcdr0=0x40600300;
++ fstartaddr =(char *)LOAD_ADDR;
++
++ Dfu_Status.bStatus = DFU_STATUS_OK;
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ //actually it should be DFU_STATE_appDETACH since appDETACH is not implemntd.
++ //fully jump to next state
++ Dfu_Status.bState=curr_dfu_state;
++ //SendZeroLengthPkt();
++ break;
++ default:
++ SendStall();
++ }
++ break;
++ case DFU_STATE_appDETACH:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_appIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ /* FIXME: implement timer to return to appIDLE */
++ break;
++ case DFU_STATE_dfuIDLE:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_DNLOAD:
++ Bytes_Written=0;
++ fstartaddr =(char *)LOAD_ADDR;
++ if (req.wLength == 0)
++ {
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ }
++ else
++ {
++ curr_dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
++ Dfu_Status.bState=curr_dfu_state;
++ ret = DownloadFirmware(Pkt_Data,req.wLength);
++ memcpy(fstartaddr,Pkt_Data,ret);
++ fstartaddr+=ret;
++ Bytes_Written+=ret;
++ //printf("Got Packet\r\n");
++ }
++ break;
++ case USB_REQ_DFU_UPLOAD:
++ curr_dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ //handle_upload(len, 1);
++ break;
++ case USB_REQ_DFU_ABORT:
++ //SendZeroLengthPkt();
++ break;
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ case USB_REQ_DFU_DETACH:
++ /* Proprietary extension: 'detach' from idle mode and
++ * get back to runtime mode in case of USB Reset. As
++ * much as I dislike this, we just can't use every USB
++ * bus reset to switch back to runtime mode, since at
++ * least the Linux USB stack likes to send a number of resets
++ * in a row :( */
++ curr_dfu_state = DFU_STATE_dfuMANIFEST_WAIT_RST;
++ Dfu_Status.bState=curr_dfu_state;
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ break;
++ case DFU_STATE_dfuDNLOAD_SYNC:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ curr_dfu_state = DFU_STATE_dfuDNLOAD_IDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStatus();
++ /* FIXME: state transition depending on block completeness */
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ }
++ break;
++ case DFU_STATE_dfuDNBUSY:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ /* FIXME: only accept getstatus if bwPollTimeout
++ * has elapsed */
++ SendStatus();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ }
++ break;
++ case DFU_STATE_dfuDNLOAD_IDLE:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_DNLOAD:
++ if(req.wLength==0)
++ {
++ //Firware download completed with zero length packet
++ printf("Firmware Dowloaded to RAM..\r\nStarting to Write to Flash\r\n");
++ if((Bytes_Written % 2) != 0)
++ Bytes_Written +=1;
++ curr_dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
++ Dfu_Status.bState=curr_dfu_state;
++ g_DFU_Download_Complete=TRUE;
++ }
++ else
++ {
++ curr_dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
++ Dfu_Status.bState=curr_dfu_state;
++ ret = DownloadFirmware(Pkt_Data,req.wLength);
++ memcpy(fstartaddr,Pkt_Data,ret);
++ fstartaddr+=ret;
++ Bytes_Written+=ret;
++ }
++ break;
++ case USB_REQ_DFU_ABORT:
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ //SendZeroLengthPkt();
++ break;
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ break;
++ case DFU_STATE_dfuMANIFEST_SYNC:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ /* We're MainfestationTolerant */
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ break;
++ case DFU_STATE_dfuMANIFEST:
++ /* we should never go here */
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ case DFU_STATE_dfuMANIFEST_WAIT_RST:
++ /* we should never go here */
++ break;
++ case DFU_STATE_dfuUPLOAD_IDLE:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_UPLOAD:
++ /* state transition if less data then requested */
++ //rc = handle_upload(urb, val, len, 0);
++ //if (rc >= 0 && rc < len)
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ break;
++ case USB_REQ_DFU_ABORT:
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ /* no zlp? */
++ //SendZeroLengthPkt();
++ break;
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ break;
++ case DFU_STATE_dfuERROR:
++ switch (req.bRequest) {
++ case USB_REQ_DFU_GETSTATUS:
++ SendStatus();
++ break;
++ case USB_REQ_DFU_GETSTATE:
++ SendState();
++ break;
++ case USB_REQ_DFU_CLRSTATUS:
++ curr_dfu_state = DFU_STATE_dfuIDLE;
++ Dfu_Status.bState=curr_dfu_state;
++ Dfu_Status.bStatus = DFU_STATUS_OK;
++ /* no zlp? */
++ //SendZeroLengthPkt();
++ break;
++ default:
++ curr_dfu_state = DFU_STATE_dfuERROR;
++ Dfu_Status.bState=curr_dfu_state;
++ SendStall();
++ break;
++ }
++ break;
++ default:
++ printf("\r\n%ssetup begin: unsupported ignored\r\nbRequest = 0x%x\n",
++ pszMe0, req.bRequest );
++ break;
++ }
++}
++/*
++ * sh_write()
++ *
++ * Due to UDC bugs we push everything into the fifo in one go.
++ * Using interrupts just didn't work right...
++ * This should be ok, since control request are small.
++ */
++static void sh_write()
++{
++ if (USB_DEBUG) printf("sh_write\n" );
++ do
++ {
++ write_fifo();
++ } while( ep0_state != EP0_END_XFER);
++}
++
++/***************************************************************************
++ Other Private Subroutines
++ ***************************************************************************/
++/*
++ * queue_and_start_write()
++ * data == data to send
++ * req == bytes host requested
++ * act == bytes we actually have
++ *
++ * Sets up the global "wr"-ite structure and load the outbound FIFO
++ * with data.
++ *
++ */
++static void queue_and_start_write( void * data, int req, int act )
++{
++ if (USB_DEBUG) printf("write start: bytes requested=%d actual=%d\n", req, act);
++
++ wr.p = (unsigned char*) data;
++ wr.bytes_left = MIN( act, req );
++
++ ep0_state = EP0_IN_DATA_PHASE;
++ sh_write();
++
++ return;
++}
++/*
++ * write_fifo()
++ * Stick bytes in the endpoint zero FIFO.
++ *
++ */
++static void write_fifo( void )
++{
++ int bytes_this_time = MIN( wr.bytes_left, EP0_FIFO_SIZE );
++ int bytes_written = 0;
++ UINT32 aligned_buf[EP0_FIFO_SIZE]; //Modified by Tharma
++ UINT8 *data=(UINT8 *)aligned_buf;
++
++ if (USB_DEBUG) printf("%swr.p=0x%08x\n", __FUNCTION__, wr.p);
++
++ if ((UDCCSR0 & UDCCSR0_IPR) == UDCCSR0_IPR)//last write not finished yet
++ return;
++ memcpy(data, wr.p, bytes_this_time);
++
++ /* 4-bytes word */
++ while( bytes_this_time >= 4 ) {
++ if (USB_DEBUG) printf("0x%2.2x ",*((UINT32*)data));
++ /* UDDR0 = *wr.p++; */
++ UDCDR0 = *((UINT32*)data);
++ data += 4;
++ bytes_written += 4;
++ bytes_this_time -= 4;
++ }
++
++ while( bytes_this_time ) {
++ *((UINT8*)&UDCDR0) = *data++;
++ bytes_written ++;
++ bytes_this_time --;
++ }
++
++ wr.p += bytes_written;
++ wr.bytes_left -= bytes_written;
++
++ usbd_info.stats.ep0_bytes_written += bytes_written;
++
++ if( (wr.bytes_left==0))
++ {
++ wr.p = 0; /* be anal */
++ if (bytes_written == EP0_FIFO_SIZE){//wait fifo write finish
++ do {
++ }while ((UDCCSR0 & UDCCSR0_IPR) == UDCCSR0_IPR);
++ }
++ //even bytes_written = EP0_FIFO_SIZE we must send a zero packet
++ //if(bytes_written < EP0_FIFO_SIZE)
++ {
++ int count;
++ int udccsr0;
++
++ /* We always end the transfer with a short or zero length packet */
++ ep0_state = EP0_END_XFER;
++ current_handler = IntrHandlr;
++
++ /* Let the packet go... */
++ UDCCSR0 |= UDCCSR0_IPR;
++
++ /* Wait until we get to status-stage, then ack.
++ *
++ * When the UDC sets the UDCCSR0[OPC] bit, an interrupt
++ * is supposed to be generated (see 12.5.1 step 14ff, PXA Dev Manual).
++ * That approach didn't work out. Usually a new SETUP command was
++ * already in the fifo. I tried many approaches but was always losing
++ * at least some OPC interrupts. Thus the polling below...
++ */
++ count = 1000;
++ udccsr0 = UDCCSR0;
++ do
++ {
++ if( (UDCCSR0 & UDCCSR0_OPC))
++ {
++ /* clear OPC, generate ack */
++ UDCCSR0 |= UDCCSR0_OPC;
++ break;
++ }
++ count--;
++ } while( count);
++
++ if (USB_DEBUG) printf("write fifo: count=%d UDCCSR0=%x UDCCSR0=%x\n", count, udccsr0, UDCCSR0);
++ }
++ }
++
++ if (USB_DEBUG) printf("write fifo: bytes sent=%d, bytes left=%d\n", bytes_written, wr.bytes_left);
++}
++
++/*
++ * read_fifo()
++ * Read bytes out of FIFO and put in request.
++ * Called to do the initial read of setup requests
++ * from the host. Return number of bytes read.
++ *
++ */
++static int read_fifo( usb_dev_request_t * request )
++{
++ int bytes_read = 0;
++ unsigned char * pOut = (unsigned char*) request;
++
++ DWORD udccsr0 = UDCCSR0;
++
++ if( (udccsr0 & SETUP_READY) == SETUP_READY)
++ {
++ /* ok it's a setup command */
++ while( UDCCSR0 & UDCCSR0_RNE)
++ {
++ if( bytes_read >= sizeof( usb_dev_request_t))
++ {
++ /* We've already read enought o fill usb_dev_request_t.
++ * Our tummy is full. Go barf...
++ */
++ printf("%sread_fifo(): read failure\n", pszMe0 );
++ usbd_info.stats.ep0_fifo_read_failures++;
++ break;
++ }
++
++ *((UINT32*)pOut) = UDCDR0;
++ pOut += 4;
++ bytes_read +=4;
++ }
++ }
++
++ if (USB_DEBUG) printf("read_fifo %d bytes\n", bytes_read );
++
++ /* clear SA & OPC */
++
++ UDCCSR0 = udccsr0;
++
++
++// UDCCSR0 |= UDCCSR0_OPC;
++// UDCCSR0 |= UDCCSR0_SA;
++//
++
++ usbd_info.stats.ep0_bytes_read += bytes_read;
++ return bytes_read;
++}
++
++/*
++ * get_descriptor()
++ * Called from IntrHandlr to handle data return
++ * for a GET_DESCRIPTOR setup request.
++ *
++ * +-----+------------------------------------------------+-----------------+
++ * | dev | cfg1 | intf 1 | ep 1..N | intf 2 | ep 1..N |...| cfg2 .......... |
++ * +-----+------------------------------------------------+-----------------+
++ */
++static void get_descriptor( usb_dev_request_t * pReq )
++{
++ string_desc_t * pString;
++
++ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
++ int type = pReq->wValue >> 8;
++ int idx = pReq->wValue & 0xFF;
++
++ if (USB_DEBUG) printf("%sget_descriptor for %d\n", pszMe0, type );
++ switch( type ) {
++ case USB_DESC_DEVICE:
++ /* return device descritpor */
++ queue_and_start_write( &pDesc->dev,
++ pReq->wLength,
++ pDesc->dev.bLength );
++ break;
++
++ // return config descriptor buffer, cfg, intf 1..N, ep 1..N
++ case USB_DESC_CONFIG:
++ {
++ int i,len;
++ config_desc_t *cfg =(config_desc_t*) (pDesc->cdb);
++
++ len=0;
++ for( i=0; i<pDesc->dev.bNumConfigurations; i++) {
++ len += cfg->wTotalLength;
++ cfg = (config_desc_t*) ( (unsigned char*) cfg
++ + cfg->wTotalLength) ;
++ }
++
++ queue_and_start_write( pDesc->cdb,
++ pReq->wLength,
++ len);
++ //printf("\r\nUSB Detected by Host Successfully\r\n");
++
++ }
++ break;
++
++ // not quite right, since doesn't do language code checking
++ case USB_DESC_STRING:
++ pString = pxa_usb_get_string_descriptor( idx );
++ if ( pString ) {
++ if ( idx != 0 ) { // if not language index
++ printf("%sReturn string %d: ", pszMe0, idx );
++ }
++ queue_and_start_write( pString,
++ pReq->wLength,
++ pString->bLength );
++ }
++ else {
++ printf("%sunkown string index %d Stall.\n", pszMe0, idx );
++ }
++ break;
++
++ /*
++ case USB_DESC_INTERFACE:
++ for( i = 0; i < pDesc->intf_num; i++) {
++ if ( idx == pDesc->intf[i].bInterfaceNumber ) {
++ queue_and_start_write( &pDesc->intf[i],
++ pReq->wLength,
++ pDesc->intf[i].bLength );
++ }
++ }
++ break;
++
++ case USB_DESC_ENDPOINT:
++ for( i = 0; i < pDesc->ep_num; i++) {
++ if ( idx == (0x0F & pDesc->ep[i].bEndpointAddress)) {
++ queue_and_start_write( &pDesc->ep[i],
++ pReq->wLength,
++ pDesc->ep[i].bLength );
++ }
++ }
++ break;
++ */
++
++ default :
++ printf("%sunknown descriptor type %d. Stall.\n", pszMe0, type );
++ break;
++
++ }
++}
++
++/* end usb_ep0.c - who needs this comment? */
++
++
++static int read_fifo_and_print( )
++{
++ int bytes_read = 0;
++ int i;
++ char data[64];
++ unsigned char * pOut = data;
++
++ int udccsr0 = UDCCSR0;
++ printf(". ");
++
++ /* ok it's a setup command */
++ while(UDCBCR0)
++ {
++ if(bytes_read>64)
++ break;
++ *((UINT32*)pOut) = UDCDR0;
++ pOut += 4;
++ bytes_read +=4;
++ }
++
++
++ for(i=0;i<bytes_read;i++)
++ printf("read_byte %c\r\n", data[i]);
++// printf("read_fifo %d bytes\r\n", bytes_read );
++
++ usbd_info.stats.ep0_bytes_read += bytes_read;
++
++
++ return bytes_read;
++}
++
++
++static int GetFifoData(char *data,UINT32 length)
++{
++ int bytes_read = 0;
++ int i;
++ unsigned char * pOut = data;
++
++// printf("<");
++ while(bytes_read<length)
++ {
++ if((*pudccsr0 & UDCCSR0_OPC))
++ {
++ if((*pudccsr0 & UDCCSR0_RNE))//&&(UDCBCR0&0x3FF))
++ {
++ *((UINT32*)pOut) = *pudcdr0;
++ pOut += 4;
++ bytes_read +=4;
++ }
++ else
++ {
++ *pudccsr0 |= UDCCSR0_OPC;
++ }
++ }
++ }
++// printf(">");
++// UDCCSR0 = udccsr0;
++
++// UDCCSR0 = UDCCSR0_IPR;
++// UDCCSR0 |= UDCCSR0_OPC;
++// UDCCSR0 |= UDCCSR0_SA;
++
++ //UDCCSR0 |= UDCCSR0_OPC;
++ //for(i=0;i<bytes_read;i++)
++ // printf("read_byte %c\r\n", data[i]);
++ //printf("\r\nread_fifo %d bytes\n", bytes_read );
++
++ usbd_info.stats.ep0_bytes_read += bytes_read;
++
++
++ return bytes_read;
++}
++
++void SendStatus()
++{
++ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
++ queue_and_start_write(&Dfu_Status,sizeof(Dfu_Status),16);
++}
++void SendState()
++{
++ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
++ queue_and_start_write(&(Dfu_Status.bState),1,16);
++}
++void SendZeroLengthPkt()
++{
++ char data=0x00;
++ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
++ queue_and_start_write(&data,0,16);
++}
++void SendStall()
++{
++ printf("\r\nStalling out...\r\n");
++ /* force stall, serviced out */
++ UDCCSR0 = UDCCSR0_FST;
++}
++int DownloadFirmware(char *fstartaddr,int length)
++{
++ printf(".");
++ return GetFifoData(fstartaddr,length);
++}
++
++
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ep0.h u-boot-2008.10/common/bvd_usb_ep0.h
+--- u-boot-2008.10_original/common/bvd_usb_ep0.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ep0.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) Intrinsyc, Inc., 2002
++ *
++ * usb_ep0.h - PXA USB controller driver.
++ * Endpoint zero management
++ *
++ * Please see:
++ * linux/Documentation/arm/SA1100/SA1100_USB
++ * for details.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) -
++ *
++ */
++
++#ifndef __USB_EP0_H
++#define __USB_EP0_H
++
++#define EP0_FIFO_SIZE 16
++#define UDCCS0_SA (1 << 7) /* Setup active */
++#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
++
++#define SETUP_READY (UDCCS0_SA | UDCCS0_OPR)
++
++/*================================================
++ * USB Protocol Stuff
++ */
++
++/* Request Codes */
++enum {
++ GET_STATUS =0,
++ CLEAR_FEATURE =1,
++ /* reserved =2 */
++ SET_FEATURE =3,
++ /* reserved =4 */
++ SET_ADDRESS =5,
++ GET_DESCRIPTOR =6,
++ SET_DESCRIPTOR =7,
++ GET_CONFIGURATION =8,
++ SET_CONFIGURATION =9,
++ GET_INTERFACE =10,
++ SET_INTERFACE =11,
++ SYNCH_FRAME =12
++};
++
++typedef enum {
++ EP0_IDLE,
++ EP0_IN_DATA_PHASE,
++ EP0_END_XFER,
++ EP0_OUT_DATA_PHASE
++} EP0_state;
++
++/* USB Device Requests */
++typedef struct
++{
++ UINT8 bmRequestType;
++ UINT8 bRequest;
++ UINT16 wValue;
++ UINT16 wIndex;
++ UINT16 wLength;
++} usb_dev_request_t;
++
++/* Data extraction from usb_request_t fields */
++enum {
++ kTargetDevice =0,
++ kTargetInterface=1,
++ kTargetEndpoint =2
++};
++#endif
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ep1.c u-boot-2008.10/common/bvd_usb_ep1.c
+--- u-boot-2008.10_original/common/bvd_usb_ep1.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ep1.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,233 @@
++/*
++ * Generic xmit layer for the PXA USB client function
++ *
++ * This code was loosely inspired by the original version which was
++ * Copyright (c) Compaq Computer Corporation, 1998-1999
++ * Copyright (c) 2001 by Nicolas Pitre
++ *
++ * 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.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100 usb_send.c
++ *
++ * TODO: Add support for DMA.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++# include <blob/config.h>
++#endif
++
++#if 0 //Commneted by Tharma
++#include <blob/arch.h>
++#include <blob/types.h>
++#include <blob/init.h>
++#endif
++
++
++//#include <linux/errno.h> //Commneted by Tharma
++
++#include <asm/errno.h> //Added by Tharma
++#include "pxa_usb.h"
++#include "bvd_usb_ctl.h"
++
++#undef DEBUG
++#if DEBUG
++static unsigned int usb_debug = DEBUG;
++#else
++#define usb_debug 0 /* gcc will remove all the debug code for us */
++#endif
++
++static char *ep1_buf;
++static int ep1_len;
++static int ep1_remain;
++static usb_callback_t ep1_callback;
++static int tx_pktsize;
++
++/* device state is changing, async */
++void
++ep1_state_change_notify( int new_state )
++{
++}
++
++/* set feature stall executing, async */
++void
++ep1_stall( void )
++{
++}
++
++static void
++ep1_send_packet(void)
++{
++ int i, bytes, bytes_this_time, bytes_left;
++ __u8 *buf = ep1_buf + ep1_len - ep1_remain;
++ int out_size = tx_pktsize;
++ __u32 aligned_buf[64];
++ __u8 *data =(__u8 *)aligned_buf;
++
++ if (usb_debug)
++ printf( "%s: enter \n", __FUNCTION__);
++
++ if( out_size > ep1_remain)
++ {
++ out_size = ep1_remain;
++ }
++
++ bytes_left = out_size;
++
++ do {
++ bytes_this_time = (bytes_left < sizeof(aligned_buf))
++ ? bytes_left : sizeof(aligned_buf);
++
++
++ data = (__u8 *)aligned_buf;
++ memcpy(data, buf, bytes_this_time);
++
++ bytes = bytes_this_time & (~0x3);
++ for( i=0; i<bytes; i+=4)
++ {
++ UDCDRA = *((__u32*)data);
++ data += 4;
++ }
++
++ bytes = bytes_this_time & 0x3;
++ for( i=0; i<bytes; i++ )
++ *((volatile u8*)&UDCDRA) = *data++;
++
++ buf += bytes_this_time;
++ bytes_left -= bytes_this_time;
++ }
++ while (bytes_left);
++
++ /* UDCCS1 = UDCCS_BI_TPC; */
++ UDCCSRA = UDCCSR_PC;
++
++ if( out_size < tx_pktsize)
++ {
++ /* short packet */
++ UDCCSRA = UDCCSR_SP;
++ }
++ ep1_remain -= out_size;
++
++ /* something goes poopy if I dont wait here ... */
++ msleep(1);
++ if (usb_debug)
++ printf("%s: exit, ep1_remain=%d bytes\n", __FUNCTION__, ep1_remain);
++}
++
++static void
++ep1_start(void)
++{
++ if (!ep1_len)
++ return;
++
++ UDCICR0 = 0x3f;
++
++ ep1_send_packet();
++}
++
++static void
++ep1_done(int flag)
++{
++ int size = ep1_len - ep1_remain;
++ if (ep1_len) {
++ ep1_len = 0;
++ if (ep1_callback) {
++ ep1_callback(flag, size);
++ }
++ }
++}
++
++int
++ep1_init(int chn)
++{
++ /*
++ int i;
++ desc_t * pdesc = pxa_usb_get_descriptor_ptr();
++ for ( i = 0; i < pdesc->ep_num; i++ ) {
++ if( BULK_IN1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) {
++ tx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize );
++ }
++ }
++ */
++
++ /* FIXME */
++ tx_pktsize = 64;
++ ep1_done(-EAGAIN);
++ return 0;
++}
++
++void
++ep1_reset(void)
++{
++ /*
++ int i;
++ desc_t * pdesc = pxa_usb_get_descriptor_ptr();
++ for ( i = 0; i < pdesc->ep_num; i++ ) {
++ if( BULK_IN1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) {
++ tx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize );
++ }
++ }
++ */
++
++ /* FIXME */
++ tx_pktsize = 64;
++
++ ep1_done(-EINTR);
++}
++
++void
++ep1_int_hndlr(int usir0)
++{
++ int status = UDCCSRA;
++
++
++ if (ep1_remain != 0) {
++ /* more data to go */
++ ep1_start();
++ } else {
++ if( status & UDCCSR_PC)
++ {
++ UDCCSRA = UDCCSR_PC;
++ }
++ ep1_done(0);
++ }
++}
++
++int
++ep1_send(char *buf, int len, usb_callback_t callback)
++{
++ int i=0;
++ int flags;
++
++ if (usb_debug) printf( "pxa_usb_send: "
++ "data len=%d state=%d blen=%d\n",
++ len, usbd_info.state, ep1_len);
++
++ if (usbd_info.state != USB_STATE_CONFIGURED)
++ return -ENODEV;
++
++ if (ep1_len) {
++ return -EBUSY;
++ }
++
++ ep1_buf = buf;
++ ep1_len = len;
++ ep1_callback = callback;
++ ep1_remain = len;
++ ep1_start();
++
++ return 0;
++}
++
++int
++ep1_xmitter_avail( void )
++{
++ if (usbd_info.state != USB_STATE_CONFIGURED)
++ return -ENODEV;
++ if (ep1_len)
++ return -EBUSY;
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/bvd_usb_ep2.c u-boot-2008.10/common/bvd_usb_ep2.c
+--- u-boot-2008.10_original/common/bvd_usb_ep2.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/bvd_usb_ep2.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,200 @@
++/*
++ * Generic receive layer for the PXA USB client function
++ *
++ * This code was loosely inspired by the original version which was
++ * Copyright (c) Compaq Computer Corporation, 1998-1999
++ * Copyright (c) 2001 by Nicolas Pitre
++ *
++ * 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.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100 usb_recv.c
++ *
++ * TODO: Add support for DMA.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++# include <blob/config.h>
++#endif
++
++#if 0 //Commneted by Tharma
++#include <blob/arch.h>
++#include <blob/types.h>
++#include <blob/init.h>
++
++#include <linux/errno.h>
++
++#endif
++#include <asm/errno.h> //Added by Tharma
++#include "pxa_usb.h"
++#include "bvd_usb_ctl.h"
++
++#undef DEBUG
++//#define DEBUG 3
++#if DEBUG
++static unsigned int usb_debug = DEBUG;
++#else
++#define usb_debug 0 /* gcc will remove all the debug code for us */
++#endif
++
++static char *ep2_buf;
++static int ep2_len;
++static int ep2_remain;
++static usb_callback_t ep2_callback;
++static int rx_pktsize;
++
++static void
++ep2_start(void)
++{
++ /* disable DMA, RPC & SST should not be cleared */
++ /* UDCCS2 &= ~( UDCCS_BO_DME | UDCCS_BO_RPC | UDCCS_BO_SST ); */
++
++ /* enable interrupts for endpoint 2 (bulk out) */
++ /* UICR0 &= ~UICR0_IM2; */
++ UDCICR0 = 0x3f;
++
++}
++
++static void
++ep2_done(int flag)
++{
++ int size = ep2_len - ep2_remain;
++
++ if (!ep2_len)
++ return;
++
++ ep2_len = 0;
++ if (ep2_callback) {
++ ep2_callback(flag, size);
++ }
++}
++
++void
++ep2_state_change_notify( int new_state )
++{
++}
++
++void
++ep2_stall( void )
++{
++ /* SET_FEATURE force stall at UDC */
++ /* UDCCS2 |= UDCCS_BO_FST; */
++}
++
++int
++ep2_init(int chn)
++{
++ /*
++ int i;
++ desc_t * pdesc = pxa_usb_get_descriptor_ptr();
++
++ for ( i = 0; i < pdesc->ep_num; i++ ) {
++ if( BULK_OUT1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) {
++ rx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize );
++ }
++ }
++ */
++
++ /* FIXME */
++ rx_pktsize = 64;
++ ep2_done(-EAGAIN);
++ return 0;
++}
++
++void
++ep2_reset(void)
++{
++ /*
++ int i;
++ desc_t * pdesc = pxa_usb_get_descriptor_ptr();
++
++ for ( i = 0; i < pdesc->ep_num; i++ ) {
++ if( BULK_OUT1 == ( 0xF & pdesc->ep[i].bEndpointAddress) ) {
++ rx_pktsize = __le16_to_cpu( pdesc->ep[i].wMaxPacketSize );
++ }
++ }
++ */
++ /* FIXME */
++ rx_pktsize = 64;
++ /* UDCCS2 &= ~UDCCS_BO_FST; */
++ ep2_done(-EINTR);
++}
++
++void
++ep2_int_hndlr(int udcsr)
++{
++ int status = UDCCSRB;
++ if( usb_debug) printf("ep2_int_hndlr: UDCCS2=%x\n", status);
++
++ if( (status & (UDCCSR_PC | UDCCSR_SP)) == UDCCSR_SP)
++ {
++ /* zero-length packet */
++ if (usb_debug) printf("%s:zero-length packet\n", __FUNCTION__);
++ UDCCSRB |= UDCCSR_PC;
++ }
++
++ if( status & UDCCSR_PC)
++ {
++ int len, ignlen;
++ int i;
++ __u8 *buf = ep2_buf + ep2_len - ep2_remain;
++
++ /* bytes in FIFO */
++ len = (UDCBCRB & 0x3ff);
++
++ if( usb_debug) printf("usb_recv: "
++ "len=%d out1_len=%d out1_remain=%d\n",
++ len,ep2_len,ep2_remain);
++
++ if( len > ep2_remain)
++ {
++ ignlen = len - ep2_remain;
++ /* FIXME: if this happens, we need a temporary overflow buffer */
++ if (usb_debug) printf("usb_recv: Buffer overwrite warning...\n");
++ len = ep2_remain;
++ }
++
++ /* read data out of fifo */
++ for( i=0; i<len; i+=4)
++ {
++ *((__u32*)buf) = UDCDRB;
++ if (usb_debug>2)
++ printf("-> %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
++ buf += 4;
++ }
++
++ /* emtpy fifo, here */
++ while(UDCCSRB & UDCCSR_BNE) {
++ __u32 data = UDCDRB;
++ }
++
++ /* ack RPC - FIXME: '|=' we may ack SST here, too */
++ UDCCSRB |= UDCCSR_PC;
++
++ ep2_remain -= len;
++ ep2_done((len) ? 0 : -EPIPE);
++ }
++
++ return;
++}
++
++int
++ep2_recv(char *buf, int len, usb_callback_t callback)
++{
++ int flags;
++
++ //if (ep2_len)
++ //return -EBUSY;
++
++ ep2_buf = buf;
++ ep2_len = len;
++ ep2_callback = callback;
++ ep2_remain = len;
++ ep2_start();
++
++ return 0;
++}
++
+diff -Naur u-boot-2008.10_original/common/cmd_3p2inchlcd.c u-boot-2008.10/common/cmd_3p2inchlcd.c
+--- u-boot-2008.10_original/common/cmd_3p2inchlcd.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_3p2inchlcd.c 2009-08-17 13:38:17.000000000 +0530
+@@ -0,0 +1,237 @@
++#include <common.h>
++#include <command.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <asm/sizes.h>
++#include <malloc.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++
++#define UINT8 char
++#define UINT16 short
++#define UINT32 int
++#define GPIO_DFLT_LOW 0x400
++#define GPIO_DFLT_HIGH 0x800
++
++#define GPIO10_SDI_GPIO (10 | GPIO_OUT | GPIO_DFLT_LOW) ////GPIO 10 Initialize as SDI_GPIO : DR - Output and AF - 0
++#define GPIO106_CLK_GPIO (106 | GPIO_OUT | GPIO_DFLT_LOW) ////GPIO 106 Initialize as CLK_GPIO : DR - Output and AF - 0
++#define GPIO53_CS_GPIO (53 | GPIO_OUT |GPIO_DFLT_HIGH) ////GPIO 53 Initialize as CS_GPIO : DR - Output and AF - 0
++
++extern int pxa_gpio_mode(int gpio_mode);
++
++#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
++
++
++//===================================================================================================
++//Configuring PXA270 GPIO 10, 106 and 53 for SPI interface..
++//===================================================================================================
++
++void SPIInit()
++{
++ SPIGPIOConfiguration();
++}
++
++//===================================================================================================
++//Configuring GPIO for SPI interface.
++//===================================================================================================
++
++void SPIGPIOConfiguration()
++{
++
++ pxa_gpio_mode(GPIO10_SDI_GPIO);
++ pxa_gpio_mode(GPIO106_CLK_GPIO);
++ pxa_gpio_mode(GPIO53_CS_GPIO);
++
++}
++
++void EnableCS()
++{
++ GPCR1 |= (0x1<< 21);
++}
++
++void DisableCS()
++{
++ GPSR1 |= (0x1<< 21);
++}
++
++void SetSDA(void)
++{
++ GPSR0 |= (0x1 << 10);
++}
++
++void ResetSDA(void)
++{
++ GPCR0 |= (0x1 << 10);
++}
++
++void SetSCL(void)
++{
++ GPSR3 |= (0x1 << 10);
++}
++
++void ResetSCL(void)
++{
++ GPCR3 |= (0x1 << 10);
++}
++
++
++void DelayMicroSeconds(UINT32 microseconds)
++{
++ udelay(microseconds);
++ return;
++
++}
++
++
++void PutBit(UINT16 Flag)
++{
++ if (Flag)
++ {
++ SetSDA();
++ }
++ else
++ {
++ ResetSDA();
++ }
++}
++
++
++void SPIWriteWord(UINT16 Data)
++{
++ UINT8 n = 0;
++ UINT32 TestData = 0x00008000;
++ EnableCS(); // Make Chip Select Low
++ DelayMicroSeconds(2);
++ while(n < 16)
++ {
++ //Transmit the Bit
++ PutBit(Data & TestData);
++
++ //Set the Clock Pin
++ SetSCL();
++
++ //Reset teh Clock Pin
++ ResetSCL();
++
++ n++;
++ TestData = TestData >>1;
++ }
++ DisableCS(); // Make Chip Select Low
++ GPCR0 |= (0x1<<10); //making Data low
++ GPCR3 |= (0x1<<10); //Making clk low
++ return ;
++}
++//====================================================================================
++//Write through SPI
++//====================================================================================
++void WriteLCDController(UINT8 Address, UINT8 Data)
++{
++ UINT16 Buffer;
++ Buffer = 0x74 << 8;
++// Buffer = Buffer;
++ Buffer = Buffer | Address;
++ SPIWriteWord(Buffer);
++ Buffer = 0x74 << 8;
++ Buffer = Buffer | (0x01 << 9);
++ Buffer = Buffer | Data;
++ SPIWriteWord(Buffer);
++
++}
++
++//===================================================================================================
++//Configuring LCD for data size and clock.
++//===================================================================================================
++void SPIInitializeLCD()
++{
++ i2c_reg_write (0x36,0x10,0x29);
++ i2c_reg_write (0x36,0xA0,0x14);
++ SPIInit();
++ WriteLCDController(0x46,0x87); //0092//0087
++ WriteLCDController(0x47,0x40); //0042
++ WriteLCDController(0x48,0x02); //0002
++ WriteLCDController(0x49,0x44); //0044
++ WriteLCDController(0x4A,0x04); //0004
++ WriteLCDController(0x4B,0x87); //0067
++ WriteLCDController(0x4C,0x70); //0033
++ WriteLCDController(0x4D,0x75); //0075
++ WriteLCDController(0x4E,0x50); //0053
++ WriteLCDController(0x4F,0x4F); //000C
++ WriteLCDController(0x50,0x45); //0046
++ WriteLCDController(0x51,0x40); //0044
++ //240x320 window setting
++ WriteLCDController(0x02,0x00); // Column address start2
++ WriteLCDController(0x03,0x00); // Column address start1
++ WriteLCDController(0x04,0x00); // Column address end2
++ WriteLCDController(0x05,0xEF); // Column address end1
++ WriteLCDController(0x06,0x00); // Row address start2
++ WriteLCDController(0x07,0x00); // Row address start1
++ WriteLCDController(0x08,0x01); // Row address end2
++ WriteLCDController(0x09,0x3F); // Row address end1
++ // Display Setting
++ WriteLCDController(0x01,0x06);
++ WriteLCDController(0x16,0xC8); //MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0
++ WriteLCDController(0x21,0x00);
++ WriteLCDController(0x23,0x95); // N_DC=1001 0101
++ WriteLCDController(0x24,0x95); // P_DC=1001 0101
++ WriteLCDController(0x25,0xFF); // I_DC=1111 1111
++ WriteLCDController(0x27,0x06); // N_BP=0000 0110
++ WriteLCDController(0x28,0x06); // N_FP=0000 0110
++ WriteLCDController(0x29,0x06); // P_BP=0000 0110
++ WriteLCDController(0x2A,0x06); // P_FP=0000 0110
++ WriteLCDController(0x2C,0x06); // I_BP=0000 0110
++ WriteLCDController(0x2D,0x06); // I_FP=0000 0110
++ WriteLCDController(0x3A,0x01); // N_RTN=0000, N_NW=001
++ WriteLCDController(0x3B,0x01); // P_RTN=0000, P_NW=001
++ WriteLCDController(0x3C,0xF0); // I_RTN=1111, I_NW=000
++ WriteLCDController(0x3D,0x00); // DIV=00
++ udelay(20);
++ WriteLCDController(0x10,0xA6); // SS=0,GS=0 CSEL=110
++ WriteLCDController(0x35,0x38); // EQS=38h
++ WriteLCDController(0x36,0x78); // EQP=78h
++ WriteLCDController(0x3E,0x38); // SON=38h
++ WriteLCDController(0x40,0x0F); // GDON=0Fh
++ WriteLCDController(0x41,0xF0); // GDOFF
++ WriteLCDController(0x38,0x10); // 0x18
++ WriteLCDController(0x39,0x03);
++ udelay(10);
++ WriteLCDController(0x70,0x66);
++ WriteLCDController(0x72,0x00);
++ // Power Supply Setting
++ WriteLCDController(0x19,0x39); // OSCADJ=10 0000, OSD_EN=1 //60Hz
++ WriteLCDController(0x93,0x0C); // RADJ=1100,
++ udelay(10);
++ WriteLCDController(0x20,0x40); // BT=0100
++ WriteLCDController(0x1D,0x07); // VC1=111
++ WriteLCDController(0x1E,0x00); // VC3=000
++ WriteLCDController(0x1F,0x04); // VRH=0100 4.12V
++ WriteLCDController(0x44,0x3C); // VCM=101 0000 3.21V
++// WriteLCDController(0x44,0x16); // VCM=101 0000 3.21V
++ WriteLCDController(0x45,0x11); // VDV=1 0001 -1.19V
++ udelay(30);
++ WriteLCDController(0x57,0x02); // Test Mode enable
++ WriteLCDController(0x55,0x00); // VDC_SL=000, VDDD=1.95V
++ WriteLCDController(0x57,0x00); // Test Mode disable
++ udelay(10);
++ WriteLCDController(0x1C,0x04); // AP=100
++ udelay(20);
++ WriteLCDController(0x43,0x80); //set VCOMG=1
++ udelay(10);
++ WriteLCDController(0x1B,0x18); // GASENB=0, PON=1, DK=1, XDK=0, DDVDH_TRI=0, STB=0
++ udelay(40);
++ WriteLCDController(0x1B,0x10); // GASENB=0, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
++ udelay(40);
++ // Display ON Setting
++ WriteLCDController(0x90,0x7F); // SAP=0111 1111
++ WriteLCDController(0x26,0x04); //GON=0, DTE=0, D=01
++ udelay(50);
++ WriteLCDController(0x26,0x24); //GON=1, DTE=0, D=01
++ udelay(50);
++ WriteLCDController(0x26,0x2C); //GON=1, DTE=0, D=11
++ udelay(50);
++ WriteLCDController(0x26,0x3C); //GON=1, DTE=1, D=11
++}
++
++U_BOOT_CMD(
++ 3p2inch, 1, 0, SPIInitializeLCD,
++ "3p2inch configure 3p2 inch lcd \n",
++ NULL
++);
+diff -Naur u-boot-2008.10_original/common/cmd_bin.c u-boot-2008.10/common/cmd_bin.c
+--- u-boot-2008.10_original/common/cmd_bin.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_bin.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,328 @@
++/*
++ * (C) Copyright 2004
++ * Andrea Scian, Dave Srl, andrea.scian@dave-tech.it
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++
++
++#include <common.h>
++#include <command.h>
++#include <linux/ctype.h>
++#include <net.h>
++
++
++#if 1 //(CONFIG_COMMANDS & CFG_CMD_BIN)
++
++
++#ifndef MAX
++#define MAX(a,b) ((a) > (b) ? (a) : (b))
++#endif
++
++#undef CMD_BIN_DEBUG
++#define CMD_BIN_DEBUG 1
++
++
++#ifdef CMD_BIN_DEBUG
++#define PRINTF(fmt,args...) printf (fmt ,##args)
++#else
++#define PRINTF(fmt,args...)
++#endif
++
++/* ======================================================================
++ * BIN file type definition
++ * ====================================================================== */
++
++#define NUM_SYNCBYTES 7
++
++#define SYNC_MAGIC "B000FF\n"
++
++struct bin_sync {
++ unsigned char syncbytes[NUM_SYNCBYTES];
++};
++
++struct bin_header {
++ unsigned int img_start;
++ unsigned int img_length;
++};
++
++#define BASE_BIN_RECORD_SIZE 12
++
++struct bin_record {
++ unsigned int address;
++ unsigned int length;
++ unsigned int checksum;
++ /*
++ ** unsigned char data[length];
++ */
++};
++
++extern int build_bin_image_parameters(char* cmdline);
++
++int valid_bin_image (unsigned long addr);
++unsigned long load_bin_image (unsigned long addr);
++
++
++/* ======================================================================
++ * Interpreter command to boot WindowsCE from a memory image. The image can
++ * be either a .bin image or a raw binary (nb0). Will attempt to setup the
++ * bootline and other parameters correctly.
++ * ====================================================================== */
++int do_bootwince ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++#if defined(CONFIG_WALNUT405) || \
++ defined(CONFIG_CPCI405) || \
++ defined(CONFIG_OCRTC) || \
++ defined(CONFIG_ORSG)
++ DECLARE_GLOBAL_DATA_PTR;
++#endif
++
++ unsigned long addr; /* Address of image */
++ unsigned long bootaddr; /* Address to put the bootline */
++ char *bootline; /* Text of the bootline */
++ char *tmp; /* Temporary char pointer */
++
++ char build_buf[80]; /* Buffer for building the bootline */
++
++ volatile unsigned int value;
++
++ /*
++ * Check the loadaddr variable.
++ * If we don't know where the image is then we're done.
++ */
++
++ if (argc>1) {
++ addr = simple_strtoul (argv[1], NULL, 16);
++ } else if ((tmp = getenv ("loadaddr")) != NULL) {
++ addr = simple_strtoul (tmp, NULL, 16);
++ } else {
++ puts ("No load address provided!\n");
++ return 1;
++ }
++
++#if (CONFIG_COMMANDS & CFG_CMD_NET)
++ /* Check to see if we need to tftp the image ourselves before starting */
++
++ if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) {
++ if (NetLoop (TFTP) <= 0)
++ return 1;
++ printf ("Automatic boot of WindowsCE image at address 0x%04x ... \n", addr);
++ }
++#endif
++
++ /*
++ * Use bootaddr to find the location in memory that WindowsCE
++ * will look for the bootline string. The default value for
++ * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which
++ * defaults to 0x4200
++ */
++ if ((tmp = getenv ("bootaddr")) == NULL)
++ bootaddr = PHYS_SDRAM_1 | 0x4200;
++ else
++ bootaddr = simple_strtoul (tmp, NULL, 16);
++
++ /*
++ * Check to see if the bootline is defined in the 'bootargs'
++ * parameter. If it is not defined, we may be able to
++ * construct the info
++ */
++
++ if ((bootline = getenv ("bootargs")) != NULL) {
++ memcpy ((void *) bootaddr, bootline, MAX(strlen(bootline), 512));
++ flush_cache (bootaddr, MAX(strlen(bootline), 512));
++ } else {
++ /* there is no command line! */
++ memset ((void *) bootaddr, 0, 512);
++ }
++
++#ifdef CONFIG_BUILD_BIN_PARAM
++ build_bin_image_parameters(bootaddr);
++#endif
++
++ /*
++ * If the data at the load address is an elf image, then
++ * treat it like an elf image. Otherwise, assume that it is a
++ * binary image
++ */
++
++ printf ("## Loading WindowsCE binary image from 0x%04x, please wait...\n", addr);
++
++ if (valid_bin_image (addr)) {
++ addr = load_bin_image (addr+NUM_SYNCBYTES);
++ } else {
++ puts ("## Not an WinCE BIN image, assuming absolute binary image (.nb0)\n");
++ /* leave addr as load_addr */
++ }
++
++ if (addr==(unsigned long)0xFFFFFFFF) {
++ printf ("## ABORTING: wrong CRC\n");
++ return 1;
++ }
++
++ PRINTF ("## Using bootline (@ 0x%lx): %s\n", bootaddr,
++ (char *) bootaddr);
++ printf ("## Starting WindowsCE at 0x%04x ...\n", addr);
++
++
++
++ ((void (*)(void)) addr) ();
++
++ /* we should NEVER get here! */
++
++ puts ("## WindowsCE terminated\n");
++ return 1;
++}
++
++/* ======================================================================
++ * Determine if a valid BIN image exists at the given memory location.
++ * Looks at the BIN header magic field.
++ * ====================================================================== */
++int valid_bin_image (unsigned long addr)
++{
++ struct bin_sync* sync;
++
++ printf(" Determine if a valid BIN image exists at the given memory location 0x%08X.\n",addr);
++ printf(" Looks at the BIN header magic field with value %s \n",SYNC_MAGIC);
++
++ sync = (struct bin_sync*) addr;
++
++ if (strncmp(sync->syncbytes, SYNC_MAGIC, NUM_SYNCBYTES) == 0)
++ {
++ printf("Strings matched \n");
++ return 1;
++ }
++ else
++ {
++ printf("Strings NOT matched \n");
++ return 0;
++ }
++}
++
++
++/* ======================================================================
++ * A simple WinCE BIN loader, assumes the image is valid, returns the
++ * entry point address.
++ * ====================================================================== */
++unsigned long load_bin_image (unsigned long addr)
++{
++ int i;
++ unsigned long current_addr;
++ unsigned long dest_addr;
++ unsigned long current_dest_addr;
++ struct bin_header header;
++ struct bin_record record;
++ int record_num;
++ long int record_checksum;
++
++ printf(" A simple WinCE BIN loader, assumes the image is valid, returns the \n");
++ printf(" entry point address. \n");
++
++
++ /* read bin header */
++
++ memcpy((char*)&header, (char*)addr, sizeof(header));
++
++ PRINTF("#### .bin image header data:\n");
++ PRINTF("#### start 0x%04x, size 0x%04x\n", header.img_start,
++ header.img_length);
++ current_addr = addr + sizeof(struct bin_header);
++ current_dest_addr = header.img_start;
++
++ PRINTF("addr 0x%08X \n",addr);
++ PRINTF("current_addr 0x%08X \n",current_addr);
++ PRINTF("current_dest_addr 0x%08X \n",current_dest_addr);
++
++
++ record_num = 0;
++ while (1) {
++ /* read record */
++ memcpy((char*)&record, (char*)current_addr, sizeof(record));
++
++ PRINTF("#### .bin record #%d:\n", record_num);
++ PRINTF("#### start 0x%04x, size 0x%04x, chksum 0x%04x\n",
++ record.address, record.length, record.checksum);
++
++ if (record.address==0) {
++ PRINTF("#### address==0->quitting!\n");
++ break;
++ }
++
++ current_addr += BASE_BIN_RECORD_SIZE;
++
++#if 0
++ /* checksum verification */
++ record_checksum = 0;
++ for (i=0; i<record.length; i++) {
++ record_checksum += ((char*)(current_addr))[i];
++ }
++
++ if (record_checksum!=record.checksum) {
++ printf("wrong checksum (having 0x%04X!=0x%04X)\n", record_checksum,
++ record.checksum);
++ return 0xFFFFFFFF;
++ }
++
++#endif
++ /* clear uninitialized memory */
++ PRINTF(" clear uninitialized memory \n");
++ PRINTF("current_addr 0x%08X \n",current_addr);
++ PRINTF("current_dest_addr 0x%08X \n",current_dest_addr);
++ PRINTF("record.address 0x%08X \n",record.address);
++ //memset((char*)current_dest_addr+PHYS_SDRAM_1, 0, record.address-current_dest_addr);
++ memset((char *)((record.address&0xF0000000)+PHYS_SDRAM_1), 0, record.length);
++ memcpy((char *)((record.address&0xF0000000)+PHYS_SDRAM_1), (char *)current_addr, record.length);
++ PRINTF(" memory copy done \n");
++
++
++ current_addr += record.length;
++
++ current_dest_addr = record.address + record.length;
++
++ record_num++;
++
++ putc ('.');
++ }
++
++ printf("\n");
++
++ //printf("Entry Point Address is 0X%08X \n",(unsigned long)(header.img_start + PHYS_SDRAM_1));
++ printf("Entry Point Address is 0X%08X \n",(unsigned long)(record.length + PHYS_SDRAM_1));
++ //if(((header.img_start + PHYS_SDRAM_1) & 0xF0000000) != 0xA0000000)
++ if(((record.length + PHYS_SDRAM_1) & 0xF0000000) != 0xA0000000)
++ {
++ //return ((header.img_start&0x0FFFFFFF)+PHYS_SDRAM_1);
++ return ((record.length&0x0FFFFFFF)+PHYS_SDRAM_1);
++ }
++ else
++ {
++ return header.img_start + PHYS_SDRAM_1;
++ }
++}
++
++/* ====================================================================== */
++
++U_BOOT_CMD(
++ bootwince, 2, 0, do_bootwince,
++ "bootwince - Boot Windows CE from a binary (.bin) image\n",
++ " [address] - load address of Windows CE BIN image.\n"
++);
++#endif /* CFG_CMD_BIN */
++
++
+diff -Naur u-boot-2008.10_original/common/cmd_bootce.c u-boot-2008.10/common/cmd_bootce.c
+--- u-boot-2008.10_original/common/cmd_bootce.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_bootce.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,1375 @@
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include <wince.h>
++#define DEBUG
++
++DECLARE_GLOBAL_DATA_PTR; /* defines global data structure pointer */
++
++
++/*/////////////////////////////////////////////////////////////////////////////////////////////*/
++/* Local macro */
++
++/* Memory macro */
++
++/* #define CE_RAM_BASE 0x80100000 */
++/* #define CE_WINCE_VRAM_BASE 0x80000000 */
++/* #define CE_FIX_ADDRESS(a) (((a) - CE_WINCE_VRAM_BASE) + CE_RAM_BASE) */
++#define CE_FIX_ADDRESS(a) (a)
++
++/* Bin image parse states */
++
++#define CE_PS_RTI_ADDR 0
++#define CE_PS_RTI_LEN 1
++#define CE_PS_E_ADDR 2
++#define CE_PS_E_LEN 3
++#define CE_PS_E_CHKSUM 4
++#define CE_PS_E_DATA 5
++
++/* Min/max */
++
++#define CE_MIN(a, b) (((a) < (b)) ? (a) : (b))
++#define CE_MAX(a, b) (((a) > (b)) ? (a) : (b))
++
++// Macro string
++
++#define _STRMAC(s) #s
++#define STRMAC(s) _STRMAC(s)
++
++
++
++
++
++
++
++///////////////////////////////////////////////////////////////////////////////////////////////
++// Global data
++
++static ce_bin __attribute__ ((aligned (32))) g_bin;
++static ce_net __attribute__ ((aligned (32))) g_net;
++
++
++///////////////////////////////////////////////////////////////////////////////////////////////
++// Local proto
++
++
++
++
++///////////////////////////////////////////////////////////////////////////////////////////////
++// Implementation
++
++int ce_bin_load(void* image, int imglen)
++{
++ printf("FUNC %s() LINE %d: Calling ce_init_bin() \n",__FUNCTION__,__LINE__);
++ ce_init_bin(&g_bin, image);
++
++ g_bin.dataLen = imglen;
++
++ printf("FUNC %s() LINE %d: Calling ce_parse_bin() \n",__FUNCTION__,__LINE__);
++ if (ce_parse_bin(&g_bin) == CE_PR_EOF)
++ {
++ ce_prepare_run_bin(&g_bin);
++ return 1;
++ }
++
++ return 0;
++}
++
++int ce_is_bin_image(void* image, int imglen)
++{
++ if (imglen < CE_BIN_SIGN_LEN)
++ {
++ printf("FUNC %s() : LINE %d : imglen is less than %d bytes (i.e len of bin signature) \n",__FUNCTION__,__LINE__);
++ return 0;
++ }
++ else
++ {
++ }
++
++ if (memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0)
++ {
++ printf("FUNC %s() : image has valid bin signature \n",__FUNCTION__,__LINE__);
++ return 1;
++ }
++ else
++ {
++ printf("FUNC %s() : image has INVALID bin signature \n",__FUNCTION__,__LINE__);
++ return 0;
++ }
++}
++
++void ce_bin_init_parser(void)
++{
++ // No buffer address by now, will be specified
++ // latter by the ce_bin_parse_next routine
++
++ ce_init_bin(&g_bin, NULL);
++}
++
++int ce_bin_parse_next(void* parseBuffer, int len)
++{
++ int rc;
++
++ g_bin.data = (unsigned char*)parseBuffer;
++ g_bin.dataLen = len;
++ rc = ce_parse_bin(&g_bin);
++
++ if (rc == CE_PR_EOF)
++ {
++ ce_prepare_run_bin(&g_bin);
++ }
++
++ return rc;
++}
++
++void ce_init_bin(ce_bin* bin, unsigned char* dataBuffer)
++{
++ memset(bin, 0, sizeof(ce_bin));
++
++ bin->data = dataBuffer;
++ bin->parseState = CE_PS_RTI_ADDR;
++ if(bin->rtiPhysAddr !=0xa0100000)
++ {
++ printf("FUNC %s() LINE %d: Actual bin->triPhysAddr is 0x%08X \n",__FUNCTION__,__LINE__,bin->rtiPhysAddr);
++ bin->rtiPhysAddr = 0xa0100000;
++ printf("FUNC %s() LINE %d: Modified bin->triPhysAddr is 0x%08X \n",__FUNCTION__,__LINE__,bin->rtiPhysAddr);
++ }
++ bin->parsePtr = (unsigned char*)&bin->rtiPhysAddr;
++ printf("FUNC %s() LINE %d: bin->parsePtr is 0x%08X \n",__FUNCTION__,__LINE__,bin->parsePtr);
++}
++
++int ce_parse_bin(ce_bin* bin)
++{
++ unsigned char* pbData = bin->data;
++ int pbLen = bin->dataLen;
++ int copyLen;
++
++ #ifdef DEBUG
++ printf("starting ce image parsing:\n\tbin->binLen: 0x%08X\n", bin->binLen);
++ printf("\tpbData: 0x%08X pbLEN: 0x%08X\n", pbData, pbLen);
++ #endif
++
++ if (pbLen)
++ {
++ if (bin->binLen == 0)
++ {
++ // Check for the .BIN signature first
++ printf("FUNC %s() : LINE %d: bin->binLen is 0 . Check for the .BIN signature first \n",__FUNCTION__,__LINE__);
++
++ if (!ce_is_bin_image(pbData, pbLen))
++ {
++ printf("Error: Invalid or corrupted .BIN image!\n");
++
++ return CE_PR_ERROR;
++ }
++
++ printf("Loading Windows CE .BIN image ...\n");
++
++ // Skip signature
++
++ pbLen -= CE_BIN_SIGN_LEN;
++ pbData += CE_BIN_SIGN_LEN;
++ printf("FUNC %s() : LINE %d : pbLen is 0x%08X ,pbData is 0x%08X \n",__FUNCTION__,__LINE__,pbLen,pbData);
++ }
++
++ while (pbLen)
++ {
++ switch (bin->parseState)
++ {
++ case CE_PS_RTI_ADDR:
++ case CE_PS_RTI_LEN:
++ case CE_PS_E_ADDR:
++ case CE_PS_E_LEN:
++ case CE_PS_E_CHKSUM:
++
++ copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, pbLen);
++
++ memcpy(&bin->parsePtr[ bin->parseLen ], pbData, copyLen);
++
++ bin->parseLen += copyLen;
++ pbLen -= copyLen;
++ pbData += copyLen;
++
++ if (bin->parseLen == sizeof(unsigned int))
++ {
++ if (bin->parseState == CE_PS_RTI_ADDR)
++ {
++ bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
++ }
++ else if (bin->parseState == CE_PS_E_ADDR)
++ {
++ if (bin->ePhysAddr)
++ {
++ bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
++ }
++ }
++
++ bin->parseState ++;
++ bin->parseLen = 0;
++ bin->parsePtr += sizeof(unsigned int);
++
++ if (bin->parseState == CE_PS_E_DATA)
++ {
++ if (bin->ePhysAddr)
++ {
++ bin->parsePtr = (unsigned char*)(bin->ePhysAddr);
++ bin->parseChkSum = 0;
++ }
++ else
++ {
++ // EOF
++
++ pbLen = 0;
++ bin->endOfBin = 1;
++ }
++ }
++ }
++
++ break;
++
++ case CE_PS_E_DATA:
++
++ if (bin->ePhysAddr)
++ {
++ copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, pbLen);
++ bin->parseLen += copyLen;
++ pbLen -= copyLen;
++ if((bin->parsePtr) !=0xa0000000)
++ {
++ unsigned int temp;
++ temp = (unsigned int)(bin->parsePtr);
++ temp &= ~0xF0000000;
++ temp |= 0xa0000000;
++ bin->parsePtr = temp;
++
++ }
++
++
++ #ifdef DEBUG
++ printf("copy %d bytes from: 0x%08X to: 0x%08X\n", copyLen, pbData, bin->parsePtr);
++ #endif
++ while (copyLen --)
++ {
++ bin->parseChkSum += *pbData;
++ *bin->parsePtr ++ = *pbData ++;
++ }
++
++ if (bin->parseLen == bin->ePhysLen)
++ {
++ printf("Section [%02d]: address 0x%08X, size 0x%08X, checksum %s\n",
++ bin->secion,
++ bin->ePhysAddr,
++ bin->ePhysLen,
++ (bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
++
++ if (bin->eChkSum != bin->parseChkSum)
++ {
++ // Checksum error!
++
++ printf("Error: Checksum error, corrupted .BIN file!\n");
++
++ bin->binLen = 0;
++
++ return CE_PR_ERROR;
++ }
++
++ bin->secion ++;
++ bin->parseState = CE_PS_E_ADDR;
++ bin->parseLen = 0;
++ bin->parsePtr = (unsigned char*)(&bin->ePhysAddr);
++ }
++ }
++ else
++ {
++ bin->parseLen = 0;
++ bin->endOfBin = 1;
++ pbLen = 0;
++ }
++
++ break;
++ }
++ }
++ }
++
++ if (bin->endOfBin)
++ {
++ // Find entry point
++
++ if (!ce_lookup_ep_bin(bin))
++ {
++ printf("Error: entry point not found!\n");
++
++ bin->binLen = 0;
++
++ return CE_PR_ERROR;
++ }
++
++ if((bin->eEntryPoint & 0xa0000000) != 0xa0000000)
++ {
++ unsigned int temp;
++ printf("Actual EntryPoint is 0x%08X \n",bin->eEntryPoint);
++ temp = (unsigned int)(bin->eEntryPoint);
++ temp &= ~0xF0000000;
++ temp |= 0xa0000000;
++ bin->eEntryPoint = temp;
++ }
++ if((bin->eEntryPoint & 0xa0101000) != 0xa0101000)
++ {
++ bin->eEntryPoint = 0xa0101000;
++ }
++ if((bin->rtiPhysAddr & 0xa0100000) != 0xa0100000)
++ {
++ bin->rtiPhysAddr = 0xa0100000;
++ }
++
++ printf("Entry point: 0x%08X, address range: 0x%08X-0x%08X\n",
++ bin->eEntryPoint,
++ bin->rtiPhysAddr,
++ bin->rtiPhysAddr + bin->rtiPhysLen);
++
++ return CE_PR_EOF;
++ }
++
++ // Need more data
++
++ bin->binLen += bin->dataLen;
++
++ return CE_PR_MORE;
++}
++
++
++
++
++
++
++
++void ce_prepare_run_bin(ce_bin* bin)
++{
++ ce_driver_globals* drv_glb;
++ char *e, *s;
++ char tmp[64];
++ int i;
++
++
++ // Clear os RAM area (if needed)
++
++ //if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT)
++ {
++
++
++ #ifdef DEBUG
++ printf("cleaning memory from 0x%08X to 0x%08X\n", bin->eRamStart, bin->eRamStart + bin->eRamLen);
++ #endif
++ printf("Preparing clean boot ... ");
++#if 0 // Added by Tharma
++ memset((void*)bin->eRamStart, 0, bin->eRamLen);
++#endif
++ printf("ok\n");
++ }
++
++ // Prepare driver globals (if needed)
++
++ if (bin->eDrvGlb)
++ {
++ drv_glb = (ce_driver_globals*)bin->eDrvGlb;
++
++ // Fill out driver globals
++
++ memset(drv_glb, 0, sizeof(ce_driver_globals));
++
++ // Signature
++
++ drv_glb->signature = DRV_GLB_SIGNATURE;
++
++ // No flags by now
++
++ drv_glb->flags = 0;
++
++ /* Local ethernet MAC address */
++ i = getenv_r ("ethaddr", tmp, sizeof (tmp));
++ s = (i > 0) ? tmp : 0;
++
++ for (i = 0; i < 6; ++i) {
++ drv_glb->macAddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
++ if (s)
++ s = (*e) ? e + 1 : e;
++ }
++
++
++ #ifdef DEBUG
++ printf("got MAC address %02X:%02X:%02X:%02X:%02X:%02X from environment\n", drv_glb->macAddr[0],drv_glb->macAddr[1],drv_glb->macAddr[2],drv_glb->macAddr[3],drv_glb->macAddr[4],drv_glb->macAddr[5]);
++ #endif
++
++ /* Local IP address */
++ drv_glb->ipAddr=(unsigned int)getenv_IPaddr("ipaddr");
++ #ifdef DEBUG
++ printf("got IP address ");
++ print_IPaddr((IPaddr_t)drv_glb->ipAddr);
++ printf(" from environment\n");
++ #endif
++
++ /* Subnet mask */
++ drv_glb->ipMask=(unsigned long)getenv_IPaddr("netmask");
++ #ifdef DEBUG
++ printf("got IP mask ");
++ print_IPaddr((IPaddr_t)drv_glb->ipMask);
++ printf(" from environment\n");
++ #endif
++
++ /* Gateway config */
++ drv_glb->ipGate=(unsigned long)getenv_IPaddr("gatewayip");
++ #ifdef DEBUG
++ printf("got gateway address ");
++ print_IPaddr((IPaddr_t)drv_glb->ipGate);
++ printf(" from environment\n");
++ #endif
++
++
++
++
++
++ // EDBG services config
++
++ memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
++
++
++
++
++ }
++
++}
++
++
++int ce_lookup_ep_bin(ce_bin* bin)
++{
++ ce_rom_hdr* header;
++ ce_toc_entry* tentry;
++ e32_rom* e32;
++ unsigned int i;
++
++ // Check image Table Of Contents (TOC) signature
++ printf(" Check image Table Of Contents (TOC) signature \n");
++
++ if (*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
++ {
++ // Error: Did not find image TOC signature!
++ printf("Error: Did not find image TOC signature! \n");
++ printf("Acutal Sign 0x%08X \n",*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET));
++ printf("Expected Sign 0x%08X \n",ROM_SIGNATURE);
++
++ //return 0;
++ return 1;
++ }
++
++
++ // Lookup entry point
++
++ printf(" Lookup entry point \n");
++
++ header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET + sizeof(unsigned int)));
++ tentry = (ce_toc_entry*)(header + 1);
++
++ for (i = 0; i < header->nummods; i ++)
++ {
++ // Look for 'nk.exe' module
++ printf(" i= %d . Look for 'nk.exe' module \n",i);
++
++ if (strcmp((char*)CE_FIX_ADDRESS(tentry[ i ].fileName), "nk.exe") == 0)
++ {
++ // Save entry point and RAM addresses
++ printf(" Save entry point and RAM addresses \n");
++
++ e32 = (e32_rom*)CE_FIX_ADDRESS(tentry[ i ].e32Offset);
++
++ bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) + e32->e32_entryrva;
++ bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
++ bin->eRamLen = header->ramEnd - header->ramStart;
++
++ // Save driver_globals address
++ // Must follow RAM section in CE config.bib file
++ //
++ // eg.
++ //
++ // RAM 80900000 03200000 RAM
++ // DRV_GLB 83B00000 00001000 RESERVED
++ //
++
++ bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd);
++
++ return 1;
++ }
++ }
++
++ // Error: Did not find 'nk.exe' module
++
++ printf(" Error: Did not find 'nk.exe' module \n");
++
++ return 0;
++}
++
++
++
++
++typedef void (*CeEntryPointPtr)(void);
++
++
++
++void ce_run_bin(ce_bin* bin)
++{
++ CeEntryPointPtr EnrtryPoint;
++
++ printf("Launching Windows CE ...\n");
++
++
++ EnrtryPoint = (CeEntryPointPtr)bin->eEntryPoint;
++
++ EnrtryPoint();
++
++}
++
++int ce_boot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ unsigned long addr;
++ unsigned long image_size;
++ unsigned char *s;
++
++
++ if (argc < 2) {
++ printf ("myUsage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ addr = simple_strtoul(argv[1], NULL, 16);
++ image_size = 0x7fffffff; /* actually we do not know the image size */
++
++ printf ("## Booting Windows CE Image from address 0x%08lX ...\n", addr);
++
++
++ /* check if there is a valid windows CE image */
++ if (ce_is_bin_image((void *)addr, image_size))
++ {
++ printf("FUNC %s() : LINE %d : Calling ce_bin_load() \n",__FUNCTION__,__LINE__);
++ if (!ce_bin_load((void*)addr, image_size))
++ {
++ /* Ops! Corrupted .BIN image! */
++ /* Handle error here ... */
++ printf("corrupted .BIN image !!!\n");
++ return 1;
++
++ }
++ if ((s = getenv("autostart")) != NULL) {
++ if (*s == 'n') {
++ /*
++ * just use bootce to load the image to SDRAM;
++ * Do not start it automatically.
++ */
++ return 0;
++ }
++ }
++ printf("FUNC %s() : LINE %d : Calling ce_run_bin() to start the image \n",__FUNCTION__,__LINE__);
++ ce_run_bin(&g_bin); /* start the image */
++
++ } else {
++ printf("Image seems to be no valid Windows CE image !\n");
++ return 1;
++
++ }
++ return 1; /* never reached - just to keep compiler happy */
++
++
++}
++
++
++
++U_BOOT_CMD(
++ bootce, 2, 0, ce_boot,
++ "bootce\t- Boot a Windows CE image from memory \n",
++ "[args..]\n"
++ "\taddr\t\t-boot image from address addr\n"
++);
++
++
++
++#if 1
++static void wince_handler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
++{
++
++
++ NetState = NETLOOP_SUCCESS; /* got input - quit net loop */
++ if(!memcmp(g_net.data + g_net.align_offset, gd->bd->bi_enetaddr, 6)) {
++ g_net.got_packet_4me=1;
++ g_net.dataLen=len;
++ } else {
++ g_net.got_packet_4me=0;
++ return;
++ }
++
++ if(1) {
++ g_net.srvAddrRecv.sin_port = ntohs(*((unsigned short *)(g_net.data + ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + g_net.align_offset)));
++ NetCopyIP(&g_net.srvAddrRecv.sin_addr, g_net.data + ETHER_HDR_SIZE + g_net.align_offset + 12);
++ memcpy(NetServerEther, g_net.data + g_net.align_offset +6, 6);
++
++ #if 0
++ printf("received packet: buffer 0x%08X Laenge %d \n", (unsigned long) pkt, len);
++ printf("from ");
++ print_IPaddr(g_net.srvAddrRecv.sin_addr);
++ printf(", port: %d\n", g_net.srvAddrRecv.sin_port);
++
++
++
++ ce_dump_block(pkt, len);
++
++ printf("Headers:\n");
++ ce_dump_block(pkt - ETHER_HDR_SIZE - IP_HDR_SIZE, ETHER_HDR_SIZE + IP_HDR_SIZE);
++ printf("\n\nmy port should be: %d\n", ntohs(*((unsigned short *)(g_net.data + ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + g_net.align_offset +2))));
++ #endif
++ }
++
++}
++
++
++
++/* returns packet lengt if successfull */
++int ce_recv_packet(char *buf, int len, struct sockaddr_in *from, struct sockaddr_in *local, struct timeval *timeout){
++
++ int rxlength;
++ ulong time_started;
++
++
++
++ g_net.got_packet_4me=0;
++ time_started = get_timer(0);
++
++
++ NetRxPackets[0] = (uchar *)buf;
++ NetSetHandler(wince_handler);
++
++ while(1) {
++ rxlength=eth_rx();
++ if(g_net.got_packet_4me)
++ return g_net.dataLen;
++ /* check for timeout */
++ if (get_timer(time_started) > timeout->tv_sec * CFG_HZ) {
++ return -1;
++ }
++ }
++}
++
++
++
++int ce_recv_frame(ce_net* net, int timeout)
++{
++ struct timeval timeo;
++
++ // Setup timeout
++
++ timeo.tv_sec = timeout;
++ timeo.tv_usec = 0;
++
++ /* Receive UDP packet */
++
++ net->dataLen = ce_recv_packet(net->data+net->align_offset, sizeof(net->data)-net->align_offset, &net->srvAddrRecv, &net->locAddr, &timeo);
++
++ if (net->dataLen < 0)
++ {
++ /* Error! No data available */
++
++ net->dataLen = 0;
++ }
++
++ return net->dataLen;
++}
++
++int ce_process_download(ce_net* net, ce_bin* bin)
++{
++ int ret = CE_PR_MORE;
++
++ if (net->dataLen >= 2)
++ {
++ unsigned short command;
++
++ command = ntohs(*(unsigned short*)(net->data+CE_DOFFSET));
++
++ #ifdef DEBUG
++ printf("command found: 0x%04X\n", command);
++ #endif
++
++ switch (command)
++ {
++ case EDBG_CMD_WRITE_REQ:
++
++ if (!net->link)
++ {
++ // Check file name for WRITE request
++ // CE EShell uses "boot.bin" file name
++
++ /*printf(">>>>>>>> First Frame, IP: %s, port: %d\n",
++ inet_ntoa((in_addr_t *)&net->srvAddrRecv),
++ net->srvAddrRecv.sin_port);*/
++
++ if (strncmp((char*)(net->data +CE_DOFFSET + 2), "boot.bin", 8) == 0)
++ {
++ // Some diag output
++
++ if (net->verbose)
++ {
++ printf("Locked Down download link, IP: ");
++ print_IPaddr(net->srvAddrRecv.sin_addr);
++ printf(", port: %d\n", net->srvAddrRecv.sin_port);
++ }
++
++
++
++
++ if (net->verbose)
++ {
++ printf("Sending BOOTME request [%d] to ", (int)net->secNum);
++ print_IPaddr(net->srvAddrSend.sin_addr);
++ printf("\n");
++ }
++
++
++
++
++ // Lock down EShell download link
++
++ net->locAddr.sin_port = (EDBG_DOWNLOAD_PORT + 1);
++ net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
++ net->srvAddrSend.sin_addr = net->srvAddrRecv.sin_addr;
++ net->link = 1;
++ }
++ else
++ {
++ // Unknown link
++
++ net->srvAddrRecv.sin_port = 0;
++ }
++
++ // Return write ack
++
++ if (net->link)
++ {
++ ce_send_write_ack(net);
++ }
++
++ break;
++ }
++
++ case EDBG_CMD_WRITE:
++
++ /* Fix data len */
++ bin->dataLen = net->dataLen - 4;
++
++ // Parse next block of .bin file
++
++ ret = ce_parse_bin(bin);
++
++ // Request next block
++
++ if (ret != CE_PR_ERROR)
++ {
++ net->blockNum ++;
++
++ ce_send_write_ack(net);
++ }
++
++ break;
++
++ case EDBG_CMD_READ_REQ:
++
++ // Read requests are not supported
++ // Do nothing ...
++
++ break;
++
++ case EDBG_CMD_ERROR:
++
++ // Error condition on the host side
++
++ printf("Error: unknown error on the host side\n");
++
++ bin->binLen = 0;
++ ret = CE_PR_ERROR;
++
++ break;
++ default:
++ printf("unknown command 0x%04X ????\n", command);
++ while(1);
++ }
++
++
++ }
++
++ return ret;
++}
++
++
++
++void ce_init_edbg_link(ce_net* net)
++{
++ /* Initialize EDBG link for commands */
++
++ net->locAddr.sin_port = EDBG_DOWNLOAD_PORT;
++ net->srvAddrSend.sin_port = EDBG_DOWNLOAD_PORT;
++ net->srvAddrRecv.sin_port = 0;
++ net->link = 0;
++}
++
++void ce_process_edbg(ce_net* net, ce_bin* bin)
++{
++ eth_dbg_hdr* header;
++
++
++
++ if (net->dataLen < sizeof(eth_dbg_hdr))
++ {
++ /* Bad packet */
++
++ net->srvAddrRecv.sin_port = 0;
++ return;
++ }
++
++ header = (eth_dbg_hdr*)(net->data + net->align_offset + ETHER_HDR_SIZE + IP_HDR_SIZE);
++
++ if (header->id != EDBG_ID)
++ {
++ /* Bad packet */
++
++ net->srvAddrRecv.sin_port = 0;
++ return;
++ }
++
++ if (header->service != EDBG_SVC_ADMIN)
++ {
++ /* Unknown service */
++
++ return;
++ }
++
++ if (!net->link)
++ {
++ /* Some diag output */
++
++ if (net->verbose)
++ {
++ printf("Locked Down EDBG service link, IP: ");
++ print_IPaddr(net->srvAddrRecv.sin_addr);
++ printf(", port: %d\n", net->srvAddrRecv.sin_port);
++ }
++
++ /* Lock down EDBG link */
++
++ net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
++ net->link = 1;
++ }
++
++ switch (header->cmd)
++ {
++ case EDBG_CMD_JUMPIMG:
++
++ net->gotJumpingRequest = 1;
++
++ if (net->verbose)
++ {
++ printf("Received JUMPING command\n");
++ }
++
++ /* Just pass through and copy CONFIG structure */
++
++ case EDBG_CMD_OS_CONFIG:
++
++ /* Copy config structure */
++
++ memcpy(&bin->edbgConfig, header->data, sizeof(edbg_os_config_data));
++
++ if (net->verbose)
++ {
++ printf("Received CONFIG command\n");
++
++ if (bin->edbgConfig.flags & EDBG_FL_DBGMSG)
++ {
++ printf("--> Enabling DBGMSG service, IP: %d.%d.%d.%d, port: %d\n",
++ (bin->edbgConfig.dbgMsgIPAddr >> 0) & 0xFF,
++ (bin->edbgConfig.dbgMsgIPAddr >> 8) & 0xFF,
++ (bin->edbgConfig.dbgMsgIPAddr >> 16) & 0xFF,
++ (bin->edbgConfig.dbgMsgIPAddr >> 24) & 0xFF,
++ (int)bin->edbgConfig.dbgMsgPort);
++ }
++
++ if (bin->edbgConfig.flags & EDBG_FL_PPSH)
++ {
++ printf("--> Enabling PPSH service, IP: %d.%d.%d.%d, port: %d\n",
++ (bin->edbgConfig.ppshIPAddr >> 0) & 0xFF,
++ (bin->edbgConfig.ppshIPAddr >> 8) & 0xFF,
++ (bin->edbgConfig.ppshIPAddr >> 16) & 0xFF,
++ (bin->edbgConfig.ppshIPAddr >> 24) & 0xFF,
++ (int)bin->edbgConfig.ppshPort);
++ }
++
++ if (bin->edbgConfig.flags & EDBG_FL_KDBG)
++ {
++ printf("--> Enabling KDBG service, IP: %d.%d.%d.%d, port: %d\n",
++ (bin->edbgConfig.kdbgIPAddr >> 0) & 0xFF,
++ (bin->edbgConfig.kdbgIPAddr >> 8) & 0xFF,
++ (bin->edbgConfig.kdbgIPAddr >> 16) & 0xFF,
++ (bin->edbgConfig.kdbgIPAddr >> 24) & 0xFF,
++ (int)bin->edbgConfig.kdbgPort);
++ }
++
++ if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT)
++ {
++ printf("--> Force clean boot\n");
++ }
++ }
++
++ break;
++
++ default:
++ if (net->verbose) {
++ printf("Received unknown command: %08X\n", header->cmd);
++ }
++ return;
++ }
++
++ /* Respond with ack */
++ header->flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
++ net->dataLen = EDBG_DATA_OFFSET;
++ ce_send_frame(net);
++}
++
++int ce_send_write_ack(ce_net* net)
++{
++ unsigned short* wdata;
++ unsigned long aligned_address;
++
++ aligned_address=(unsigned long)net->data+ETHER_HDR_SIZE+IP_HDR_SIZE+net->align_offset;
++
++ wdata = (unsigned short*)aligned_address;
++ wdata[ 0 ] = htons(EDBG_CMD_WRITE_ACK);
++ wdata[ 1 ] = htons(net->blockNum);
++
++ net->dataLen = 4;
++
++ return ce_send_frame(net);
++}
++
++
++
++int ce_send_frame(ce_net* net)
++{
++ /* Send UDP packet */
++ NetTxPacket = (uchar *)net->data + net->align_offset;
++ return NetSendUDPPacket(NetServerEther, net->srvAddrSend.sin_addr, (int)net->srvAddrSend.sin_port, (int)net->locAddr.sin_port, net->dataLen);
++}
++
++
++
++
++
++
++
++int ce_send_bootme(ce_net* net)
++{
++ eth_dbg_hdr* header;
++ edbg_bootme_data* data;
++
++ char *e, *s;
++ int i;
++ unsigned char tmp[64];
++ unsigned char *macp;
++
++ #ifdef DEBUG
++ char *pkt;
++ #endif
++
++
++ /* Fill out BOOTME packet */
++ memset(net->data, 0, PKTSIZE);
++ header = (eth_dbg_hdr*)(net->data +CE_DOFFSET);
++ data = (edbg_bootme_data*)header->data;
++
++ header->id=EDBG_ID;
++ header->service = EDBG_SVC_ADMIN;
++ header->flags = EDBG_FL_FROM_DEV;
++ header->seqNum = net->secNum ++;
++ header->cmd = EDBG_CMD_BOOTME;
++
++ data->versionMajor = 0;
++ data->versionMinor = 0;
++ data->cpuId = EDBG_CPU_TYPE_ARM;
++ data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
++ data->bootFlags = 0;
++ data->downloadPort = 0;
++ data->svcPort = 0;
++
++ macp=(unsigned char *)data->macAddr;
++ /* MAC address from environment*/
++ i = getenv_r ("ethaddr", tmp, sizeof (tmp));
++ s = (i > 0) ? tmp : 0;
++ for (i = 0; i < 6; ++i) {
++ macp[i] = s ? simple_strtoul (s, &e, 16) : 0;
++ if (s)
++ s = (*e) ? e + 1 : e;
++ }
++
++ /* IP address from environment */
++ data->ipAddr = (unsigned int)getenv_IPaddr("ipaddr");
++
++ // Device name string (NULL terminated). Should include
++ // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
++
++ // We will use lower MAC address segment to create device name
++ // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
++
++ strcpy(data->platformId, "Triton");
++ sprintf(data->deviceName, "%s%02X", data->platformId, macp[5]);
++
++
++#ifdef DEBUG
++
++ printf("header->id: %08X\r\n", header->id);
++ printf("header->service: %08X\r\n", header->service);
++ printf("header->flags: %08X\r\n", header->flags);
++ printf("header->seqNum: %08X\r\n", header->seqNum);
++ printf("header->cmd: %08X\r\n\r\n", header->cmd);
++
++ printf("data->versionMajor: %08X\r\n", data->versionMajor);
++ printf("data->versionMinor: %08X\r\n", data->versionMinor);
++ printf("data->cpuId: %08X\r\n", data->cpuId);
++ printf("data->bootmeVer: %08X\r\n", data->bootmeVer);
++ printf("data->bootFlags: %08X\r\n", data->bootFlags);
++ printf("data->svcPort: %08X\r\n\r\n", data->svcPort);
++
++ printf("data->macAddr: %02X-%02X-%02X-%02X-%02X-%02X\r\n",
++ (data->macAddr[0] >> 0) & 0xFF,
++ (data->macAddr[0] >> 8) & 0xFF,
++ (data->macAddr[1] >> 0) & 0xFF,
++ (data->macAddr[1] >> 8) & 0xFF,
++ (data->macAddr[2] >> 0) & 0xFF,
++ (data->macAddr[2] >> 8) & 0xFF);
++
++ printf("data->ipAddr: %d.%d.%d.%d\r\n",
++ (data->ipAddr >> 0) & 0xFF,
++ (data->ipAddr >> 8) & 0xFF,
++ (data->ipAddr >> 16) & 0xFF,
++ (data->ipAddr >> 24) & 0xFF);
++
++ printf("data->platformId: %s\r\n", data->platformId);
++
++ printf("data->deviceName: %s\r\n", data->deviceName);
++
++#endif
++
++
++ // Some diag output ...
++
++ if (net->verbose)
++ {
++ printf("Sending BOOTME request [%d] to ", (int)net->secNum);
++ print_IPaddr(net->srvAddrSend.sin_addr);
++ printf("\n");
++ }
++
++ // Send packet
++
++ net->dataLen = BOOTME_PKT_SIZE;
++
++
++ #ifdef DEBUG
++ printf("\n\n\nStart of buffer: 0x%08X\n", (unsigned long)net->data);
++ printf("Start of ethernet buffer: 0x%08X\n", (unsigned long)net->data+net->align_offset);
++ printf("Start of CE header: 0x%08X\n", (unsigned long)header);
++ printf("Start of CE data: 0x%08X\n", (unsigned long)data);
++
++ pkt = (uchar *)net->data+net->align_offset;
++ printf("\n\npacket to send (ceconnect): \n");
++ for(i=0; i<(net->dataLen+ETHER_HDR_SIZE+IP_HDR_SIZE); i++) {
++ printf("0x%02X ", pkt[i]);
++ if(!((i+1)%16))
++ printf("\n");
++ }
++ printf("\n\n");
++ #endif
++
++ memcpy(NetServerEther, NetBcastAddr, 6);
++
++ return ce_send_frame(net);
++}
++
++
++
++void ce_dump_block(unsigned char *ptr, int length) {
++
++ int i;
++ int j;
++
++ for(i=0; i<length; i++) {
++ if(!(i%16)) {
++ printf("\n0x%08X: ", (unsigned long)ptr + i);
++ }
++
++ printf("0x%02X ", ptr[i]);
++
++ if(!((i+1)%16)){
++ printf(" ");
++ for(j=i-15; j<i; j++){
++ if((ptr[j]>0x1f) && (ptr[j]<0x7f)) {
++ printf("%c", ptr[j]);
++ } else {
++ printf(".");
++ }
++ }
++ }
++
++ }
++
++ printf("\n\n");
++}
++
++
++
++
++
++
++
++
++
++
++void ce_init_download_link(ce_net* net, ce_bin* bin, struct sockaddr_in* host_addr, int verbose)
++{
++ unsigned long aligned_address;
++ /* Initialize EDBG link for download */
++
++
++ memset(net, 0, sizeof(ce_net));
++
++ /* our buffer contains space for ethernet- ip- and udp- headers */
++ /* calucalate an offset that our ce field is aligned to 4 bytes */
++ aligned_address=(unsigned long)net->data; /* this is the start of our physical buffer */
++ aligned_address += (ETHER_HDR_SIZE+IP_HDR_SIZE); /* we need 42 bytes room for headers (14 Ethernet , 20 IPv4, 8 UDP) */
++ net->align_offset = 4-(aligned_address%4); /* want CE header aligned to 4 Byte boundary */
++ if(net->align_offset == 4) {
++ net->align_offset=0;
++ }
++
++ net->locAddr.sin_family = AF_INET;
++ net->locAddr.sin_addr = getenv_IPaddr("ipaddr");
++ net->locAddr.sin_port = EDBG_DOWNLOAD_PORT;
++
++ net->srvAddrSend.sin_family = AF_INET;
++ net->srvAddrSend.sin_port = EDBG_DOWNLOAD_PORT;
++
++ net->srvAddrRecv.sin_family = AF_INET;
++ net->srvAddrRecv.sin_port = 0;
++
++ if (host_addr->sin_addr)
++ {
++ /* Use specified host address ... */
++
++ net->srvAddrSend.sin_addr = host_addr->sin_addr;
++ net->srvAddrRecv.sin_addr = host_addr->sin_addr;
++ }
++ else
++ {
++ /* ... or use default server address */
++
++ net->srvAddrSend.sin_addr = getenv_IPaddr("serverip");
++ net->srvAddrRecv.sin_addr = getenv_IPaddr("serverip");
++ }
++
++ net->verbose = verbose;
++ /* Initialize .BIN parser */
++ ce_init_bin(bin, net->data + CE_DOFFSET + 4);
++
++
++
++ eth_halt();
++
++#ifdef CONFIG_NET_MULTI
++ eth_set_current();
++#endif
++ if (eth_init(gd->bd) < 0) {
++ #ifdef ET_DEBUG
++ puts("ceconnect: failed to init ethernet !\n");
++ #endif
++ eth_halt();
++ return;
++ }
++ #ifdef ET_DEBUG
++ puts("ceconnect: init ethernet done!\n");
++ #endif
++
++
++ memcpy (NetOurEther, gd->bd->bi_enetaddr, 6);
++ NetCopyIP(&NetOurIP, &gd->bd->bi_ip_addr);
++ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
++ NetOurSubnetMask= getenv_IPaddr ("netmask");
++ NetServerIP = getenv_IPaddr ("serverip");
++
++}
++
++
++int ce_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ int i;
++ int verbose, use_timeout;
++ int timeout, recv_timeout, ret;
++ struct sockaddr_in host_ip_addr;
++
++ // -v verbose
++
++ verbose = 0;
++ use_timeout = 0;
++ timeout = 0;
++
++
++ for(i=0;i<argc;i++){
++ if (strcmp(argv[i+1], "-v") == 0){
++ verbose = 1;
++ }
++ }
++
++
++ for(i=0;i<(argc-1);i++){
++ if (strcmp(argv[i+1], "-t") == 0){
++ use_timeout = 1;
++ timeout = simple_strtoul(argv[i+2], NULL, 10);
++ }
++ }
++
++ #ifdef DEBUG
++ printf("verbose=%d, use_timeout=%d, timeout=%d\n", verbose, use_timeout, timeout);
++ #endif
++
++ // Check host IP address (if specified)
++
++ *((unsigned int *)&host_ip_addr) = 0xFFFFFFFF;
++
++
++ // Initialize download link
++
++ ce_init_download_link(&g_net, &g_bin, &host_ip_addr, verbose);
++
++ // Download loop
++
++ while (1)
++ {
++ if (g_net.link)
++ {
++ recv_timeout = 3;
++ }
++ else
++ {
++ recv_timeout = 1;
++
++ if (use_timeout)
++ {
++ if (timeout <= 0)
++ {
++ printf("CELOAD - Canceled, timeout\n");
++ eth_halt();
++ return 1;
++ }
++ } else {
++ /* Try to catch ^C */
++ #ifdef DEBUG
++ puts("try to catch ^C\n");
++ #endif
++ if (ctrlc())
++ {
++ printf("CELOAD - canceled by user\n");
++ eth_halt();
++ return 1;
++ }
++ }
++ #ifdef DEBUG
++ puts("sending broadcast frame bootme\n");
++ #endif
++
++ if (ce_send_bootme(&g_net))
++ {
++ printf("CELOAD - error while sending BOOTME request\n");
++ eth_halt();
++ return 1;
++ }
++ printf("net state is: %d\n", NetState);
++ if (verbose)
++ {
++ if (use_timeout)
++ {
++ printf("Waiting for connection, timeout %d sec\n", timeout);
++ }
++ else
++ {
++ printf("Waiting for connection, enter ^C to abort\n");
++ }
++ }
++ }
++
++ // Try to receive frame
++
++ if (ce_recv_frame(&g_net, recv_timeout))
++ {
++ // Process received data
++
++ ret = ce_process_download(&g_net, &g_bin);
++
++ if (ret != CE_PR_MORE)
++ {
++ break;
++ }
++ }
++ else if (use_timeout)
++ {
++ timeout -= recv_timeout;
++ }
++ }
++
++ if (g_bin.binLen)
++ {
++ // Try to receive edbg commands from host
++
++ ce_init_edbg_link(&g_net);
++
++ if (verbose)
++ {
++ printf("Waiting for EDBG commands ...\n");
++ }
++
++ while (ce_recv_frame(&g_net, 3))
++ {
++ ce_process_edbg(&g_net, &g_bin);
++ }
++
++ // Prepare WinCE image for execution
++
++ ce_prepare_run_bin(&g_bin);
++
++ // Launch WinCE, if necessary
++
++ if (g_net.gotJumpingRequest)
++ {
++ ce_run_bin(&g_bin);
++ }
++ }
++ eth_halt();
++ return 0;
++}
++
++
++
++
++
++
++
++U_BOOT_CMD(
++ ceconnect, 2, 1, ce_load,
++ "ceconnect - Set up a connection to the CE host PC over TCP/IP and download the run-time image\n",
++ "ceconnect [-v] [-t <timeout>]\n"
++ " -v verbose operation\n"
++ " -t <timeout> - max wait time (#sec) for the connection\n"
++);
++
++#endif
++
++/* CFG_CMD_WINCE */
+diff -Naur u-boot-2008.10_original/common/cmd_cpuspeed.c u-boot-2008.10/common/cmd_cpuspeed.c
+--- u-boot-2008.10_original/common/cmd_cpuspeed.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_cpuspeed.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,488 @@
++#include <common.h>
++#include <command.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++extern int do_pwrread (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++extern int do_pwrwrite (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++extern int pwr_i2c_reg_write(uchar chip, uchar reg, uchar val);
++extern uchar pwr_i2c_reg_read (uchar chip, uchar reg);
++
++
++#define TPS65020_CHIP_ADDR 0x48 // 7bit Address = 100 1000
++
++#define CLKCFG_TURBO_MODE (1 << 0)
++#define CLKCFG_FREQUENCY_CHANGE (1 << 1)
++#define CLKCFG_HALF_TURBO_MODE (1 << 2)
++#define CLKCFG_FAST_BUS_MODE (1 << 3)
++
++#define CCCR_2N_MASK (0xF << 7)
++#define PMIC_READ_SINGLE_REG 0x1000
++#define PMIC_WRITE_SINGLE_REG 0x1001
++#define PMIC_SET_CORE_VOLTAGE 0x1002
++#define PMIC_GET_CORE_VOLTAGE 0x1003
++#define PMIC_SET_CORE_FREQUENCY 0x1004
++#define PMIC_GET_CORE_FREQUENCY 0x1005
++#define CORE_FREQ_104M 104
++#define CORE_FREQ_208M 208
++#define CORE_FREQ_312M 312
++#define CORE_FREQ_416M 416
++#define CORE_FREQ_520M 520
++#define CORE_FREQ_624M 624
++#define CCCR_L_FIELD (0)
++#define CCCR_2N_FIELD (7)
++#define CCCR_A_FIELD (25)
++
++#define CCCR_L_VALUE_FOR_104M 8
++#define CCCR_L_VALUE_FOR_208M 16
++#define CCCR_L_VALUE_FOR_312M 16
++#define CCCR_L_VALUE_FOR_416M 16
++#define CCCR_L_VALUE_FOR_520M 16
++
++#define CCCR_2N_VALUE_FOR_104M 2
++#define CCCR_2N_VALUE_FOR_208M 2
++#define CCCR_2N_VALUE_FOR_312M 3
++#define CCCR_2N_VALUE_FOR_416M 4
++#define CCCR_2N_VALUE_FOR_520M 5
++
++#ifdef MEMCLK208
++#warning "MEMCLK is 208"
++#define CCCR_A_VALUE_FOR_104M 1
++#define CCCR_A_VALUE_FOR_208M 1
++#define CCCR_A_VALUE_FOR_312M 1
++#define CCCR_A_VALUE_FOR_416M 1
++#define CCCR_A_VALUE_FOR_520M 1
++#elif defined(MEMCLK104)
++#warning "MEMCLK is 104"
++#define CCCR_A_VALUE_FOR_104M 0
++#define CCCR_A_VALUE_FOR_208M 0
++#define CCCR_A_VALUE_FOR_312M 0
++#define CCCR_A_VALUE_FOR_416M 0
++#define CCCR_A_VALUE_FOR_520M 0
++#endif
++
++#define CON_CTRL_GO (1 << 7)
++#define CON_CTRL_CORE_ADJ (1 << 6)
++#define DEFCORE_VALUE_FOR_1P15V 0x0E
++#define DEFCORE_VALUE_FOR_1P25V 0x12
++#define DEFCORE_VALUE_FOR_1P35V 0x16
++#define DEFCORE_VALUE_FOR_1P45V 0x1A
++#define DEFCORE_VALUE_FOR_1P55V 0x1E
++
++#define VERSION_REG_OFFSET 0x00
++#define PGOODZ_REG_OFFSET 0x01
++#define MASK_REG_OFFSET 0x02
++#define REG_CTRL_REG_OFFSET 0x03
++#define CON_CTRL_REG_OFFSET 0x04
++#define CON_CTRL2_REG_OFFSET 0x05
++#define DEFCORE_REG_OFFSET 0x06
++#define DEFSLEW_REG_OFFSET 0x07
++#define LDO_CTRL_REG_OFFSET 0x08
++
++#define CORE_VOLT_1P15V 115
++#define CORE_VOLT_1P25V 125
++#define CORE_VOLT_1P35V 135
++#define CORE_VOLT_1P45V 145
++#define CORE_VOLT_1P55V 155
++
++int do_cpuspeed (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++U_BOOT_CMD(
++ cpuspeed, 3, 1, do_cpuspeed,
++ "cpuspeed get - Getting the CPUSPEED of PXA270 \n cpuspeed set <speed_in_MHz> - Setting the CPUSPEED of PXA270 \n",
++ "Usage: cpuspeed get (or) cpuspeed set 104 (or) cpuspeed set 208 (or) cpuspeed set 312 cpuspeed set 416 (or) cpuspeed 520 \n"
++);
++
++
++int set_change_freq_bit_in_ckcfg(void)
++{
++ int ret =0;
++ int clkcfg_data =0;
++ /* read from CLKCFG register */
++ asm ("mrc p14, 0, %0, c6, c0, 0":"=r" (clkcfg_data));
++
++ if((clkcfg_data & CLKCFG_TURBO_MODE) == CLKCFG_TURBO_MODE)
++ {
++ clkcfg_data |= CLKCFG_FREQUENCY_CHANGE;
++ }
++ else
++ {
++ clkcfg_data |= (CLKCFG_FREQUENCY_CHANGE | CLKCFG_TURBO_MODE);
++ }
++ /* write into CLKCFG register */
++ asm ("mcr p14, 0, %0, c6, c0, 0": :"r" (clkcfg_data));
++
++ return ret;
++}
++
++
++int get_core_voltage(void)
++{
++ int core_volt=0;
++
++ // Read the DEFCORE Register
++ core_volt = (int)pwr_i2c_reg_read(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET);
++ switch(core_volt)
++ {
++ case DEFCORE_VALUE_FOR_1P15V:
++ //printf("core voltage is 1.15V \n");
++ return CORE_VOLT_1P15V;
++ case DEFCORE_VALUE_FOR_1P25V:
++ //printf("core voltage is 1.25V \n");
++ return CORE_VOLT_1P25V;
++ case DEFCORE_VALUE_FOR_1P35V:
++ //printf("core voltage is 1.35V \n");
++ return CORE_VOLT_1P35V;
++ case DEFCORE_VALUE_FOR_1P45V:
++ //printf("core voltage is 1.45V \n");
++ return CORE_VOLT_1P45V;
++ case DEFCORE_VALUE_FOR_1P55V:
++ //printf("core voltage is 1.55V \n");
++ return CORE_VOLT_1P55V;
++ default:
++ break;
++ }
++
++ return core_volt;
++}
++
++
++int set_core_voltage(int core_volt_value)
++{
++ int ret = 0;
++ int con_control_data=0;
++ int cpu_speed = 0;
++ int current_core_volt=0;
++ cpu_speed = get_core_frequency();
++
++ // Read the DEFCORE Register
++ current_core_volt = (int)pwr_i2c_reg_read(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET);
++ if(current_core_volt == core_volt_value)
++ {
++ printf("No Need to change CORE VOLTAGE. Because the Current Core Voltage is same as Required SET CORE VOLTAGE value \n");
++ return ret;
++ }
++
++ switch(core_volt_value)
++ {
++ case CORE_VOLT_1P15V:
++ if(cpu_speed > CORE_FREQ_208M)
++ {
++ ret = -1;
++ break;
++ }
++ con_control_data = pwr_i2c_reg_read(TPS65020_CHIP_ADDR,CON_CTRL2_REG_OFFSET);
++ // Clear the CORE ADJ Field in CON_CTRL Register
++ con_control_data &= ~CON_CTRL_CORE_ADJ;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ // Program the DEFCORE Register
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET,DEFCORE_VALUE_FOR_1P15V);
++ // Set GO Field in CON_CTRL Register
++ con_control_data |= CON_CTRL_GO;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ break;
++ case CORE_VOLT_1P25V:
++ if(cpu_speed > CORE_FREQ_312M)
++ {
++ ret = -1;
++ break;
++ }
++ con_control_data = pwr_i2c_reg_read(TPS65020_CHIP_ADDR,CON_CTRL2_REG_OFFSET);
++ // Clear the CORE ADJ Field in CON_CTRL Register
++ con_control_data &= ~CON_CTRL_CORE_ADJ;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ // Program the DEFCORE Register
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET,DEFCORE_VALUE_FOR_1P25V);
++ // Set GO Field in CON_CTRL Register
++ con_control_data |= CON_CTRL_GO;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ break;
++ case CORE_VOLT_1P35V:
++ if(cpu_speed > CORE_FREQ_416M)
++ {
++ ret = -1;
++ break;
++ }
++ con_control_data = pwr_i2c_reg_read(TPS65020_CHIP_ADDR,CON_CTRL2_REG_OFFSET);
++ // Clear the CORE ADJ Field in CON_CTRL Register
++ con_control_data &= ~CON_CTRL_CORE_ADJ;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ // Program the DEFCORE Register
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET,DEFCORE_VALUE_FOR_1P35V);
++ // Set GO Field in CON_CTRL Register
++ con_control_data |= CON_CTRL_GO;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ break;
++ case CORE_VOLT_1P45V:
++ if(cpu_speed > CORE_FREQ_520M)
++ {
++ ret = -1;
++ break;
++ }
++ con_control_data = pwr_i2c_reg_read(TPS65020_CHIP_ADDR,CON_CTRL2_REG_OFFSET);
++ // Clear the CORE ADJ Field in CON_CTRL Register
++ con_control_data &= ~CON_CTRL_CORE_ADJ;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ // Program the DEFCORE Register
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET,DEFCORE_VALUE_FOR_1P45V);
++ // Set GO Field in CON_CTRL Register
++ con_control_data |= CON_CTRL_GO;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ break;
++ case CORE_VOLT_1P55V:
++ if(cpu_speed > CORE_FREQ_624M)
++ {
++ ret = -1;
++ break;
++ }
++
++ con_control_data = pwr_i2c_reg_read(TPS65020_CHIP_ADDR,CON_CTRL2_REG_OFFSET);
++ // Clear the CORE ADJ Field in CON_CTRL Register
++ con_control_data &= ~CON_CTRL_CORE_ADJ;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ // Program the DEFCORE Register
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, DEFCORE_REG_OFFSET,DEFCORE_VALUE_FOR_1P55V);
++ // Set GO Field in CON_CTRL Register
++ con_control_data |= CON_CTRL_GO;
++ ret = pwr_i2c_reg_write(TPS65020_CHIP_ADDR, CON_CTRL2_REG_OFFSET,con_control_data);
++ break;
++ default:
++ printf(" %d is Unsupported Core Volatge Option \n",core_volt_value);
++ ret = -1;
++ break;
++ }
++
++ return ret;
++}
++
++
++int set_core_frequency(int core_freq_value)
++{
++ int ret = 0;
++ int current_core_freq = 0;
++ int core_volt =0;
++ int cccr_data = 0;
++ int mdrefr_data =0;
++
++ mdrefr_data = MDREFR;
++ //printf("mdrefr_data is 0x%08X \n",mdrefr_data);
++ core_volt = get_core_voltage();
++ current_core_freq = get_core_frequency();
++ if(current_core_freq == core_freq_value)
++ {
++ printf("No Need to change CORE FREQUENCY. Because the Current Core Freq is same as Required SET FREQUENCY value \n");
++ return ret;
++ }
++
++ switch(core_freq_value)
++ {
++ case CORE_FREQ_104M:
++ core_volt = get_core_voltage();
++ if(core_volt < CORE_VOLT_1P15V)
++ {
++ set_core_voltage(CORE_VOLT_1P15V);
++ }
++ cccr_data |= ( (CCCR_A_VALUE_FOR_104M << CCCR_A_FIELD) | (CCCR_2N_VALUE_FOR_104M << CCCR_2N_FIELD) |(CCCR_L_VALUE_FOR_104M << CCCR_L_FIELD));
++ CCCR = cccr_data;
++ set_change_freq_bit_in_ckcfg();
++ MDREFR = mdrefr_data;
++ set_core_voltage(CORE_VOLT_1P15V);
++ break;
++ case CORE_FREQ_208M:
++ core_volt = get_core_voltage();
++ if(core_volt < CORE_VOLT_1P15V)
++ {
++ set_core_voltage(CORE_VOLT_1P15V);
++ }
++ cccr_data |= ( (CCCR_A_VALUE_FOR_208M << CCCR_A_FIELD) | (CCCR_2N_VALUE_FOR_208M << CCCR_2N_FIELD) |(CCCR_L_VALUE_FOR_208M << CCCR_L_FIELD));
++ CCCR = cccr_data;
++ set_change_freq_bit_in_ckcfg();
++ MDREFR = mdrefr_data;
++ set_core_voltage(CORE_VOLT_1P15V);
++ break;
++ case CORE_FREQ_312M:
++ core_volt = get_core_voltage();
++ if(core_volt < CORE_VOLT_1P25V)
++ {
++ set_core_voltage(CORE_VOLT_1P25V);
++ }
++ cccr_data |= ( (CCCR_A_VALUE_FOR_312M << CCCR_A_FIELD) | (CCCR_2N_VALUE_FOR_312M << CCCR_2N_FIELD) |(CCCR_L_VALUE_FOR_312M << CCCR_L_FIELD));
++ CCCR = cccr_data;
++ set_change_freq_bit_in_ckcfg();
++ MDREFR = mdrefr_data;
++ set_core_voltage(CORE_VOLT_1P25V);
++ break;
++ case CORE_FREQ_416M:
++ core_volt = get_core_voltage();
++ if(core_volt < CORE_VOLT_1P35V)
++ {
++ set_core_voltage(CORE_VOLT_1P35V);
++ }
++ cccr_data |= ( (CCCR_A_VALUE_FOR_416M << CCCR_A_FIELD) | (CCCR_2N_VALUE_FOR_416M << CCCR_2N_FIELD) |(CCCR_L_VALUE_FOR_416M << CCCR_L_FIELD));
++ CCCR = cccr_data;
++ set_change_freq_bit_in_ckcfg();
++ MDREFR = mdrefr_data;
++ set_core_voltage(CORE_VOLT_1P35V);
++ break;
++ case CORE_FREQ_520M:
++ core_volt = get_core_voltage();
++ if(core_volt < CORE_VOLT_1P45V)
++ {
++ set_core_voltage(CORE_VOLT_1P45V);
++ }
++ cccr_data |= ( (CCCR_A_VALUE_FOR_520M << CCCR_A_FIELD) | (CCCR_2N_VALUE_FOR_520M << CCCR_2N_FIELD) |(CCCR_L_VALUE_FOR_520M << CCCR_L_FIELD));
++ CCCR = cccr_data;
++ set_change_freq_bit_in_ckcfg();
++ MDREFR = mdrefr_data;
++ set_core_voltage(CORE_VOLT_1P45V);
++ break;
++ default:
++ ret = -1;
++ printf("%d is Unsupported CORE FREQUENCY \n",core_freq_value);
++ }
++
++ //printf("mdrefr_data is 0x%08X \n",mdrefr_data);
++ return ret;
++}
++
++
++int get_core_frequency(void)
++{
++ int core_freq=0;
++ int i=0;
++ int cccr_2N_value=0,L_value=0;
++ int N_value = 0;
++ int cccr_read_data=0;
++ int cpu_speed = 0;
++ cccr_read_data = CCCR;
++ cccr_2N_value = (((cccr_read_data & CCCR_2N_MASK)>>7));
++ //printf("cccr_2N_value is %d \n",cccr_2N_value);
++
++ if(cccr_2N_value <=2)
++ {
++ N_value = 1;
++ //printf(" LINE %d : N_value is %d \n",__LINE__,N_value);
++ }
++ else if(cccr_2N_value >2)
++ {
++ N_value = (cccr_2N_value /2);
++ //printf(" LINE %d : N_value is %d \n",__LINE__,N_value);
++ }
++
++ L_value = cccr_read_data & CCCR_L_MASK;
++ if(L_value <=2)
++ {
++ L_value = 1;
++ //printf(" LINE %d : L_value is %d \n",__LINE__,L_value);
++ }
++ else if((L_value >2) && (L_value<=0x1E))
++ {
++ L_value = L_value;
++ //printf(" LINE %d : L_value is %d \n",__LINE__,L_value);
++ }
++ else
++ {
++ printf("L_value is a reserved value \n");
++ }
++
++ /* read CLKCFG register */
++ asm ("mrc p14, 0, %0, c6, c0, 0":"=r" (i));
++
++ if((i & CLKCFG_TURBO_MODE) == CLKCFG_TURBO_MODE)
++ {
++
++ //printf("TURBO MODE \n");
++ cpu_speed = 13 * L_value * N_value;
++ //printf("cpu_speed is %d \n",cpu_speed);
++ if(cccr_2N_value >2)
++ {
++ if((cccr_2N_value%2)==1)
++ {
++ //printf("cccr_2N_value is an ODD number \n");
++ cpu_speed += ((13 * L_value)/2);
++ //printf("Final cpu_speed is %d \n",cpu_speed);
++ }
++ }
++ }
++ else
++ {
++ //printf("RUN MODE \n");
++ cpu_speed = 13 * L_value;
++ }
++
++ core_freq = cpu_speed;
++ //printf("core_freq is %d \n",core_freq);
++
++ return core_freq;
++}
++
++
++
++int do_cpuspeed (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++ int ret = 0;
++ int core_volt_value=0;
++ int core_freq_value=0;
++
++ if(argc<2)
++ {
++ printf( "Usage: cpuspeed get (or) cpuspeed set 104 (or) cpuspeed set 208 (or) cpuspeed set 312 cpuspeed set 416 (or) cpuspeed 520 \n");
++ return 0;
++ }
++ else if(argc>=2)
++ {
++ //printf("argv[1] is %s \n",argv[1]);
++ if(strcmp(argv[1],"get")==0)
++ {
++ core_freq_value = get_core_frequency();
++ printf("core_freq_value is %d \n",core_freq_value);
++ }
++ else if(strcmp(argv[1],"set")==0)
++ {
++ if(argc>=3)
++ {
++ //printf("argv[2] is %s \n",argv[2]);
++ if(strcmp(argv[2],"104")==0)
++ {
++ core_freq_value = CORE_FREQ_104M;
++ set_core_frequency(core_freq_value);
++ }
++ else if(strcmp(argv[2],"208")==0)
++ {
++ core_freq_value = CORE_FREQ_208M;
++ set_core_frequency(core_freq_value);
++ }
++ else if(strcmp(argv[2],"312")==0)
++ {
++ core_freq_value = CORE_FREQ_312M;
++ set_core_frequency(core_freq_value);
++ }
++ else if(strcmp(argv[2],"416")==0)
++ {
++ core_freq_value = CORE_FREQ_416M;
++ set_core_frequency(core_freq_value);
++ }
++ else if(strcmp(argv[2],"520")==0)
++ {
++ core_freq_value = CORE_FREQ_520M;
++ set_core_frequency(core_freq_value);
++ }
++ else
++ {
++ printf( "Usage: cpuspeed set 104 (or) cpuspeed set 208 (or) cpuspeed set 312 cpuspeed set 416 (or) cpuspeed 520 \n");
++ return 0;
++ }
++ }
++ else
++ {
++ printf( "Usage: cpuspeed set 104 (or) cpuspeed set 208 (or) cpuspeed set 312 cpuspeed set 416 (or) cpuspeed 520 \n");
++ }
++ }
++ else
++ {
++ printf( "Usage: cpuspeed get (or) cpuspeed set 104 (or) cpuspeed set 208 (or) cpuspeed set 312 cpuspeed set 416 (or) cpuspeed 520 \n");
++ return 0;
++ }
++
++ }
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_bootwince.c u-boot-2008.10/common/cmd_econ_bootwince.c
+--- u-boot-2008.10_original/common/cmd_econ_bootwince.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_bootwince.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,217 @@
++
++#include <common.h>
++#include <command.h>
++
++int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++U_BOOT_CMD(
++ bootwince, 2, 0, do_bootwince,
++ "bootwince\t- Boot a Windows CE image from memory (econ code)\n",
++ "[args..]\n"
++ "\taddr\t\t-boot image from address addr\n"
++);
++
++
++int do_parserec (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++U_BOOT_CMD(
++ parserec, 2, 0, do_parserec,
++ "parserec\t- Parse a Windows CE image Records from memory (econ code)\n",
++ "[args..]\n"
++ "\taddr\t\t-boot image from address addr\n"
++);
++
++
++#define KITLOutputDebugString printf
++void (*theWinCEKernel)(void);
++
++typedef unsigned int UINT32;
++typedef unsigned short int UINT16;
++typedef unsigned char UINT8;
++
++#if 0
++void Launch(unsigned int WinCEKernelAddr)
++{
++ theWinCEKernel = (void (*)(void))WinCEKernelAddr;
++ printf("Running WinCE kernel \n");
++ theWinCEKernel();
++}
++#endif
++
++struct RecordHead
++{
++ UINT32 RecAddr;
++ UINT32 RecLen;
++ UINT32 RecChkSum;
++};
++
++void NKLoader(UINT8 *flashaddr)
++{
++ struct RecordHead *rec;
++
++
++ UINT8 *ramaddr;
++ UINT32 phyaddr;
++ int i,j;
++ UINT8 tmp[12];
++ UINT32 * plSrc;
++ int cnt=0;
++ int len;
++
++
++ KITLOutputDebugString("Image start address 0x%x \nThe signature is : ", flashaddr);
++ for(i=0; i<7; i++)
++ KITLOutputDebugString("%c ", *flashaddr++);
++
++ KITLOutputDebugString("\n\rRuntime Image Addr 0x%x\n", *((UINT32*)(flashaddr)));
++ flashaddr+=4;
++ KITLOutputDebugString("\n\rRuntime Image Length 0x%x\n", *((UINT32*)(flashaddr)));
++ flashaddr+=4;
++
++ do
++ {
++ for(i=0;i<12;i++)
++ {
++ tmp[i] = *flashaddr++;
++ }
++ rec=(struct RecordHead *)tmp;
++ if((rec->RecAddr !=0x00000000) && ((rec->RecAddr & 0xa0000000) != 0xa0000000))
++ {
++ printf("Actual RecAddr is 0x%08X \n",rec->RecAddr);
++ rec->RecAddr &= ~(0xF0000000);
++ rec->RecAddr |= (0xa0000000);
++ printf("Modified RecAddr is 0x%08X \n",rec->RecAddr);
++
++ }
++ else if((rec->RecAddr == 0x00000000) && ((rec->RecLen & 0xa0000000) != 0xa0000000))
++ {
++ printf("Actual RecALen is 0x%08X \n",rec->RecLen);
++ rec->RecLen &= ~(0xF0000000);
++ rec->RecLen |= (0xa0000000);
++ printf("Modified RecLen is 0x%08X \n",rec->RecLen);
++ }
++
++ KITLOutputDebugString("Record %d, Addr 0x%x, Length 0x%x\r\n", cnt++, rec->RecAddr, rec->RecLen);
++
++ if(rec->RecAddr==(UINT32)0x0)
++ {
++ phyaddr = (UINT32) ((void *)rec->RecLen);
++ KITLOutputDebugString("Launching at phy address 0x%x\n\r", phyaddr);
++ //Launch(phyaddr);
++ return 0;
++ }
++ else
++ {
++ ramaddr=(UINT8 *)(rec->RecAddr);;
++ len = rec->RecLen;
++ KITLOutputDebugString("copying %d bytes from 0x%x to 0x%x...\r\n",len,flashaddr,ramaddr);
++
++ for(j=0;j<len;j++)
++ {
++ *ramaddr++ = *flashaddr++;
++ }
++ KITLOutputDebugString("Done\n\r");
++ }
++
++ }while(1);
++}
++
++
++
++
++void NKParseRec(UINT8 *flashaddr)
++{
++ struct RecordHead *rec;
++
++
++ UINT8 *ramaddr;
++ UINT32 phyaddr;
++ int i,j;
++ UINT8 tmp[12];
++ UINT32 * plSrc;
++ int cnt=0;
++ int len;
++
++
++ KITLOutputDebugString("Image start address 0x%08x \nThe signature is : ", flashaddr);
++ for(i=0; i<7; i++)
++ {
++ KITLOutputDebugString("flash_addr is 0x%08X , char at this addr is %c \n",(unsigned long)flashaddr, *flashaddr++);
++ }
++
++ printf("\n");
++
++ KITLOutputDebugString("flashaddr is 0x%08X .Runtime Image Addr 0x%x\n",(unsigned long)flashaddr, *((UINT32*)(flashaddr)));
++ flashaddr+=4;
++ KITLOutputDebugString("flashaddr is 0x%08X .Runtime Image Length 0x%x\n",(unsigned long)flashaddr, *((UINT32*)(flashaddr)));
++ flashaddr+=4;
++
++ do
++ {
++ printf("flashaddr is 0x%08X ",(unsigned long)flashaddr);
++ for(i=0;i<12;i++)
++ {
++ tmp[i] = *flashaddr++;
++ }
++ rec=(struct RecordHead *)tmp;
++
++ KITLOutputDebugString("Record No: %d ,Addr 0x%x, Length 0x%x\n", cnt++,rec->RecAddr, rec->RecLen);
++
++ if(rec->RecAddr==(UINT32)0x0)
++ {
++ phyaddr = (UINT32) ((void *)rec->RecLen);
++ KITLOutputDebugString("Launching at phy address 0x%x\n", phyaddr);
++ return 0;
++ }
++ else
++ {
++ ramaddr=(UINT8 *)(rec->RecAddr);
++ //ramaddr=(UINT8 *)0xa0000000;
++ printf("flashaddr is 0x%08X ,ramaddr is 0x%08X \n",(unsigned long)flashaddr,(unsigned long)ramaddr);
++ len = rec->RecLen;
++ for(j=0;j<len;j++)
++ {
++ *ramaddr++ = *flashaddr++;
++ }
++ }
++
++ }while(1);
++}
++
++
++int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ unsigned long addr;
++
++ if (argc < 2) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ addr = simple_strtoul(argv[1], NULL, 16);
++
++ printf ("## Parsing Windows CE Image from address 0x%08lX ...\n", addr);
++
++ NKLoader(addr);
++
++ return 0;
++}
++
++
++int do_parserec (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ unsigned long addr;
++
++ if (argc < 2) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ addr = simple_strtoul(argv[1], NULL, 16);
++
++ printf ("## Parsing Windows CE Image Records from address 0x%08lX ...\n", addr);
++
++ NKParseRec((unsigned char *)addr);
++
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_flash_lock_unlock.c u-boot-2008.10/common/cmd_econ_flash_lock_unlock.c
+--- u-boot-2008.10_original/common/cmd_econ_flash_lock_unlock.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_flash_lock_unlock.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,226 @@
++
++
++
++#include <common.h>
++#include <command.h>
++
++
++#define READ_ARRAY_MODE 0xff
++#define UNLOCK_BLOCK 0x60
++#define UNLOCK_CONFIRM 0xd0
++#define LOCK_BLOCK 0x60
++#define LOCK_CONFIRM 0x01
++#define BLOCK_ERASE 0x20
++#define ERASE_CONFIRM 0xd0
++#define WORD_PROGRAM 0x40
++#define READ_STATUS 0x70
++#define CLEAR_STATUS 0x50
++#define DEVICE_BASE_ADDR 0x00000000
++#define DBA DEVICE_BASE_ADDR
++
++extern int do_unlock(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++int do_lock(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++extern int do_protect(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern unsigned long flash_init (void);
++
++
++U_BOOT_CMD(
++ lock, CFG_MAXARGS, 1, do_lock,
++ "lock - locking all the flash sectors\n",
++ "no arguments needed\n"
++ );
++
++U_BOOT_CMD(
++ unlock, CFG_MAXARGS, 1, do_unlock,
++ "unlock - unlocking all the flash sectors\n",
++ "no arguments needed\n"
++ );
++
++int do_unlock(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ volatile unsigned short *addr;
++ unsigned short data;
++ unsigned int block, block_addr;
++ char *arg[16];
++ unsigned int size,total_number_of_blocks=0;
++ int count = 0;
++#if ECON_DEBUG
++ printf("\nUnlocking all flash sectors ...\n");
++#endif
++
++
++ size =flash_init();
++ size = size /( 1024*1024);
++
++ //printf("%s(): LINE %d: Flash_size is %d \n",__FUNCTION__,__LINE__,size);
++ total_number_of_blocks = 4 + 255 ; // 4 small sectors of each size 32KB. 255 sectors of each size 128KB
++
++ if (size==16)
++ {
++ //printf(" 4 small sectors of each size 32KB. 127 sectors of each size 128KB \n");
++ total_number_of_blocks = 4 + 127 ; // 4 small sectors of each size 32KB. 127 sectors of each size 128KB
++ }
++ else if(size==32)
++ {
++ //printf(" 4 small sectors of each size 32KB. 255 sectors of each size 128KB \n");
++ total_number_of_blocks = 4 + 255 ; // 4 small sectors of each size 32KB. 255 sectors of each size 128KB
++ }
++
++
++ //printf(" Total number of blocks is %d \n",total_number_of_blocks);
++
++ for(block=0;block<=total_number_of_blocks;block++)
++ {
++ if(block<4)
++ block_addr = (block*0x8000)+0x00000000;
++ else
++ block_addr = ((block-3)*0x20000)+0x00000000;
++
++ //printf("Block Number is %d . Block_address is 0x%08X \n",block,block_addr);
++
++
++#if ECON_DEBUG
++ if(block%2==0)
++ {
++ printf("\r\\");
++ udelay(4000);
++ printf("\r-");
++ }
++ else
++ {
++ udelay(4000);
++ printf("\r/");
++ }
++#endif
++
++ //printf(" %d\r",block);
++
++ //clear status reg.
++ //printf(" clear status reg.\n");
++ addr = (volatile unsigned short *)DBA;
++ *addr= (unsigned short)CLEAR_STATUS;
++
++ //Unlock block
++ //printf(" Unlock the block 0x%08X \n",block_addr);
++ addr = (volatile unsigned short *)block_addr;
++ //printf("addr is 0x%08X \n",(unsigned int)addr);
++ *addr = (unsigned short)UNLOCK_BLOCK;
++ *addr = (unsigned short)UNLOCK_CONFIRM;
++
++ count = 0;
++ //Check status reg.
++ //printf(" Check status reg. \n");
++ do
++ {
++ addr = (volatile unsigned short *)DBA;
++ data = (unsigned short)(*addr);
++ //printf(" status is 0x%04X \n",data);
++ if(count > 0x100)
++ {
++ printf("Count exceeds 0x1000. Breaking from do_while() loop \n");
++ break;
++ }
++ }while((data&0x80)!=0x80);
++
++ }
++ //printf("Change to Read array mode \n");
++ // Read array mode
++ addr = (volatile unsigned short *)DBA;
++ *addr = (unsigned short)READ_ARRAY_MODE;
++
++#if 1
++// printf("\nAll sectors all unlocked\n");
++// printf("\n Update the flash sectors info as all the sectors are protected off \n");
++ arg[0]=(char *)"do_protect";
++ arg[1]=(char *)"off";
++ arg[2]=(char *)"all";
++ do_protect(NULL,0,3,arg);
++#endif
++ return 0;
++}
++
++
++
++int do_lock(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ volatile unsigned short *addr;
++ unsigned short data;
++ unsigned int block,block_addr;
++ char *arg[16];
++ unsigned int size,total_number_of_blocks=0;
++ int count = 0;
++#if ECON_DEBUG
++ printf("\nLocking all flash sectors starts\n");
++#endif
++ size =flash_init();
++ size = size /( 1024*1024);
++ //printf("%s(): LINE %d: Flash_size is %d \n",__FUNCTION__,__LINE__,size);
++
++ if (size==16)
++ {
++ //printf(" 4 small sectors of each size 32KB. 127 sectors of each size 128KB \n");
++ total_number_of_blocks = 4 + 127 ; // 4 small sectors of each size 32KB. 127 sectors of each size 128KB
++ }
++ else if(size==32)
++ {
++ //printf(" 4 small sectors of each size 32KB. 255 sectors of each size 128KB \n");
++ total_number_of_blocks = 4 + 255 ; // 4 small sectors of each size 32KB. 255 sectors of each size 128KB
++ }
++
++
++ //printf(" Total number of blocks is %d \n",total_number_of_blocks);
++ for(block=0;block<=total_number_of_blocks;block++)
++ {
++
++ if(block<4)
++ block_addr = (block*0x8000)+0x00000000;
++ else
++ block_addr = ((block-3)*0x20000)+0x00000000;
++
++ // printf("Block Number is %d . Block_address is 0x%08X \n",block,block_addr);
++
++
++ //printf(" %d\r",block);
++ //clear status reg.
++ //printf(" clear status reg.\n");
++ addr = (volatile unsigned short *)DBA;
++ *addr= (unsigned short)CLEAR_STATUS;
++
++ //printf(" Unlock the block 0x%08X \n",block_addr);
++ //lock block
++ addr = (volatile unsigned short *)block_addr;
++ //printf("addr is 0x%08X \n",(unsigned int)addr);
++ *addr = (unsigned short)LOCK_BLOCK;
++ *addr = (unsigned short)LOCK_CONFIRM;
++
++ //printf(" Check status reg. \n");
++ count =0;
++ //Check status reg.
++ do
++ {
++ addr = (volatile unsigned short *)DBA;
++ data = (unsigned short)(*addr);
++ //printf(" status is 0x%04X \n",data);
++ if(count > 0x100)
++ {
++ printf("Count exceeds 0x100. Breaking from do_while() loop \n");
++ break;
++ }
++ }while((data&0x80)!=0x80);
++
++ }
++
++ //printf("Change to Read array mode \n");
++ addr = (volatile unsigned short *)DBA;
++ *addr = (unsigned short)READ_ARRAY_MODE;
++
++// printf("\n All sectors are locked \n");
++// printf("\n Update the flash sectors info as all the sectors are protected on \n");
++ arg[0]=(char *)"do_protect";
++ arg[1]=(char *)"on";
++ arg[2]=(char *)"all";
++ do_protect(NULL,0,3,arg);
++
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_launchwince.c u-boot-2008.10/common/cmd_econ_launchwince.c
+--- u-boot-2008.10_original/common/cmd_econ_launchwince.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_launchwince.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,43 @@
++#include <common.h>
++#include <command.h>
++
++int do_launchwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++U_BOOT_CMD(
++ launchwince, 2, 0, do_launchwince,
++ "launchwince\t- Launch a Windows CE image from memory (econ code)\n",
++ "[args..]\n"
++ "\taddr\t\t-launch image from address addr\n"
++);
++
++int do_launchwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ unsigned long addr;
++ void (*theWinCEKernel)(int zero);
++
++
++ if (argc < 2) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ addr = simple_strtoul(argv[1], NULL, 16);
++
++ printf ("## Launching Windows CE Image from address 0x%08lX ...\n", addr);
++
++#if 1
++ theWinCEKernel = (void (*)(int))ntohl(addr);
++
++ cleanup_before_linux ();
++ printf("Calling theWinCEKernel() \n");
++ theWinCEKernel (0);
++#endif
++ cleanup_before_linux ();
++
++ /* Mov PC to the launch address */
++ asm ("mov pc, %0": :"r" (addr));
++
++ //Launch(addr);
++
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_lcd_test.c u-boot-2008.10/common/cmd_econ_lcd_test.c
+--- u-boot-2008.10_original/common/cmd_econ_lcd_test.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_lcd_test.c 2010-03-03 16:39:57.000000000 +0530
+@@ -0,0 +1,1170 @@
++#include <common.h>
++#include <command.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/types.h>
++#include <lcd.h>
++typedef s64 INT64;
++typedef u64 UINT64;
++typedef s32 INT32;
++typedef u32 UINT32;
++typedef s16 INT16;
++typedef u16 UINT16;
++typedef s8 INT8;
++typedef u8 UINT8;
++
++
++typedef unsigned char boolean_t;
++typedef unsigned char BOOL;
++typedef unsigned long DWORD;
++typedef unsigned short WORD;
++typedef unsigned char BYTE;
++typedef unsigned char BOOLEAN;
++extern vidinfo_t panel_info;
++extern int drv_lcd_init (void);
++#define mdelay(n) udelay((n)*1000)
++#ifndef TRUE
++#define TRUE ((boolean_t)(0==0))
++#endif
++#ifndef FALSE
++#define FALSE (!TRUE)
++#endif
++
++#define RAMBUFFER 0xa2000000
++#define NOR_STD_BMPBIN_SIZE (320*240*2)
++#define DESCRIPTOR_ADDR0 (0xa3FA0000)
++#define NEXTDESADDR (0xa3FA0010)
++#define FRAME_ID (0x87654321)
++//--------------------------------------------------------------------
++#define FDAR0_ADDR (0x44000200)
++#define FDAR1_ADDR (0x44000210)
++#define FDAR2_ADDR (0x44000220)
++#define FDAR3_ADDR (0x44000230)
++#define FDAR4_ADDR (0x44000240)
++#define FDAR5_ADDR (0x44000250)
++#define FDAR6_ADDR (0x44000260)
++//-------------------------------------------------------------------
++#define LCCR0_ADDR (0x44000000)
++#define LCCR1_ADDR (0x44000004)
++#define LCCR2_ADDR (0x44000008)
++#define LCCR3_ADDR (0x4400000c)
++#define LCCR4_ADDR (0x44000010)
++#define LCCR5_ADDR (0x44000014)
++#define FRAME_BUFFER (0xA3F00400) //(SDRAM_BMPBIN_ADDR)
++//---------------------------------------------------------------------
++//LCD CONTROLLER REGISTER 0 - 5
++#define PPL35 239 // Pixels Per Line
++#define LPP35 319 // Lines Per Plane
++#define LCCR0_DATA35 (0x07B008f8)
++#define LCCR1_DATA35 (0x3A103400|PPL35) //0x3A1034EF
++#define LCCR2_DATA35 (0x00041C00|LPP35) //0x41D3F
++#define LCCR3_DATA35 (0x04440007)
++#define LCCR4_DATA35 (0x00000000)
++#define LCCR5_DATA35 (0x00000000)
++////--------------------------------------------------------------------
++//LCD CONTROLLER REGISTER 0 - 5
++#define PPL32 239 // Pixels Per Line
++#define LPP32 319 // Lines Per Plane
++#define LCCR0_DATA32 (0x07B008f8)
++#define LCCR1_DATA32 0x3A1034EF//(0x3A1034EF|PPL35)
++#define LCCR2_DATA32 0x07041D3F//(0x07041D3F|LPP35)
++#define LCCR3_DATA32 (0x04300007)
++#define LCCR4_DATA32 (0x00000000)
++#define LCCR5_DATA32 (0x00000000)
++////--------------------------------------------------------------------
++#define PPL43 479// Pixels Per Line
++#define LPP43 271// Lines Per Plane
++#define LCCR0_DATA43 (0x07b008f8)
++#define LCCR1_DATA43 (0x0101A000|PPL43)
++#define LCCR2_DATA43 (0x02022400|LPP43)
++#define LCCR3_DATA43 (0x44700007)
++#define LCCR4_DATA43 (0x80000000)
++#define LCCR5_DATA43 (0x00000000)
++////--------------------------------------------------------------------
++#define PPL57 639// Pixels Per Line
++#define LPP57 479// Lines Per Plane
++#define LCCR0_DATA57 (0x07b008f8)
++#define LCCR1_DATA57 (0x50501000|PPL57)
++#define LCCR2_DATA57 (0x13130800|LPP57)
++#define LCCR3_DATA57 (0x04700001)
++#define LCCR4_DATA57 (0x00000000)
++#define LCCR5_DATA57 (0x00000000)
++////------------------------------------------------------------------
++#define PPL65 639// Pixels Per Line
++#define LPP65 479// Lines Per Plane
++#define LCCR0_DATA65 (0x07b008f8)
++#define LCCR1_DATA65 (0x06001000|PPL65)
++#define LCCR2_DATA65 (0x13130800|LPP65)
++#define LCCR3_DATA65 (0x04700001)
++#define LCCR4_DATA65 (0x00000000)
++#define LCCR5_DATA65 (0x00000000)
++//--------------------------------------------------------------------
++#define LCCR0_DATACRT (0x07b008f8)
++#define LCCR1_DATACRT (0x5010FE7F)
++#define LCCR2_DATACRT (0x0E01B1DF)
++#define LCCR3_DATACRT (0x04000001)
++#define LCCR4_DATACRT (0x00000000)
++#define LCCR5_DATACRT (0x00000000)
++//--------------------------------------------------------------------
++
++/******************************************************************************************************/
++//definitions for lcd test apps
++//
++#define FRAME_BUFFER_ADDR FRAME_BUFFER
++#define RGB(r,g,b) ( ((0x1f&(r>>3))<<11) | ((0x3f&(g>>2))<<5) | ((0x1f &(b>>3))<<0) ) // Neglecting the lsb bits for getting 565 format from 888 format.
++
++
++
++#define WHITE RGB(0xff,0xff,0xff)
++#define BLACK 0x00
++#define RED RGB(0xff,0x00,0x00)
++#define BLUE RGB(0x00,0x00,0xff)
++#define GREEN RGB(0x00,0xff,0x00)
++#define GREY RGB(0x80,0x80,0x80)
++#define MEGENTA RGB(0xff,0x00,0xff)
++#define YELLOW RGB(0xff,0xff,0x00)
++#define CYAN RGB(0x00,0xff,0xff)
++#define COLORS 8
++
++
++#define BUS_HIGH 0xffff
++#define BUS_LOW 0x0000
++/*=====================================================================================
++=======================================================================================*/
++ /* global variables */
++unsigned short int econ_color[9];
++unsigned short int mono_crome[2];
++unsigned short int alter_color[9];
++
++#if 0
++#if defined(CONFIG_LCD_DISPLAY_3P5_INCH_320_240)
++#warning "LCD Display 3.5 inch 320x240 resln is selected"
++#define PPL 239
++#define LPP 319
++#define LCCR0_DATA 0x079008f8
++#define LCCR1_DATA ( 0x3A103400 | PPL )
++#define LCCR2_DATA ( 0x00041C00 | LPP )
++#define LCCR3_DATA 0x04440007
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++DWORD g_XRES = 240;
++DWORD g_YRES = 320;
++DWORD g_DEVICE = 35;
++DWORD g_LDCMD0 = (240*320*2);
++#elif defined(CONFIG_LCD_DISPLAY_5P7_INCH_640_480)
++#warning "LCD Display 5.7 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x5050127F
++#define LCCR2_DATA 0x131309DF
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++DWORD g_XRES = 640;
++DWORD g_YRES = 480;
++DWORD g_DEVICE = 57;
++DWORD g_LDCMD0 = (640*480*2);
++#elif defined(CONFIG_LCD_DISPLAY_6P5_INCH_640_480)
++#warning "LCD Display 6.5 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008d8
++#define LCCR1_DATA 0x0600127f
++#define LCCR2_DATA 0x131309df
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++DWORD g_XRES = 640;
++DWORD g_YRES = 480;
++DWORD g_DEVICE = 64;
++DWORD g_LDCMD0 = (640*480*2);
++#elif defined(CONFIG_CRT_DISPLAY_640_480)
++#warning "CRT Display 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x3030FE7F
++#define LCCR2_DATA 0x251109DF
++#define LCCR3_DATA 0x04000001
++#define LCCR4_DATA 0x80000000
++#define LCCR5_DATA 0x00000000
++DWORD g_XRES = 640;
++DWORD g_YRES = 480;
++DWORD g_DEVICE = 64;
++DWORD g_LDCMD0 = (640*480*2);
++#error "Display Type is Not selected for REGULUS Board. Select the Display type and build the image"
++#endif
++#endif
++
++struct DMADescriptor
++{
++ volatile unsigned long fdadr;
++ volatile unsigned long fsadr;
++ volatile unsigned long fidr;
++ volatile unsigned long ldcmd;
++};
++int do_selectlcd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++int do_drawlcd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++#ifdef CONFIG_LCD
++int do_lcdinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++#endif
++void Config_LCDController(DWORD Cx, DWORD Cy);
++int draw_colorchecker(DWORD Cx, DWORD Cy);
++int draw_monochecker(DWORD Cx, DWORD Cy);
++int draw_horizontal(DWORD Cx, DWORD Cy);
++int draw_vertical(DWORD Cx, DWORD Cy);
++int draw_megenta(DWORD Cx, DWORD Cy);
++int draw_yellow(DWORD Cx, DWORD Cy);
++int draw_white(DWORD Cx, DWORD Cy);
++int draw_green(DWORD Cx, DWORD Cy);
++int draw_grey(DWORD Cx, DWORD Cy);
++int draw_blue(DWORD Cx, DWORD Cy);
++int draw_cyan(DWORD Cx, DWORD Cy);
++int draw_all(DWORD Cx, DWORD Cy);
++int draw_red(DWORD Cx, DWORD Cy);
++void show_lcd(DWORD Cx, DWORD Cy, DWORD Device);
++void Drawlogo(DWORD Cx, DWORD Cy);
++int draw_toggle(DWORD Cx, DWORD Cy);
++void color_set(void);
++void DisableLCDController(void);
++void EnableLCDController(void);
++void Disable35LCDbackLight(BOOL Status);
++void ReadCRTSpecification();
++void MapHardware();
++DWORD g_LCCR0, g_LCCR1, g_LCCR2, g_LCCR3, g_LCCR4, g_LCCR5;
++
++//Default Display Type is LCD 3.7INCH 240x320 RESLN.
++DWORD g_XRES = 240;
++DWORD g_YRES = 320;
++DWORD g_DEVICE = 37;
++DWORD g_LDCMD0 = (240*320*2);
++
++void ConfigGPIOforLCD(void)
++{
++#define PXA_LAST_GPIO 127
++#define GPIO_IN 0x000
++#define GPIO_OUT 0x080
++#define GPIO_ALT_FN_1_IN 0x100
++#define GPIO_ALT_FN_1_OUT 0x180
++#define GPIO_ALT_FN_2_IN 0x200
++#define GPIO_ALT_FN_2_OUT 0x280
++#define GPIO_ALT_FN_3_IN 0x300
++#define GPIO_ALT_FN_3_OUT 0x380
++#define GPIO_MD_MASK_NR 0x07f
++#define GPIO_MD_MASK_DIR 0x080
++#define GPIO_MD_MASK_FN 0x300
++#define GPIO_DFLT_LOW 0x400
++#define GPIO_DFLT_HIGH 0x800
++#define GPIO50_LCD_BACKLIGHT_MD (50 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define GPIO53_PSAVE_MD (53 | GPIO_OUT | GPIO_DFLT_HIGH)
++ //printf("FUNC %s(): LCD Initialization \n",__FUNCTION__);
++ pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
++ pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD);
++ pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
++ pxa_gpio_mode(GPIO73_LDD_15_MD);
++ pxa_gpio_mode(GPIO72_LDD_14_MD);
++ pxa_gpio_mode(GPIO70_LDD_12_MD);
++ pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
++ pxa_gpio_mode(GPIO69_LDD_11_MD);
++ pxa_gpio_mode(GPIO64_LDD_6_MD);
++ pxa_gpio_mode(GPIO62_LDD_4_MD);
++ pxa_gpio_mode(GPIO61_LDD_3_MD);
++ pxa_gpio_mode(GPIO68_LDD_10_MD);
++ pxa_gpio_mode(GPIO60_LDD_2_MD);
++ pxa_gpio_mode(GPIO58_LDD_0_MD);
++ pxa_gpio_mode(GPIO59_LDD_1_MD);
++ pxa_gpio_mode(GPIO63_LDD_5_MD);
++ pxa_gpio_mode(GPIO66_LDD_8_MD);
++ pxa_gpio_mode(GPIO65_LDD_7_MD);
++ pxa_gpio_mode(GPIO67_LDD_9_MD);
++ pxa_gpio_mode(GPIO71_LDD_13_MD);
++ pxa_gpio_mode(GPIO50_LCD_BACKLIGHT_MD);
++ pxa_gpio_mode(GPIO53_PSAVE_MD);
++ CKEN |= CKEN16_LCD;
++}
++/*=====================================================================================
++=======================================================================================*/
++void Config_LCDController(DWORD Cx, DWORD Cy)
++{
++ LCCR5 = g_LCCR5;
++ LCCR4 = g_LCCR4;
++ LCCR3 = g_LCCR3;
++ LCCR2 = g_LCCR2;
++ LCCR1 = g_LCCR1;
++ LCCR0 = (g_LCCR0 & ~(LCCR0_ENB));
++/*******************************************************************************************************************************************************/
++/* Below lines of code is added by J.Balakrishnan on 03/03/2010, In LCD 4.3", to increase the brightness, PWM3 duty cycle is configured as maximum */
++ if(Cx == 480 && Cy == 272)
++ {
++#define PWM_PWDUTY3 __REG(0x40C00014) /* PWM 3 Duty Cycle Register */
++ PWM_PWDUTY3 = 0x1E;
++ }
++/*******************************************************************************************************************************************************/
++
++}
++/*=====================================================================================
++=======================================================================================*/
++
++//This is the LCD Initialisation Function
++#ifdef CONFIG_LCD
++U_BOOT_CMD(
++ selectlcd, 4, 0, do_selectlcd,
++ "selectlcd - Select the Display by providing width , height and LCD/CRT Type\n",
++ "selectlcd 240 320 35 \nselectlcd 640 480 57 \nselectlcd 640 480 65 \nselectlcd 640 480 640 crt\n"
++ );
++#endif
++
++#if 0
++U_BOOT_CMD(
++ drawlcd, 2, 0, do_drawlcd,
++ "drawlcd - Draw a Color pattern of the Display unit \n",
++ "drawlcd red\ndrawlcd white\ndrawlcd yellow\ndrawlcd megenta\ndrawlcd green\ndrawlcd grey\ndrawlcd blue\ndrawlcd megentaor\ndrawlcd horizontal\ndrawlcd vertical\ndrawlcd monochecker\ndrawlcd colorchecker\ndrawlcd all\n"
++ );
++#else
++U_BOOT_CMD(
++ fill, 2, 0, do_drawlcd,
++ "fill - Draw a Color pattern of the Display unit \n",
++ "fill red\nfill white\nfill yellow\nfill megenta\nfill green\nfill grey\nfill blue\nfill megentaor\nfill horizontal\nfill vertical\nfill monochecker\nfill colorchecker\nfill all\n"
++ );
++#endif
++
++
++//This is the LCD Initialisation Function
++#ifdef CONFIG_LCD
++U_BOOT_CMD(
++ lcdinit, 1, 0, do_lcdinit,
++ "lcdinit - Initialize the LCD driver with the panel info strutcure \n",
++ "No Arguments \n"
++ );
++
++
++int do_lcdinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ serial_printf("WHITE is 0x%04X \n",WHITE);
++ serial_printf("YELLOW is 0x%04X \n",YELLOW);
++ serial_printf("CYAN is 0x%04X \n",CYAN);
++ serial_printf("GREEN is 0x%04X \n",GREEN);
++ serial_printf("MEGENTA is 0x%04X \n",MEGENTA);
++ serial_printf("RED is 0x%04X \n",RED);
++ serial_printf("BLUE is 0x%04X \n",BLUE);
++ serial_printf("GREY is 0x%04X \n",GREY);
++ serial_printf("BLACK is 0x%04X \n",BLACK);
++ serial_printf("Panel Info :: \n");
++ panel_info.vl_col = g_XRES;
++ panel_info.vl_row = g_YRES;
++ serial_printf("panel_info.vl_col is %d \n",panel_info.vl_col);
++ serial_printf("panel_info.vl_row is %d \n",panel_info.vl_row);
++ serial_printf("panel_info.vl_width is %d \n",panel_info.vl_width);
++ serial_printf("panel_info.vl_height is %d \n",panel_info.vl_height);
++ serial_printf("panel_info.vl_clkp is %d \n",panel_info.vl_clkp);
++ serial_printf("panel_info.vl_oep is %d \n",panel_info.vl_oep);
++ serial_printf("panel_info.vl_hsp is %d \n",panel_info.vl_hsp);
++ LCCR0 &= ~LCCR0_ENB;
++ drv_lcd_init();
++ return 0;
++
++}
++
++int lcd_driver_reset(void)
++{
++ printf("Panel Info :: \n");
++ panel_info.vl_col = g_XRES;
++ panel_info.vl_row = g_YRES;
++ printf("panel_info.vl_col is %d \n",panel_info.vl_col);
++ printf("panel_info.vl_row is %d \n",panel_info.vl_row);
++ printf("panel_info.vl_width is %d \n",panel_info.vl_width);
++ printf("panel_info.vl_height is %d \n",panel_info.vl_height);
++ printf("panel_info.vl_clkp is %d \n",panel_info.vl_clkp);
++ printf("panel_info.vl_oep is %d \n",panel_info.vl_oep);
++ printf("panel_info.vl_hsp is %d \n",panel_info.vl_hsp);
++ LCCR0 &= ~LCCR0_ENB;
++ drv_lcd_init();
++ return 0;
++}
++#endif
++
++int do_drawlcd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++
++ if(argc != 2)
++ {
++#if 0
++ printf("Usage:\ndrawlcd red\ndrawlcd white\ndrawlcd yellow\ndrawlcd megenta\ndrawlcd green\ndrawlcd grey\n drawlcd blue\ndrawlcd megentaor\ndrawlcd horizontal\ndrawlcd vertical\ndrawlcd monochecker\ndrawlcd colorchecker\ndrawlcd all\n" );
++#else
++ printf("Usage:\nfill red\nfill white\nfill yellow\nfill megenta\nfill green\nfill grey\n fill blue\nfill megentaor\nfill horizontal\nfill vertical\nfill monochecker\nfill colorchecker\nfill all\n" );
++#endif
++ return 0;
++ }
++ color_set();
++ if(!strcmp(argv[1],"horizontal"))
++ {
++ DisableLCDController();
++ draw_horizontal(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"vertical"))
++ {
++ DisableLCDController();
++ draw_vertical(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"monochecker"))
++ {
++ DisableLCDController();
++ draw_monochecker(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"colorchecker"))
++ {
++ DisableLCDController();
++ draw_colorchecker(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"white"))
++ {
++ DisableLCDController();
++ draw_white(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"red"))
++ {
++ DisableLCDController();
++ draw_red(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"yellow"))
++ {
++ DisableLCDController();
++ draw_yellow(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"megenta"))
++ {
++ DisableLCDController();
++ draw_megenta(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"green"))
++ {
++ DisableLCDController();
++ draw_green(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"grey"))
++ {
++ DisableLCDController();
++ draw_grey(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"blue"))
++ {
++ DisableLCDController();
++ draw_blue(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else if(!strcmp(argv[1],"cyan"))
++ {
++ DisableLCDController();
++ draw_cyan(g_XRES,g_YRES);
++ EnableLCDController();
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++
++ else if(!strcmp(argv[1],"all"))
++ {
++ DisableLCDController();
++ draw_black(g_XRES,g_YRES);
++ EnableLCDController();
++ draw_all(g_XRES,g_YRES);
++ //mdelay(2000);
++ //lcd_driver_reset();
++ }
++ else
++ {
++#if 0
++ printf("Usage:\ndrawlcd red\ndrawlcd white\ndrawlcd yellow\ndrawlcd megenta\ndrawlcd green\ndrawlcd grey\n drawlcd blue\ndrawlcd megentaor\ndrawlcd horizontal\ndrawlcd vertical\ndrawlcd monochecker\ndrawlcd colorchecker\ndrawlcd all\n" );
++#else
++ printf("Usage:\nfill red\nfill white\nfill yellow\nfill megenta\nfill green\nfill grey\n fill blue\nfill megentaor\nfill horizontal\nfill vertical\nfill monochecker\nfill colorchecker\nfill all\n" );
++#endif
++ }
++ return 0;
++}
++
++#ifdef CONFIG_LCD
++int do_selectlcd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ if(argc != 4)
++ {
++ printf("selectlcd 240 320 35\nselectlcd 640 480 57\nselectlcd 640 480 65\nselectlcd 640 480 crt\n" );
++ return 0;
++ }
++ else
++ {
++ if((strcmp(argv[1],"240")==0) && (strcmp(argv[2],"320")==0) && (strcmp(argv[3],"35")==0))
++ {
++ select_lcd(240,320,35);
++ }
++ else if( (strcmp(argv[1],"640")==0) && (strcmp(argv[2],"480")==0) && (strcmp(argv[3],"57")==0))
++ {
++ select_lcd(640,480,57);
++ }
++ else if( (strcmp(argv[1],"640")==0) && (strcmp(argv[2],"480")==0) && (strcmp(argv[3],"65")==0))
++ {
++ select_lcd(640,480,65);
++ }
++ else if( (strcmp(argv[1],"640")==0) && (strcmp(argv[2],"480")==0) && (strcmp(argv[3],"crt")==0))
++ {
++ select_lcd(640,480,64);
++ }
++ else
++ {
++ printf("Invalid options \n");
++ printf("selectlcd 240 320 35\nselectlcd 640 480 57\nselectlcd 640 480 65\nselectlcd 640 480 64\n" );
++ }
++ }
++ return 0;
++}
++#endif
++extern void SPIInitializeLCD();
++void select_lcd(DWORD Cx, DWORD Cy, DWORD Device)
++{
++ int count=20;
++ struct DMADescriptor *dmadescriptor0 ;
++ if((Cx == 240) && (Cy == 320) && (Device == 35)) //On Board 3.5" LCD
++ {
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATA35;
++ g_LCCR1 = LCCR1_DATA35;
++ g_LCCR2 = LCCR2_DATA35;
++ g_LCCR3 = LCCR3_DATA35;
++ g_LCCR4 = LCCR4_DATA35;
++ g_LCCR5 = LCCR5_DATA35;
++ g_XRES = 240;
++ g_YRES = 320;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else if((Cx == 240) && (Cy == 320) && (Device == 32)) //On Board 3.2" LCD
++ {
++ SPIInitializeLCD();
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATA32;
++ g_LCCR1 = LCCR1_DATA32;
++ g_LCCR2 = LCCR2_DATA32;
++ g_LCCR3 = LCCR3_DATA32;
++ g_LCCR4 = LCCR4_DATA32;
++ g_LCCR5 = LCCR5_DATA32;
++ g_XRES = 240;
++ g_YRES = 320;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else if((Cx == 480) && (Cy == 272) && (Device == 43)) //On Board 4.3" LCD
++ {
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATA43;
++ g_LCCR1 = LCCR1_DATA43;
++ g_LCCR2 = LCCR2_DATA43;
++ g_LCCR3 = LCCR3_DATA43;
++ g_LCCR4 = LCCR4_DATA43;
++ g_LCCR5 = LCCR5_DATA43;
++ g_XRES = 480;
++ g_YRES = 272;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else if((Cx == 640) && (Cy == 480) && (Device == 57)) //On Board 5.7" LCD
++ {
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATA57;
++ g_LCCR1 = LCCR1_DATA57;
++ g_LCCR2 = LCCR2_DATA57;
++ g_LCCR3 = LCCR3_DATA57;
++ g_LCCR4 = LCCR4_DATA57;
++ g_LCCR5 = LCCR5_DATA57;
++ g_XRES = 640;
++ g_YRES = 480;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else if((Cx == 640) && (Cy == 480) && (Device == 65)) //On Board 6.5" LCD
++ {
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATA65;
++ g_LCCR1 = LCCR1_DATA65;
++ g_LCCR2 = LCCR2_DATA65;
++ g_LCCR3 = LCCR3_DATA65;
++ g_LCCR4 = LCCR4_DATA65;
++ g_LCCR5 = LCCR5_DATA65;
++ g_XRES = 640;
++ g_YRES = 480;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else if((Cx == 640) && (Cy == 480) && (Device == 64)) //External 640x480@60Hz CRT
++ {
++ DisableLCDController();
++ g_LCCR0 = LCCR0_DATACRT;
++ g_LCCR1 = LCCR1_DATACRT;
++ g_LCCR2 = LCCR2_DATACRT;
++ g_LCCR3 = LCCR3_DATACRT;
++ g_LCCR4 = LCCR4_DATACRT;
++ g_LCCR5 = LCCR5_DATACRT;
++ g_XRES = 640;
++ g_YRES = 480;
++ g_LDCMD0 = (g_XRES * g_YRES * 2);
++ }
++ else
++ {
++ return 0;
++ }
++ ConfigGPIOforLCD();
++ Config_LCDController(g_XRES,g_YRES);
++
++ dmadescriptor0 = (struct DMADescriptor *)(DESCRIPTOR_ADDR0);
++
++ dmadescriptor0->fdadr = (volatile unsigned long)DESCRIPTOR_ADDR0;
++ dmadescriptor0->fsadr = (volatile unsigned long)FRAME_BUFFER;
++ dmadescriptor0->fidr = (volatile unsigned long)FRAME_ID;
++ dmadescriptor0->ldcmd = (volatile unsigned long)g_LDCMD0;
++
++ FDADR0 = DESCRIPTOR_ADDR0;
++ draw_horizontal(g_XRES, g_YRES);
++ EnableLCDController();
++}
++/*=====================================================================================
++=======================================================================================*/
++//Call to draw Horizontal Bars
++int draw_horizontal(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *) (FRAME_BUFFER_ADDR);
++ DWORD i,j;
++ color_set();
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=econ_color[i];
++ buf++;
++ }
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_toggle(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ if((j%2)==0)
++ {
++ *(buf) = BUS_HIGH;
++ }
++ else if((j%2)==1)
++ {
++ *(buf) = BUS_LOW;
++ }
++
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_red(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=RED;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_white(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=WHITE;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_black(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=BLACK;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_yellow(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=YELLOW;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_megenta(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *) (FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=MEGENTA;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_green(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=(UINT16)GREEN;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_grey(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=(UINT16)GREY;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_blue(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=(UINT16)BLUE;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_cyan(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j;
++
++ for(i=0;i<8;i++)
++ {
++ for(j=0;j<(Cx*(Cy/8));j++)
++ {
++ *(buf)=(UINT16)CYAN;
++ buf++;
++ }
++
++
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++//Call to draw Vertical Bars
++int draw_vertical(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j,k;
++
++ color_set();
++
++ for(i=0;i<Cy;i++)
++ {
++ k=-1;
++ for(j=0;j<Cx;j++)
++ {
++ if((j%(Cx/8))==0)
++ k++;
++ *(buf)=econ_color[k];
++ buf++;
++ }
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++//Call to draw MonoCrome Checkers
++int draw_monochecker(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j,k,f;
++ color_set();
++ for(i=0;i<8;i++)
++ {
++ if(i % 2 == 0)
++ {
++ for(f=0;f<(Cy/8);f++)
++ {
++ for(j=0;j<8;j++)
++ {
++ if(j % 2 == 0)
++ {
++ for(k=0;k<(Cx/8);k++)
++ {
++ *(buf)=mono_crome[0];
++ buf++;
++ }
++ }
++ else
++ {
++ for(k=0;k<(Cx/8);k++)
++ {
++ *(buf)=mono_crome[1];
++ buf++;
++ }
++ }
++ }
++ }
++
++ }
++ else
++ {
++ for(f=0;f<(Cy/8);f++)
++ {
++ for(j=0;j<8;j++)
++ {
++ if(j % 2 == 0)
++ {
++ for(k=0;k<(Cx/8);k++)
++ {
++ *(buf)=mono_crome[1];
++ buf++;
++ }
++ }
++ else
++ {
++ for(k=0;k<(Cx/8);k++)
++ {
++ *(buf)=mono_crome[0];
++ buf++;
++ }
++
++ }
++ }
++ }
++
++ }
++ }
++
++
++return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++ //Call to draw Color Checkers
++int draw_colorchecker(DWORD Cx, DWORD Cy)
++{
++ unsigned short int *buf=(unsigned short int *)(FRAME_BUFFER_ADDR);
++ DWORD i,j,k,f;
++ color_set();
++ for(i=0;i<8;i++){
++ if(i%2==0){
++ for(f=0;f<(Cy/8);f++){
++ k=-1;
++ for(j=0;j<Cx;j++){
++ if((j%(Cx/8))==0)
++ k++;
++ *(buf)=econ_color[k];
++ buf++;
++ }
++ }
++ }else{
++ for(f=0;f<(Cy/8);f++){
++ k=-1;
++ for(j=0;j<Cx;j++){
++ if((j%(Cx/8))==0)
++ k++;
++ *(buf)=alter_color[k];
++ buf++;
++ }
++ }
++ }
++ }
++ return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++void color_set(void)
++{
++ econ_color[0] = (UINT16) WHITE;
++ econ_color[1] = (UINT16) YELLOW;
++ econ_color[2] = (UINT16) CYAN;
++ econ_color[3] = (UINT16) GREEN;
++ econ_color[4] = (UINT16) MEGENTA;
++ econ_color[5] = (UINT16) RED;
++ econ_color[6] = (UINT16) BLUE;
++ econ_color[7] = (UINT16) GREY;
++ mono_crome[0] = (UINT16) WHITE;
++ mono_crome[1] = (UINT16) BLACK;
++ alter_color[0] = (UINT16) YELLOW;
++ alter_color[1] = (UINT16) CYAN;
++ alter_color[2] = (UINT16) GREEN;
++ alter_color[3] = (UINT16) MEGENTA;
++ alter_color[4] = (UINT16) RED;
++ alter_color[5] = (UINT16) BLUE;
++ alter_color[6] = (UINT16) GREY;
++ alter_color[7] = (UINT16) WHITE;
++
++ //serial_printf("econ_color[0] is 0x%04X . WHITE is 0x%04X \n",econ_color[0],WHITE);
++ //serial_printf("econ_color[1] is 0x%04X . YELLOW is 0x%04X \n",econ_color[1],YELLOW);
++ //serial_printf("econ_color[2] is 0x%04X . CYAN is 0x%04X \n",econ_color[2],CYAN);
++ //serial_printf("econ_color[3] is 0x%04X . WHITE is 0x%04X \n",econ_color[3],GREEN);
++
++}
++/*=====================================================================================
++=======================================================================================*/
++int draw_all(DWORD Cx, DWORD Cy)
++{
++ int i=0;
++ while(i<1)
++{
++ draw_white(Cx, Cy);
++ mdelay(250);
++ draw_yellow(Cx, Cy);
++ mdelay(250);
++ draw_cyan(Cx, Cy);
++ mdelay(250);
++ draw_green(Cx, Cy);
++ mdelay(250);
++ draw_megenta(Cx, Cy);
++ mdelay(250);
++ draw_red(Cx, Cy);
++ mdelay(250);
++ draw_blue(Cx, Cy);
++ mdelay(250);
++ draw_grey(Cx, Cy);
++ mdelay(250);
++ draw_horizontal(Cx, Cy);
++ mdelay(250);
++ draw_vertical(Cx, Cy);
++ mdelay(250);
++ draw_monochecker(Cx, Cy);
++ mdelay(250);
++ draw_colorchecker(Cx, Cy);
++ mdelay(250);
++ i++;
++}
++return 0;
++}
++/*=====================================================================================
++=======================================================================================*/
++void DisableLCDController(void)
++{
++ struct DMADescriptor *dmadescriptor0 ;
++ LCCR0 &= ~LCCR0_ENB;
++ dmadescriptor0 = (struct DMADescriptor *)(DESCRIPTOR_ADDR0);
++ dmadescriptor0->fdadr = (volatile unsigned long)DESCRIPTOR_ADDR0;
++ dmadescriptor0->fsadr = (volatile unsigned long)FRAME_BUFFER;
++ dmadescriptor0->fidr = (volatile unsigned long)FRAME_ID;
++ dmadescriptor0->ldcmd = (volatile unsigned long)g_LDCMD0;
++ FDADR0 = DESCRIPTOR_ADDR0;
++
++}
++void EnableLCDController(void)
++{
++ LCCR0 |= LCCR0_ENB;
++}
++void Disable35LCDbackLight(BOOL Status)
++{
++#define BACKLIGHT_GPIO 50
++ int i;
++ if(Status)
++ {
++ GPCR(BACKLIGHT_GPIO) =GPIO_bit(BACKLIGHT_GPIO);
++ }
++ else
++ {
++ GPSR(BACKLIGHT_GPIO) =GPIO_bit(BACKLIGHT_GPIO);
++ }
++}
++/*=====================================================================================
++=======================================================================================*/
++void DrawColor(UINT8 Jump, DWORD Cx, DWORD Cy)
++{
++ switch(Jump)
++ {
++ case '0': draw_red(Cx, Cy);
++ break;
++ case '1': draw_green(Cx, Cy);
++ break;
++ case '2': draw_blue(Cx, Cy);
++ break;
++ case '3': draw_cyan(Cx, Cy);
++ break;
++ case '4': draw_megenta(Cx, Cy);
++ break;
++ case '5': draw_yellow(Cx, Cy);
++ break;
++ case '6': draw_grey(Cx, Cy);
++ break;
++ case '7': draw_white(Cx, Cy);
++ break;
++ case '8': draw_black(Cx, Cy);
++ break;
++ case '9': draw_horizontal(Cx, Cy);
++ break;
++ case 'a':
++ case 'A': draw_vertical(Cx, Cy);
++ break;
++ case 'b':
++ case 'B': draw_colorchecker(Cx, Cy);
++ break;
++ case 'c':
++ case 'C': draw_monochecker(Cx, Cy);
++ break;
++ case 'd':
++ case 'D': Drawlogo(Cx, Cy);
++ break;
++ }
++}
++/*======================================================================================
++*Draw 240x320 Logo on Display
++=======================================================================================*/
++void Drawlogo(DWORD Cx, DWORD Cy)
++{
++ DWORD i, j, w,z;
++ DWORD Hw, Vw;
++
++
++#if 0
++ volatile UINT16 *RamBuffer=(volatile UINT16 *)RAMBUFFER;
++ volatile UINT16 *RamBinAddress = (volatile UINT16*)SDRAM_BMPBIN_ADDR;
++ FlashRead(((UINT32) OALPAtoVA(IMAGE_BOOT_BLDRIMAGE_FLASH_PA_START,FALSE) +NOR_FLASH_BMPBIN_OFFSET), RAMBUFFER, NOR_STD_BMPBIN_SIZE);
++ Hw = (Cy - 320)/2;
++ Vw = (Cx-240)/2;
++ for(w=0;w<Hw*Cx; w=w+Cx)
++ {
++ for(i=0;i<Cx;i++)
++ {
++ *(RamBinAddress + i + w) = 0xFFFF;
++ }
++ }
++ for(j=0;j<320*Cx;j=j + Cx)
++ {
++ for(i=0;i< Vw;i++)
++ {
++ *(RamBinAddress + i + j +w) = 0xFFFF;
++ }
++ for(i=Vw;i<Vw+ 240;i++)
++ {
++ *(RamBinAddress + i + j + w) = *(RamBuffer);
++ RamBuffer++;
++ }
++ for(i=Vw+ 240;i<Vw+ 240 + Vw;i++)
++ {
++ *(RamBinAddress + i + j + w) = 0xFFFF;
++ }
++ }
++ for(z=0;z<Hw*Cx; z=z+Cx)
++ {
++ for(i=0;i<Cx;i++)
++ {
++ *(RamBinAddress + i + j + w +z) = 0xFFFF;
++ }
++ }
++#endif
++}
++/*===================================================================================== */
+diff -Naur u-boot-2008.10_original/common/cmd_econ_loade.c u-boot-2008.10/common/cmd_econ_loade.c
+--- u-boot-2008.10_original/common/cmd_econ_loade.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_loade.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,249 @@
++/*
++ * (C) Copyright 2000-2002
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++/*
++ * Boot support
++ */
++#include <common.h>
++#include <command.h>
++
++#define BASIC_START_ADDR "0x00000000"
++#define BASIC_END_ADDR "0x00007fff"
++#define UBOOT_START_ADDR "0x00020000"
++#define UBOOT_END_ADDR "0x0009ffff"
++#define UBOOT_PARAMS_START_ADDR "0x000A0000"
++#define UBOOT_PARAMS_END_ADDR "0x000Bffff"
++#define KERNEL_START_ADDR "0x000C0000"
++#define KERNEL_END_ADDR "0x004Bffff"
++#define KRAMDISK_START_ADDR "0x000C0000"
++#define KRAMDISK_END_ADDR "0x00ABffff"
++#define DB_START_ADDR "0x01800000"
++#define DB_END_ADDR "0x01ffffff"
++#define ROOTFS_START_ADDR "0x004C0000"
++#define ROOTFS_END_ADDR "0x017fffff"
++#define FLASH2_START_ADDR "0x01800000"
++#define FLASH2_END_ADDR "0x01ffffff"
++
++/*
++ * Added for uboot logo display
++ */
++#define UBOOTLOGO_START_ADDR "0x01f00000"
++#define UBOOTLOGO_END_ADDR "0x01ffffff"
++
++
++
++#define SDRAM_ADDR "0xa0000000"
++
++#define MKBIN_START_ADDR "0x00100000"
++#define MKBIN_END_ADDR "0x00ffffff"
++
++#define FLASH_START_ADDR "0x00000000"
++#define FLASH_END_ADDR "0x01ffffff"
++
++extern int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_unlock (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_mem_cp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++
++
++int do_load_eth(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++
++
++U_BOOT_CMD(
++ loade, 3, 0, do_load_eth,
++ "loade -load the specifiied image into SDRAM and copy it to FLASH\n",
++ "loade basic (or) loade uboot (or) loade kernel (or) \n loade rootfs (or) loade ram <filename>\n"
++ );
++
++int do_load_eth(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ char *fstartaddr=NULL;
++ char *fendaddr=NULL;
++ char *filename=NULL;
++ unsigned int size=0;
++ char filesize[10];
++ char *arg[10];
++ if(argc < 2)
++ {
++ printf("usage: \n \
++ loade basic (or) \n \
++ loade uboot (or) \n \
++ loade kernel (or) \n \
++ loade rootfs (or) \n \
++ loade ram <filename> \n");
++ return 0;
++ }
++ if(!strcmp(argv[1],"basic"))
++ {
++ fstartaddr =(char *) BASIC_START_ADDR;
++ fendaddr = (char *)BASIC_END_ADDR;
++ filename = "basic-boot.bin";
++ }
++ else if(!strcmp(argv[1],"uboot"))
++ {
++ fstartaddr =(char *) UBOOT_START_ADDR;
++ fendaddr = (char *)UBOOT_END_ADDR;
++ filename = "u-boot.bin";
++ }
++ else if(!strcmp(argv[1],"kernel"))
++ {
++ fstartaddr = (char *)KERNEL_START_ADDR;
++ fendaddr = (char *)KERNEL_END_ADDR;
++ filename ="kernel.img";
++ }
++#if 0
++ else if(!strcmp(argv[1],"kramdisk"))
++ {
++ fstartaddr = (char *)KRAMDISK_START_ADDR;
++ fendaddr = (char *)KRAMDISK_END_ADDR;
++ filename ="deneb_kernel.img";
++ }
++ else if(!strcmp(argv[1],"db"))
++ {
++ fstartaddr = (char *)DB_START_ADDR;
++ fendaddr = (char *)DB_END_ADDR;
++ filename ="deneb_db.img";
++ }
++#endif
++ else if(!strcmp(argv[1],"rootfs"))
++ {
++ fstartaddr = (char *)ROOTFS_START_ADDR;
++ fendaddr = (char *)ROOTFS_END_ADDR;
++ filename = "rootfs.jffs2";
++ }
++#if 0
++ else if(!strcmp(argv[1],"flash2"))
++ {
++ fstartaddr = (char *)FLASH2_START_ADDR;
++ fendaddr = (char *)FLASH2_END_ADDR;
++ filename = "flash2.jffs2";
++ }
++ else if(!strcmp(argv[1],"logo"))
++ {
++ fstartaddr = (char *)UBOOTLOGO_START_ADDR;
++ fendaddr = (char *)UBOOTLOGO_END_ADDR;
++ filename = "logo_555.bmp";
++ }
++
++ else if(!strcmp(argv[1],"flash"))
++ {
++ fstartaddr = (char *)FLASH_START_ADDR;
++ fendaddr = (char *)FLASH_END_ADDR;
++ filename ="flash_32mb.img";
++ }
++#endif
++ else if(!strcmp(argv[1],"ram"))
++ {
++ if(argc >=3)
++ {
++ arg[0] = "tftpboot";
++ arg[1] = SDRAM_ADDR;
++ arg[2] = argv[2];
++ if((size = do_tftpb (NULL,0, 3 , arg))==0)
++ {
++ printf("Filesize=0x%x bytes",size);
++ return 0;
++ }
++ else if(size == -1)
++ {
++ printf("econ loade debug: Unable to dowload the file \n");
++ return 0;
++ }
++ else if((size !=1)&&(size > 0))
++ {
++ // do nothing here
++ return 0;
++ }
++ }
++ else
++ {
++ printf("usage: \n \
++ loade basic (or) \n \
++ loade uboot (or) \n \
++ loade kernel (or) \n \
++ loade rootfs (or) \n \
++ loade ram <filename> \n");
++ return 0;
++
++ }
++ }
++ else
++ {
++ printf("usage: \n \
++ loade basic (or) \n \
++ loade uboot (or) \n \
++ loade kernel (or) \n \
++ loade rootfs (or) \n \
++ loade ram <filename> \n");
++ return 0;
++ }
++ arg[0] = "tftpboot";
++ arg[1] = SDRAM_ADDR;
++ arg[2] = filename;
++ if((size = do_tftpb (NULL,0, 3 , arg))==0)
++ {
++ printf("Filesize=0x%x bytes",size);
++ return 0;
++ }
++ else if(size == -1)
++ {
++ printf("econ loade debug: Unable to dowload the file \n");
++ return 0;
++ }
++ else if((size !=1)&&(size > 0))
++ {
++
++ size += 1; //for avoiding the CRC error while checking the image ig the copied image size is an odd number
++ size /= 2;
++
++ sprintf(filesize,"%lx",size);
++ //unlock the flash
++ //do_unlock(NULL,0,1,NULL);
++ arg[0] = (char *)"protect";
++ arg[1] = (char *)"off";
++ arg[2] = (char *)"all";
++ do_protect(NULL,0,3,arg);
++
++ //erase the flash for the given address
++ printf("Erasing Flash from start addr=%s to end addr=%s \r\n",fstartaddr,fendaddr);
++ arg[0] = (char *)"erase";
++ arg[1] = (char *)fstartaddr;
++ arg[2] = (char *)fendaddr;
++ do_flerase(NULL,0,3,arg);
++ //copy data from sdram to flash
++ printf("Copying %s words(word=16bit)from source addr "SDRAM_ADDR" to target addr %s \r\n",filesize,fstartaddr);
++ arg[0] = (char *)"cp.w";
++ arg[1] = (char *)SDRAM_ADDR;
++ arg[2] = (char *)fstartaddr;
++ arg[3] = (char *)filesize;
++ do_mem_cp(NULL,0,4,arg);
++ return 0;
++ }
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_loady.c u-boot-2008.10/common/cmd_econ_loady.c
+--- u-boot-2008.10_original/common/cmd_econ_loady.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_loady.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,621 @@
++/* YMODEM support for bootldr
++ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
++ * Copyright (C) 2001 John G Dorsey
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * The author may be contacted via electronic mail at <john+@cs.cmu.edu>,
++ * or at the following address:
++ *
++ * John Dorsey
++ * Carnegie Mellon University
++ * HbH2201 - ICES
++ * 5000 Forbes Avenue
++ * Pittsburgh, PA 15213
++ *
++ *
++ * Notes:
++ * ^^^^^^
++ * Tested against lsz (`sb') from within Minicom. The YMODEM spec says
++ * that the receiver should just keep sending CRC/NAKs to the sender
++ * until the transfer begins, but something breaks if a CRC/NAK is
++ * sent out while the user is typing in a filename to Minicom. Best
++ * solution currently is just to repeat the transfer.
++ *
++ * History:
++ * ^^^^^^^^
++ * 12 March, 2001 - created. (jd)
++ *
++ */
++
++
++
++
++
++
++
++//Commented by Tharma on May29 2006 for Qtopia
++/*
++#define UBOOT_START_ADDR "0x00020000"
++#define UBOOT_END_ADDR "0x0003ffff"
++#define ROOTFS_START_ADDR "0x1e0000"
++#define ROOTFS_END_ADDR "0x1ffffff"
++#define KERNEL_START_ADDR "0x60000"
++#define KERNEL_END_ADDR "0x1dffff"
++#define SDRAM_ADDR "0xa0000000"
++#define LOAD_ADDR ((unsigned int)0xa0000000)
++*/
++
++//Added by Tharma on May29 2006 for Qtopia
++
++#define BASIC_START_ADDR "0x00000000"
++#define BASIC_END_ADDR "0x00007fff"
++#define UBOOT_START_ADDR "0x00020000"
++#define UBOOT_END_ADDR "0x0009ffff"
++#define UBOOT_PARAMS_START_ADDR "0x000A0000"
++#define UBOOT_PARAMS_END_ADDR "0x000Bffff"
++#define KERNEL_START_ADDR "0x000C0000"
++#define KERNEL_END_ADDR "0x004Bffff"
++#define ROOTFS_START_ADDR "0x004C0000"
++#define ROOTFS_END_ADDR "0x017fffff"
++#define FLASH2_START_ADDR "0x01800000"
++#define FLASH2_END_ADDR "0x01ffffff"
++#define EBOOT_START_ADDR "0x01e00000"
++#define EBOOT_END_ADDR "0x01ffffff"
++#define SDRAM_ADDR "0xa0000000"
++#define KRAMDISK_START_ADDR "0x000C0000"
++#define KRAMDISK_END_ADDR "0x00ABffff"
++
++#define LOAD_ADDR ((unsigned int)0xa0000000)
++
++#define FLASH_START_ADDR "0x00000000"
++#define FLASH_END_ADDR "0x01ffffff"
++
++#include <common.h>
++#include <ymodem.h>
++#include<command.h>
++#define mmalloc(x) malloc(x)
++
++
++/* Constants used in generating the CRC tables: */
++
++#define CRC_TABLE_SIZE (256)
++
++#define CRC16_POLYNOMIAL (0x1021)
++#define CRC32_POLYNOMIAL (0xedb88320)
++
++static int crc16_init(void);
++static int crc32_init(void);
++
++static unsigned short crc16_buf(unsigned char *buf, unsigned int length);
++
++
++/* error bits in LSR */
++#define DR 0x00
++#define OE 0x02
++#define PE 0x04
++#define FE 0x08
++#define BI 0x10
++
++extern int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_mem_cp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++/* address where the file load in sram */
++
++
++
++/* RECEIVE BUFFER REGISTER AND LINE STATUS REGISTER */
++/* RECEIVE BUFFER REGISTER AND LINE STATUS REGISTER */
++
++#ifdef CONFIG_STUART
++#warning "YMODEM will use STUART"
++volatile unsigned char *RBR=(volatile unsigned char *)0x40700000;
++volatile unsigned char *LSR=(volatile unsigned char *)0x40700014;
++#elif defined(CONFIG_FFUART)
++#warning "YMODEM will use FFUART"
++volatile unsigned char *RBR=(volatile unsigned char *)0x40100000;
++volatile unsigned char *LSR=(volatile unsigned char *)0x40100014;
++#elif defined(CONFIG_BTUART)
++#warning "YMODEM will use BTUART"
++volatile unsigned char *RBR=(volatile unsigned char *)0x40200000;
++volatile unsigned char *LSR=(volatile unsigned char *)0x40200014;
++#endif
++//extern int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++uchar strtoul_err;
++// char HEX_TO_ASCII_TABLE[16];
++#if 0
++static int do_econloady(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++#else
++static int do_loady(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++#endif
++
++
++unsigned short *crc16_table = (unsigned short *)NULL;
++/**********************************************************************************************************/
++
++static uchar awaitkey(unsigned long delay, int *error_p)
++{
++ unsigned long i = delay;
++ uchar c;
++ int errors = 0;
++
++ while (1) //while
++{
++ i = delay;
++
++ while((((*(volatile unsigned char*)LSR) & 0x01) != 0x01) && i) /*VINOTH*/
++ i--;
++
++ if (i)
++ {
++ errors = 0;
++
++
++ c = *((volatile unsigned char *)RBR);
++
++ /*VINOTH*/
++ if(((*(volatile unsigned char*) LSR) & BI) == BI) { errors=0; }
++ if(((*(volatile unsigned char*)LSR) & FE) == FE) { errors=3; }
++ if(((*(volatile unsigned char*)LSR) & PE) == PE) { errors=2; }
++ if(((*(volatile unsigned char*)LSR) & OE) == OE) { errors=1; }
++
++
++ if (!errors)
++ break;
++ }
++else
++ {
++ c = 0; /* no one pressed a key. return a NULL and get out of here */
++ errors = -1;
++ break;
++ }
++ } /* END OF WHILE 1*/
++
++ if (error_p != NULL)
++ {
++ *error_p = errors;
++ }
++ return(c);
++
++return 0;
++}
++
++/**********************************************************************************************************************/
++
++
++/* Generate the table of constants used in executing the CRC32 algorithm: */
++static int crc16_init(void){
++ int i, j;
++ unsigned short crc;
++
++ if(crc16_table == NULL){
++
++ /* This table is currently _not_ freed: */
++ if((crc16_table =
++ (unsigned short *)mmalloc(CRC_TABLE_SIZE *
++ sizeof(unsigned short))) == NULL)
++ return -1;
++
++ for(i = 0; i < CRC_TABLE_SIZE; ++i){
++
++ crc = i << 8;
++
++ for(j = 8; j > 0; --j){
++
++ if(crc & 0x8000)
++ crc = (crc << 1) ^ CRC16_POLYNOMIAL;
++ else
++ crc <<= 1;
++
++ }
++
++ crc16_table[i] = crc;
++
++ }
++
++ }
++
++ return 0;
++}
++
++
++/* Perform a CRC16 computation over `buf'. This method was derived from
++ * an algorithm (C) 1986 by Gary S. Brown, and was checked against an
++ * implementation (C) 2000 by Compaq Computer Corporation, authored by
++ * George France.
++ */
++static unsigned short crc16_buf(unsigned char *buf, unsigned int length)
++{
++ unsigned short crc = 0;
++
++ while(length-- > 0)
++ crc = crc16_table[(crc >> 8) & 0xff] ^ (crc << 8) ^ *buf++;
++
++ return crc;
++}
++
++
++/*************************************************************************************/
++
++#if 0
++
++U_BOOT_CMD(econloady, 3, 0, do_econloady,
++ "econloady - load binary file over serial line (ymodem mode)\n",
++ "Usage : econloady basic (or) econloady uboot (or) econloady kernel (or) econloady rootfs (or) econloady ram \n"
++);
++#else
++U_BOOT_CMD(loady, 3, 0, do_loady,
++ "loady - load binary file over serial line (ymodem mode)\n",
++ "Usage : loady basic (or) loady uboot (or) loady kernel (or) loady rootfs (or) loady ram \n"
++);
++
++#endif
++
++/****************************************************************************************/
++
++static inline void delay(int units)
++{
++ volatile int i;
++ for(i = 0; i < units * DELAY_UNIT; ++i);
++}
++
++static int receive_byte(char *c, int timeout)
++{
++ int error = 0;
++ *c = awaitkey(timeout * AWAITKEY_UNIT, &error);
++ return error ? -1 : 0;
++
++}
++
++/* Returns 0 on success, 1 on corrupt packet, -1 on error (timeout): */
++static int receive_packet(char *data, int *length, int use_crc, int timeout)
++{
++ int i;
++ unsigned int packet_size, sum;
++ char c;
++ *length = 0;
++ if(receive_byte(&c, timeout) < 0)
++ return -1;
++ switch(c)
++ {
++ case SOH:
++ packet_size = PACKET_SIZE;
++ break;
++ case STX:
++ packet_size = PACKET_1K_SIZE;
++ break;
++ case EOT:
++ return 0;
++ case CAN:
++ if(receive_byte(&c, timeout) == 0 && c == CAN)
++ {
++ *length = -1;
++ return 0;
++ }
++ default:
++
++ /* This case could be the result of corruption on the first octet
++ * of the packet, but it's more likely that it's the user banging
++ * on the terminal trying to abort a transfer. Technically, the
++ * former case deserves a NAK, but for now we'll just treat this
++ * as an abort case.
++ */
++
++ *length = -1;
++ return 0;
++ }
++
++ *data = c;
++
++ for(i = 1; i < (packet_size +
++ (use_crc ? PACKET_OVERHEAD_CRC : PACKET_OVERHEAD)); ++i)
++ if(receive_byte(data + i, timeout) < 0)
++ return -1;
++
++ /* Just a sanity check on the sequence number/complement value.
++ * Caller should check for in-order arrival.
++ */
++ if(data[PACKET_SEQNO_INDEX] !=
++ (data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff)
++ return 1;
++
++ if(use_crc){
++
++ /* It seems odd that the CRC doesn't cover the three preamble bytes. */
++ if(crc16_buf(data + PACKET_HEADER, packet_size + PACKET_TRAILER_CRC) != 0)
++ return 1;
++
++ } else {
++
++ for(i = PACKET_HEADER, sum = 0; i < packet_size + PACKET_HEADER; ++i)
++ sum += data[i];
++
++ if((sum & 0xff) != (data[i] & 0xff))
++ return 1;
++
++ }
++
++ *length = packet_size;
++
++ return 0;
++}
++
++
++//vinoth
++#if 0
++static int do_econloady(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++#else
++static int do_loady(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++#endif
++{
++
++ char *fstartaddr=NULL;
++ char *fendaddr=NULL;
++ char *filename=NULL;
++ unsigned int size=0;
++ char filesize[10];
++ char *arg[10];
++ if(argc != 2)
++ {
++#if 0
++ printf("usage: econloady basic (or) econloady uboot (or) econloady kernel (or) \n econloady rootfs (or) econloady ram \n ");
++#else
++ printf("usage: loady basic (or) loady uboot (or) loady kernel (or) loady rootfs (or) loady ram \n ");
++#endif
++ return 0;
++ }
++ if(!strcmp(argv[1],"basic"))
++ {
++ fstartaddr =(char *) BASIC_START_ADDR;
++ fendaddr = (char *)BASIC_END_ADDR;
++ }
++ else if(!strcmp(argv[1],"uboot"))
++ {
++ fstartaddr =(char *) UBOOT_START_ADDR;
++ fendaddr = (char *)UBOOT_END_ADDR;
++ }
++#if 0
++ else if(!strcmp(argv[1],"eboot"))
++ {
++ fstartaddr =(char *) EBOOT_START_ADDR;
++ fendaddr = (char *)EBOOT_END_ADDR;
++ }
++#endif
++ else if(!strcmp(argv[1],"kernel"))
++ {
++ fstartaddr = (char *)KERNEL_START_ADDR;
++ fendaddr = (char *)KERNEL_END_ADDR;
++ }
++ else if(!strcmp(argv[1],"rootfs"))
++ {
++ fstartaddr = (char *)ROOTFS_START_ADDR;
++ fendaddr = (char *)ROOTFS_END_ADDR;
++ }
++#if 0
++ else if(!strcmp(argv[1],"flash2"))
++ {
++ fstartaddr = (char *)FLASH2_START_ADDR;
++ fendaddr = (char *)FLASH2_END_ADDR;
++ }
++
++ else if(!strcmp(argv[1],"flash"))
++ {
++ fstartaddr = (char *)FLASH_START_ADDR;
++ fendaddr = (char *)FLASH_END_ADDR;
++ }
++ else if(!strcmp(argv[1],"kramdisk"))
++ {
++ fstartaddr = (char *)KRAMDISK_START_ADDR;
++ fendaddr = (char *)KRAMDISK_END_ADDR;
++ }
++#endif
++ else if(!strcmp(argv[1],"ram"))
++ {
++ printf(" Loading the file to sdram at address = 0x%x\n",LOAD_ADDR);
++ size=ymodem_receive((char *)LOAD_ADDR);
++ printf(" file of size = 0x%x bytes is loaded in SDRAM successfully \n",size);
++ return 0;
++ }
++ else
++ {
++#if 0
++ printf("usage: econloady basic (or) econloady uboot (or) econloady kernel (or) \n econloady rootfs (or) econloady ram \n");
++
++#else
++ printf("usage: loady basic (or) loady uboot (or) loady kernel (or) loady rootfs (or) loady ram \n");
++#endif
++ return 0;
++ }
++
++
++ printf(" Loading the file to sdram at address = 0x%x\n",LOAD_ADDR);
++ size=ymodem_receive((char *)LOAD_ADDR);
++ if(size == 0)
++ {
++ printf(" file of size = 0x%x bytes is loaded in SDRAM successfully \n",size);
++ printf(" Download valid file on non-zero size \n");
++ return 0;
++ }
++
++ printf(" file of size = 0x%x bytes is loaded in SDRAM successfully \n",size);
++ size += 1; //Added by Tharma on 8July 2007 for avoiding the CRC error while checking the image if the copied image size is an odd number
++ size /= 2;
++ sprintf(filesize,"%lx",size);
++ //unlock the flash
++ arg[0] = (char *)"protect";
++ arg[1] = (char *)"off";
++ arg[2] = (char *)"all";
++ do_protect(NULL,0,3,arg);
++
++ //erase the flash for the given address
++ printf("Erasing Flash from start addr=%s to end addr=%s \r\n",fstartaddr,fendaddr);
++ arg[0] = (char *)"erase";
++ arg[1] = (char *)fstartaddr;
++ arg[2] = (char *)fendaddr;
++ do_flerase(NULL,0,3,arg);
++ //copy data from sdram to flash
++ printf("Copying %s words(word=16bit)from source addr "SDRAM_ADDR" to target addr %s \r\n",filesize,fstartaddr);
++
++ arg[0] = (char *)"cp.w";
++ arg[1] = (char *)SDRAM_ADDR;
++ arg[2] = (char *)fstartaddr;
++ arg[3] = (char *)filesize;
++ do_mem_cp(NULL,0,4,arg);
++ return 0;
++}
++
++
++
++//char buf[2048];
++
++/* Returns the length of the file received, or 0 on error: */
++unsigned int ymodem_receive(char *buf)
++{
++ unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
++ int packet_length, i, file_done, session_done, crc_tries, crc_nak, use_crc;
++ unsigned int packets_received, errors, timeout, first_try = 1;
++ char file_name[FILE_NAME_LENGTH], file_size[FILE_SIZE_LENGTH], *file_ptr;
++ char *buf_ptr;
++ unsigned long size;
++#ifdef CONFIG_MD5
++ unsigned int sum[MD5_SUM_WORDS];
++#endif
++
++ if(crc16_init() < 0)
++ {
++ printf("Unable to generate CRC16 lookup table\r\n");
++ return 0;
++ }
++
++ printf("ready for YMODEM transfer...\r\n");
++
++ /* Give the user time to frantically type in the file name: */
++ timeout = INITIAL_TIMEOUT;
++
++ for(session_done = 0, errors = 0; ; )
++ {
++ crc_tries = crc_nak = use_crc = 1;
++ if(!first_try)
++ serial_putc(CRC);
++ first_try = 0;
++ for(packets_received = 0, file_done = 0, buf_ptr = buf; ; )
++ {
++ switch(receive_packet(packet_data, &packet_length, use_crc, timeout))
++ {
++ case 0:
++ errors = 0;
++ switch(packet_length)
++ {
++ case -1: /* abort */
++ serial_putc(ACK);
++ return 0;
++ case 0: /* end of transmission */
++ serial_putc(ACK);
++ /* Should add some sort of sanity check on the number of
++ * packets received and the advertised file length.
++ */
++ file_done = 1;
++ break;
++ default: /* normal packet */
++ if((packet_data[PACKET_SEQNO_INDEX] & 0xff) !=
++ (packets_received & 0xff))
++ {
++ serial_putc(NAK);
++ }
++ else
++ {
++ if(packets_received == 0)
++ {
++ /* The spec suggests that the whole data section should
++ * be zeroed, but I don't think all senders do this. If
++ * we have a NULL filename and the first few digits of
++ * the file length are zero, we'll call it empty.
++ */
++ for(i = PACKET_HEADER; i < PACKET_HEADER + 4; ++i)
++ if(packet_data[i] != 0)
++ break;
++ if(i < PACKET_HEADER + 4)
++ { /* filename packet has data */
++ for(file_ptr = packet_data + PACKET_HEADER, i = 0;
++ *file_ptr && i < FILE_NAME_LENGTH;)
++ file_name[i++] = *file_ptr++;
++ file_name[i++] = '\0';
++ for(++file_ptr, i = 0;*file_ptr != ' ' && i < FILE_SIZE_LENGTH;)
++ file_size[i++] = *file_ptr++;
++ file_size[i++] = '\0';
++ serial_putc(ACK);
++ serial_putc(crc_nak ? CRC : NAK);
++ crc_nak = 0;
++ }
++ else
++ { /* filename packet is empty; end session */
++ serial_putc(ACK);
++ file_done = 1;
++ session_done = 1;
++ break;
++ }
++ }
++ else
++ {
++ memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
++ buf_ptr += packet_length;
++ serial_putc(ACK);
++ }
++ ++packets_received;
++ } /* sequence number ok */
++ }
++ break;
++ default:
++ if(++errors >= ((packets_received == 0 ? MAX_CRC_TRIES : 0) + MAX_ERRORS))
++ {
++ serial_putc(CAN);
++ serial_putc(CAN);
++ delay(1);
++ printf("Too many errors during receive; giving up.\r\n");
++ return 0;
++ }
++ if(packets_received == 0)
++ {
++ if(crc_tries < MAX_CRC_TRIES)
++ {
++ ++crc_tries;
++ timeout = CRC_TIMEOUT;
++ }
++ else
++ {
++ crc_nak = use_crc = 0;
++ timeout = NAK_TIMEOUT;
++ }
++ }
++ serial_putc(crc_nak ? CRC : NAK);
++ }
++ if(file_done)
++ break;
++
++ } /* receive packets */
++ if(session_done)
++ break;
++ } /* receive files */
++
++ delay(2);
++ printf("\n File Name : %s\n",file_name);
++ printf("\n File Size : 0x%x\n",(unsigned int)(simple_strtoul(file_size,NULL,10)));
++ return (unsigned int)(simple_strtoul(file_size,NULL,10));
++
++}
+diff -Naur u-boot-2008.10_original/common/cmd_econ_usbdfu.c u-boot-2008.10/common/cmd_econ_usbdfu.c
+--- u-boot-2008.10_original/common/cmd_econ_usbdfu.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_econ_usbdfu.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,192 @@
++/*
++ * serial-pxausb.c : "serial-over-usb" driver for BLOB
++ *
++ * Copyright (c) 2004, Intel Corporation (alek.du@intel.com)
++ * slightly modified from Ether-bvdusb.c which is from
++ * Copyright (c) 2003, Intel Corporation (yu.tang@intel.com)
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <common.h>
++#include <command.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/pxa-regs.h>
++
++#include "pxa_usb.h"
++
++
++void usb_driver_reset(void);
++static void usb_serial_tx_callback(int flag, int size);
++int usb_dfu_init(void);
++
++#define msleep(x) udelay(x*1000)
++#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
++
++#define SERIAL_VENDOR_ID 0x0483
++#define SERIAL_PRODUCT_ID 0xDF11
++
++
++#include "usb_dfu.h"
++#include "bvd_usb_ctl.c"
++#include "bvd_usb_ep0.c"
++#include "bvd_usb_ep1.c"
++#include "bvd_usb_ep2.c"
++
++desc_t * pdesc;
++config_desc_t *cfg;
++intf_desc_t *intf;
++dfu_func_desc_t *dfu_func;
++ep_desc_t *ep;
++
++void usb_driver_reset(void)
++{
++ printf("+++ usb_driver_reset\n");
++ pdesc = pxa_usb_get_descriptor_ptr();
++
++
++ /* setup device descriptor */
++ pdesc->dev.idVendor = SERIAL_VENDOR_ID;
++ pdesc->dev.idProduct = SERIAL_PRODUCT_ID;
++ pdesc->dev.bNumConfigurations = 1;
++
++ cfg = (config_desc_t*) (pdesc->cdb);
++
++ cfg->bLength = sizeof( config_desc_t );
++ cfg->bDescriptorType = USB_DESC_CONFIG;
++ cfg->wTotalLength = make_word_c( sizeof(config_desc_t) +
++ sizeof(intf_desc_t) * 1+
++ sizeof(ep_desc_t) * 2);
++ cfg->bNumInterfaces = 1;
++ cfg->bConfigurationValue = 1;
++ cfg->iConfiguration = 0;
++ cfg->bmAttributes = USB_CONFIG_SELFPOWERED;
++ cfg->MaxPower = USB_POWER( 500 );
++
++ intf = (intf_desc_t *) ( cfg + 1);
++ intf->bLength = sizeof( intf_desc_t );
++ intf->bDescriptorType = USB_DESC_INTERFACE;
++ intf->bInterfaceNumber = 0;
++ intf->bAlternateSetting = 0;
++ intf->bNumEndpoints = 2;
++ intf->bInterfaceClass = 0xFE;
++ intf->bInterfaceSubClass = 0x01;
++ intf->bInterfaceProtocol = 0x02;
++ intf->iInterface = 0;
++
++// dfu_func=(dfu_func_desc_t*) (intf + 1);
++
++// dfu_func->bLength = sizeof(dfu_func_desc_t);
++// dfu_func->bDescriptorType = USB_DESC_FUNCTIONAL;
++// dfu_func->bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_MANIFEST_TOL|USB_DFU_WILL_DETACH;
++// dfu_func->wDetachTimeOut = 0xff00;
++// dfu_func->wTransferSize = 0xffff;
++// dfu_func->bcdDFUVersion = 0x0100;
++ ep = (ep_desc_t *) (intf + 1);
++ ep[0].bLength = sizeof( ep_desc_t );
++ ep[0].bDescriptorType = USB_DESC_ENDPOINT;
++ ep[0].bEndpointAddress = USB_EP_ADDRESS( 1, USB_IN );
++ ep[0].bmAttributes = USB_EP_BULK;
++ ep[0].wMaxPacketSize = make_word( 64 );
++ ep[0].bInterval = 0;
++
++ ep[1].bLength = sizeof( ep_desc_t );
++ ep[1].bDescriptorType = USB_DESC_ENDPOINT;
++ ep[1].bEndpointAddress = USB_EP_ADDRESS( 2, USB_OUT );
++ ep[1].bmAttributes = USB_EP_BULK;
++ ep[1].wMaxPacketSize = make_word( 64 );
++ ep[1].bInterval = 0;
++
++
++ printf("starting ep2 receive\n");
++ /* setup to receive */
++ printf("--- usb_driver_reset\n");
++}
++
++//static int usb_serial_init()
++int do_client()
++{
++ printf("usb client code start\n");
++
++
++ /* initialize PXA USB controller */
++ usb_dfu_init();
++ g_DFU_Download_Complete=FALSE;
++ UDCCSR0=UDCCSR0_IPR;
++ while(1)
++ {
++ if( (UDCISR0 & 0x1) == 1)
++ {
++ // printf("Interrupt is occured \n");
++ ep0_int_hndlr();
++ // printf(" Clearing the Interrrupt for Ep0 \n");
++ UDCISR0 = 0x01;
++
++ }
++ if(g_DFU_Download_Complete)
++ {
++ udc_disable();
++ //FlashRead( ((UINT32) OALPAtoVA(IMAGE_BOOT_BLDRIMAGE_FLASH_PA_START,FALSE) +NOR_FLASH_BMPBIN_OFFSET), SDRAM_BMPBIN_ADDR, NOR_FLASH_BMPBIN_SIZE);
++
++ break;
++ }
++ /*if( (UDCISR0 & 0x10) == 0x10)
++ {
++ printf("ep2 Interrupt is occured \n");
++ printf(" Clearing the Interrrupt for Ep2 \n");
++ UDCISR0 = 0x10;
++
++ }
++ if( (UDCISR0 & 0x04) == 0x04)
++ {
++ printf("ep1 Interrupt is occured \n");
++ printf(" Clearing the Interrrupt for Ep1 \n");
++ UDCISR0 = 0x04;
++
++ } */
++ }
++
++ return 0;
++}
++
++
++int usb_dfu_init(void)
++{
++
++
++ /* initialize PXA USB controller */
++ pxa_usb_open();
++ pxa_usb_start();
++
++ return 0;
++}
++
++
++
++int do_econdfu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++U_BOOT_CMD(
++ edfu, 1, 0, do_econdfu,
++ "edfu\t- download image from PC to board's SDRAM memory at address 0xa0060000 (econ code)\n",
++ "no arguments\n"
++ "edfu\t- download image from PC to board's SDRAM memory at address 0xa0060000 (econ code)\n"
++);
++
++int do_econdfu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ do_client();
++ return 0;
++}
++
+diff -Naur u-boot-2008.10_original/common/cmd_lcd_i2c.c u-boot-2008.10/common/cmd_lcd_i2c.c
+--- u-boot-2008.10_original/common/cmd_lcd_i2c.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_lcd_i2c.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,205 @@
++/***************************************************************************
++ * Copyright (C) 2007 by e-con Systems All Rights Reserved. *
++ * www.e-consystems.com *
++ * *
++ * The source code contained or described herein and all documents *
++ * related to the source code (Material) are owned by e-con Systems *
++ * *
++ * *
++ * *
++ * *
++ * Version No : 000-0001 CODE_REV : 0.0.0.0 *
++ ***************************************************************************/
++
++/***************************************************/
++
++#include <common.h>
++#include <command.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++
++#define CHECK_IN_FAIL_LIMIT(x) ((x >= ERROR_BASE) && (x <= ERROR_END))
++#define SLAVE_ADDRESS (0x58)
++#define DISABLE 0x0
++#define ENABLE 0x1
++#define DRIVER_SUCCESS_BASE (0x7EEFFFFF)
++#define DRIVER_ERROR_BASE (0xFEEFFFFF)
++#define BAND_LIMIT (0x00100000)
++#define DRIVER_BASIC_SUCCESS (DRIVER_SUCCESS_BASE -BAND_LIMIT)
++#define DRIVER_I2C_SUCCESS (DRIVER_BASIC_SUCCESS -BAND_LIMIT)
++#define I2C_TX_EMPTY_SEND_SUCCESS (DRIVER_I2C_SUCCESS -2)
++#define DRIVER_BASIC_ERRORS (DRIVER_ERROR_BASE -BAND_LIMIT)
++#define DRIVER_I2C_ERROR (DRIVER_BASIC_ERRORS -BAND_LIMIT)
++#define I2C_TX_EMPTY_SEND_FAIL (DRIVER_I2C_ERROR -2)
++#define I2C_INIT_SUCCESS (DRIVER_I2C_SUCCESS -1)
++#define I2C_WRITE_SUCCESS (DRIVER_I2C_SUCCESS -3)
++#define I2C_RX_FULL_FAIL (DRIVER_I2C_ERROR -4)
++#define I2C_RX_FULL_SUCCESS (DRIVER_I2C_SUCCESS -4)
++#define I2C_READ_SUCCESS (DRIVER_I2C_SUCCESS -5)
++#define I2C_CAM_READ_REGISTER_SUCCESS (DRIVER_I2C_SUCCESS -6)
++
++typedef unsigned char UINT8;
++typedef unsigned short UINT16;
++typedef unsigned int UINT32;
++typedef signed char INT8;
++typedef signed short INT16;
++typedef signed int INT32;
++
++typedef unsigned char* UPINT8;
++
++#define SUCCESS_BASE (0x00000000)
++#define SUCCESS_END (0x7FFFFFFF)
++
++#define ERROR_BASE (0x80000000)
++#define ERROR_END (0xFFFFFFFF)
++
++#define BOOL int
++#define IDBR_MODE (0x01)
++
++typedef UINT32 FNRESLT;
++#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
++
++
++
++extern void set_GPIO_mode(int gpio_mode);
++#define pxa_gpio_mode(x) set_GPIO_mode(x)
++#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT)
++#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_OUT)
++
++
++int do_lcd_i2c_write (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++FNRESLT i2c_tx_empty(UINT32 timeout);
++FNRESLT lcd_i2c_write(UINT16 reg_address,UINT8 reg_value);
++FNRESLT i2c_rx_full(INT32 timeout);
++FNRESLT ov3640_cam_read(UINT16 reg_address,UPINT8 reg_value);
++
++
++U_BOOT_CMD(
++ lcdi2cwrite, 3, 0, do_lcd_i2c_write,
++ "lcdi2cwrite -write the value in the digital pot for tuning vcom\n",
++ "\tUsage: lcdi2cwrite\n"
++ );
++int do_lcd_i2c_write (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++// lcd_i2c_write(0x00,0x6E);
++ lcd_i2c_write(0x2D,0x6E);
++ return 0;
++}
++
++
++FNRESLT i2c_tx_empty(UINT32 timeout)
++{
++ UINT32 temp=0;
++
++ while (timeout--)
++ {
++ temp = ISR;
++ if((temp & ISR_ITE) == ISR_ITE)
++ {
++ ISR = temp | ISR_ITE;
++
++ if ((temp & ISR_ALD) == ISR_ALD)
++ {
++ ISR |= ISR_ALD;
++ }
++
++ return I2C_TX_EMPTY_SEND_SUCCESS;
++ }
++ mdelay(1);
++ }
++ printf("ISR %x\n",temp);
++ return I2C_TX_EMPTY_SEND_FAIL;
++}
++
++
++/*
++ * Wait for Receive empty status
++ *
++ * RETURNS: 0 success
++ * 1 failure
++ */
++FNRESLT i2c_rx_full(INT32 timeout)
++{
++ UINT32 temp;
++
++ while (timeout--)
++ {
++ temp = ISR;
++ if ((temp & ISR_IRF) == ISR_IRF)
++ {
++ ISR = temp | ISR_IRF;
++ return I2C_RX_FULL_SUCCESS;
++ }
++ mdelay(1);
++ }
++
++ return I2C_RX_FULL_FAIL;
++}
++
++FNRESLT ov3640_cam_read(UINT16 reg_address,UPINT8 reg_value)
++{
++ UINT8 bytes_buf[2];
++ FNRESLT ret_val;
++
++ ret_val=i2c_init(0x00);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ return ret_val;
++ }
++
++ bytes_buf[0] = (reg_address>> 8) & 0xFF;
++ bytes_buf[1] = (reg_address & 0xFF);
++
++ ret_val=i2c_write(SLAVE_ADDRESS,bytes_buf,2,(BOOL)DISABLE);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ return ret_val;
++ }
++ else
++ {
++ bytes_buf[0] = 0x00;
++ ret_val=i2c_read(SLAVE_ADDRESS,bytes_buf,1,(BOOL)ENABLE);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ return ret_val;
++ }
++ *reg_value = bytes_buf[0];
++ }
++ return I2C_CAM_READ_REGISTER_SUCCESS;
++}
++
++
++
++FNRESLT lcd_i2c_write(UINT16 reg_address,UINT8 reg_value)
++{
++ UINT8 bytes_buf[3];
++ UINT8 *reg_val_read;
++ FNRESLT ret_val;
++ mdelay(100);
++ ret_val=i2c_init(0x00);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ return ret_val;
++ }
++ bytes_buf[0] = (reg_address>> 8) & 0xFF;
++ bytes_buf[1] = (reg_address & 0xFF);
++ bytes_buf[2] = (reg_value & 0xFF);
++
++ ret_val=i2c_write(SLAVE_ADDRESS,bytes_buf,3,(BOOL)ENABLE);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ // return ret_val;
++ }
++
++ reg_address=0x59;
++ ret_val=ov3640_cam_read(reg_address,®_val_read);
++ if(CHECK_IN_FAIL_LIMIT(ret_val))
++ {
++ // return (ret_val);
++ }
++ printf("%x %x \n",reg_address,reg_val_read);
++
++ return I2C_WRITE_SUCCESS;
++}
++
++
++/*************************************************/
+diff -Naur u-boot-2008.10_original/common/cmd_mac_program.c u-boot-2008.10/common/cmd_mac_program.c
+--- u-boot-2008.10_original/common/cmd_mac_program.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_mac_program.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,127 @@
++#include <common.h>
++#include <command.h>
++
++extern int do_unlock (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++extern int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_mem_cp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++extern int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++int do_setmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++int do_getmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++U_BOOT_CMD(
++ setmac, CFG_MAXARGS, 1, do_setmac,
++ "setmac - set the MAC address for the ASIX Chip\n",
++ "MAC Address (i.e 12 bytes string)\n"
++ );
++U_BOOT_CMD(
++ getmac, CFG_MAXARGS, 1, do_getmac,
++ "getmac - get the MAC address for the ASIX Chip\n",
++ "no arguments needed\n"
++ );
++
++#define mdelay(n) udelay((n)*1000)
++
++int do_setmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++#define MAC_ADDRESS_IN_NOR_FLASH_START "0x00008000"
++#define MAC_ADDRESS_IN_NOR_FLASH_END "0x0000ffff"
++#define MAC_ADDRESS_SIZE_IN_WORDS "3"
++#define MAC_ADDDRESS_LENGTH 6
++#define SDRAM_ADDR 0xa0000000
++#define MACWRITE_STRING "unlock;protect off all;erase 0x8000 0xffff;cp.w 0xa0000000 0x8000 0x03"
++
++
++ char *fstartaddr=MAC_ADDRESS_IN_NOR_FLASH_START;
++ char *fendaddr=MAC_ADDRESS_IN_NOR_FLASH_END;
++ char *filename=NULL;
++ unsigned int i=0;
++ char filesize[10]=MAC_ADDRESS_SIZE_IN_WORDS;
++ char *arg[10];
++ volatile unsigned char *mac_addr=SDRAM_ADDR;
++ unsigned char buf[3];
++
++
++ if(argc>=2)
++ {
++ if(strlen(argv[1])!=12)
++ {
++ printf("MAC address is nvalid. The MAC address should be a 12 bytes string \n");
++ return 0;
++ }
++ else
++ {
++ buf[2]='\0'; // null character
++ memset(buf,0,3);
++ for(i=0;i<6;i++)
++ {
++ memcpy(buf,&(argv[1][i*2]),2);
++ mac_addr[i]=(unsigned char)simple_strtoul(buf,NULL,16);
++ memset(buf,0,3);
++ }
++
++ printf("MAC Address to be written into NOR flash is :");
++ for (i = 0; i <MAC_ADDDRESS_LENGTH ; i++)
++ {
++ printf (" %2.2x", mac_addr[i]);
++ }
++ printf("\n");
++
++ setenv("macwrite",MACWRITE_STRING);
++
++
++ arg[0] = (char *)"run";
++ arg[1] = (char *)"macwrite";
++ do_run(NULL,0,2,arg);
++#if 0
++ //unlock the flash
++ do_unlock(NULL,0,1,NULL);
++ arg[0] = (char *)"protect";
++ arg[1] = (char *)"off";
++ arg[2] = (char *)"all";
++ do_protect(NULL,0,3,arg);
++
++ //erase the flash for the given address
++ printf("Erasing Flash from start addr=%s to end addr=%s \r\n",fstartaddr,fendaddr);
++ arg[0] = (char *)"erase";
++ arg[1] = (char *)fstartaddr;
++ arg[2] = (char *)fendaddr;
++ do_flerase(NULL,0,3,arg);
++ mdelay(1000);
++ //copy data from sdram to flash
++ printf("Copying %s words(word=16bit)from source addr 0x%08X to target addr %s \r\n",filesize,mac_addr,fstartaddr);
++
++ arg[0] = (char *)"cp.w";
++ arg[1] = (char *)mac_addr;
++ arg[2] = (char *)fstartaddr;
++ arg[3] = (char *)filesize;
++ do_mem_cp(NULL,0,4,arg);
++#endif
++ printf("MAC address is programmed in the NOR Flash memory \n");
++ }
++ }
++ else
++ {
++ printf("give MAC address of 12 bytes string as argument \n");
++ }
++
++ return 0;
++}
++
++int do_getmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ int i=0;
++ unsigned char mac_addr[6];
++#define MAC_ADDDRESS_LENGTH 6
++#define MAC_ADDRESS_IN_NOR_FLASH 0x00008000
++ memcpy(mac_addr,MAC_ADDRESS_IN_NOR_FLASH,MAC_ADDDRESS_LENGTH);
++ printf("MAC Address read from NOR flash is :");
++ for (i = 0; i <MAC_ADDDRESS_LENGTH ; i++)
++ {
++ printf (" %2.2x", mac_addr[i]);
++ }
++ printf("\n");
++
++ return 0;
++}
+diff -Naur u-boot-2008.10_original/common/cmd_net.c u-boot-2008.10/common/cmd_net.c
+--- u-boot-2008.10_original/common/cmd_net.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/common/cmd_net.c 2009-08-12 18:21:20.000000000 +0530
+@@ -190,7 +190,8 @@
+ show_boot_progress (80);
+ if ((size = NetLoop(proto)) < 0) {
+ show_boot_progress (-81);
+- return 1;
++ return size; // Added by Tharma on July20, 2007
++ //return 1;
+ }
+
+ show_boot_progress (81);
+@@ -236,7 +237,9 @@
+ show_boot_progress (-83);
+ else
+ show_boot_progress (84);
+- return rcode;
++ return size; // Added by econ on July20, 2007
++ //return rcode;
++
+ }
+
+ #if defined(CONFIG_CMD_PING)
+diff -Naur u-boot-2008.10_original/common/cmd_nvedit.c u-boot-2008.10/common/cmd_nvedit.c
+--- u-boot-2008.10_original/common/cmd_nvedit.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/common/cmd_nvedit.c 2009-08-12 18:21:20.000000000 +0530
+@@ -212,7 +212,11 @@
+ printf("Can't delete \"%s\"\n", name);
+ return 1;
+ }
+-
++#ifdef CONFIG_CONSOLE_MUX
++ i = iomux_doenv(console, argv[2]);
++ if (i)
++ return i;
++#else
+ /* Try assigning specified device */
+ if (console_assign (console, argv[2]) < 0)
+ return 1;
+@@ -221,6 +225,8 @@
+ if (serial_assign (argv[2]) < 0)
+ return 1;
+ #endif
++#endif /* CONFIG_CONSOLE_MUX */
++
+ }
+
+ /*
+diff -Naur u-boot-2008.10_original/common/cmd_pwr_i2c.c u-boot-2008.10/common/cmd_pwr_i2c.c
+--- u-boot-2008.10_original/common/cmd_pwr_i2c.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_pwr_i2c.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,545 @@
++/*
++ * (C) Copyright 2000
++ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
++ *
++ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2003 Pengutronix e.K.
++ * Robert Schwebel <r.schwebel@pengutronix.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ * Back ported to the 8xx platform (from the 8260 platform) by
++ * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
++ */
++
++/* FIXME: this file is PXA255 specific! What about other XScales? */
++
++#include <common.h>
++#include <command.h>
++#define CONFIG_HARD_PWR_I2C
++#ifdef CONFIG_HARD_PWR_I2C
++
++/*
++ * - CFG_PWR_I2C_SPEED
++ * - PWR_I2C_PXA_SLAVE_ADDR
++ */
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <i2c.h>
++
++/*#define DEBUG_PWR_I2C 1 /###* activate local debugging output */
++#define PWR_I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */
++#define PWR_I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
++#define PWR_I2C_ISR_INIT 0x7FF
++
++#ifdef DEBUG_PWR_I2C
++#define PRINTD(x) printf x
++#else
++#define PRINTD(x)
++#endif
++
++
++/* Shall the current transfer have a start/stop condition? */
++#define PWR_I2C_COND_NORMAL 0
++#define PWR_I2C_COND_START 1
++#define PWR_I2C_COND_STOP 2
++
++/* Shall the current transfer be ack/nacked or being waited for it? */
++#define PWR_I2C_ACKNAK_WAITACK 1
++#define PWR_I2C_ACKNAK_SENDACK 2
++#define PWR_I2C_ACKNAK_SENDNAK 4
++
++/* Specify who shall transfer the data (master or slave) */
++#define PWR_I2C_READ 0
++#define PWR_I2C_WRITE 1
++
++/* All transfers are described by this data structure */
++struct pwr_i2c_msg {
++ u8 condition;
++ u8 acknack;
++ u8 direction;
++ u8 data;
++};
++
++
++#define TPS65020_CHIP_ADDR 0x48 // 7bit Address = 100 1000
++
++/**
++ * pwr_i2c_pxa_reset: - reset the host controller
++ *
++ */
++
++static void pwr_i2c_reset( void )
++{
++ PCFR |= PCFR_PI2C_EN;
++ PWRICR &= ~ICR_IUE; /* disable unit */
++ PWRICR |= ICR_UR; /* reset the unit */
++ udelay(100);
++ PWRICR &= ~ICR_IUE; /* disable unit */
++ CKEN |= CKEN15_PWRI2C; /* set the global PWR_I2C clock on */
++ PWRISAR = PWR_I2C_PXA_SLAVE_ADDR; /* set our slave address */
++ PWRICR = PWR_I2C_ICR_INIT; /* set control register values */
++ PWRISR = PWR_I2C_ISR_INIT; /* set clear interrupt bits */
++ PWRICR |= ICR_IUE; /* enable unit */
++ udelay(100);
++}
++
++
++/**
++ * pwr_i2c_isr_set_cleared: - wait until certain bits of the pwr_i2c status register
++ * are set and cleared
++ *
++ * @return: 0 in case of success, 1 means timeout (no match within 10 ms).
++ */
++
++static int pwr_i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
++{
++ int timeout = 10000;
++
++ while( ((PWRISR & set_mask)!=set_mask) || ((PWRISR & cleared_mask)!=0) )
++ {
++ udelay( 10 );
++ if( timeout-- < 0 ) return 0;
++ }
++
++ return 1;
++}
++
++
++/**
++ * pwr_i2c_transfer: - Transfer one byte over the pwr_i2c bus
++ *
++ * This function can tranfer a byte over the pwr_i2c bus in both directions.
++ * It is used by the public API functions.
++ *
++ * @return: 0: transfer successful
++ * -1: message is empty
++ * -2: transmit timeout
++ * -3: ACK missing
++ * -4: receive timeout
++ * -5: illegal parameters
++ * -6: bus is busy and couldn't be aquired
++ */
++int pwr_i2c_transfer(struct pwr_i2c_msg *msg)
++{
++ int ret;
++
++ if (!msg)
++ goto transfer_error_msg_empty;
++
++ switch(msg->direction) {
++
++ case PWR_I2C_WRITE:
++
++ /* check if bus is not busy */
++ if (!pwr_i2c_isr_set_cleared(0,ISR_IBB))
++ goto transfer_error_bus_busy;
++
++ /* start transmission */
++ PWRICR &= ~ICR_START;
++ PWRICR &= ~ICR_STOP;
++ PWRIDBR = msg->data;
++ if (msg->condition == PWR_I2C_COND_START) PWRICR |= ICR_START;
++ if (msg->condition == PWR_I2C_COND_STOP) PWRICR |= ICR_STOP;
++ if (msg->acknack == PWR_I2C_ACKNAK_SENDNAK) PWRICR |= ICR_ACKNAK;
++ if (msg->acknack == PWR_I2C_ACKNAK_SENDACK) PWRICR &= ~ICR_ACKNAK;
++ PWRICR &= ~ICR_ALDIE;
++ PWRICR |= ICR_TB;
++
++ /* transmit register empty? */
++ if (!pwr_i2c_isr_set_cleared(ISR_ITE,0))
++ {
++ goto transfer_error_transmit_timeout;
++ }
++
++
++ /* clear 'transmit empty' state */
++ PWRISR |= ISR_ITE;
++
++ /* wait for ACK from slave */
++ if (msg->acknack == PWR_I2C_ACKNAK_WAITACK)
++ if (!pwr_i2c_isr_set_cleared(0,ISR_ACKNAK))
++ goto transfer_error_ack_missing;
++ break;
++
++ case PWR_I2C_READ:
++
++ /* check if bus is not busy */
++ if (!pwr_i2c_isr_set_cleared(0,ISR_IBB))
++ goto transfer_error_bus_busy;
++
++ /* start receive */
++ PWRICR &= ~ICR_START;
++ PWRICR &= ~ICR_STOP;
++ if (msg->condition == PWR_I2C_COND_START) PWRICR |= ICR_START;
++ if (msg->condition == PWR_I2C_COND_STOP) PWRICR |= ICR_STOP;
++ if (msg->acknack == PWR_I2C_ACKNAK_SENDNAK) PWRICR |= ICR_ACKNAK;
++ if (msg->acknack == PWR_I2C_ACKNAK_SENDACK) PWRICR &= ~ICR_ACKNAK;
++ PWRICR &= ~ICR_ALDIE;
++ PWRICR |= ICR_TB;
++
++ /* receive register full? */
++ if (!pwr_i2c_isr_set_cleared(ISR_IRF,0))
++ goto transfer_error_receive_timeout;
++
++ msg->data = PWRIDBR;
++
++ /* clear 'receive empty' state */
++ PWRISR |= ISR_IRF;
++
++ break;
++
++ default:
++
++ goto transfer_error_illegal_param;
++
++ }
++
++ return 0;
++
++transfer_error_msg_empty:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: 'msg' is empty\n"));
++ ret = -1; goto pwr_i2c_transfer_finish;
++
++transfer_error_transmit_timeout:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: transmit timeout\n"));
++ ret = -2; goto pwr_i2c_transfer_finish;
++
++transfer_error_ack_missing:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: ACK missing\n"));
++ ret = -3; goto pwr_i2c_transfer_finish;
++
++transfer_error_receive_timeout:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: receive timeout\n"));
++ ret = -4; goto pwr_i2c_transfer_finish;
++
++transfer_error_illegal_param:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: illegal parameters\n"));
++ ret = -5; goto pwr_i2c_transfer_finish;
++
++transfer_error_bus_busy:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: error: bus is busy\n"));
++ ret = -6; goto pwr_i2c_transfer_finish;
++
++pwr_i2c_transfer_finish:
++ // printf("PWRISR = 0x%08lx \n",(unsigned long)PWRISR);
++ // printf("PWRICR = 0x%08lx \n",(unsigned long)PWRICR);
++ PRINTD(("pwr_i2c_transfer: ISR: 0x%04x\n",ISR));
++ pwr_i2c_reset();
++ return ret;
++
++}
++
++/* ------------------------------------------------------------------------ */
++/* API Functions */
++/* ------------------------------------------------------------------------ */
++
++void pwr_i2c_init(int speed, int slaveaddr)
++{
++#ifdef CFG_PWR_I2C_INIT_BOARD
++ /* call board specific pwr_i2c bus reset routine before accessing the */
++ /* environment, which might be in a chip on that bus. For details */
++ /* about this problem see doc/pwr_i2c_Edge_Conditions. */
++ pwr_i2c_init_board();
++#endif
++}
++
++
++/**
++ * pwr_i2c_probe: - Test if a chip answers for a given pwr_i2c address
++ *
++ * @chip: address of the chip which is searched for
++ * @return: 0 if a chip was found, -1 otherwhise
++ */
++
++int pwr_i2c_probe(uchar chip)
++{
++ struct pwr_i2c_msg msg;
++
++ pwr_i2c_reset();
++
++ msg.condition = PWR_I2C_COND_START;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = (chip << 1) + 1;
++ if (pwr_i2c_transfer(&msg)) return -1;
++
++ msg.condition = PWR_I2C_COND_STOP;
++ msg.acknack = PWR_I2C_ACKNAK_SENDNAK;
++ msg.direction = PWR_I2C_READ;
++ msg.data = 0x00;
++ if (pwr_i2c_transfer(&msg)) return -1;
++
++ return 0;
++}
++
++
++/**
++ * pwr_i2c_read: - Read multiple bytes from an pwr_i2c device
++ *
++ * The higher level routines take into account that this function is only
++ * called with len < page length of the device (see configuration file)
++ *
++ * @chip: address of the chip which is to be read
++ * @addr: pwr_i2c data address within the chip
++ * @alen: length of the pwr_i2c data address (1..2 bytes)
++ * @buffer: where to write the data
++ * @len: how much byte do we want to read
++ * @return: 0 in case of success
++ */
++
++int pwr_i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
++{
++ struct pwr_i2c_msg msg;
++ u8 addr_bytes[3]; /* lowest...highest byte of data address */
++ int ret;
++ PRINTD(("pwr_i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
++
++
++ pwr_i2c_reset();
++ /* dummy chip address write */
++ PRINTD(("pwr_i2c_read: dummy chip address write\n"));
++ msg.condition = PWR_I2C_COND_START;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = (chip << 1);
++ msg.data &= 0xFE;
++ if ((ret=pwr_i2c_transfer(&msg)))
++ {
++ return -1;
++ }
++
++ /*
++ * send memory address bytes;
++ * alen defines how much bytes we have to send.
++ */
++ /*addr &= ((1 << CFG_EEPROM_PAGE_WRITE_BITS)-1); */
++ addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF);
++ addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF);
++ addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
++
++ while (--alen >= 0) {
++
++ PRINTD(("pwr_i2c_read: send memory word address byte %1d\n",alen));
++ msg.condition = PWR_I2C_COND_NORMAL;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = addr_bytes[alen];
++ if ((ret=pwr_i2c_transfer(&msg))) return -1;
++ }
++
++
++ /* start read sequence */
++ PRINTD(("pwr_i2c_read: start read sequence\n"));
++ msg.condition = PWR_I2C_COND_START;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = (chip << 1);
++ msg.data |= 0x01;
++ if ((ret=pwr_i2c_transfer(&msg))) return -1;
++
++
++ /* read bytes; send NACK at last byte */
++ while (len--)
++ {
++
++ if (len==0)
++ {
++ msg.condition = PWR_I2C_COND_STOP;
++ msg.acknack = PWR_I2C_ACKNAK_SENDNAK;
++ }
++ else
++ {
++ msg.condition = PWR_I2C_COND_NORMAL;
++ msg.acknack = PWR_I2C_ACKNAK_SENDACK;
++ }
++
++ msg.direction = PWR_I2C_READ;
++ msg.data = 0x00;
++ if ((ret=pwr_i2c_transfer(&msg))) return -1;
++
++ *(buffer++) = msg.data;
++
++ PRINTD(("pwr_i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
++
++ }
++
++ pwr_i2c_reset();
++
++ return 0;
++}
++
++
++/**
++ * pwr_i2c_write: - Write multiple bytes to an pwr_i2c device
++ *
++ * The higher level routines take into account that this function is only
++ * called with len < page length of the device (see configuration file)
++ *
++ * @chip: address of the chip which is to be written
++ * @addr: pwr_i2c data address within the chip
++ * @alen: length of the pwr_i2c data address (1..2 bytes)
++ * @buffer: where to find the data to be written
++ * @len: how much byte do we want to read
++ * @return: 0 in case of success
++ */
++
++int pwr_i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
++{
++ struct pwr_i2c_msg msg;
++ u8 addr_bytes[3]; /* lowest...highest byte of data address */
++
++ PRINTD(("pwr_i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
++
++ pwr_i2c_reset();
++
++ /* chip address write */
++ PRINTD(("pwr_i2c_write: chip address write\n"));
++ msg.condition = PWR_I2C_COND_START;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = (chip << 1);
++ msg.data &= 0xFE;
++ if (pwr_i2c_transfer(&msg)) return -1;
++
++ /*
++ * send memory address bytes;
++ * alen defines how much bytes we have to send.
++ */
++ addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF);
++ addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF);
++ addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
++
++ while (--alen >= 0) {
++
++ PRINTD(("pwr_i2c_write: send memory word address\n"));
++ msg.condition = PWR_I2C_COND_NORMAL;
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = addr_bytes[alen];
++ if (pwr_i2c_transfer(&msg)) return -1;
++ }
++
++ /* write bytes; send NACK at last byte */
++ while (len--) {
++
++ PRINTD(("pwr_i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
++
++ if (len==0)
++ msg.condition = PWR_I2C_COND_STOP;
++ else
++ msg.condition = PWR_I2C_COND_NORMAL;
++
++ msg.acknack = PWR_I2C_ACKNAK_WAITACK;
++ msg.direction = PWR_I2C_WRITE;
++ msg.data = *(buffer++);
++
++ if (pwr_i2c_transfer(&msg)) return -1;
++
++ }
++
++ pwr_i2c_reset();
++
++ return 0;
++
++}
++
++uchar pwr_i2c_reg_read (uchar chip, uchar reg)
++{
++ char buf;
++ chip = (uchar)TPS65020_CHIP_ADDR;
++
++ PRINTD(("pwr_i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg));
++ pwr_i2c_read(chip, reg, 1, &buf, 1);
++ return (buf);
++}
++
++int pwr_i2c_reg_write(uchar chip, uchar reg, uchar val)
++{
++ chip = (uchar)TPS65020_CHIP_ADDR;
++ PRINTD(("pwr_i2c_reg_write(chip=0x%02x, reg=0x%02x, val=0x%02x)\n",chip,reg,val));
++ pwr_i2c_write(chip, reg, 1, &val, 1);
++}
++
++#endif /* CONFIG_HARD_PWR_I2C */
++
++
++int do_pwrread (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++
++ unsigned char rtcreg_value[9];
++ int reg;
++
++ for(reg=0x00; reg<=0x08; reg++)
++ {
++ rtcreg_value[reg] = pwr_i2c_reg_read(0x48, reg);
++ printf("register[0x%02lx] =0x%02lx\n",reg,rtcreg_value[reg]);
++ }
++
++ return 0;
++
++}
++int do_pwrwrite (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++
++ unsigned char val;
++ unsigned char reg;
++ if(argc < 3)
++ {
++ printf("Usage : pwrwrite <address> <data> \n address range = 0x00-0x08 \n");
++ return 0;
++ }
++ else
++ {
++ reg = (unsigned char)(simple_strtoul(argv[1],NULL,10));
++ val = (unsigned char)(simple_strtoul(argv[2],NULL,10));
++ pwr_i2c_reg_write(0x48, reg, val);
++ }
++ return 0;
++
++}
++
++#if 0
++U_BOOT_CMD(
++ pwrread, 1, 0, do_pwrread,
++ "pwrread - Reading the register values of TPS65020 IC \n",
++ "pwrread - no arguments"
++);
++U_BOOT_CMD(
++ pwrwrite, 3, 0, do_pwrwrite,
++ "pwrwrite - Writing the register of TPS65020 IC \n",
++ "pwrwrite <address> <data> \n"
++);
++
++#endif
+diff -Naur u-boot-2008.10_original/common/cmd_rtc.c u-boot-2008.10/common/cmd_rtc.c
+--- u-boot-2008.10_original/common/cmd_rtc.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_rtc.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,118 @@
++#include <common.h>
++#include <command.h>
++#include <rtc.h>
++#include "i2c.h"
++#include <devices.h>
++#include <asm/arch/pxa-regs.h>
++
++int do_rtcread (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++int do_rtcreadall (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++int do_rtcwrite (cmd_tbl_t * cmd, int flag, int argc, char *argv[]);
++
++extern uchar i2c_reg_read (uchar chip, uchar reg);
++
++U_BOOT_CMD(
++ rtcread, 3, 1, do_rtcread,
++ "rtcread - get the time and date \n",
++ "rtcread - no arguments"
++);
++U_BOOT_CMD(
++ rtcreadall, 3, 1, do_rtcreadall,
++ "rtcreadall - get the value of all the register of rtc \n",
++ "rtcreadall - no arguments"
++);
++U_BOOT_CMD(
++ rtcwrite, 8, 1, do_rtcwrite,
++ "rtcwrite - set the time and date \n",
++ "rtcwrite 0xsec 0xmin 0xhr 0xday 0xdd 0xmm 0xyy"
++);
++
++static unsigned bcd2bin (uchar n)
++{
++ return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
++}
++
++static unsigned char bin2bcd (unsigned int n)
++{
++ return (((n / 10) << 4) | (n % 10));
++}
++
++int do_rtcreadall (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++
++ char rtcreg_value[12];
++ int reg;
++ char *function[20] = {"Seconds","Minutes","Hours","Days","Date","month/Century","year","Alarm 1 Second","Alarm 1 Minute","Alarm 1 Hours","Alarm 1 day/date","alarm 2 minute ","Alarm 2 Hours","Alarm 2 day/date","Control","Control/Status","Aging offset","msb of temp","Lsb of temp"};
++ int i;
++
++ for(reg = 0; reg<0x12; reg++)
++ {
++ rtcreg_value[reg] = i2c_reg_read(0x68, reg);
++ rtcreg_value[reg] = bcd2bin(rtcreg_value[reg]);
++ printf("\n\t\t%d\t- %d \n",reg,rtcreg_value[reg]);
++ }
++
++// printf(" Register Address\t Function \t Value \n");
++// for(i = 0; i <=19; i++)
++
++ {
++// printf("%d \t %s \t %s \n",i,function[i],rtcreg_value[i]);
++// printf("%d \t %c \n",i,rtcreg_value[i]);
++ }
++}
++
++
++int do_rtcread (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++
++ char rtcreg_value[12];
++ int reg;
++ char *day[20] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","saturday"};
++
++ for(reg = 0; reg<12; reg++)
++ {
++ rtcreg_value[reg] = i2c_reg_read(0x68, reg);
++// printf("RTC register %d, RTC register value %x\n",reg,rtcreg_value[reg]);
++ rtcreg_value[reg] = bcd2bin(rtcreg_value[reg]);
++ }
++
++ printf("\tTime : %d:%d:%d \t\tDate(DD:MM:YYYY): %d:%d:200%d\n\tDay of Week : %s\n", rtcreg_value[2], rtcreg_value[1], rtcreg_value[0],rtcreg_value[4], rtcreg_value[5], rtcreg_value[6],
++day[rtcreg_value[3]-1]);
++
++}
++
++int do_rtcwrite (cmd_tbl_t * cmd, int flag, int argc, char *argv[])
++{
++
++ char rtcreg_value;
++ int reg;
++
++#if 1
++ /* seconds */
++ i2c_reg_write(0x68, 0x00, bin2bcd(simple_strtoul(argv[1],NULL,10)));
++
++ /* minutes - 28 mins*/
++ i2c_reg_write(0x68, 0x01, bin2bcd(simple_strtoul(argv[2],NULL,10)));
++
++ /* Hours -- 13 (24 hr mode)*/
++ i2c_reg_write(0x68, 0x02, bin2bcd(simple_strtoul(argv[3],NULL,10)));
++
++ /*Day of week -- 1*/
++ i2c_reg_write(0x68, 0x03, bin2bcd(simple_strtoul(argv[4],NULL,10)));
++
++ /*Date of Month -- 14 BOGI*/
++ i2c_reg_write(0x68, 0x04, bin2bcd(simple_strtoul(argv[5],NULL,10)));
++
++ /* Month -- January */
++ i2c_reg_write(0x68, 0x05, bin2bcd(simple_strtoul(argv[6],NULL,10)));
++
++ /*Year of the Centuray -- 7 (2007)*/
++ i2c_reg_write(0x68, 0x06, bin2bcd(simple_strtoul(argv[7],NULL,10)));
++#endif
++}
++
++
++
++
++/***************************************************/
++
+diff -Naur u-boot-2008.10_original/common/cmd_ucb1400.c u-boot-2008.10/common/cmd_ucb1400.c
+--- u-boot-2008.10_original/common/cmd_ucb1400.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/cmd_ucb1400.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,305 @@
++#include <common.h>
++#include <command.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <asm/sizes.h>
++#include <malloc.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++
++#define UINT8 char
++#define UINT16 short
++#define UINT32 int
++#define TRUE 1
++#define FALSE 0
++
++
++#define ECON_DEBUG 0
++
++extern int pxa_gpio_mode(int gpio_mode);
++
++
++#define GPIO0_AC97_TOUCH_IRQ_MD (0 | GPIO_IN)
++#define GPIO116_AC97_SDATA_IN_MD (116 | GPIO_ALT_FN_2_IN)
++#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT)
++#define GPIO_DFLT_HIGH 0x800
++
++#define CKEN_AC97 (1<<2) /* AC97 Unit Clock Enable */
++#define CKEN_AC97CONF (1<<31)
++
++#define UCB_TS_CR 0x64
++#define UCB_TS_CR_TSMX_POW (1 << 0)
++#define UCB_TS_CR_TSPX_POW (1 << 1)
++#define UCB_TS_CR_TSMY_POW (1 << 2)
++#define UCB_TS_CR_TSPY_POW (1 << 3)
++#define UCB_TS_CR_TSMX_GND (1 << 4)
++#define UCB_TS_CR_TSPX_GND (1 << 5)
++#define UCB_TS_CR_TSMY_GND (1 << 6)
++#define UCB_TS_CR_TSPY_GND (1 << 7)
++#define UCB_TS_CR_MODE_INT (0 << 8)
++#define UCB_TS_CR_MODE_PRES (1 << 8)
++#define UCB_TS_CR_MODE_POS (2 << 8)
++#define UCB_TS_CR_BIAS_ENA (1 << 11)
++#define UCB_TS_CR_TSPX_LOW (1 << 12)
++#define UCB_TS_CR_TSMX_LOW (1 << 13)
++
++#define UCB_ADC_CR 0x66
++#define UCB_ADC_SYNC_ENA (1 << 0)
++#define UCB_ADC_VREFBYP_CON (1 << 1)
++#define UCB_ADC_INP_TSPX (0 << 2)
++#define UCB_ADC_INP_TSMX (1 << 2)
++#define UCB_ADC_INP_TSPY (2 << 2)
++#define UCB_ADC_INP_TSMY (3 << 2)
++#define UCB_ADC_INP_AD0 (4 << 2)
++#define UCB_ADC_INP_AD1 (5 << 2)
++#define UCB_ADC_INP_AD2 (6 << 2)
++#define UCB_ADC_INP_AD3 (7 << 2)
++#define UCB_ADC_EXT_REF (1 << 5)
++#define UCB_ADC_START (1 << 7)
++#define UCB_ADC_ENA (1 << 15)
++
++
++#define UCB_ADC_DATA 0x68
++#define UCB_ADC_DAT_VALID (1 << 15)
++#define UCB_ADC_DAT_VALUE(x) ((x) & 0x3ff)
++
++#define UCB_ID 0x7e
++#define UCB_ID_1400 0x4304
++
++
++#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
++
++int *PAC,*gsr,*cken;
++
++static volatile long gsr_bits;
++
++
++//-----------------------------------------------------------------------------
++//
++// Function:
++//
++// Configure GPIO pins Directions and Alternate FUnction Related to UCB1400
++//
++//-----------------------------------------------------------------------------
++void ucb1400_gpio_config()
++{
++
++ //Initialize GPIO for ac97 interface
++
++ pxa_gpio_mode(GPIO0_AC97_TOUCH_IRQ_MD);
++ pxa_gpio_mode(GPIO116_AC97_SDATA_IN_MD);
++ pxa_gpio_mode(GPIO113_AC97_RESET_N_MD);
++ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
++ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
++ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
++
++ CKEN|=CKEN_AC97;
++
++ return;
++}
++
++
++static unsigned short pxa2xx_ac97_read(unsigned short reg)
++{
++ unsigned short val = -1;
++ volatile u32 *reg_addr;
++
++
++ /* set up primary or secondary codec space */
++ reg_addr = &PAC_REG_BASE;
++ reg_addr += (reg >> 1);
++
++ /* start read access across the ac97 link */
++ GSR = GSR_CDONE | GSR_SDONE;
++ gsr_bits = 0;
++ val = *reg_addr;
++
++ udelay(50);
++ /* valid data now */
++ GSR = GSR_CDONE | GSR_SDONE;
++ gsr_bits = 0;
++ val = *reg_addr;
++ udelay(50);
++ return val;
++}
++
++static void pxa2xx_ac97_write(unsigned short reg, unsigned short val)
++{
++ volatile u32 *reg_addr;
++
++
++ /* set up primary or secondary codec space */
++ reg_addr = &PAC_REG_BASE;
++ reg_addr += (reg >> 1);
++
++ GSR = GSR_CDONE | GSR_SDONE;
++ gsr_bits = 0;
++ *reg_addr = val;
++ udelay(50);
++}
++
++
++static inline u16 ucb1400_reg_read(u16 reg)
++{
++ return pxa2xx_ac97_read(reg);
++}
++
++static inline void ucb1400_reg_write(u16 reg, u16 val)
++{
++ pxa2xx_ac97_write(reg, val);
++}
++
++static unsigned int ucb1400_adc_read( u16 adc_channel)
++{
++ unsigned int val;
++
++ ucb1400_reg_write( UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
++ ucb1400_reg_write( UCB_ADC_CR, UCB_ADC_ENA | adc_channel | UCB_ADC_START);
++
++ for (;;)
++ {
++ val = ucb1400_reg_read( UCB_ADC_DATA);
++ if (val & UCB_ADC_DAT_VALID)
++ break;
++
++ printf("I trying to get ADC valid data %d \n",val);
++ }
++
++ return UCB_ADC_DAT_VALUE(val);
++}
++
++static inline void ucb1400_adc_enable()
++{
++ ucb1400_reg_write( UCB_ADC_CR, UCB_ADC_ENA);
++}
++
++static inline void ucb1400_adc_disable()
++{
++ ucb1400_reg_write( UCB_ADC_CR, 0);
++}
++
++
++static inline unsigned int ucb1400_ts_read_xpos()
++{
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
++ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
++ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
++ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
++
++ udelay(55);
++
++ return ucb1400_adc_read( UCB_ADC_INP_TSPY);
++}
++
++static inline unsigned int ucb1400_ts_read_ypos()
++{
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
++ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
++ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
++ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
++
++ udelay(55);
++
++ return ucb1400_adc_read( UCB_ADC_INP_TSPX);
++}
++
++static inline unsigned int ucb1400_ts_read_pressure()
++{
++ ucb1400_reg_write( UCB_TS_CR,
++ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
++ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
++ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
++ udelay(55);
++ return ucb1400_adc_read( UCB_ADC_INP_TSPY);
++}
++
++static void pxa2xx_ac97_reset()
++{
++ /* First, try cold reset */
++ GCR &= GCR_COLD_RST; /* clear everything but nCRST */
++ GCR &= ~GCR_COLD_RST; /* then assert nCRST */
++
++ gsr_bits = 0;
++
++ udelay(5);
++ GCR = GCR_COLD_RST;
++ udelay(50);
++
++ if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
++ /* let's try warm reset */
++ gsr_bits = 0;
++ /* warm reset broken on Bulverde,
++ so manually keep AC97 reset high */
++ pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
++ udelay(10);
++ GCR |= GCR_WARM_RST;
++ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
++ udelay(500);
++
++ if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
++ {}
++ }
++
++ GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
++ GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
++}
++
++
++
++int ucb1400_complete(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ pxa2xx_ac97_reset();
++ ucb1400_gpio_config();
++
++ udelay(55);
++ int id=0;
++
++ id = ucb1400_reg_read(UCB_ID);
++ if (id != UCB_ID_1400) {
++ printf("can't read the ID. Present ID is %x\n ", id);
++ }
++
++
++ unsigned int x, y, p;
++#if 1
++ while (1)
++ {
++ ucb1400_adc_enable();
++ x = ucb1400_ts_read_xpos(); // first dummy read x
++ x = ucb1400_ts_read_xpos(); // second dummy read x
++ x = ucb1400_ts_read_xpos(); // actual read x
++
++ y = ucb1400_ts_read_ypos(); // first dumy read y
++ y = ucb1400_ts_read_ypos(); // second dummy read y
++ y = ucb1400_ts_read_ypos(); // actual read y
++
++ p = ucb1400_ts_read_pressure(); // first dummy read p
++ p = ucb1400_ts_read_pressure(); // second dummy read p
++ p = ucb1400_ts_read_pressure(); // actual read y
++ ucb1400_adc_disable();
++ if(p>100)
++ printf("x-value %d y-value %d z-value %d\n",x,y,p);
++
++ }
++
++#endif
++ return 0;
++}
++
++
++
++
++U_BOOT_CMD(
++ ucb1400, 1, 0, ucb1400_complete,
++ "ucb1400 perform x,y,z read from UCB1400 \n",
++ NULL
++);
+diff -Naur u-boot-2008.10_original/common/console.c u-boot-2008.10/common/console.c
+--- u-boot-2008.10_original/common/console.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/common/console.c 2009-08-12 18:21:20.000000000 +0530
+@@ -93,6 +93,119 @@
+ return error;
+ }
+
++
++
++#if defined(CONFIG_CONSOLE_MUX)
++/** Console I/O multiplexing *******************************************/
++
++static device_t *tstcdev;
++device_t **console_devices[MAX_FILES];
++int cd_count[MAX_FILES];
++
++/*
++ * This depends on tstc() always being called before getc().
++ * This is guaranteed to be true because this routine is called
++ * only from fgetc() which assures it.
++ * No attempt is made to demultiplex multiple input sources.
++ */
++static int console_getc(void)
++{
++ unsigned char ret;
++
++ /* This is never called with testcdev == NULL */
++ ret = tstcdev->getc();
++ tstcdev = NULL;
++ return ret;
++}
++
++static int console_tstc(int file)
++{
++ int i, ret;
++ device_t *dev;
++
++ disable_ctrlc(1);
++ for (i = 0; i < cd_count[file]; i++) {
++ dev = console_devices[file][i];
++ if (dev->tstc != NULL) {
++ ret = dev->tstc();
++ if (ret > 0) {
++ tstcdev = dev;
++ disable_ctrlc(0);
++ return ret;
++ }
++ }
++ }
++ disable_ctrlc(0);
++
++ return 0;
++}
++
++static void console_putc(int file, const char c)
++{
++ int i;
++ device_t *dev;
++
++ for (i = 0; i < cd_count[file]; i++) {
++ dev = console_devices[file][i];
++ if (dev->putc != NULL)
++ dev->putc(c);
++ }
++}
++
++static void console_puts(int file, const char *s)
++{
++ int i;
++ device_t *dev;
++
++ for (i = 0; i < cd_count[file]; i++) {
++ dev = console_devices[file][i];
++ if (dev->puts != NULL)
++ dev->puts(s);
++ }
++}
++
++static inline void console_printdevs(int file)
++{
++ iomux_printdevs(file);
++}
++
++static inline void console_doenv(int file, device_t *dev)
++{
++ iomux_doenv(file, dev->name);
++}
++#else
++static inline int console_getc(int file)
++{
++ return stdio_devices[file]->getc();
++}
++
++static inline int console_tstc(int file)
++{
++ return stdio_devices[file]->tstc();
++}
++
++static inline void console_putc(int file, const char c)
++{
++ stdio_devices[file]->putc(c);
++}
++
++static inline void console_puts(int file, const char *s)
++{
++ stdio_devices[file]->puts(s);
++}
++
++static inline void console_printdevs(int file)
++{
++ printf("%s\n", stdio_devices[file]->name);
++}
++
++static inline void console_doenv(int file, device_t *dev)
++{
++ console_setfile(file, dev);
++}
++#endif /* defined(CONFIG_CONSOLE_MUX) */
++
++
+ /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
+
+ void serial_printf (const char *fmt, ...)
+@@ -115,7 +228,32 @@
+ int fgetc (int file)
+ {
+ if (file < MAX_FILES)
+- return stdio_devices[file]->getc ();
++ {
++#if defined(CONFIG_CONSOLE_MUX)
++ /*
++ * Effectively poll for input wherever it may be available.
++ */
++ for (;;) {
++ /*
++ * Upper layer may have already called tstc() so
++ * check for that first.
++ */
++ if (tstcdev != NULL)
++ return console_getc();
++ console_tstc(file);
++#ifdef CONFIG_WATCHDOG
++ /*
++ * If the watchdog must be rate-limited then it should
++ * already be handled in board-specific code.
++ */
++ udelay(1);
++#endif
++ }
++#else
++ return stdio_devices[file]->getc ();
++#endif
++ }
++
+
+ return -1;
+ }
+@@ -123,21 +261,38 @@
+ int ftstc (int file)
+ {
+ if (file < MAX_FILES)
+- return stdio_devices[file]->tstc ();
+-
++ {
++#if defined(CONFIG_CONSOLE_MUX)
++ return console_tstc(file);
++#else
++ return stdio_devices[file]->tstc ();
++#endif
++ }
+ return -1;
+ }
+
+ void fputc (int file, const char c)
+ {
+ if (file < MAX_FILES)
+- stdio_devices[file]->putc (c);
++ {
++#if defined(CONFIG_CONSOLE_MUX)
++ console_putc(file, c);
++#else
++ stdio_devices[file]->putc (c);
++#endif
++ }
+ }
+
+ void fputs (int file, const char *s)
+ {
+ if (file < MAX_FILES)
+- stdio_devices[file]->puts (s);
++ {
++#if defined(CONFIG_CONSOLE_MUX)
++ console_puts(file, s);
++#else
++ stdio_devices[file]->puts (s);
++#endif
++ }
+ }
+
+ void fprintf (int file, const char *fmt, ...)
+@@ -145,7 +300,6 @@
+ va_list args;
+ uint i;
+ char printbuffer[CFG_PBSIZE];
+-
+ va_start (args, fmt);
+
+ /* For this to work, printbuffer must be larger than
+@@ -298,6 +452,7 @@
+
+ int had_ctrlc (void)
+ {
++ ctrlc_was_pressed = 1; // Added by e-con for avoiding repeatance of the previous command while just entering the 'enter' key
+ return ctrlc_was_pressed;
+ }
+
+@@ -407,6 +562,9 @@
+ #ifdef CFG_CONSOLE_ENV_OVERWRITE
+ int i;
+ #endif /* CFG_CONSOLE_ENV_OVERWRITE */
++#ifdef CONFIG_CONSOLE_MUX
++ int iomux_err = 0;
++#endif
+
+ /* set default handlers at first */
+ gd->jt[XF_getc] = serial_getc;
+@@ -425,6 +583,14 @@
+ inputdev = search_device (DEV_FLAGS_INPUT, stdinname);
+ outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
+ errdev = search_device (DEV_FLAGS_OUTPUT, stderrname);
++#ifdef CONFIG_CONSOLE_MUX
++ iomux_err = iomux_doenv(stdin, stdinname);
++ iomux_err += iomux_doenv(stdout, stdoutname);
++ iomux_err += iomux_doenv(stderr, stderrname);
++ if (!iomux_err)
++ /* Successful, so skip all the code below. */
++ goto done;
++#endif
+ }
+ /* if the devices are overwritten or not found, use default device */
+ if (inputdev == NULL) {
+@@ -438,15 +604,33 @@
+ }
+ /* Initializes output console first */
+ if (outputdev != NULL) {
+- console_setfile (stdout, outputdev);
++#ifdef CONFIG_CONSOLE_MUX
++ /* need to set a console if not done above. */
++ iomux_doenv(stdout, outputdev->name);
++#else
++ console_setfile (stdout, outputdev);
++#endif
+ }
+ if (errdev != NULL) {
+- console_setfile (stderr, errdev);
++#ifdef CONFIG_CONSOLE_MUX
++ /* need to set a console if not done above. */
++ iomux_doenv(stderr, errdev->name);
++#else
++ console_setfile (stderr, errdev);
++#endif
+ }
+ if (inputdev != NULL) {
+- console_setfile (stdin, inputdev);
++#ifdef CONFIG_CONSOLE_MUX
++ /* need to set a console if not done above. */
++ iomux_doenv(stdin, inputdev->name);
++#else
++ console_setfile (stdin, inputdev);
++#endif
+ }
+-
++#ifdef CONFIG_CONSOLE_MUX
++done:
++#endif
++
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+
+ #ifndef CFG_CONSOLE_INFO_QUIET
+@@ -455,21 +639,33 @@
+ if (stdio_devices[stdin] == NULL) {
+ puts ("No input devices available!\n");
+ } else {
+- printf ("%s\n", stdio_devices[stdin]->name);
++#ifdef CONFIG_CONSOLE_MUX
++ iomux_printdevs(stdin);
++#else
++ printf ("%s\n", stdio_devices[stdin]->name);
++#endif
+ }
+
+ puts ("Out: ");
+ if (stdio_devices[stdout] == NULL) {
+ puts ("No output devices available!\n");
+ } else {
+- printf ("%s\n", stdio_devices[stdout]->name);
++#ifdef CONFIG_CONSOLE_MUX
++ iomux_printdevs(stdout);
++#else
++ printf ("%s\n", stdio_devices[stdout]->name);
++#endif
+ }
+
+ puts ("Err: ");
+ if (stdio_devices[stderr] == NULL) {
+ puts ("No error devices available!\n");
+ } else {
+- printf ("%s\n", stdio_devices[stderr]->name);
++#ifdef CONFIG_CONSOLE_MUX
++ iomux_printdevs(stderr);
++#else
++ printf ("%s\n", stdio_devices[stderr]->name);
++#endif
+ }
+ #endif /* CFG_CONSOLE_INFO_QUIET */
+
+@@ -524,11 +720,18 @@
+ if (outputdev != NULL) {
+ console_setfile (stdout, outputdev);
+ console_setfile (stderr, outputdev);
++#ifdef CONFIG_CONSOLE_MUX
++ console_devices[stdout][0] = outputdev;
++ console_devices[stderr][0] = outputdev;
++#endif
+ }
+
+ /* Initializes input console */
+ if (inputdev != NULL) {
+ console_setfile (stdin, inputdev);
++#ifdef CONFIG_CONSOLE_MUX
++ console_devices[stdin][0] = inputdev;
++#endif
+ }
+
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+diff -Naur u-boot-2008.10_original/common/iomux.c u-boot-2008.10/common/iomux.c
+--- u-boot-2008.10_original/common/iomux.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/iomux.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,177 @@
++/*
++ * (C) Copyright 2008
++ * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <serial.h>
++#include <malloc.h>
++#include <devices.h>
++#ifdef CONFIG_CONSOLE_MUX
++extern device_t **console_devices[MAX_FILES];
++extern int cd_count[MAX_FILES];
++void iomux_printdevs(const int console)
++{
++ int i;
++ device_t *dev;
++
++ for (i = 0; i < cd_count[console]; i++) {
++ dev = console_devices[console][i];
++ printf("%s ", dev->name);
++ }
++ printf("\n");
++}
++
++/* This tries to preserve the old list if an error occurs. */
++int iomux_doenv(const int console, const char *arg)
++{
++ char *console_args, *temp, **start;
++ int i, j, k, io_flag, cs_idx, repeat;
++ device_t *dev;
++ device_t **cons_set;
++
++ console_args = strdup(arg);
++ if (console_args == NULL)
++ return 1;
++ /*
++ * Check whether a comma separated list of devices was
++ * entered and count how many devices were entered.
++ * The array start[] has pointers to the beginning of
++ * each device name (up to MAX_CONSARGS devices).
++ *
++ * Have to do this twice - once to count the number of
++ * commas and then again to populate start.
++ */
++ i = 0;
++ temp = console_args;
++ for (;;) {
++ temp = strchr(temp, ',');
++ if (temp != NULL) {
++ i++;
++ temp++;
++ continue;
++ }
++ /* There's always one entry more than the number of commas. */
++ i++;
++ break;
++ }
++ start = (char **)malloc(i * sizeof(char *));
++ if (start == NULL) {
++ free(console_args);
++ return 1;
++ }
++ i = 0;
++ start[0] = console_args;
++ for (;;) {
++ temp = strchr(start[i++], ',');
++ if (temp == NULL)
++ break;
++ *temp = '\0';
++ start[i] = temp + 1;
++ }
++ cons_set = (device_t **)calloc(i, sizeof(device_t *));
++ if (cons_set == NULL) {
++ free(start);
++ free(console_args);
++ return 1;
++ }
++
++ switch (console) {
++ case stdin:
++ io_flag = DEV_FLAGS_INPUT;
++ break;
++ case stdout:
++ case stderr:
++ io_flag = DEV_FLAGS_OUTPUT;
++ break;
++ default:
++ free(start);
++ free(console_args);
++ free(cons_set);
++ return 1;
++ }
++
++ cs_idx = 0;
++ for (j = 0; j < i; j++) {
++ /*
++ * Check whether the device exists and is valid.
++ * console_assign() also calls search_device(),
++ * but I need the pointer to the device.
++ */
++ dev = search_device(io_flag, start[j]);
++ if (dev == NULL)
++ continue;
++ /*
++ * Prevent multiple entries for a device.
++ */
++ repeat = 0;
++ for (k = 0; k < cs_idx; k++) {
++ if (dev == cons_set[k]) {
++ repeat++;
++ break;
++ }
++ }
++ if (repeat)
++ continue;
++ /*
++ * Try assigning the specified device.
++ * This could screw up the console settings for apps.
++ */
++ if (console_assign(console, start[j]) < 0)
++ continue;
++#ifdef CONFIG_SERIAL_MULTI
++ /*
++ * This was taken from common/cmd_nvedit.c.
++ * This will never work because serial_assign() returns
++ * 1 upon error, not -1.
++ * This would almost always return an error anyway because
++ * serial_assign() expects the name of a serial device, like
++ * serial_smc, but the user generally only wants to set serial.
++ */
++ if (serial_assign(start[j]) < 0)
++ continue;
++#endif
++ cons_set[cs_idx++] = dev;
++ }
++ free(console_args);
++ free(start);
++ /* failed to set any console */
++ if (cs_idx == 0) {
++ free(cons_set);
++ return 1;
++ } else {
++ /* Works even if console_devices[console] is NULL. */
++ console_devices[console] =
++ (device_t **)realloc(console_devices[console],
++ cs_idx * sizeof(device_t *));
++ if (console_devices[console] == NULL) {
++ free(cons_set);
++ return 1;
++ }
++ memcpy(console_devices[console], cons_set, cs_idx *
++ sizeof(device_t *));
++
++ cd_count[console] = cs_idx;
++ }
++ free(cons_set);
++ return 0;
++}
++#endif /* CONFIG_CONSOLE_MUX */
+diff -Naur u-boot-2008.10_original/common/lcd.c u-boot-2008.10/common/lcd.c
+--- u-boot-2008.10_original/common/lcd.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/common/lcd.c 2009-08-12 18:21:20.000000000 +0530
+@@ -42,7 +42,7 @@
+ #include <lcd.h>
+ #include <watchdog.h>
+
+-#if defined(CONFIG_PXA250)
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ #include <asm/byteorder.h>
+ #endif
+
+@@ -55,6 +55,14 @@
+ #include <nand.h>
+ #endif
+
++#if defined(CONFIG_REGULUS)
++#include <nand.h>
++#endif
++#ifndef CFG_LOGO_CMAP_MODE
++#define CFG_LOGO_CMAP_MODE 444 /* the default */
++#endif
++
++
+ /************************************************************************/
+ /* ** FONT DATA */
+ /************************************************************************/
+@@ -65,7 +73,7 @@
+ /************************************************************************/
+ #ifdef CONFIG_LCD_LOGO
+ # include <bmp_logo.h> /* Get logo data, width and height */
+-# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
++# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP <COLOR16)
+ # error Default Color Map overlaps with Logo Color Map
+ # endif
+ #endif
+@@ -86,7 +94,7 @@
+ static void *lcd_logo (void);
+
+
+-#if LCD_BPP == LCD_COLOR8
++#if LCD_BPP == LCD_COLOR8 || LCD_BPP == LCD_COLOR16
+ extern void lcd_setcolreg (ushort regno,
+ ushort red, ushort green, ushort blue);
+ #endif
+@@ -113,7 +121,7 @@
+
+ static void console_scrollup (void)
+ {
+-#if 1
++#if 0
+ /* Copy up rows ignoring the first one */
+ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
+
+@@ -237,9 +245,13 @@
+ dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
+ off = x * (1 << LCD_BPP) % 8;
+
++
+ for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
+ uchar *s = str;
+ uchar *d = dest;
++#if LCD_BPP == LCD_COLOR16
++ ushort *d16 = dest;
++#endif
+ int i;
+
+ #if LCD_BPP == LCD_MONOCHROME
+@@ -266,7 +278,7 @@
+ }
+ #elif LCD_BPP == LCD_COLOR16
+ for (c=0; c<16; ++c) {
+- *d++ = (bits & 0x80) ?
++ *d16++ = (bits & 0x80) ?
+ lcd_color_fg : lcd_color_bg;
+ bits <<= 1;
+ }
+@@ -320,7 +332,11 @@
+ ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
+ ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR;
+ ushort v, h;
++#if LCD_BPP == LCD_COLOR16
++ ushort *pix = (ushort *)lcd_base;
++#else
+ uchar *pix = (uchar *)lcd_base;
++#endif
+
+ printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
+ h_max, v_max, h_step, v_step);
+@@ -348,6 +364,134 @@
+
+ lcd_base = (void *)(gd->fb_base);
+
++#if CONFIG_REGULUS
++
++/*
++LCD Display 3.5 Inch 240x320 resln:
++###################################
++LCLK = 104MHz, PCD=7, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(7+1)) = 6.5Mhz.
++pixelclock in seconds = 1/6.5Mhz = 0.153846*(10^-6) = 153846*(10^-12) = 153846 picoseconds
++
++insmod pxafb.ko options=mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 5.7 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 6.5 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++CRT Display 640x480 resln:
++##########################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single
++*/
++
++#define BOOTARGS_FOR_LCD3P5 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD5P7 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD6P5 "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_CRT "console=ttyS2,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++
++#define KGDB_BOOTARGS_FOR_LCD3P5 "console=ttyS0,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD5P7 "console=ttyS0,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD6P5 "console=ttyS0,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_CRT "console=ttyS0,115200 rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single kgdbwait"
++
++ char *s=NULL;
++ char *s1=NULL;
++ s1 = getenv ("kgdb");
++ if((s1==NULL)||(strcmp(s1,"off")==0)&&(strcmp(s1,"on")!=0))
++ {
++ s = getenv ("display_type");
++ //printf("display_type is %s \n",s);
++ if(s==NULL)
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p5")==0)
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd5p7")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",BOOTARGS_FOR_LCD5P7);
++ }
++ else if(strcmp(s,"lcd6p5")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",BOOTARGS_FOR_LCD6P5);
++ }
++ else if(strcmp(s,"crt")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",BOOTARGS_FOR_CRT);
++ }
++ else
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ }
++ else if(strcmp(s1,"on")==0)
++ {
++ s = getenv ("display_type");
++ //printf("display_type is %s \n",s);
++ if(s==NULL)
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p5")==0)
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd5p7")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD5P7);
++ }
++ else if(strcmp(s,"lcd6p5")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD6P5);
++ }
++ else if(strcmp(s,"crt")==0)
++ {
++ panel_info.vl_col = 640;
++ panel_info.vl_row = 480;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_CRT);
++ }
++ else
++ {
++ panel_info.vl_col = 240;
++ panel_info.vl_row = 320;
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ }
++#endif
+ lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
+
+ lcd_init (lcd_base); /* LCD initialization */
+@@ -406,8 +550,17 @@
+ debug ("[LCD] Drawing the logo...\n");
+ lcd_console_address = lcd_logo ();
+
++#if 0
+ console_col = 0;
+ console_row = 0;
++#else
++ console_col = 0;
++#ifdef CONFIG_LCD_INFO_BELOW_LOGO
++ console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
++#else
++ console_row = 1; /* leave 1 blank line below logo */
++#endif
++#endif
+
+ return (0);
+ }
+@@ -477,7 +630,8 @@
+
+ static void lcd_setfgcolor (int color)
+ {
+-#ifdef CONFIG_ATMEL_LCD
++#if defined(CONFIG_ATMEL_LCD) || defined(CONFIG_REGULUS)
++#warning "CONFIG_REGULUS is defined here"
+ lcd_color_fg = color;
+ #else
+ lcd_color_fg = color & 0x0F;
+@@ -488,7 +642,8 @@
+
+ static void lcd_setbgcolor (int color)
+ {
+-#ifdef CONFIG_ATMEL_LCD
++#if defined(CONFIG_ATMEL_LCD) || defined(CONFIG_REGULUS)
++#warning "CONFIG_REGULUS is defined here"
+ lcd_color_bg = color;
+ #else
+ lcd_color_bg = color & 0x0F;
+@@ -528,23 +683,25 @@
+ uchar *bmap;
+ uchar *fb;
+ ushort *fb16;
+-#if defined(CONFIG_PXA250)
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ struct pxafb_info *fbi = &panel_info.pxa;
+ #elif defined(CONFIG_MPC823)
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = &(immr->im_cpm);
+ #endif
+-
++ uint palette;
+ debug ("Logo: width %d height %d colors %d cmap %d\n",
+ BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
+- (int)(sizeof(bmp_logo_palette)/(sizeof(ushort))));
++ (int)(sizeof(bmp_logo_palette)/(sizeof(uint))));
+
+ bmap = &bmp_logo_bitmap[0];
++ serial_printf("bmap is 0x%08X . bmp_logo_bitmap is 0x%08X \n",bmap,bmp_logo_bitmap);
+ fb = (uchar *)(lcd_base + y * lcd_line_length + x);
+
+ if (NBITS(panel_info.vl_bpix) < 12) {
+ /* Leave room for default color map */
+-#if defined(CONFIG_PXA250)
++ serial_printf(" Leave room for default color map \n");
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ cmap = (ushort *)fbi->palette;
+ #elif defined(CONFIG_MPC823)
+ cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
+@@ -555,8 +712,8 @@
+ WATCHDOG_RESET();
+
+ /* Set color map */
+- for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
+- ushort colreg = bmp_logo_palette[i];
++ for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(uint))); ++i) {
++ palette = bmp_logo_palette[i];
+ #ifdef CONFIG_ATMEL_LCD
+ uint lut_entry;
+ #ifdef CONFIG_ATMEL_LCD_BGR555
+@@ -571,6 +728,19 @@
+ *(cmap + BMP_LOGO_OFFSET) = lut_entry;
+ cmap++;
+ #else /* !CONFIG_ATMEL_LCD */
++#if CFG_LOGO_CMAP_MODE == 444
++ ushort colreg = ((palette & 0xf00000)>>12) | \
++ ((palette & 0x00f000)>>8) | \
++ ((palette & 0x0000f0)>>4);
++#elif CFG_LOGO_CMAP_MODE == 565
++ ushort colreg = ((palette & 0xf80000)>>8) | \
++ ((palette & 0x00fc00)>>5) | \
++ ((palette & 0x0000f8)>>3);
++#else
++# error "Unsupported CMAP mode"
++#endif
++
++
+ #ifdef CFG_INVERT_COLORS
+ *cmap++ = 0xffff - colreg;
+ #else
+@@ -588,15 +758,34 @@
+ }
+ }
+ else { /* true color mode */
++ serial_printf("true color mode \n");
+ fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
++ serial_printf("fb16 is 0x%08X, lcd_base is 0x%08X , lcd_line_length is %d , y is %d, x is %d \n",fb16,lcd_base,lcd_line_length,y,x);
++
++#if 0
+ for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
+ for (j=0; j<BMP_LOGO_WIDTH; j++) {
+ fb16[j] = bmp_logo_palette[(bmap[j])];
+ }
++#else
++ for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
++ for (j=0; j<BMP_LOGO_WIDTH; j++) {
++ palette = bmp_logo_palette[bmap[j]-BMP_LOGO_OFFSET];
++#if CFG_LOGO_CMAP_MODE == 444
++ fb16[j] = ((palette & 0xf00000)>>12) | \
++ ((palette & 0x00f000)>>8) | \
++ ((palette & 0x0000f0)>>4);
++#elif CFG_LOGO_CMAP_MODE == 565
++ fb16[j] = ((palette & 0xf80000)>>8) | \
++ ((palette & 0x00fc00)>>5) | \
++ ((palette & 0x0000f8)>>3);
++ }
++#endif
+ bmap += BMP_LOGO_WIDTH;
+ fb16 += panel_info.vl_col;
+ }
+ }
++#endif
+
+ WATCHDOG_RESET();
+ }
+@@ -624,7 +813,7 @@
+ unsigned long pwidth = panel_info.vl_col;
+ unsigned colors,bpix;
+ unsigned long compression;
+-#if defined(CONFIG_PXA250)
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ struct pxafb_info *fbi = &panel_info.pxa;
+ #elif defined(CONFIG_MPC823)
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+@@ -643,8 +832,8 @@
+ compression = le32_to_cpu (bmp->header.compression);
+
+ bpix = NBITS(panel_info.vl_bpix);
+-
+- if ((bpix != 1) && (bpix != 8)) {
++ serial_printf("bpix is %d \n",bpix);
++ if ((bpix != 1) && (bpix != 8) && (bpix !=16)) {
+ printf ("Error: %d bit/pixel mode not supported by U-Boot\n",
+ bpix);
+ return 1;
+@@ -663,7 +852,8 @@
+ #if !defined(CONFIG_MCC200)
+ /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */
+ if (bpix==8) {
+-#if defined(CONFIG_PXA250)
++ serial_printf(" MCC200 LCD doesn't need CMAP, supports 1bpp b&w only \n");
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ cmap = (ushort *)fbi->palette;
+ #elif defined(CONFIG_MPC823)
+ cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
+@@ -686,7 +876,7 @@
+ #else
+ *cmap = colreg;
+ #endif
+-#if defined(CONFIG_PXA250)
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X)
+ cmap++;
+ #elif defined(CONFIG_MPC823)
+ cmap--;
+@@ -726,10 +916,11 @@
+ bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);
+ fb = (uchar *) (lcd_base +
+ (y + height - 1) * lcd_line_length + x);
++#if 0
+ for (i = 0; i < height; ++i) {
+ WATCHDOG_RESET();
+ for (j = 0; j < width ; j++)
+-#if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)
++#if defined(CONFIG_PXA250) || defined(CONFIG_PXA27X) || defined(CONFIG_ATMEL_LCD)
+ *(fb++) = *(bmap++);
+ #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
+ *(fb++)=255-*(bmap++);
+@@ -737,6 +928,53 @@
+ bmap += (width - padded_line);
+ fb -= (width + lcd_line_length);
+ }
++#else
++
++
++ switch (bpix) {
++ case 1: /* pass through */
++ case 8:
++ for (i = 0; i < height; ++i) {
++ WATCHDOG_RESET();
++ for (j = 0; j < width ; j++)
++ #if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)
++ *(fb++) = *(bmap++);
++ #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
++ *(fb++)=255-*(bmap++);
++ #endif
++ bmap += (width - padded_line);
++ fb -= (width + lcd_line_length);
++ }
++ break;
++
++#if defined(CONFIG_BMP_16BPP)
++ case 16:
++ for (i = 0; i < height; ++i) {
++ WATCHDOG_RESET();
++ for (j = 0; j < width; j++) {
++#if defined(CONFIG_ATMEL_LCD_BGR555)
++ *(fb++) = ((bmap[0] & 0x1f) << 2) | (bmap[1] &
++0x03);
++ *(fb++) = (bmap[0] & 0xe0) | ((bmap[1] & 0x7c)
++>> 2);
++ bmap += 2;
++#else
++ *(fb++) = *(bmap++);
++ *(fb++) = *(bmap++);
++#endif
++ }
++ bmap += (padded_line - width) * 2;
++ fb -= (width * 2 + lcd_line_length);
++ }
++ break;
++#endif /* CONFIG_BMP_16BPP */
++
++ default:
++ break;
++ };
++
++#endif
++
+
+ return (0);
+ }
+@@ -755,6 +993,10 @@
+ int i;
+ ulong dram_size, nand_size;
+ #endif
++#ifdef CONFIG_REGULUS
++ int i;
++ ulong dram_size, nand_size;
++#endif
+ #endif /* CONFIG_LCD_INFO */
+
+ #ifdef CONFIG_SPLASH_SCREEN
+@@ -855,6 +1097,40 @@
+ # endif /* CONFIG_LCD_INFO */
+ #endif /* CONFIG_ATMEL_LCD */
+
++#ifdef CONFIG_REGULUS
++# ifdef CONFIG_LCD_INFO
++extern int get_cpu_speed(void);
++ sprintf (info, "%s", U_BOOT_VERSION);
++ lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, (uchar *)info, strlen(info));
++
++ sprintf (info, "(C) 2009 e-con Systems India Pvt Ltd");
++ lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT,
++ (uchar *)info, strlen(info));
++
++ sprintf (info, "techsupport@e-consystems.com");
++ lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2,
++ (uchar *)info, strlen(info));
++
++ sprintf (info, "%s CPU at %d MHz",
++ REGULUS_CPU_NAME,
++ get_cpu_speed());
++ lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3,
++ (uchar *)info, strlen(info));
++
++ dram_size = 0;
++ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
++ dram_size += gd->bd->bi_dram[i].size;
++ nand_size = 0;
++ for (i = 0; i < CFG_MAX_NAND_DEVICE; i++)
++ nand_size += nand_info[i].size;
++ sprintf (info, " %ld MB SDRAM, %ld MB NAND",
++ dram_size >> 20,
++ nand_size >> 20 );
++ lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
++ (uchar *)info, strlen(info));
++# endif /* CONFIG_LCD_INFO */
++#endif /* CONFIG_REGULUS */
++
+
+ #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+ return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
+diff -Naur u-boot-2008.10_original/common/Makefile u-boot-2008.10/common/Makefile
+--- u-boot-2008.10_original/common/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/common/Makefile 2009-08-17 13:38:17.000000000 +0530
+@@ -60,6 +60,22 @@
+ COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
+
+ # command
++ifdef CONFIG_REGULUS
++COBJS-$(CONFIG_REGULUS) += cmd_econ_flash_lock_unlock.o
++COBJS-$(CONFIG_REGULUS) += cmd_econ_loady.o
++COBJS-$(CONFIG_REGULUS) += cmd_econ_loade.o
++COBJS-$(CONFIG_REGULUS) += cmd_cpuspeed.o
++COBJS-$(CONFIG_REGULUS) += cmd_pwr_i2c.o
++COBJS-$(CONFIG_REGULUS) += cmd_econ_lcd_test.o
++COBJS-$(CONFIG_REGULUS) += cmd_mac_program.o
++COBJS-$(CONFIG_REGULUS) += cmd_ucb1400.o
++COBJS-$(CONFIG_REGULUS) += cmd_3p2inchlcd.o
++#COBJS-$(CONFIG_REGULUS) += cmd_econ_usbdfu.o
++#COBJS-$(CONFIG_REGULUS) += cmd_econ_bootwince.o
++#COBJS-$(CONFIG_REGULUS) += cmd_econ_launchwince.o
++#COBJS-$(CONFIG_REGULUS) += cmd_bin.o
++#COBJS-$(CONFIG_REGULUS) += cmd_bootce.o
++endif
+ COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
+ COBJS-$(CONFIG_AUTOSCRIPT) += cmd_autoscript.o
+ COBJS-$(CONFIG_CMD_AUTOSCRIPT) += cmd_autoscript.o
+@@ -110,7 +126,9 @@
+ COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o
+ COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o
+ COBJS-$(CONFIG_CMD_LICENSE) += cmd_license.o
++ifndef CONFIG_REGULUS
+ COBJS-y += cmd_load.o
++endif
+ COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
+ COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o
+ COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o
+@@ -149,6 +167,7 @@
+ COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
+ COBJS-$(CONFIG_VFD) += cmd_vfd.o
+ COBJS-$(CONFIG_CMD_DOC) += docecc.o
++COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
+ COBJS-y += flash.o
+ COBJS-y += kgdb.o
+ COBJS-$(CONFIG_LCD) += lcd.o
+diff -Naur u-boot-2008.10_original/common/pxa_usb.h u-boot-2008.10/common/pxa_usb.h
+--- u-boot-2008.10_original/common/pxa_usb.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/pxa_usb.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,248 @@
++/*
++ * pxa_usb.h
++ *
++ * Public interface to the pxa USB core. For use by client modules
++ * like usb-eth and usb-char.
++ *
++ * 02-May-2002
++ * Frank Becker (Intrinsyc) - derived from sa1100_usb.h
++ *
++ */
++
++#ifndef _PXA_USB_H
++#define _PXA_USB_H
++//#include <asm/byteorder.h>
++
++#define MAX_CONFIGS 3
++#define MAX_INTERFACES 2
++#define MAX_ENDPOINTS 4
++
++typedef void (*usb_callback_t)(int flag, int size);
++
++/* in usb_ctl.c (see also descriptor methods at bottom of file) */
++
++// Open the USB client for client and initialize data structures
++// to default values, but _do not_ start UDC.
++int pxa_usb_open(void);
++
++// Start UDC running
++int pxa_usb_start( void );
++
++// Immediately stop udc, fire off completion routines w/-EINTR
++int pxa_usb_stop( void ) ;
++
++// Disconnect client from usb core
++int pxa_usb_close( void ) ;
++
++// set notify callback for when core reaches configured state
++// return previous pointer (if any)
++typedef void (*usb_notify_t)(void);
++usb_notify_t pxa_set_configured_callback( usb_notify_t callback );
++
++/* in usb_send.c */
++int pxa_usb_xmitter_avail( void );
++int pxa_usb_send(char *buf, int len, usb_callback_t callback);
++void sa110a_usb_send_reset(void);
++
++/* in usb_recev.c */
++int pxa_usb_recv(char *buf, int len, usb_callback_t callback);
++void pxa_usb_recv_reset(void);
++
++typedef unsigned int UINT32;
++typedef unsigned short int UINT16;
++typedef unsigned char UINT8;
++//////////////////////////////////////////////////////////////////////////////
++// Descriptor Management
++//////////////////////////////////////////////////////////////////////////////
++
++#define DescriptorHeader \
++ UINT8 bLength; \
++ UINT8 bDescriptorType
++
++
++// --- Device Descriptor -------------------
++
++typedef struct {
++ DescriptorHeader;
++ UINT16 bcdUSB; /* USB specification revision number in BCD */
++ UINT8 bDeviceClass; /* USB class for entire device */
++ UINT8 bDeviceSubClass; /* USB subclass information for entire device */
++ UINT8 bDeviceProtocol; /* USB protocol information for entire device */
++ UINT8 bMaxPacketSize0; /* Max packet size for endpoint zero */
++ UINT16 idVendor; /* USB vendor ID */
++ UINT16 idProduct; /* USB product ID */
++ UINT16 bcdDevice; /* vendor assigned device release number */
++ UINT8 iManufacturer; /* index of manufacturer string */
++ UINT8 iProduct; /* index of string that describes product */
++ UINT8 iSerialNumber; /* index of string containing device serial number */
++ UINT8 bNumConfigurations; /* number fo configurations */
++}device_desc_t;
++
++// --- Configuration Descriptor ------------
++
++typedef struct {
++ DescriptorHeader;
++ UINT16 wTotalLength; /* total # of bytes returned in the cfg buf 4 this cfg */
++ UINT8 bNumInterfaces; /* number of interfaces in this cfg */
++ UINT8 bConfigurationValue; /* used to uniquely ID this cfg */
++ UINT8 iConfiguration; /* index of string describing configuration */
++ UINT8 bmAttributes; /* bitmap of attributes for ths cfg */
++ UINT8 MaxPower; /* power draw in 2ma units */
++}config_desc_t;
++
++// bmAttributes:
++enum {
++ USB_CONFIG_REMOTEWAKE=0xA0,
++ USB_CONFIG_SELFPOWERED=0xC0,
++ USB_CONFIG_BUSPOWERED=0x80
++};
++
++// MaxPower:
++#define USB_POWER( x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
++
++// --- Interface Descriptor ---------------
++
++typedef struct {
++ DescriptorHeader;
++ UINT8 bInterfaceNumber; /* Index uniquely identfying this interface */
++ UINT8 bAlternateSetting; /* ids an alternate setting for this interface */
++ UINT8 bNumEndpoints; /* number of endpoints in this interface */
++ UINT8 bInterfaceClass; /* USB class info applying to this interface */
++ UINT8 bInterfaceSubClass; /* USB subclass info applying to this interface */
++ UINT8 bInterfaceProtocol; /* USB protocol info applying to this interface */
++ UINT8 iInterface; /* index of string describing interface */
++}intf_desc_t;
++
++// --- Endpoint Descriptor ---------------
++
++typedef struct {
++ DescriptorHeader;
++ UINT8 bEndpointAddress; /* 0..3 ep num, bit 7: 0 = 0ut 1= in */
++ UINT8 bmAttributes; /* 0..1 = 0: ctrl, 1: isoc, 2: bulk 3: intr */
++ UINT16 wMaxPacketSize; /* data payload size for this ep in this cfg */
++ UINT8 bInterval; /* polling interval for this ep in this cfg */
++}ep_desc_t;
++
++// bEndpointAddress:
++enum {
++ USB_OUT =0,
++ USB_IN =1
++};
++
++#define USB_EP_ADDRESS(a,d) (((a)&0xf) | ((d) << 7))
++// bmAttributes:
++enum {
++ USB_EP_CNTRL =0,
++ USB_EP_BULK =2,
++ USB_EP_INT =3,
++ USB_EP_ISO =4
++};
++
++// --- String Descriptor -------------------
++
++typedef struct {
++ DescriptorHeader;
++ UINT16 bString[16]; /* unicode string .. actaully 'n' UINT16s */
++}string_desc_t;
++
++/*=======================================================
++ * Handy helpers when working with above
++ *
++ */
++// these are x86-style 16 bit "words" ...
++#define make_word_c( w ) w
++#define make_word( w ) w
++
++// descriptor types
++enum {
++ USB_DESC_DEVICE = 1,
++ USB_DESC_CONFIG = 2,
++ USB_DESC_STRING = 3,
++ USB_DESC_INTERFACE = 4,
++ USB_DESC_ENDPOINT = 5,
++ USB_DESC_FUNCTIONAL = 0x21
++};
++
++
++/*=======================================================
++ * Default descriptor layout for SA-1100 and SA-1110 UDC
++ */
++
++enum {
++ UNUSED = 0,
++
++ BULK_IN1 = 1,
++ BULK_OUT1 = 2,
++ ISO_IN1 = 3,
++ ISO_OUT1 = 4,
++ INT_IN1 = 5,
++
++ BULK_IN2 = 6,
++ BULK_OUT2 = 7,
++ ISO_IN2 = 8,
++ ISO_OUT2 = 9,
++ INT_IN2 = 10,
++
++ BULK_IN3 = 11,
++ BULK_OUT3 = 12,
++ ISO_IN3 = 13,
++ ISO_OUT3 = 14,
++ INT_IN3 = 15
++} /*endpoint_type*/;
++
++/* "config descriptor buffer" - that is, one config,
++ ..one interface and 2 endpoints */
++//struct cdb {
++// config_desc_t cfg;
++// intf_desc_t intf;
++// ep_desc_t ep1;
++// ep_desc_t ep2;
++//} __attribute__ ((packed));
++
++/* all SA device descriptors */
++//typedef struct {
++// device_desc_t dev; /* device descriptor */
++// struct cdb b; /* bundle of descriptors for this cfg */
++//} __attribute__ ((packed)) desc_t;
++
++typedef struct {
++ device_desc_t dev; /* device descriptor */
++ char cdb[1024]; /* FIXME */
++} desc_t;
++
++/*=======================================================
++ * Descriptor API
++ */
++
++/* Get the address of the statically allocated desc_t structure
++ in the usb core driver. Clients can modify this between
++ the time they call pxa_usb_open() and pxa_usb_start()
++*/
++desc_t *
++pxa_usb_get_descriptor_ptr( void );
++
++/* Set a pointer to the string descriptor at "index". The driver
++ ..has room for 8 string indicies internally. Index zero holds
++ ..a LANGID code and is set to US English by default. Inidices
++ ..1-7 are available for use in the config descriptors as client's
++ ..see fit. This pointer is assumed to be good as long as the
++ ..SA usb core is open (so statically allocate them). Returnes -EINVAL
++ ..if index out of range */
++int pxa_usb_set_string_descriptor( int index, string_desc_t * p );
++
++/* reverse of above */
++string_desc_t *
++pxa_usb_get_string_descriptor( int index );
++
++config_desc_t *
++pxa_usb_get_config(int cfgval);
++
++intf_desc_t *
++pxa_usb_get_intf(config_desc_t *cfg, int idx);
++
++ep_desc_t *
++pxa_usb_get_endpoint(intf_desc_t *intf, int idx);
++
++
++
++#endif /* _PXA_USB_H */
+diff -Naur u-boot-2008.10_original/common/usb_dfu.c u-boot-2008.10/common/usb_dfu.c
+--- u-boot-2008.10_original/common/usb_dfu.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/usb_dfu.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,7 @@
++#define DFU_DETACH 0
++#define DFU_DNLOAD 1
++#define DFU_UPLOAD 2
++#define DFU_GETSTATUS 3
++#define DFU_CLRSTATUS 4
++#define DFU_GETSTATE 5
++#define DFU_ABORT 6
+diff -Naur u-boot-2008.10_original/common/usb_dfu.h u-boot-2008.10/common/usb_dfu.h
+--- u-boot-2008.10_original/common/usb_dfu.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/common/usb_dfu.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,127 @@
++#define DFU_DETACH 0
++#define DFU_DNLOAD 1
++#define DFU_UPLOAD 2
++#define DFU_GETSTATUS 3
++#define DFU_CLRSTATUS 4
++#define DFU_GETSTATE 5
++#define DFU_ABORT 6
++#define DFU_START 7
++#define DFU_END 8
++
++
++
++
++#define UPDATE_SPLASH_IMG 0x01
++
++#define USB_DFU_CAN_DOWNLOAD (1 << 0)
++#define USB_DFU_CAN_UPLOAD (1 << 1)
++#define USB_DFU_MANIFEST_TOL (1 << 2)
++#define USB_DFU_WILL_DETACH (1 << 3)
++
++struct send_pkt{
++ UINT8 data[1024*2];
++ UINT8 CRC;
++};
++
++struct status_pkt{
++ UINT8 LastCompletedFrame;
++ UINT8 NextExpectedFrame;
++ UINT8 Mode;
++ UINT32 TotalFramesCompleted;
++ UINT8 CRC;
++};
++
++struct start_setup_pkt{
++ UINT32 TotalSize;
++ UINT8 Type;
++ UINT8 CRC;
++};
++
++// --- Interface Descriptor ---------------
++
++typedef struct {
++ UINT8 bLength;
++ UINT8 bDescriptorType;
++ UINT8 bmAttributes;
++ UINT16 wDetachTimeOut;
++ UINT16 wTransferSize;
++ UINT16 bcdDFUVersion;
++}dfu_func_desc_t;
++ UINT8 FrameCnt=0;
++ UINT32 FileSize;
++ UINT32 TotalFrames,BBytes_Written=0;ytesLeft;
++
++/* receive buffer management */
++static UINT8 rx_buf[1024*64];
++
++
++/* DFU states */
++#define USB_REQ_DFU_DETACH 0x00
++#define USB_REQ_DFU_DNLOAD 0x01
++#define USB_REQ_DFU_UPLOAD 0x02
++#define USB_REQ_DFU_GETSTATUS 0x03
++#define USB_REQ_DFU_CLRSTATUS 0x04
++#define USB_REQ_DFU_GETSTATE 0x05
++#define USB_REQ_DFU_ABORT 0x06
++
++
++/* DFU status */
++#define DFU_STATUS_OK 0x00
++#define DFU_STATUS_ERROR_TARGET 0x01
++#define DFU_STATUS_ERROR_FILE 0x02
++#define DFU_STATUS_ERROR_WRITE 0x03
++#define DFU_STATUS_ERROR_ERASE 0x04
++#define DFU_STATUS_ERROR_CHECK_ERASED 0x05
++#define DFU_STATUS_ERROR_PROG 0x06
++#define DFU_STATUS_ERROR_VERIFY 0x07
++#define DFU_STATUS_ERROR_ADDRESS 0x08
++#define DFU_STATUS_ERROR_NOTDONE 0x09
++#define DFU_STATUS_ERROR_FIRMWARE 0x0a
++#define DFU_STATUS_ERROR_VENDOR 0x0b
++#define DFU_STATUS_ERROR_USBR 0x0c
++#define DFU_STATUS_ERROR_POR 0x0d
++#define DFU_STATUS_ERROR_UNKNOWN 0x0e
++#define DFU_STATUS_ERROR_STALLEDPKT 0x0f
++
++typedef unsigned long DWORD;
++typedef unsigned short WORD;
++typedef unsigned char BYTE;
++typedef unsigned char BOOLEAN;
++#ifndef TRUE
++#define TRUE 1
++#endif
++#ifndef FALSE
++#define FALSE 0
++#endif
++static BOOLEAN g_DFU_Download_Complete=FALSE;
++
++enum dfu_state {
++ DFU_STATE_appIDLE = 0,
++ DFU_STATE_appDETACH = 1,
++ DFU_STATE_dfuIDLE = 2,
++ DFU_STATE_dfuDNLOAD_SYNC = 3,
++ DFU_STATE_dfuDNBUSY = 4,
++ DFU_STATE_dfuDNLOAD_IDLE = 5,
++ DFU_STATE_dfuMANIFEST_SYNC = 6,
++ DFU_STATE_dfuMANIFEST = 7,
++ DFU_STATE_dfuMANIFEST_WAIT_RST = 8,
++ DFU_STATE_dfuUPLOAD_IDLE = 9,
++ DFU_STATE_dfuERROR = 10,
++};
++
++enum dfu_state curr_dfu_state=0;
++
++struct dfu_status {
++ UINT8 bStatus;
++ UINT8 bwPollTimeout[3];
++ UINT8 bState;
++ UINT8 iString;
++};
++
++struct dfu_status Dfu_Status;
++
++UINT32 Bytes_Written=0;
++
++volatile UINT32 *pudccsr0;
++volatile UINT32 *pudcdr0;
++
+diff -Naur u-boot-2008.10_original/cpu/pxa/cpu.c u-boot-2008.10/cpu/pxa/cpu.c
+--- u-boot-2008.10_original/cpu/pxa/cpu.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/cpu.c 2009-08-12 18:21:20.000000000 +0530
+@@ -37,7 +37,24 @@
+ #ifdef CONFIG_USE_IRQ
+ DECLARE_GLOBAL_DATA_PTR;
+ #endif
++#ifdef CONFIG_PXA27X
++#define PXA_LAST_GPIO 127
++#define GPIO_IN 0x000
++#define GPIO_OUT 0x080
++#define GPIO_ALT_FN_1_IN 0x100
++#define GPIO_ALT_FN_1_OUT 0x180
++#define GPIO_ALT_FN_2_IN 0x200
++#define GPIO_ALT_FN_2_OUT 0x280
++#define GPIO_ALT_FN_3_IN 0x300
++#define GPIO_ALT_FN_3_OUT 0x380
++#define GPIO_MD_MASK_NR 0x07f
++#define GPIO_MD_MASK_DIR 0x080
++#define GPIO_MD_MASK_FN 0x300
++#define GPIO_DFLT_LOW 0x400
++#define GPIO_DFLT_HIGH 0x800
+
++#define EINVAL -1;
++#endif
+ int cpu_init (void)
+ {
+ /*
+@@ -164,3 +181,29 @@
+ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
+ }
+ #endif /* CONFIG_CPU_MONAHANS */
++
++#ifdef CONFIG_PXA27X
++int pxa_gpio_mode(int gpio_mode)
++{
++ int gpio = gpio_mode & GPIO_MD_MASK_NR;
++ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
++ int gafr;
++
++ if (gpio > PXA_LAST_GPIO)
++ return -EINVAL;
++
++ if (gpio_mode & GPIO_DFLT_LOW)
++ GPCR(gpio) = GPIO_bit(gpio);
++ else if (gpio_mode & GPIO_DFLT_HIGH)
++ GPSR(gpio) = GPIO_bit(gpio);
++ if (gpio_mode & GPIO_MD_MASK_DIR)
++ GPDR(gpio) |= GPIO_bit(gpio);
++ else
++ GPDR(gpio) &= ~GPIO_bit(gpio);
++ gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
++ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
++
++ return 0;
++}
++#endif
++
+diff -Naur u-boot-2008.10_original/cpu/pxa/interrupts.c.orig u-boot-2008.10/cpu/pxa/interrupts.c.orig
+--- u-boot-2008.10_original/cpu/pxa/interrupts.c.orig 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/interrupts.c.orig 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,114 @@
++/*
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Alex Zuepke <azu@sysgo.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <asm/arch/pxa-regs.h>
++
++#ifdef CONFIG_USE_IRQ
++#error: interrupts not implemented yet
++#endif
++
++int interrupt_init (void)
++{
++ /* nothing happens here - we don't setup any IRQs */
++ return (0);
++}
++
++void reset_timer (void)
++{
++ reset_timer_masked ();
++}
++
++ulong get_timer (ulong base)
++{
++ return get_timer_masked () - base;
++}
++
++void set_timer (ulong t)
++{
++ /* nop */
++}
++
++void udelay (unsigned long usec)
++{
++ udelay_masked (usec);
++}
++
++
++void reset_timer_masked (void)
++{
++ OSCR = 0;
++}
++
++ulong get_timer_masked (void)
++{
++ return OSCR;
++}
++
++void udelay_masked (unsigned long usec)
++{
++ ulong tmo;
++ ulong endtime;
++ signed long diff;
++
++ if (usec >= 1000) {
++ tmo = usec / 1000;
++ tmo *= CFG_HZ;
++ tmo /= 1000;
++ } else {
++ tmo = usec * CFG_HZ;
++ tmo /= (1000*1000);
++ }
++
++ endtime = get_timer_masked () + tmo;
++
++ do {
++ ulong now = get_timer_masked ();
++ diff = endtime - now;
++ } while (diff >= 0);
++}
++
++/*
++ * This function is derived from PowerPC code (read timebase as long long).
++ * On ARM it just returns the timer value.
++ */
++unsigned long long get_ticks(void)
++{
++ return get_timer(0);
++}
++
++/*
++ * This function is derived from PowerPC code (timebase clock frequency).
++ * On ARM it returns the number of timer ticks per second.
++ */
++ulong get_tbclk (void)
++{
++ ulong tbclk;
++ tbclk = CFG_HZ;
++ return tbclk;
++}
+diff -Naur u-boot-2008.10_original/cpu/pxa/mmc.c u-boot-2008.10/cpu/pxa/mmc.c
+--- u-boot-2008.10_original/cpu/pxa/mmc.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/mmc.c 2009-08-12 18:21:20.000000000 +0530
+@@ -560,7 +560,7 @@
+ #endif
+ CKEN |= CKEN12_MMC; /* enable MMC unit clock */
+
+- MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
++ MMC_CLKRT = MMC_CLKRT_20MHZ; //MMC_CLKRT_0_3125MHZ;
+ MMC_RESTO = MMC_RES_TO_MAX;
+ MMC_SPI = MMC_SPI_DISABLE;
+
+@@ -585,7 +585,7 @@
+ break;
+ }
+ #ifdef CONFIG_PXA27X
+- udelay(10000);
++ udelay(50000);
+ #else
+ udelay(200000);
+ #endif
+@@ -599,7 +599,7 @@
+ retries = 10;
+ while (retries-- && resp && !(resp[0] & 0x80000000)) {
+ #ifdef CONFIG_PXA27X
+- udelay(10000);
++ udelay(50000);
+ #else
+ udelay(200000);
+ #endif
+diff -Naur u-boot-2008.10_original/cpu/pxa/pxafb.c u-boot-2008.10/cpu/pxa/pxafb.c
+--- u-boot-2008.10_original/cpu/pxa/pxafb.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/pxafb.c 2009-08-12 18:21:20.000000000 +0530
+@@ -37,6 +37,88 @@
+ #include <asm/arch/pxa-regs.h>
+
+ /* #define DEBUG */
++//#define debug(fmt,args...) printf (fmt ,##args)
++#if 0
++#ifdef CONFIG_LCD_DISPLAY_3P5_INCH_320_240
++#warning "LCD Display 3.5 inch 320x240 resln is selected"
++#define PPL 239
++#define LPP 319
++#define LCCR0_DATA 0x079008f8
++#define LCCR1_DATA ( 0x3A103400 | PPL )
++#define LCCR2_DATA ( 0x00041C00 | LPP )
++#define LCCR3_DATA 0x04440007
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_LCD_DISPLAY_5P7_INCH_640_480)
++#warning "LCD Display 5.7 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x5050127F
++#define LCCR2_DATA 0x131309DF
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_LCD_DISPLAY_6P5_INCH_640_480)
++#warning "LCD Display 6.5 inch 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008d9
++#define LCCR1_DATA 0x0600127f
++#define LCCR2_DATA 0x131309df
++#define LCCR3_DATA 0x04700001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#elif defined(CONFIG_CRT_DISPLAY_640_480)
++#warning "CRT Display 640x480 resln is selected"
++#define LCCR0_DATA 0x07b008f8
++#define LCCR1_DATA 0x3030FE7F
++#define LCCR2_DATA 0x251109DF
++#define LCCR3_DATA 0x04000001
++#define LCCR4_DATA 0x00000000
++#define LCCR5_DATA 0x00000000
++#else
++#error "Display Type is Not selected for REGULUS Board. Select the Display type and build the image"
++#endif
++#endif
++
++//LCD CONTROLLER REGISTER 0 - 5
++#define PPL35 239 // Pixels Per Line
++#define LPP35 319 // Lines Per Plane
++#define LCCR0_DATA35 (0x079008f8)
++#define LCCR1_DATA35 (0x3A103400|PPL35)
++#define LCCR2_DATA35 (0x00041C00|LPP35)
++#define LCCR3_DATA35 (0x04440007)
++#define LCCR4_DATA35 (0x00000000)
++#define LCCR5_DATA35 (0x00000000)
++////--------------------------------------------------------------------
++#define PPL57 639// Pixels Per Line
++#define LPP57 479// Lines Per Plane
++#define LCCR0_DATA57 (0x07b008f8)
++#define LCCR1_DATA57 (0x50501000|PPL57)
++#define LCCR2_DATA57 (0x13130800|LPP57)
++#define LCCR3_DATA57 (0x04700001)
++#define LCCR4_DATA57 (0x00000000)
++#define LCCR5_DATA57 (0x00000000)
++////------------------------------------------------------------------
++#define PPL65 639// Pixels Per Line
++#define LPP65 479// Lines Per Plane
++#define LCCR0_DATA65 (0x07b008f8)
++#define LCCR1_DATA65 (0x06001000|PPL65)
++#define LCCR2_DATA65 (0x13130800|LPP65)
++#define LCCR3_DATA65 (0x04700001)
++#define LCCR4_DATA65 (0x00000000)
++#define LCCR5_DATA65 (0x00000000)
++//--------------------------------------------------------------------
++#define LCCR0_DATACRT (0x07b008f8)
++#define LCCR1_DATACRT (0x5010FE7F)
++#define LCCR2_DATACRT (0x0E01B1DF)
++#define LCCR3_DATACRT (0x04000001)
++#define LCCR4_DATACRT (0x00000000)
++#define LCCR5_DATACRT (0x00000000)
++//--------------------------------------------------------------------
++#define LCCR0_DATA_CRT_800_600 0x07b008f8
++#define LCCR1_DATA_CRT_800_600 0xB528FF1F //0xFD104F1F
++#define LCCR2_DATA_CRT_800_600 0x18014257 //0x20010E57
++#define LCCR3_DATA_CRT_800_600 0x04000001
++#define LCCR4_DATA_CRT_800_600 0x80000000
++
+
+ #ifdef CONFIG_LCD
+
+@@ -147,8 +229,158 @@
+ #endif /* CONFIG_HITACHI_SX14 */
+
+ /*----------------------------------------------------------------------*/
++#if CONFIG_REGULUS
++# define LCD_BPP LCD_COLOR16
++/* you have to set lccr0 and lccr3 (including pcd) */
++#define REG_LCCR0 LCCR0_DATA35
++#define REG_LCCR3 LCCR3_DATA35
++vidinfo_t panel_info = {
++ vl_col: 240,
++ vl_row: 320,
++ vl_width: 109,
++ vl_height: 167,
++ vl_clkp: CFG_HIGH,
++ vl_oep: CFG_HIGH,
++ vl_hsp: CFG_HIGH,
++ vl_vsp: CFG_HIGH,
++ vl_dp: CFG_HIGH,
++ vl_bpix: LCD_BPP,
++ vl_lbw: 2,
++ vl_splt: 0,
++ vl_clor: 1,
++ vl_tft: 1,
++ vl_hpw: 1,
++ vl_blw: 0,
++ vl_elw: 0,
++ vl_vpw: 0,
++ vl_bfw: 0,
++ vl_efw: 0,
++};
++#endif /* CONFIG_REGULUS */
++#if 0
++#ifdef CONFIG_LCD_DISPLAY_3P5_INCH_320_240
++
++# define LCD_BPP LCD_COLOR16
++/* you have to set lccr0 and lccr3 (including pcd) */
++#define REG_LCCR0 LCCR0_DATA
++#define REG_LCCR3 LCCR3_DATA
++vidinfo_t panel_info = {
++ vl_col: 240,
++ vl_row: 320,
++ vl_width: 109,
++ vl_height: 167,
++ vl_clkp: CFG_HIGH,
++ vl_oep: CFG_HIGH,
++ vl_hsp: CFG_HIGH,
++ vl_vsp: CFG_HIGH,
++ vl_dp: CFG_HIGH,
++ vl_bpix: LCD_BPP,
++ vl_lbw: 2,
++ vl_splt: 0,
++ vl_clor: 1,
++ vl_tft: 1,
++ vl_hpw: 1,
++ vl_blw: 0,
++ vl_elw: 0,
++ vl_vpw: 0,
++ vl_bfw: 0,
++ vl_efw: 0,
++};
++#endif /* CONFIG_LCD_DISPLAY_3P5_INCH_320_240 */
++/*----------------------------------------------------------------------*/
++#ifdef CONFIG_LCD_DISPLAY_5P7_INCH_640_480
++
++# define LCD_BPP LCD_COLOR16
++/* you have to set lccr0 and lccr3 (including pcd) */
++#define REG_LCCR0 LCCR0_DATA
++#define REG_LCCR3 LCCR3_DATA
++vidinfo_t panel_info = {
++ vl_col: 480,
++ vl_row: 640,
++ vl_width: 109,
++ vl_height: 167,
++ vl_clkp: CFG_HIGH,
++ vl_oep: CFG_HIGH,
++ vl_hsp: CFG_HIGH,
++ vl_vsp: CFG_HIGH,
++ vl_dp: CFG_HIGH,
++ vl_bpix: LCD_BPP,
++ vl_lbw: 2,
++ vl_splt: 0,
++ vl_clor: 1,
++ vl_tft: 1,
++ vl_hpw: 1,
++ vl_blw: 0,
++ vl_elw: 0,
++ vl_vpw: 0,
++ vl_bfw: 0,
++ vl_efw: 0,
++};
++#endif /* CONFIG_LCD_DISPLAY_P7_INCH_640_480 */
++/*----------------------------------------------------------------------*/
++#ifdef CONFIG_LCD_DISPLAY_6P5_INCH_640_480
++
++# define LCD_BPP LCD_COLOR16
++/* you have to set lccr0 and lccr3 (including pcd) */
++#define REG_LCCR0 LCCR0_DATA
++#define REG_LCCR3 LCCR3_DATA
++vidinfo_t panel_info = {
++ vl_col: 480,
++ vl_row: 640,
++ vl_width: 109,
++ vl_height: 167,
++ vl_clkp: CFG_HIGH,
++ vl_oep: CFG_HIGH,
++ vl_hsp: CFG_HIGH,
++ vl_vsp: CFG_HIGH,
++ vl_dp: CFG_HIGH,
++ vl_bpix: LCD_BPP,
++ vl_lbw: 2,
++ vl_splt: 0,
++ vl_clor: 1,
++ vl_tft: 1,
++ vl_hpw: 1,
++ vl_blw: 0,
++ vl_elw: 0,
++ vl_vpw: 0,
++ vl_bfw: 0,
++ vl_efw: 0,
++};
++#endif /* CONFIG_LCD_DISPLAY_6P5_INCH_640_480 */
++/*----------------------------------------------------------------------*/
++#ifdef CONFIG_CRT_DISPLAY_640_480
+
+-#if LCD_BPP == LCD_COLOR8
++# define LCD_BPP LCD_COLOR16
++/* you have to set lccr0 and lccr3 (including pcd) */
++#define REG_LCCR0 LCCR0_DATA
++#define REG_LCCR3 LCCR3_DATA
++vidinfo_t panel_info = {
++ vl_col: 480,
++ vl_row: 640,
++ vl_width: 109,
++ vl_height: 167,
++ vl_clkp: CFG_HIGH,
++ vl_oep: CFG_HIGH,
++ vl_hsp: CFG_HIGH,
++ vl_vsp: CFG_HIGH,
++ vl_dp: CFG_HIGH,
++ vl_bpix: LCD_BPP,
++ vl_lbw: 2,
++ vl_splt: 0,
++ vl_clor: 1,
++ vl_tft: 1,
++ vl_hpw: 1,
++ vl_blw: 0,
++ vl_elw: 0,
++ vl_vpw: 0,
++ vl_bfw: 0,
++ vl_efw: 0,
++};
++#endif /* CONFIG_CRT_DISPLAY_640_480 */
++/*----------------------------------------------------------------------*/
++#endif
++
++#if LCD_BPP == LCD_COLOR8 || LCD_BPP == LCD_COLOR16
+ void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue);
+ #endif
+ #if LCD_BPP == LCD_MONOCHROME
+@@ -185,6 +417,7 @@
+
+ void lcd_ctrl_init (void *lcdbase)
+ {
++
+ pxafb_init_mem(lcdbase, &panel_info);
+ pxafb_init(&panel_info);
+ pxafb_setup_gpio(&panel_info);
+@@ -200,7 +433,7 @@
+ #endif /* NOT_USED_SO_FAR */
+
+ /*----------------------------------------------------------------------*/
+-#if LCD_BPP == LCD_COLOR8
++#if LCD_BPP == LCD_COLOR8 || LCD_BPP == LCD_COLOR16
+ void
+ lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
+ {
+@@ -225,7 +458,7 @@
+ red, green, blue,
+ palette[regno]);
+ }
+-#endif /* LCD_COLOR8 */
++#endif /* LCD_COLOR8 || LCD_BPP == LCD_COLOR16 */
+
+ /*----------------------------------------------------------------------*/
+ #if LCD_BPP == LCD_MONOCHROME
+@@ -355,10 +588,78 @@
+ debug("Enabling LCD controller\n");
+
+ /* Sequence from 11.7.10 */
++#if !CONFIG_REGULUS
+ LCCR3 = vid->pxa.reg_lccr3;
+ LCCR2 = vid->pxa.reg_lccr2;
+ LCCR1 = vid->pxa.reg_lccr1;
+ LCCR0 = vid->pxa.reg_lccr0 & ~LCCR0_ENB;
++#else
++ char *s=NULL;
++ s = getenv ("display_type");
++ //printf("display_type is %s \n",s);
++ if(s==NULL)
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATA35;
++ LCCR4 = LCCR4_DATA35;
++ LCCR3 = LCCR3_DATA35;
++ LCCR2 = LCCR2_DATA35;
++ LCCR1 = LCCR1_DATA35;
++ LCCR0 = LCCR0_DATA35;
++ }
++ else if(strcmp(s,"lcd3p5")==0)
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATA35;
++ LCCR4 = LCCR4_DATA35;
++ LCCR3 = LCCR3_DATA35;
++ LCCR2 = LCCR2_DATA35;
++ LCCR1 = LCCR1_DATA35;
++ LCCR0 = LCCR0_DATA35;
++ }
++ else if(strcmp(s,"lcd5p7")==0)
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATA57;
++ LCCR4 = LCCR4_DATA57;
++ LCCR3 = LCCR3_DATA57;
++ LCCR2 = LCCR2_DATA57;
++ LCCR1 = LCCR1_DATA57;
++ LCCR0 = LCCR0_DATA57;
++ }
++ else if(strcmp(s,"lcd6p5")==0)
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATA65;
++ LCCR4 = LCCR4_DATA65;
++ LCCR3 = LCCR3_DATA65;
++ LCCR2 = LCCR2_DATA65;
++ LCCR1 = LCCR1_DATA65;
++ LCCR0 = LCCR0_DATA65;
++ }
++ else if(strcmp(s,"crt")==0)
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATACRT;
++ LCCR4 = LCCR4_DATACRT;
++ LCCR3 = LCCR3_DATACRT;
++ LCCR2 = LCCR2_DATACRT;
++ LCCR1 = LCCR1_DATACRT;
++ LCCR0 = LCCR0_DATACRT;
++ }
++ else
++ {
++ LCCR0 &= ~LCCR0_ENB;
++ LCCR5 = LCCR5_DATA35;
++ LCCR4 = LCCR4_DATA35;
++ LCCR3 = LCCR3_DATA35;
++ LCCR2 = LCCR2_DATA35;
++ LCCR1 = LCCR1_DATA35;
++ LCCR0 = LCCR0_DATA35;
++ }
++
++
++#endif
+ FDADR0 = vid->pxa.fdadr0;
+ FDADR1 = vid->pxa.fdadr1;
+ LCCR0 |= LCCR0_ENB;
+diff -Naur u-boot-2008.10_original/cpu/pxa/start_modified.S u-boot-2008.10/cpu/pxa/start_modified.S
+--- u-boot-2008.10_original/cpu/pxa/start_modified.S 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/start_modified.S 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,2657 @@
++@-------------------------------------------------------------@
++/* LED Blinking in and Getting Serial Port Message in Sirius */
++@-------------------------------------------------------------@
++
++#include <config.h>
++#include <version.h>
++#include </usr/include/linux/linkage.h>
++
++#define ASENTRY(x_) ENTRY(x_)
++#define _C_FUNC(x_) /**/x_/**/
++#define _C_LABEL(x_) /**/x_/**/
++#define DEBUG
++
++@#define CORE_104MHz
++@#define CORE_208MHz
++#define CORE_312MHz
++@#define CORE_416MHz
++@#define CORE_520MHz
++@#define RUN_MODE
++#define TURBO_MODE
++
++
++
++#define ENABLE_PRINT_BYTE 1
++#define PRINT_SDRAM_SIZE 1
++#define SDRAM_TEST_SKIP_HIGHER_DATALINES 0
++
++
++#define SDRAM_32bit 1
++#define SDRAM_16bit 0
++
++
++
++#define PWRMODE_IDLE 0x1
++#define PWRMODE_STANDBY 0x2
++#define PWRMODE_SLEEP 0x3
++#define PWRMODE_DEEPSLEEP 0x7
++#define PSSR 0x40F00004
++#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
++#define PSSR_STS (1 << 3) /* Standby Mode Status */
++#define UNCACHED_PHYS_0 0xff000000
++
++/* More handy macros. The argument is a literal GPIO number. */
++#define GPIO_bit(x) 1 << ((x) & 0x1f)
++
++
++.globl _start
++_start: b reset
++ ldr pc, _undefined_instruction
++ ldr pc, _software_interrupt
++ ldr pc, _prefetch_abort
++ ldr pc, _data_abort
++ ldr pc, _not_used
++ ldr pc, _irq
++ ldr pc, _fiq
++
++_undefined_instruction: .word undefined_instruction
++_software_interrupt: .word software_interrupt
++_prefetch_abort: .word prefetch_abort
++_data_abort: .word data_abort
++_not_used: .word not_used
++_irq: .word irq
++_fiq: .word fiq
++
++ .balignl 16,0xdeadbeef
++
++
++/*
++ * Startup Code (reset vector)
++ *
++ * do important init only if we don't start from RAM!
++ * - relocate armboot to ram
++ * - setup stack
++ * - jump to second stage
++ */
++
++_TEXT_BASE:
++ .word TEXT_BASE
++
++.globl _armboot_start
++_armboot_start:
++ .word _start
++
++/*
++ * These are defined in the board-specific linker script.
++ */
++.globl _bss_start
++_bss_start:
++ .word __bss_start
++
++.globl _bss_end
++_bss_end:
++ .word _end
++
++#ifdef CONFIG_USE_IRQ
++/* IRQ stack memory (calculated at run-time) */
++.globl IRQ_STACK_START
++IRQ_STACK_START:
++ .word 0x0badc0de
++
++/* IRQ stack memory (calculated at run-time) */
++.globl FIQ_STACK_START
++FIQ_STACK_START:
++ .word 0x0badc0de
++#endif
++
++
++
++
++
++
++/****************** STAGE7 - Uboot Relocation Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage5_uboot_relocation_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++/****************************************************************************/
++/* */
++/* the actual reset code */
++/* */
++/****************************************************************************/
++
++reset:
++ mrs r0,cpsr /* set the cpu to SVC32 mode */
++ bic r0,r0,#0x1f /* (superviser mode, M=10011) */
++ orr r0,r0,#0x13
++ msr cpsr,r0
++
++ /*
++ * we do sys-critical inits only at reboot,
++ * not when booting from ram!
++ */
++#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++ bl cpu_init_crit /* we do sys-critical inits */
++#endif
++
++#ifndef CONFIG_SKIP_RELOCATE_UBOOT
++relocate:
++ adr r0, _start /* r0 <- current position of code */
++ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
++ cmp r0, r1 /* don't reloc during debug */
++ beq stack_setup
++
++ /*reload the r0 and r1 before proceeding*/
++ adr r0, _start
++ ldr r1, _TEXT_BASE
++ ldr r2, _armboot_start
++ ldr r3, _bss_start
++ sub r2, r3, r2 /* r2 <- size of armboot */
++ add r2, r0, r2 /* r2 <- source end address */
++
++copy_loop:
++ ldmia r0!, {r3-r10} /* copy from source address [r0] */
++ stmia r1!, {r3-r10} /* copy to target address [r1] */
++ cmp r0, r2 /* until source end addreee [r2] */
++ ble copy_loop
++#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
++
++ /* Set up the stack */
++
++
++stack_setup:
++#if 0
++ mov r0, #'A'
++ bl print_byte
++#endif
++
++ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
++ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
++ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
++#ifdef CONFIG_USE_IRQ
++ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
++#endif
++ sub sp, r0, #12 /* leave 3 words for abort-stack */
++
++clear_bss:
++ ldr r0, _bss_start /* find start of bss segment */
++ ldr r1, _bss_end /* stop here */
++ mov r2, #0x00000000 /* clear */
++
++clbss_l:str r2, [r0] /* clear loop... */
++ add r0, r0, #4
++ cmp r0, r1
++ ble clbss_l
++#if 0
++ mov r0, #'D'
++ bl print_byte
++#endif
++ print_stage5_uboot_relocation_completed
++
++ ldr pc, _start_armboot
++_start_armboot: .word start_armboot
++
++/****************************************************************************/
++/* */
++/* CPU_init_critical registers */
++/* */
++/* - setup important registers */
++/* - setup memory timing */
++/* */
++
++/****************************************************************************/
++
++/* Interrupt-Controller base address */
++IC_BASE: .word 0x40d00000
++#define ICMR 0x04
++
++/* Reset-Controller */
++RST_BASE: .word 0x40f00030
++#define RCSR 0x00
++
++/* Operating System Timer */
++//OSTIMER_BASE: .word 0x40a00000
++#define OSTIMER_BASE 0x40a00000
++#define OSMR3 0x0C
++#define OSCR 0x10
++#define OWER 0x18
++#define OIER 0x1C
++
++
++
++/* Clock Manager Registers */
++#ifdef CFG_CPUSPEED
++CC_BASE: .word 0x41300000
++#define CCCR 0x00
++@cpuspeed: .word CFG_CPUSPEED @tharma
++
++#ifdef CORE_104MHz
++cpuspeed: .word 0x02000108 @ L = 8, 2N = 2, A = 1
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x0000000a @ B = 1, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++
++#ifdef CORE_208MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000110 @ L = 16, 2N = 2, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000110 @ L = 16, 2N = 2, A = 1
++#endif
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x00000002 @ B = 0, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x00000003 @ B = 0, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++#ifdef CORE_312MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000190 @ L = 16, 2N = 3, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000190 @ L = 16, 2N = 3, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_416MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000210 @ L= 16, 2N = 4, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000210 @ L= 16, 2N = 4, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_520MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++
++@#error "You have to define CFG_CPUSPEED!!"
++#endif
++
++
++
++
++
++ /* RS: ??? */
++ .macro CPWAIT
++ mrc p15,0,r0,c2,c0,0
++ mov r0,r0
++ sub pc,pc,#4
++ .endm
++
++
++
++#define GAFR2_L_ADDR 0x40E00064
++#define GAFR2_L_MASK_VALUE_FOR_GPIO71 0xFFFF3FFF
++#define GPDR2_ADDR 0x40E00014
++#define GPDR2_VALUE_FOR_GPIO71 0x00000080
++#define GPCR2_ADDR 0x40E0002C
++#define GPSR2_ADDR 0x40E00020
++
++
++/****************** BUZZER GPIO config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++
++.macro buzzer_gpio_config
++
++ ldr r0, =GAFR2_L_ADDR @Addr of GAFR2_L
++ ldr r1, [r0] @Get the value present in GAFR2_L
++ ldr r2, =GAFR2_L_MASK_VALUE_FOR_GPIO71
++ and r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =GPDR2_ADDR @Addr of GPDR2
++ ldr r1, [r0] @Get the value present in GPDR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++.endm
++
++
++
++#ifdef CONFIG_ESOM270
++/****************** BUZZER ON ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_on
++ ldr r0, =GPSR2_ADDR @Addr of GPSR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ str r2, [r0]
++.endm
++
++
++/****************** BUZZER OFF ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_off
++ ldr r0, =GPCR2_ADDR @Addr of GPCR2
++ ldr r1, [r0] @Get the value present in GPCR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++
++.endm
++#endif
++
++
++/************************* print_stage0_booting_in_progress ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_stage0_booting_in_progress
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'B'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'t'
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'p'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'e'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE1 - Serial Port Init Completed ****************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage1_serial_port_init_completed
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'1'
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE2 - Stack Setup in Internal SRAM Completed ****
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage2_stack_setup_in_internal_sram_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE3 - Setting Cpuspeed Completed***************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage3_setting_cpuspeed_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE4 - Static ChipSelect Config Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage4_static_chip_select_config_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++/****************** STAGE6 - SDRAM Memory Test Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage6_sdram_memory_test_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++cpu_init_crit:
++ mov r11, lr
++ bl irq_masking
++ENTRY(return_from_c)
++ bl serial_port_init
++ print_stage1_serial_port_init_completed
++ /*Now initalize the SP before calling putstr or print_byte */
++ mov r0, #0x5c000000
++ add r0, r0, #0x8000
++ mov sp, r0
++ print_stage2_stack_setup_in_internal_sram_completed
++ bl setting_cpuspeed
++ print_stage3_setting_cpuspeed_completed
++ @buzzer_gpio_config
++ bl flash_config
++ print_stage4_static_chip_select_config_completed
++ bl sdram_config
++@No Need to test the SDRAM
++ @bl auto_detect_memory_test
++ mov pc, r11 @cpu_crit_init ends here
++
++
++
++
++/***********************************
++** Flash Config **
++** Registers used : r0,r1,lr **
++***********************************/
++
++MSC0_ADDR: .word 0x48000008
++MSC1_ADDR: .word 0x4800000c
++MSC2_ADDR: .word 0x48000010
++SA1110_ADDR: .word 0x48000064
++MECR_ADDR: .word 0x48000014
++MCMEM0_ADDR: .word 0x48000028
++MCMEM1_ADDR: .word 0x4800002c
++MCATT0_ADDR: .word 0x48000030
++MCATT1_ADDR: .word 0x48000034
++MCIO_0_ADDR: .word 0x48000038
++MCIO_1_ADDR: .word 0x4800003c
++FLYCNFG_ADDR: .word 0x48000020
++
++
++
++MSC0_VALUE: .word 0x7ff87ff8
++MSC1_VALUE: .word 0x7ff87ff8
++MSC2_VALUE: .word 0x7ff87ff8
++SA1110_VALUE: .word 0x00000000
++MECR_VALUE: .word 0x00000000
++
++@Minimun value ( default ) configuration
++/*
++MCMEM0_VALUE: .word 0x00000000
++MCMEM1_VALUE: .word 0x00000000
++MCATT0_VALUE: .word 0x00000000
++MCATT1_VALUE: .word 0x00000000
++MCIO_0_VALUE: .word 0x00000000
++MCIO_1_VALUE: .word 0x00000000
++*/
++
++@Maximum value configuration
++MCMEM0_VALUE: .word 0x000fcfff
++MCMEM1_VALUE: .word 0x000fcfff
++MCATT0_VALUE: .word 0x000fcfff
++MCATT1_VALUE: .word 0x000fcfff
++MCIO_0_VALUE: .word 0x000fcfff
++MCIO_1_VALUE: .word 0x000fcfff
++
++FLYCNFG_VALUE: .word 0x00010001
++
++flash_config:
++ stmdb sp!, {r0, r1, lr}
++
++ ldr r0, MSC0_ADDR
++ ldr r1, MSC0_VALUE
++ str r1, [r0]
++ ldr r1, [r0] @read it back
++
++ ldr r0, MSC1_ADDR
++ ldr r1, MSC1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MSC2_ADDR
++ ldr r1, MSC2_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, SA1110_ADDR
++ ldr r1, SA1110_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MECR_ADDR
++ ldr r1, MECR_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCMEM0_ADDR
++ ldr r1, MCMEM0_VALUE
++ str r1, [r0]
++
++ ldr r0, MCMEM1_ADDR
++ ldr r1, MCMEM1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT0_ADDR
++ ldr r1, MCATT0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT1_ADDR
++ ldr r1, MCATT1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_0_ADDR
++ ldr r1, MCIO_0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_1_ADDR
++ ldr r1, MCIO_1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, FLYCNFG_ADDR
++ ldr r1, FLYCNFG_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++ ldmia sp!, {r0, r1, pc}
++
++
++
++
++MDCNFG_ADDR: .word 0x48000000
++MDMRS_ADDR: .word 0x48000040
++MDMRSLP_ADDR: .word 0x48000058
++MDREFR_ADDR: .word 0x48000004
++MDMRS_VALUE: .word 0x00000032
++
++
++
++#ifdef SDRAM32
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x0ba80ba8
++ MDCNFG_VAL_EN: .word 0x0ba80bab
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x0bac0bac
++ MDCNFG_VAL_EN: .word 0x0bac0baf
++ #endif
++
++ #warning "SDRAM SIZE is 32MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26030 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x030 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6030
++ MDREFR_VAL_NOCLK: .word 0x208f6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe030
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c26060 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x060 for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6060
++ MDREFR_VAL_NOCLK: .word 0x208f6060
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe060
++ #endif
++
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06030 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x030 for memclk = 104Mhz. The DRI is 0x20 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6030
++ MDREFR_VAL_NOCLK: .word 0x208d6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de030
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06028 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x028 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6028
++ MDREFR_VAL_NOCLK: .word 0x208d6028
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de028
++ #endif
++ #endif
++#elif defined (SDRAM64)
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x0ba80bc8
++ MDCNFG_VAL_EN: .word 0x0ba80bcb
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x0bac0bcc
++ MDCNFG_VAL_EN: .word 0x0bac0bcf
++ #endif
++ #warning "SDRAM SIZE is 64MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif define(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++#elif defined (SDRAM128)
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x8ba80bd0
++ MDCNFG_VAL_EN: .word 0x8ba80bd3
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x8bac0bd4
++ MDCNFG_VAL_EN: .word 0x8bac0bd7
++ #endif
++ #warning "SDRAM SIZE is 128MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++
++ #elif defined(MEMCLK91)
++ #warning "MEMCLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c26013 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6013
++ MDREFR_VAL_NOCLK: .word 0x208f6013
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe013
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++
++
++
++
++LED_GREEN: .word GPIO_bit(16)
++LED_YELLOW: .word GPIO_bit(96)
++
++REG_GPCR: .word 0x40e00024
++REG_GPSR: .word 0x40e00018
++
++
++/****************** SDRAM config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++sdram_config:
++ /*stack pointer is already set in SRAM */
++ stmdb sp!, {r0, r1, r2, r3, lr}
++ ldr r0, MDCNFG_ADDR
++ ldr r1, [r0]
++ ldr r2, =0xfffcfffc
++ and r1, r1, r2 @disable all banks
++ str r1, [r0]
++
++ @Config K0DB2, K0DB4 and DRI. SLFRSH=1, APD=0, K0RUN=1
++ ldr r0, MDREFR_ADDR
++ ldr r1, MDREFR_VAL_START
++ str r1, [r0]
++
++ @Enter Selfresfresh with ClkStop. K1RUN = 1, K2RUN=1, K1DB2=1 (MEMCLK/2), K2DB2 = 1
++ ldr r1, MDREFR_VAL_SR_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go out of self-refresh SLFRSH = 0 (Goes to PWRDWN)
++ ldr r1, MDREFR_VAL_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go to PWRDWNX (powerdown exit)
++ @E1PIN = 1, K1RUN =1 (already set to 1)
++ ldr r1, MDREFR_VAL_PWRDWNEXIT
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Now the SDRAM is in NOP mode
++
++ @configure the SDRAM with partitions disabled
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_DIS
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++
++ @Dummy Write and Read from SDRAM banks
++ mov r0, #0xa0000000
++ mov r1, #0xa0000000
++ str r1, [r0]
++ mov r2, #0x10
++loop:
++ add r1, r1, #0x04
++ str r1, [r0, #0x04]
++ sub r2, r2, #0x01
++ cmp r2, #0x00
++ bne loop
++
++ @enable sdram partion
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_EN
++ str r1, [r0]
++
++ @Configure MRS
++ ldr r0, MDMRS_ADDR
++ ldr r1, MDMRS_VALUE
++ str r1, [r0]
++
++
++ ldmia sp!, {r0,r1,r2,r3,pc}
++
++
++
++
++/************************* print_string_booting_failed ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_string_booting_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'n'
++ bl print_byte
++
++ mov r0, #'g'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_sdram_test_failed ***********
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_sdram_test_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'O'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'Y'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++
++
++
++
++/************************* print_string_address *********************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_address
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'r'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_expected_data ***************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_expected_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'x'
++ bl print_byte
++
++ mov r0, #'p'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++.endm
++
++
++/************************* print_string_actual_data *****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_actual_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'u'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++
++
++
++
++
++@---------------------------------------@
++@ Autodetect the SDRAM size @
++@---------------------------------------@
++
++@registers used: r0,,r1,r2,r3,r4,r5,r6,r7,r8,lr
++#ifdef SDRAM32
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x02000000
++#elif defined(SDRAM64)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x04000000
++#elif defined(SDRAM128)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x08000000
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++SIZE_0M: .word 0x00000000
++SIZE_8M: .word 0x00800000
++SIZE_16M: .word 0x01000000
++SIZE_32M: .word 0x02000000
++SIZE_64M: .word 0x04000000
++SIZE_128M: .word 0x08000000
++SIZE_256M: .word 0x10000000
++
++
++auto_detect_memory_test:
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,lr}
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_0M
++ add r1, r1, r0
++ str r1, [r1]
++
++#if defined(SDRAM16) || defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++check_sd16M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram16
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd32M
++#endif
++
++print_sdram16:
++ mov r8, #0x1000000 @16MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd32M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram32
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd64M
++#endif
++print_sdram32:
++ mov r8, #0x2000000 /*Move to r8 the size of SDRAM */ @32MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd64M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram64
++#if defined(SDRAM128) || defined (SDRAM256)
++ b check_sd128M
++#endif
++
++print_sdram64:
++ mov r8, #0x4000000 @64MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined(SDRAM128) || defined (SDRAM256)
++check_sd128M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram128
++#if defined (SDRAM256)
++ b check_sd256M
++#endif
++
++print_sdram128:
++ mov r8, #0x8000000 @128MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'8'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined (SDRAM256)
++check_sd256M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_256M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram256
++print_sdram256:
++ mov r8, #0x10000000 @256MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++decodercs:
++
++#if 1
++test_mem:
++ /*; Data bus test */
++ /* Start the memory tester, hardcoded bank 0 & 1 for now */
++
++ ldr r7, SDRAM_BASE
++@ ldr r8, SDRAM_SIZE
++ add r6, r7, r8
++ mov r4, r7
++
++memoryload:
++ str r4, [r4]
++ add r4, r4, #0x4
++
++ cmp r4, r6
++ blt memoryload
++
++ mov r4, r7
++memorytest:
++ ldr r5, [r4]
++#if SDRAM_TEST_SKIP_HIGHER_DATALINES
++ ldr r7, =0x0000FFFF
++ and r5, r5, r7
++ and r4, r4, r7
++#endif
++ cmp r5, r4
++ bne memoryfail
++ add r4, r4, #0x4
++ cmp r4, r6
++ blt memorytest
++
++test_done:
++ mov r0, #0x0a
++ ldr r1, LED_YELLOW
++ bl led_blink_sp
++ bl bdelay
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++memoryfail:
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_on
++#endif
++ bl bdelay
++ print_string_booting_failed
++
++ print_string_sdram_test_failed
++ print_string_address
++
++ mov r0, r4 @address
++ bl print_hex
++ bl bdelay
++
++
++ print_string_expected_data
++
++ mov r0, r4 @expected data
++ bl print_hex
++ bl bdelay
++
++ print_string_actual_data
++
++ mov r0, r5 @actual data
++ bl print_hex
++ bl bdelay
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_off
++#endif
++ mov r0, #0x0a
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++
++infinite_loop:
++ bl infinite_loop
++
++
++#endif
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++
++
++
++
++
++
++
++
++
++
++
++
++/****************** led_blink_sp **************************
++ registers used r0,r1, r2
++ r0 - number of times to blink
++ r1 - led to blink
++******************************************************************/
++
++ENTRY(led_blink_sp)
++ stmdb sp!, {r0,r1,r2,lr}
++ cmp r1, #GPIO_bit(96)
++ beq yellow_led_blink_loop
++
++green_led_blink_loop:
++ @switch on the GREEN LED
++ ldr r2, GREEN_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the GREEN LED
++ ldr r2, GREEN_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne green_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++yellow_led_blink_loop:
++ @switch on the YELLOW LED
++ ldr r2, YELLOW_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the YELLOW LED
++ ldr r2, YELLOW_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne yellow_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++
++/******************************* bdelay_sp *************************
++ uses registers: r0, r1
++
++*******************************************************************/
++
++bdelay_sp:
++ stmdb sp!, {r0,r1,lr}
++ mov r0, #0x0 @ zero out r4
++loop_out:
++ mov r1, #0x0
++loop_in:
++ add r1, r1, #1 @ increment it
++ cmp r1, #0x0001000 @ compare against constant
++ bne loop_in @ if not equal, loop
++ add r0, r0, #1
++ cmp r0, #0x400
++ bne loop_out
++ ldmia sp!, {r0,r1, pc}
++
++
++@--------------------------------------------@
++@ IRQ Masking @
++@--------------------------------------------@
++irq_masking:
++ /* mask all IRQs */
++ ldr r0, IC_BASE
++ mov r1, #0x00
++ str r1, [r0, #ICMR]
++ mov pc, r14
++
++
++
++#if 1
++setting_cpuspeed:
++#if defined(CFG_CPUSPEED)
++
++ /* set clock speed */
++ ldr r0, CC_BASE
++ ldr r1, cpuspeed
++ str r1, [r0, #CCCR]
++ ldr r0, CLKCFG_VALUE
++ mcr p14, 0, r0, c6, c0, 0
++ CPWAIT
++#endif
++
++
++#endif
++ mov ip, lr
++@ bl lowlevel_init
++ bl econ_lowlevel_init
++ mov lr, ip
++
++/*To clear the RDH of PSSR Reg */
++
++ ldr r0, =0x40F00004
++ mov r1, #0x20
++ str r1, [r0]
++
++ mov pc, r14
++
++
++/******************************************
++ ** econ_lowlevel_init GPIO Configuration
++******************************************/
++GPSR0: .word 0x40e00018
++GPSR1: .word 0x40e0001c
++GPSR2: .word 0x40e00020
++GPSR3: .word 0x40e00118
++
++YELLOW_LED_GPSR: .word 0x40e00118
++YELLOW_LED_GPCR: .word 0x40e00124
++GREEN_LED_GPSR: .word 0x40e00018
++GREEN_LED_GPCR: .word 0x40e00024
++
++
++GPCR0: .word 0x40e00024
++GPCR1: .word 0x40e00028
++GPCR2: .word 0x40e0002c
++GPCR3: .word 0x40e00124
++
++GPDR0: .word 0x40e0000c
++GPDR1: .word 0x40e00010
++GPDR2: .word 0x40e00014
++GPDR3: .word 0x40e0010c
++
++GAFR0_L: .word 0x40e00054
++GAFR0_U: .word 0x40e00058
++GAFR1_L: .word 0x40e0005c
++GAFR1_U: .word 0x40e00060
++GAFR2_L: .word 0x40e00064
++GAFR2_U: .word 0x40e00068
++GAFR3_L: .word 0x40e0006c
++GAFR3_U: .word 0x40e00070
++
++
++GPSR0_VAL: .word 0x9a5f7e18
++GPSR1_VAL: .word 0x00100000
++GPSR2_VAL: .word 0x0c400000
++GPSR3_VAL: .word 0x00040c20
++
++GPCR0_VAL: .word 0x00200000
++GPCR1_VAL: .word 0x00000000
++GPCR2_VAL: .word 0x00080000
++GPCR3_VAL: .word 0x0018002e
++
++GPDR0_VAL: .word 0xdbdbf618
++GPDR1_VAL: .word 0xfcbf8b87
++GPDR2_VAL: .word 0x1ab1ffff
++GPDR3_VAL: .word 0x006e0440
++
++GAFR0_L_VAL: .word 0xa7800000
++GAFR0_U_VAL: .word 0x591a8053
++GAFR1_L_VAL: .word 0x699a555a
++GAFR1_U_VAL: .word 0xaaa5b8aa
++GAFR2_L_VAL: .word 0x5aaaaaaa
++GAFR2_U_VAL: .word 0xa909af06
++GAFR3_L_VAL: .word 0x55055003
++GAFR3_U_VAL: .word 0x00001405
++
++PSKTSEL_SET: .word 0x00008000
++econ_lowlevel_init:
++@ Configure the gpio pin:79 PSKTSEL as general gpio, output,value = high
++
++ ldr r0, GPSR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GPDR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GAFR2_L
++ mov r1, #0x00
++ str r1, [r0]
++
++ mov pc, lr
++
++
++
++/* Delay Routine */
++@------------------------------------------------------@
++@ time delay subroutine @
++@ uses r9 and r10 registers @
++@------------------------------------------------------@
++
++
++bdelay:
++ mov r9, #0x0 @ zero out r4
++outloop:
++ mov r10, #0x0
++inloop:
++ add r10, r10, #1 @ increment it
++ cmp r10, #0x0001000 @ compare against constant
++ bne inloop @ if not equal, loop
++ add r9, r9, #1
++ cmp r9, #0x2000
++ bne outloop
++ mov pc, r14 @ return from subroutine
++
++
++
++
++
++
++
++
++
++@-------------------------------------------@
++@ Serial Port Initialization @
++@-------------------------------------------@
++
++serial_port_init:
++#ifdef CONFIG_STUART
++#warning "DEBUG UART IS STUART"
++
++/* Setting the GPIO46 and GPIO47 as input pin (STD_RXD) and output pin (STD_TXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E00010 @Addr of GPDR1
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x8000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ str r1, [r0]
++
++/* Setting the GPIO46 and GPIO47 for alter.func af2 and af1 respectively */
++ ldr r0, =0x40E0005C @Addr of GAFR1_L
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ orr r1, r1, #0x60000000 @AF47 = 0b01 , AF46 = 0b10
++ str r1, [r0]
++
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x700000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++#elif defined(CONFIG_FFUART)
++#warning "DEBUG UART IS FFUART"
++
++/* Setting the GPIO96 and GPIO16 as input pin (FFRXD) and output pin (FFTXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E0000C @Addr of GPDR0
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x10000 @ GPIO16 = 1 o/p
++ str r1, [r0]
++
++ ldr r0, =0x40E0010C @Addr of GPDR3
++ ldr r1, [r0] @Get the value present in GPDR1
++ bic r1, r1, #0x0001 @ GPIO96 = 0 i/p
++ str r1, [r0]
++
++/* Setting the GPIO16 and GPIO96 for alter.func af3 and af3 respectively */
++ ldr r0, =0x40E00058
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x40E0006c
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000040 /* FFUART CLK ENABLE CKEN6 in CLK Enable Register */
++ str r1, [r0]
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x100000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++
++#endif
++@#elif defined(CONFIG_BTUART)
++#if 1
++#warning " ADDITION UART IS BTUART"
++
++/* Setting the GPIO42 and GPIO43 as input pin (BT_RXD) and output pin (BT_TXD) respectively */
++@--------------------------------------------------------------@
++config_btuart:
++
++ ldr r0, =0x40e00010
++ ldr r1, [r0]
++ orr r1, r1, #0x0002800
++ str r1, [r0]
++
++ ldr r0, =0x40e00014
++ ldr r1, [r0]
++ orr r1, r1, #0x00300000
++ str r1, [r0]
++
++ ldr r0, =0x40e0005c
++ ldr r1, [r0]
++ orr r1, r1, #0x09900000
++ str r1, [r0]
++
++bt_uart_start:
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000080 /* STUART CLK ENABLE CKEN7 in CLK Enable Register */
++ str r1, [r0]
++
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x200000 @ BTUART register start addr
++
++ /* disable the UART */
++bt_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++bt_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++bt_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++bt_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++
++#endif
++
++
++
++/**************************************************
++ Dumping registers r0 - r8
++**************************************************
++*/
++
++ENTRY(dump_reg)
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
++
++ mov r0, r0
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r1
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r2
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r4
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r5
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r6
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r7
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r8
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r9
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r10
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r11
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r12
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r13
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r14
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r15
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,pc}
++
++@-------------------------------------@
++@ Printing String @
++@-------------------------------------@
++
++/* registers used r2, lr */
++
++print_str:
++/*Save the return address */
++ stmdb sp!, {r2, lr}
++ mov r2, r0
++prs1:
++ ldrsb r0, [r2]
++ add r2, r2, #0x01
++ ands r0, r0, #0xFF
++ beq prs2
++ bl print_byte
++ b prs1
++
++prs2:
++ /* Return */
++ ldmia sp!, {r2, pc}
++
++ENTRY(nand_boot)
++ ldr r1, =0x04000000
++ mov pc, r1
++
++
++
++
++
++@----------------------------------@
++@ Printing Byte without stack @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte_without_stack)
++ /* Wait for room in the tx holding register */
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++
++check_without_stack:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check_without_stack
++send_byte_without_stack:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ mov pc, lr
++
++
++@----------------------------------@
++@ Printing Byte @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte)
++ /* Wait for room in the tx holding register */
++ stmdb sp!, {r0,r1, r12, lr}
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++check:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check
++send_byte:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ ldmia sp!, {r0, r1, r12, pc}
++
++@------------------------------------------@
++@ Print_Hex @
++@------------------------------------------@
++
++
++ /* Subroutine to send a hex word (in r0) over the serial port */
++.globl print_hex
++ /* registers used r2, r3, r14(lr) */
++print_hex:
++ stmdb sp!, {r0,r2, r3, lr}
++ mov r2, r0
++ mov r3, #0x08
++ mov r0, #0x30
++ bl print_byte
++ mov r0, #0x78
++ bl print_byte
++prh1:
++ and r0, r2, #0xF0000000
++ mov r0, r0, lsr #28
++ add r0, r0, #0x30
++ cmp r0, #0x3A
++ addge r0, r0, #0x07
++ bl print_byte
++ mov r2, r2, lsl #4
++ subs r3, r3, #0x01
++ bne prh1
++
++ ldmia sp!, {r0,r2, r3, pc}
++
++
++/****************************************************************************/
++/* */
++/* Interrupt handling */
++/* */
++/****************************************************************************/
++
++/* IRQ stack frame */
++
++#define S_FRAME_SIZE 72
++
++#define S_OLD_R0 68
++#define S_PSR 64
++#define S_PC 60
++#define S_LR 56
++#define S_SP 52
++
++#define S_IP 48
++#define S_FP 44
++#define S_R10 40
++#define S_R9 36
++#define S_R8 32
++#define S_R7 28
++#define S_R6 24
++#define S_R5 20
++#define S_R4 16
++#define S_R3 12
++#define S_R2 8
++#define S_R1 4
++#define S_R0 0
++
++#define MODE_SVC 0x13
++
++ /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
++
++ .macro bad_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++
++ ldr r2, _armboot_start
++ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
++ ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
++ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
++
++ add r5, sp, #S_SP
++ mov r1, lr
++ stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
++ mov r0, sp
++ .endm
++
++
++ /* use irq_save_user_regs / irq_restore_user_regs for */
++ /* IRQ/FIQ handling */
++
++ .macro irq_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++ stmdb r8, {sp, lr}^ /* Calling SP, LR */
++ str lr, [r8, #0] /* Save calling PC */
++ mrs r6, spsr
++ str r6, [r8, #4] /* Save CPSR */
++ str r0, [r8, #8] /* Save OLD_R0 */
++ mov r0, sp
++ .endm
++
++ .macro irq_restore_user_regs
++ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
++ mov r0, r0
++ ldr lr, [sp, #S_PC] @ Get PC
++ add sp, sp, #S_FRAME_SIZE
++ subs pc, lr, #4 @ return & move spsr_svc into cpsr
++ .endm
++
++ .macro get_bad_stack
++ ldr r13, _armboot_start @ setup our mode stack
++ sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
++
++ str lr, [r13] @ save caller lr / spsr
++ mrs lr, spsr
++ str lr, [r13, #4]
++
++ mov r13, #MODE_SVC @ prepare SVC-Mode
++ msr spsr_c, r13
++ mov lr, pc
++ movs pc, lr
++ .endm
++
++ .macro get_irq_stack @ setup IRQ stack
++ ldr sp, IRQ_STACK_START
++ .endm
++
++ .macro get_fiq_stack @ setup FIQ stack
++ ldr sp, FIQ_STACK_START
++ .endm
++
++
++/****************************************************************************/
++/* */
++/* exception handlers */
++/* */
++/****************************************************************************/
++
++ .align 5
++undefined_instruction:
++@ bl dump_reg
++ sub r0, r14,#0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, r13
++ bl print_hex
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, undef_msg
++ bl print_str
++ bl bdelay
++endless1:
++ b endless1
++
++
++ .align 5
++software_interrupt:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, soft_msg
++ bl print_str
++ bl bdelay
++endless2:
++ b endless2
++
++ .align 5
++prefetch_abort:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, prefetch_msg
++ bl print_str
++ bl bdelay
++endless3:
++ b endless3
++
++ .align 5
++data_abort:
++@ mov r3, r14
++ sub r0, r14, #0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++
++ sub r3, r3, #0x4
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, data_msg
++ bl print_str
++ bl bdelay
++endless4:
++ b endless4
++
++ .align 5
++not_used:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, not_used_msg
++ bl print_str
++ bl bdelay
++endless5:
++ b endless5
++
++#ifdef CONFIG_USE_IRQ
++
++ .align 5
++irq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless6:
++ b endless6
++
++ .align 5
++fiq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless7:
++ b endless7
++
++#else
++
++ .align 5
++irq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless8:
++ b endless8
++
++ .align 5
++fiq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless9:
++ b endless9
++
++
++#endif
++
++.align 4
++booting_progress:
++ .string "\r\n Booting is in progress.......\r\n"
++.align 4
++booting_fail:
++ .string "\r\n SDRAM MEMORY TEST :Failed \r\n"
++.align 4
++fail_address:
++ .string "\r\n Address : "
++.align 4
++expected_data:
++ .string "\r\n Expected Data : "
++.align 4
++actual_data:
++ .string "\r\n Actual Data : "
++.align 4
++undef_msg:
++ .string "\r\n Undefined instruction \r\n"
++.align 4
++soft_msg:
++ .string "\r\n Software interrupt never ends \r\n"
++.align 4
++prefetch_msg:
++ .string "\r\n Inside Prefetch abort loop\r\n"
++.align 4
++data_msg:
++ .string "\r\n inside the Data abort loop\r\n"
++.align 4
++not_used_msg:
++ .string "\r\n inside the not_used loop\r\n"
++.align 4
++irq_msg:
++ .string "\r\n Inside the irq exception loop\r\n"
++.align 4
++fiq_msg:
++ .string "\r\n Inside the fiq exception loop \r\n"
++
++/****************************************************************************/
++/* */
++/* Reset function: the PXA250 doesn't have a reset function, so we have to */
++/* perform a watchdog timeout for a soft reset. */
++/* */
++/****************************************************************************/
++
++ .align 5
++.globl reset_cpu
++
++ /* FIXME: this code is PXA250 specific. How is this handled on */
++ /* other XScale processors? */
++
++reset_cpu:
++
++ /* We set OWE:WME (watchdog enable) and wait until timeout happens */
++
++ ldr r0, =OSTIMER_BASE
++ ldr r1, [r0, #OWER]
++ orr r1, r1, #0x0001 /* bit0: WME */
++ str r1, [r0, #OWER]
++
++ /* OS timer does only wrap every 1165 seconds, so we have to set */
++ /* the match register as well. */
++
++ ldr r1, [r0, #OSCR] /* read OS timer */
++ add r1, r1, #0x800 /* let OSMR3 match after */
++ add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
++ str r1, [r0, #OSMR3]
++
++reset_endless:
++
++
++ b reset_endless
++
++
++ENTRY(pxa_cpu_standby)
++ ldr r0, =PSSR
++ mov r1, #(PSSR_PH | PSSR_STS)
++ mov r2, #PWRMODE_STANDBY
++@ mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
++@ ldr ip, [r3]
++ b 1f
++
++ .align 5
++1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
++ str r1, [r0] @ make sure PSSR_PH/STS are clear
++ mov pc, lr
+diff -Naur u-boot-2008.10_original/cpu/pxa/start.S u-boot-2008.10/cpu/pxa/start.S
+--- u-boot-2008.10_original/cpu/pxa/start.S 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/start.S 2009-08-12 18:21:20.000000000 +0530
+@@ -1,36 +1,46 @@
+-/*
+- * armboot - Startup Code for XScale
+- *
+- * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+- * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+- * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+- * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
+- * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
+- * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+- * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
+- *
+- * See file CREDITS for list of people who contributed to this
+- * project.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License as
+- * published by the Free Software Foundation; either version 2 of
+- * the License, or (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+- * MA 02111-1307 USA
+- */
++@-------------------------------------------------------------@
++/* LED Blinking in and Getting Serial Port Message in Sirius */
++@-------------------------------------------------------------@
+
+ #include <config.h>
+ #include <version.h>
+-#include <asm/arch/pxa-regs.h>
++#include </usr/include/linux/linkage.h>
++
++#define ASENTRY(x_) ENTRY(x_)
++#define _C_FUNC(x_) /**/x_/**/
++#define _C_LABEL(x_) /**/x_/**/
++#define DEBUG
++
++@#define CORE_104MHz
++@#define CORE_208MHz
++#define CORE_312MHz
++@#define CORE_416MHz
++@#define CORE_520MHz
++@#define RUN_MODE
++#define TURBO_MODE
++
++
++
++#define ENABLE_PRINT_BYTE 0
++#define PRINT_SDRAM_SIZE 0
++#define SDRAM_TEST_SKIP_HIGHER_DATALINES 0
++
++
++
++
++
++#define PWRMODE_IDLE 0x1
++#define PWRMODE_STANDBY 0x2
++#define PWRMODE_SLEEP 0x3
++#define PWRMODE_DEEPSLEEP 0x7
++#define PSSR 0x40F00004
++#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
++#define PSSR_STS (1 << 3) /* Standby Mode Status */
++#define UNCACHED_PHYS_0 0xff000000
++
++/* More handy macros. The argument is a literal GPIO number. */
++#define GPIO_bit(x) 1 << ((x) & 0x1f)
++
+
+ .globl _start
+ _start: b reset
+@@ -57,7 +67,7 @@
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from RAM!
+- * - relocate armboot to RAM
++ * - relocate armboot to ram
+ * - setup stack
+ * - jump to second stage
+ */
+@@ -74,11 +84,11 @@
+ */
+ .globl _bss_start
+ _bss_start:
+- .word __bss_start
++ .word __bss_start
+
+ .globl _bss_end
+ _bss_end:
+- .word _end
++ .word _end
+
+ #ifdef CONFIG_USE_IRQ
+ /* IRQ stack memory (calculated at run-time) */
+@@ -90,7 +100,39 @@
+ .globl FIQ_STACK_START
+ FIQ_STACK_START:
+ .word 0x0badc0de
+-#endif /* CONFIG_USE_IRQ */
++#endif
++
++
++
++
++
++
++/****************** STAGE7 - Uboot Relocation Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage5_uboot_relocation_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
+
+
+ /****************************************************************************/
+@@ -100,63 +142,97 @@
+ /****************************************************************************/
+
+ reset:
+- mrs r0,cpsr /* set the CPU to SVC32 mode */
++ mrs r0,cpsr /* set the cpu to SVC32 mode */
+ bic r0,r0,#0x1f /* (superviser mode, M=10011) */
+ orr r0,r0,#0x13
+ msr cpsr,r0
++
++ mov r0, #0x40000000 @Addr of GPSR1
++ add r0, r0, #0x00E00000
++ add r0, r0, #0x001C
++ ldr r1, [r0]
++ orr r1, r1, #0xC000 @Set the GPIOs 46 and 47
++ str r1, [r0]
++ mov r0, #0x40000000 @Addr of GPDR1
++ add r0, r0, #0x00E00000
++ add r0, r0, #0x0010
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0xC000 @ GPIO47 = 1 ( bit15 ) GPIO46= 1 (bit14)for o/p and o/p respectively
++ str r1, [r0]
+
++/* Setting the GPIO46 and GPIO47 for alter.func af0 and af0 respectively */
++ mov r0, #0x40000000 @Addr of GAFR1_L
++ add r0, r0, #0x00E00000
++ add r0, r0, #0x005C
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ bic r1, r1, #0xF0000000 @AF47 = 0b00 , AF46 = 0b00
++ str r1, [r0]
+ /*
+ * we do sys-critical inits only at reboot,
+- * not when booting from RAM!
++ * not when booting from ram!
+ */
+ #ifndef CONFIG_SKIP_LOWLEVEL_INIT
++
+ bl cpu_init_crit /* we do sys-critical inits */
+-#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
++#endif
+
+ #ifndef CONFIG_SKIP_RELOCATE_UBOOT
+-relocate: /* relocate U-Boot to RAM */
++relocate:
+ adr r0, _start /* r0 <- current position of code */
+ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+- cmp r0, r1 /* don't reloc during debug */
+- beq stack_setup
++ cmp r0, r1 /* don't reloc during debug */
++ beq stack_setup
+
++ /*reload the r0 and r1 before proceeding*/
++ adr r0, _start
++ ldr r1, _TEXT_BASE
+ ldr r2, _armboot_start
+ ldr r3, _bss_start
+- sub r2, r3, r2 /* r2 <- size of armboot */
+- add r2, r0, r2 /* r2 <- source end address */
++ sub r2, r3, r2 /* r2 <- size of armboot */
++ add r2, r0, r2 /* r2 <- source end address */
+
+ copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+- cmp r0, r2 /* until source end address [r2] */
++ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+-#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
++#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+
+ /* Set up the stack */
++
++
+ stack_setup:
++#if 0
++ mov r0, #'A'
++ bl print_byte
++#endif
++
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+- sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+- sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
++ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
++ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+ #ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+-#endif /* CONFIG_USE_IRQ */
++#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+
+ clear_bss:
+- ldr r0, _bss_start /* find start of bss segment */
+- ldr r1, _bss_end /* stop here */
+- mov r2, #0x00000000 /* clear */
++ ldr r0, _bss_start /* find start of bss segment */
++ ldr r1, _bss_end /* stop here */
++ mov r2, #0x00000000 /* clear */
+
+-clbss_l:str r2, [r0] /* clear loop... */
++clbss_l:str r2, [r0] /* clear loop... */
+ add r0, r0, #4
+ cmp r0, r1
+ ble clbss_l
+-
++#if 0
++ mov r0, #'D'
++ bl print_byte
++#endif
++ print_stage5_uboot_relocation_completed
++
+ ldr pc, _start_armboot
+-
+ _start_armboot: .word start_armboot
+
+-
+ /****************************************************************************/
+ /* */
+ /* CPU_init_critical registers */
+@@ -164,17 +240,10 @@
+ /* - setup important registers */
+ /* - setup memory timing */
+ /* */
++
+ /****************************************************************************/
+-/* mk@tbd: Fix this! */
+-#undef RCSR
+-#undef ICMR
+-#undef OSMR3
+-#undef OSCR
+-#undef OWER
+-#undef OIER
+-#undef CCCR
+
+-/* Interrupt-Controller base address */
++/* Interrupt-Controller base address */
+ IC_BASE: .word 0x40d00000
+ #define ICMR 0x04
+
+@@ -183,117 +252,2119 @@
+ #define RCSR 0x00
+
+ /* Operating System Timer */
+-OSTIMER_BASE: .word 0x40a00000
++//OSTIMER_BASE: .word 0x40a00000
++#define OSTIMER_BASE 0x40a00000
+ #define OSMR3 0x0C
+ #define OSCR 0x10
+ #define OWER 0x18
+ #define OIER 0x1C
+
+-/* Clock Manager Registers */
+-#ifdef CONFIG_CPU_MONAHANS
+-# ifndef CFG_MONAHANS_RUN_MODE_OSC_RATIO
+-# error "You have to define CFG_MONAHANS_RUN_MODE_OSC_RATIO!!"
+-# endif /* !CFG_MONAHANS_RUN_MODE_OSC_RATIO */
+-# ifndef CFG_MONAHANS_TURBO_RUN_MODE_RATIO
+-# define CFG_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
+-# endif /* !CFG_MONAHANS_TURBO_RUN_MODE_RATIO */
+-#else /* !CONFIG_CPU_MONAHANS */
++
++
++/* Clock Manager Registers */
+ #ifdef CFG_CPUSPEED
+ CC_BASE: .word 0x41300000
+ #define CCCR 0x00
+-cpuspeed: .word CFG_CPUSPEED
+-#else /* !CFG_CPUSPEED */
+-#error "You have to define CFG_CPUSPEED!!"
+-#endif /* CFG_CPUSPEED */
+-#endif /* CONFIG_CPU_MONAHANS */
+-
+- /* takes care the CP15 update has taken place */
+- .macro CPWAIT reg
+- mrc p15,0,\reg,c2,c0,0
+- mov \reg,\reg
++@cpuspeed: .word CFG_CPUSPEED @tharma
++
++#ifdef CORE_104MHz
++cpuspeed: .word 0x02000108 @ L = 8, 2N = 2, A = 1
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x0000000a @ B = 1, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++
++#ifdef CORE_208MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000110 @ L = 16, 2N = 2, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000110 @ L = 16, 2N = 2, A = 1
++#endif
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x00000002 @ B = 0, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x00000003 @ B = 0, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++#ifdef CORE_312MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000190 @ L = 16, 2N = 3, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000190 @ L = 16, 2N = 3, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_416MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000210 @ L= 16, 2N = 4, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000210 @ L= 16, 2N = 4, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_520MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++
++@#error "You have to define CFG_CPUSPEED!!"
++#endif
++
++
++
++
++
++ /* RS: ??? */
++ .macro CPWAIT
++ mrc p15,0,r0,c2,c0,0
++ mov r0,r0
+ sub pc,pc,#4
+ .endm
+
++
++
++#define GAFR2_L_ADDR 0x40E00064
++#define GAFR2_L_MASK_VALUE_FOR_GPIO71 0xFFFF3FFF
++#define GPDR2_ADDR 0x40E00014
++#define GPDR2_VALUE_FOR_GPIO71 0x00000080
++#define GPCR2_ADDR 0x40E0002C
++#define GPSR2_ADDR 0x40E00020
++
++
++/****************** BUZZER GPIO config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++
++.macro buzzer_gpio_config
++
++ ldr r0, =GAFR2_L_ADDR @Addr of GAFR2_L
++ ldr r1, [r0] @Get the value present in GAFR2_L
++ ldr r2, =GAFR2_L_MASK_VALUE_FOR_GPIO71
++ and r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =GPDR2_ADDR @Addr of GPDR2
++ ldr r1, [r0] @Get the value present in GPDR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++.endm
++
++
++
++#ifdef CONFIG_ESOM270
++/****************** BUZZER ON ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_on
++ ldr r0, =GPSR2_ADDR @Addr of GPSR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ str r2, [r0]
++.endm
++
++
++/****************** BUZZER OFF ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_off
++ ldr r0, =GPCR2_ADDR @Addr of GPCR2
++ ldr r1, [r0] @Get the value present in GPCR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++
++.endm
++#endif
++
++
++/************************* print_stage0_booting_in_progress ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_stage0_booting_in_progress
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'B'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'t'
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'p'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'e'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE1 - Serial Port Init Completed ****************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage1_serial_port_init_completed
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'1'
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE2 - Stack Setup in Internal SRAM Completed ****
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage2_stack_setup_in_internal_sram_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE3 - Setting Cpuspeed Completed***************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage3_setting_cpuspeed_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE4 - Static ChipSelect Config Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage4_static_chip_select_config_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++/****************** STAGE6 - SDRAM Memory Test Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage6_sdram_memory_test_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
++
++
+ cpu_init_crit:
++ mov r11, lr
++ bl irq_masking
++ENTRY(return_from_c)
++ bl serial_port_init
++ print_stage1_serial_port_init_completed
++ /*Now initalize the SP before calling putstr or print_byte */
++ mov r0, #0x5c000000
++ add r0, r0, #0x8000
++ mov sp, r0
++ print_stage2_stack_setup_in_internal_sram_completed
++ bl setting_cpuspeed
++ print_stage3_setting_cpuspeed_completed
++ @buzzer_gpio_config
++ bl flash_config
++ print_stage4_static_chip_select_config_completed
++ bl sdram_config
++@No Need to test the SDRAM
++ @bl auto_detect_memory_test
++ mov pc, r11 @cpu_crit_init ends here
++
++
++
++
++/***********************************
++** Flash Config **
++** Registers used : r0,r1,lr **
++***********************************/
++
++MSC0_ADDR: .word 0x48000008
++MSC1_ADDR: .word 0x4800000c
++MSC2_ADDR: .word 0x48000010
++SA1110_ADDR: .word 0x48000064
++MECR_ADDR: .word 0x48000014
++MCMEM0_ADDR: .word 0x48000028
++MCMEM1_ADDR: .word 0x4800002c
++MCATT0_ADDR: .word 0x48000030
++MCATT1_ADDR: .word 0x48000034
++MCIO_0_ADDR: .word 0x48000038
++MCIO_1_ADDR: .word 0x4800003c
++FLYCNFG_ADDR: .word 0x48000020
++
++
++
++MSC0_VALUE: .word 0x7ff87ff8
++MSC1_VALUE: .word 0x7ff87ff8
++MSC2_VALUE: .word 0x7ff87ff8
++SA1110_VALUE: .word 0x00000000
++MECR_VALUE: .word 0x00000000
++
++@Minimun value ( default ) configuration
++/*
++MCMEM0_VALUE: .word 0x00000000
++MCMEM1_VALUE: .word 0x00000000
++MCATT0_VALUE: .word 0x00000000
++MCATT1_VALUE: .word 0x00000000
++MCIO_0_VALUE: .word 0x00000000
++MCIO_1_VALUE: .word 0x00000000
++*/
++
++@Maximum value configuration
++MCMEM0_VALUE: .word 0x000fcfff
++MCMEM1_VALUE: .word 0x000fcfff
++MCATT0_VALUE: .word 0x000fcfff
++MCATT1_VALUE: .word 0x000fcfff
++MCIO_0_VALUE: .word 0x000fcfff
++MCIO_1_VALUE: .word 0x000fcfff
++
++FLYCNFG_VALUE: .word 0x00010001
++
++flash_config:
++ stmdb sp!, {r0, r1, lr}
++
++ ldr r0, MSC0_ADDR
++ ldr r1, MSC0_VALUE
++ str r1, [r0]
++ ldr r1, [r0] @read it back
++
++ ldr r0, MSC1_ADDR
++ ldr r1, MSC1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MSC2_ADDR
++ ldr r1, MSC2_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, SA1110_ADDR
++ ldr r1, SA1110_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MECR_ADDR
++ ldr r1, MECR_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCMEM0_ADDR
++ ldr r1, MCMEM0_VALUE
++ str r1, [r0]
++
++ ldr r0, MCMEM1_ADDR
++ ldr r1, MCMEM1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT0_ADDR
++ ldr r1, MCATT0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT1_ADDR
++ ldr r1, MCATT1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_0_ADDR
++ ldr r1, MCIO_0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_1_ADDR
++ ldr r1, MCIO_1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, FLYCNFG_ADDR
++ ldr r1, FLYCNFG_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++ ldmia sp!, {r0, r1, pc}
++
++
++
++
++MDCNFG_ADDR: .word 0x48000000
++MDMRS_ADDR: .word 0x48000040
++MDMRSLP_ADDR: .word 0x48000058
++MDREFR_ADDR: .word 0x48000004
++MDMRS_VALUE: .word 0x00000032
++
++
++
++#ifdef SDRAM32
++ MDCNFG_VAL_DIS: .word 0x0ba80ba8
++ MDCNFG_VAL_EN: .word 0x0ba80bab
++ #warning "SDRAM SIZE is 32MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26030 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x030 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6030
++ MDREFR_VAL_NOCLK: .word 0x208f6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe030
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c26060 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x060 for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6060
++ MDREFR_VAL_NOCLK: .word 0x208f6060
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe060
++ #endif
++
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06030 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x030 for memclk = 104Mhz. The DRI is 0x20 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6030
++ MDREFR_VAL_NOCLK: .word 0x208d6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de030
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06028 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x028 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6028
++ MDREFR_VAL_NOCLK: .word 0x208d6028
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de028
++ #endif
++ #endif
++#elif defined (SDRAM64)
++ MDCNFG_VAL_DIS: .word 0x0ba80bc8
++ MDCNFG_VAL_EN: .word 0x0ba80bcb
++ #warning "SDRAM SIZE is 64MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif define(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++#elif defined (SDRAM128)
++ MDCNFG_VAL_DIS: .word 0x8ba80bd0
++ MDCNFG_VAL_EN: .word 0x8ba80bd3
++ #warning "SDRAM SIZE is 128MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++
++ #elif defined(MEMCLK91)
++ #warning "MEMCLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c26013 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6013
++ MDREFR_VAL_NOCLK: .word 0x208f6013
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe013
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++
++
++
++
++LED_GREEN: .word GPIO_bit(16)
++LED_YELLOW: .word GPIO_bit(96)
++
++REG_GPCR: .word 0x40e00024
++REG_GPSR: .word 0x40e00018
++
++
++/****************** SDRAM config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++sdram_config:
++ /*stack pointer is already set in SRAM */
++ stmdb sp!, {r0, r1, r2, r3, lr}
++ ldr r0, MDCNFG_ADDR
++ ldr r1, [r0]
++ ldr r2, =0xfffcfffc
++ and r1, r1, r2 @disable all banks
++ str r1, [r0]
++
++ @Config K0DB2, K0DB4 and DRI. SLFRSH=1, APD=0, K0RUN=1
++ ldr r0, MDREFR_ADDR
++ ldr r1, MDREFR_VAL_START
++ str r1, [r0]
++
++ @Enter Selfresfresh with ClkStop. K1RUN = 1, K2RUN=1, K1DB2=1 (MEMCLK/2), K2DB2 = 1
++ ldr r1, MDREFR_VAL_SR_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go out of self-refresh SLFRSH = 0 (Goes to PWRDWN)
++ ldr r1, MDREFR_VAL_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go to PWRDWNX (powerdown exit)
++ @E1PIN = 1, K1RUN =1 (already set to 1)
++ ldr r1, MDREFR_VAL_PWRDWNEXIT
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Now the SDRAM is in NOP mode
++
++ @configure the SDRAM with partitions disabled
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_DIS
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++
++ @Dummy Write and Read from SDRAM banks
++ mov r0, #0xa0000000
++ mov r1, #0xa0000000
++ str r1, [r0]
++ mov r2, #0x10
++loop:
++ add r1, r1, #0x04
++ str r1, [r0, #0x04]
++ sub r2, r2, #0x01
++ cmp r2, #0x00
++ bne loop
++
++ @enable sdram partion
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_EN
++ str r1, [r0]
++
++ @Configure MRS
++ ldr r0, MDMRS_ADDR
++ ldr r1, MDMRS_VALUE
++ str r1, [r0]
++
++
++ ldmia sp!, {r0,r1,r2,r3,pc}
++
++
++
++
++/************************* print_string_booting_failed ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_string_booting_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'n'
++ bl print_byte
++
++ mov r0, #'g'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_sdram_test_failed ***********
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_sdram_test_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'O'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'Y'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
+
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++
++
++
++
++/************************* print_string_address *********************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_address
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'r'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_expected_data ***************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_expected_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'x'
++ bl print_byte
++
++ mov r0, #'p'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++.endm
++
++
++/************************* print_string_actual_data *****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_actual_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'u'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++
++
++
++
++
++@---------------------------------------@
++@ Autodetect the SDRAM size @
++@---------------------------------------@
++
++@registers used: r0,,r1,r2,r3,r4,r5,r6,r7,r8,lr
++#ifdef SDRAM32
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x02000000
++#elif defined(SDRAM64)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x04000000
++#elif defined(SDRAM128)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x08000000
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++SIZE_0M: .word 0x00000000
++SIZE_8M: .word 0x00800000
++SIZE_16M: .word 0x01000000
++SIZE_32M: .word 0x02000000
++SIZE_64M: .word 0x04000000
++SIZE_128M: .word 0x08000000
++SIZE_256M: .word 0x10000000
++
++
++auto_detect_memory_test:
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,lr}
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_0M
++ add r1, r1, r0
++ str r1, [r1]
++
++#if defined(SDRAM16) || defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++check_sd16M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram16
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd32M
++#endif
++
++print_sdram16:
++ mov r8, #0x1000000 @16MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd32M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram32
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd64M
++#endif
++print_sdram32:
++ mov r8, #0x2000000 /*Move to r8 the size of SDRAM */ @32MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd64M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram64
++#if defined(SDRAM128) || defined (SDRAM256)
++ b check_sd128M
++#endif
++
++print_sdram64:
++ mov r8, #0x4000000 @64MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined(SDRAM128) || defined (SDRAM256)
++check_sd128M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram128
++#if defined (SDRAM256)
++ b check_sd256M
++#endif
++
++print_sdram128:
++ mov r8, #0x8000000 @128MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'8'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined (SDRAM256)
++check_sd256M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_256M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram256
++print_sdram256:
++ mov r8, #0x10000000 @256MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++decodercs:
++
++#if 1
++test_mem:
++ /*; Data bus test */
++ /* Start the memory tester, hardcoded bank 0 & 1 for now */
++
++ ldr r7, SDRAM_BASE
++@ ldr r8, SDRAM_SIZE
++ add r6, r7, r8
++ mov r4, r7
++
++memoryload:
++ str r4, [r4]
++ add r4, r4, #0x4
++
++ cmp r4, r6
++ blt memoryload
++
++ mov r4, r7
++memorytest:
++ ldr r5, [r4]
++#if SDRAM_TEST_SKIP_HIGHER_DATALINES
++ ldr r7, =0x0000FFFF
++ and r5, r5, r7
++ and r4, r4, r7
++#endif
++ cmp r5, r4
++ bne memoryfail
++ add r4, r4, #0x4
++ cmp r4, r6
++ blt memorytest
++
++test_done:
++ mov r0, #0x0a
++ ldr r1, LED_YELLOW
++ bl led_blink_sp
++ bl bdelay
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++memoryfail:
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_on
++#endif
++ bl bdelay
++ print_string_booting_failed
++
++ print_string_sdram_test_failed
++ print_string_address
++
++ mov r0, r4 @address
++ bl print_hex
++ bl bdelay
++
++
++ print_string_expected_data
++
++ mov r0, r4 @expected data
++ bl print_hex
++ bl bdelay
++
++ print_string_actual_data
++
++ mov r0, r5 @actual data
++ bl print_hex
++ bl bdelay
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_off
++#endif
++ mov r0, #0x0a
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++
++infinite_loop:
++ bl infinite_loop
++
++
++#endif
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++
++
++
++
++
++
++
++
++
++
++
++
++/****************** led_blink_sp **************************
++ registers used r0,r1, r2
++ r0 - number of times to blink
++ r1 - led to blink
++******************************************************************/
++
++ENTRY(led_blink_sp)
++ stmdb sp!, {r0,r1,r2,lr}
++ cmp r1, #GPIO_bit(96)
++ beq yellow_led_blink_loop
++
++green_led_blink_loop:
++ @switch on the GREEN LED
++ ldr r2, GREEN_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the GREEN LED
++ ldr r2, GREEN_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne green_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++yellow_led_blink_loop:
++ @switch on the YELLOW LED
++ ldr r2, YELLOW_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the YELLOW LED
++ ldr r2, YELLOW_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne yellow_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++
++/******************************* bdelay_sp *************************
++ uses registers: r0, r1
++
++*******************************************************************/
++
++bdelay_sp:
++ stmdb sp!, {r0,r1,lr}
++ mov r0, #0x0 @ zero out r4
++loop_out:
++ mov r1, #0x0
++loop_in:
++ add r1, r1, #1 @ increment it
++ cmp r1, #0x0001000 @ compare against constant
++ bne loop_in @ if not equal, loop
++ add r0, r0, #1
++ cmp r0, #0x400
++ bne loop_out
++ ldmia sp!, {r0,r1, pc}
++
++
++@--------------------------------------------@
++@ IRQ Masking @
++@--------------------------------------------@
++irq_masking:
+ /* mask all IRQs */
+-#ifndef CONFIG_CPU_MONAHANS
+ ldr r0, IC_BASE
+ mov r1, #0x00
+ str r1, [r0, #ICMR]
+-#else /* CONFIG_CPU_MONAHANS */
+- /* Step 1 - Enable CP6 permission */
+- mrc p15, 0, r1, c15, c1, 0 @ read CPAR
+- orr r1, r1, #0x40
+- mcr p15, 0, r1, c15, c1, 0
+- CPWAIT r1
+-
+- /* Step 2 - Mask ICMR & ICMR2 */
+- mov r1, #0
+- mcr p6, 0, r1, c1, c0, 0 @ ICMR
+- mcr p6, 0, r1, c7, c0, 0 @ ICMR2
+-
+- /* turn off all clocks but the ones we will definitly require */
+- ldr r1, =CKENA
+- ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
+- str r2, [r1]
+- ldr r1, =CKENB
+- ldr r2, =(CKENB_6_IRQ)
+- str r2, [r1]
+-#endif /* !CONFIG_CPU_MONAHANS */
++ mov pc, r14
++
++
++
++#if 1
++setting_cpuspeed:
++#if defined(CFG_CPUSPEED)
+
+ /* set clock speed */
+-#ifdef CONFIG_CPU_MONAHANS
+- ldr r0, =ACCR
+- ldr r1, =(((CFG_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CFG_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
+- str r1, [r0]
+-#else /* !CONFIG_CPU_MONAHANS */
+-#ifdef CFG_CPUSPEED
+ ldr r0, CC_BASE
+ ldr r1, cpuspeed
+ str r1, [r0, #CCCR]
+- mov r0, #2
++ ldr r0, CLKCFG_VALUE
+ mcr p14, 0, r0, c6, c0, 0
++ CPWAIT
++#endif
+
+-setspeed_done:
+-
+-#endif /* CFG_CPUSPEED */
+-#endif /* CONFIG_CPU_MONAHANS */
+
+- /*
+- * before relocating, we have to setup RAM timing
+- * because memory timing is board-dependend, you will
+- * find a lowlevel_init.S in your board directory.
+- */
++#endif
+ mov ip, lr
+- bl lowlevel_init
++@ bl lowlevel_init
++ bl econ_lowlevel_init
+ mov lr, ip
+
+- /* Memory interfaces are working. Disable MMU and enable I-cache. */
+- /* mk: hmm, this is not in the monahans docs, leave it now but
+- * check here if it doesn't work :-) */
++/*To clear the RDH of PSSR Reg */
++
++ ldr r0, =0x40F00004
++ mov r1, #0x20
++ str r1, [r0]
++
++ mov pc, r14
++
++
++/******************************************
++ ** econ_lowlevel_init GPIO Configuration
++******************************************/
++GPSR0: .word 0x40e00018
++GPSR1: .word 0x40e0001c
++GPSR2: .word 0x40e00020
++GPSR3: .word 0x40e00118
++
++YELLOW_LED_GPSR: .word 0x40e00118
++YELLOW_LED_GPCR: .word 0x40e00124
++GREEN_LED_GPSR: .word 0x40e00018
++GREEN_LED_GPCR: .word 0x40e00024
++
++
++GPCR0: .word 0x40e00024
++GPCR1: .word 0x40e00028
++GPCR2: .word 0x40e0002c
++GPCR3: .word 0x40e00124
++
++GPDR0: .word 0x40e0000c
++GPDR1: .word 0x40e00010
++GPDR2: .word 0x40e00014
++GPDR3: .word 0x40e0010c
++
++GAFR0_L: .word 0x40e00054
++GAFR0_U: .word 0x40e00058
++GAFR1_L: .word 0x40e0005c
++GAFR1_U: .word 0x40e00060
++GAFR2_L: .word 0x40e00064
++GAFR2_U: .word 0x40e00068
++GAFR3_L: .word 0x40e0006c
++GAFR3_U: .word 0x40e00070
++
++
++GPSR0_VAL: .word 0x9a5f7e18
++GPSR1_VAL: .word 0x00100000
++GPSR2_VAL: .word 0x0c400000
++GPSR3_VAL: .word 0x00040c20
++
++GPCR0_VAL: .word 0x00200000
++GPCR1_VAL: .word 0x00000000
++GPCR2_VAL: .word 0x00080000
++GPCR3_VAL: .word 0x0018002e
++
++GPDR0_VAL: .word 0xdbdbf618
++GPDR1_VAL: .word 0xfcbf8b87
++GPDR2_VAL: .word 0x1ab1ffff
++GPDR3_VAL: .word 0x006e0440
++
++GAFR0_L_VAL: .word 0xa7800000
++GAFR0_U_VAL: .word 0x591a8053
++GAFR1_L_VAL: .word 0x699a555a
++GAFR1_U_VAL: .word 0xaaa5b8aa
++GAFR2_L_VAL: .word 0x5aaaaaaa
++GAFR2_U_VAL: .word 0xa909af06
++GAFR3_L_VAL: .word 0x55055003
++GAFR3_U_VAL: .word 0x00001405
++
++PSKTSEL_SET: .word 0x00008000
++econ_lowlevel_init:
++@ Configure the gpio pin:79 PSKTSEL as general gpio, output,value = high
++
++ ldr r0, GPSR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GPDR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GAFR2_L
++ mov r1, #0x00
++ str r1, [r0]
++
++ mov pc, lr
++
++
++
++/* Delay Routine */
++@------------------------------------------------------@
++@ time delay subroutine @
++@ uses r9 and r10 registers @
++@------------------------------------------------------@
++
++
++bdelay:
++ mov r9, #0x0 @ zero out r4
++outloop:
++ mov r10, #0x0
++inloop:
++ add r10, r10, #1 @ increment it
++ cmp r10, #0x0001000 @ compare against constant
++ bne inloop @ if not equal, loop
++ add r9, r9, #1
++ cmp r9, #0x2000
++ bne outloop
++ mov pc, r14 @ return from subroutine
++
++
++
++
++
++
++
+
+- ldr r0, =0x2001 /* enable access to all coproc. */
+- mcr p15, 0, r0, c15, c1, 0
+- CPWAIT r0
+
+- mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
+- CPWAIT r0
++@-------------------------------------------@
++@ Serial Port Initialization @
++@-------------------------------------------@
+
+- mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
+- CPWAIT r0
++serial_port_init:
+
+- mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
+- CPWAIT r0
++@#ifdef CONFIG_STUART
++@#warning "DEBUG UART IS STUART"
+
+- /* Enable the Icache */
++/* Setting the GPIO46 and GPIO47 as input pin (STD_RXD) and output pin (STD_TXD) respectively */
++@--------------------------------------------------------------@
++stuart_gpiosetup_serialport:
++
++ ldr r0, =0x40E00010 @Addr of GPDR1
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x8000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ bic r1, r1, #0x4000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ str r1, [r0]
++
++/* Setting the GPIO46 and GPIO47 for alter.func af2 and af1 respectively */
++ ldr r0, =0x40E0005C @Addr of GAFR1_L
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ orr r1, r1, #0x60000000 @AF47 = 0b01 , AF46 = 0b10
++ str r1, [r0]
++
++
++stuart_uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x700000 @ Standard UART register start addr
++
++ /* disable the UART */
++stuart_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++stuart_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++
++stuart_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++stuart_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++@ mov pc, lr @ serial_port_init ends here
++@#elif defined(CONFIG_FFUART)
++@#warning "DEBUG UART IS FFUART"
++
++/* Setting the GPIO99 and GPIO102 as output pin (FFTXD) and output pin (FFRXD) respectively */
++@--------------------------------------------------------------@
++ffuart_gpiosetup_serialport:
++
++ ldr r0, =0x40E0010C @Addr of GPDR0
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x0008 @ GPIO99 = 1 o/p
++ str r1, [r0]
++
++ ldr r0, =0x40E0010C @Addr of GPDR3
++ ldr r1, [r0] @Get the value present in GPDR1
++ bic r1, r1, #0x0004 @ GPIO102 = 0 i/p
++ str r1, [r0]
++
++/* Setting the GPIO99 and GPIO102 for alter.func af3 and af3 respectively */
++ ldr r0, =0x40E0006C
++ ldr r1, [r0]
++ orr r1, r1, #0x000000C0
++ str r1, [r0]
++
++ ldr r0, =0x40E0006C
++ ldr r1, [r0]
++ orr r1, r1, #0x00003000
++ str r1, [r0]
++
++
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000040 /* FFUART CLK ENABLE CKEN6 in CLK Enable Register */
++ str r1, [r0]
++
++ffuart_uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x100000 @ Standard UART register start addr
++
++ /* disable the UART */
++ffuart_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++ffuart_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++ffuart_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++ffuart_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++@ mov pc, lr @ serial_port_init ends here
++
++@#endif
++@#elif defined(CONFIG_BTUART)
++@#if 1
++@#warning " ADDITION UART IS BTUART"
++
++/* Setting the GPIO42 and GPIO43 as input pin (BT_RXD) and output pin (BT_TXD) respectively */
++@--------------------------------------------------------------@
++btuart_config_btuart:
++
++ ldr r0, =0x40e00010
++ ldr r1, [r0]
++ orr r1, r1, #0x0002800
++ str r1, [r0]
++
++ ldr r0, =0x40e00014
++ ldr r1, [r0]
++ orr r1, r1, #0x00300000
++ str r1, [r0]
++
++ ldr r0, =0x40e0005c
++ ldr r1, [r0]
++ orr r1, r1, #0x09900000
++ str r1, [r0]
++
++bt_uart_start:
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000080 /* STUART CLK ENABLE CKEN7 in CLK Enable Register */
++ str r1, [r0]
++
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x200000 @ BTUART register start addr
++
++ /* disable the UART */
++bt_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++bt_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++bt_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++bt_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++
++@#endif
++
++
++
++/**************************************************
++ Dumping registers r0 - r8
++**************************************************
++*/
++
++ENTRY(dump_reg)
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
++
++ mov r0, r0
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r1
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r2
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r4
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r5
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r6
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r7
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r8
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r9
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r10
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r11
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r12
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r13
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r14
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r15
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,pc}
++
++@-------------------------------------@
++@ Printing String @
++@-------------------------------------@
++
++/* registers used r2, lr */
++
++print_str:
++/*Save the return address */
++ stmdb sp!, {r2, lr}
++ mov r2, r0
++prs1:
++ ldrsb r0, [r2]
++ add r2, r2, #0x01
++ ands r0, r0, #0xFF
++ beq prs2
++ bl print_byte
++ b prs1
++
++prs2:
++ /* Return */
++ ldmia sp!, {r2, pc}
++
++ENTRY(nand_boot)
++ ldr r1, =0x04000000
++ mov pc, r1
++
++
++
++
++
++@----------------------------------@
++@ Printing Byte without stack @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte_without_stack)
++ /* Wait for room in the tx holding register */
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++
++check_without_stack:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check_without_stack
++send_byte_without_stack:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ mov pc, lr
++
++
++@----------------------------------@
++@ Printing Byte @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte)
++ /* Wait for room in the tx holding register */
++ stmdb sp!, {r0,r1, r12, lr}
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++check:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check
++send_byte:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ ldmia sp!, {r0, r1, r12, pc}
++
++@------------------------------------------@
++@ Launch WinCE @
++@------------------------------------------@
++
++
++ENTRY(Launch)
++/* r3 now contains the physical launch address.
++*/
++ mov r3, r0
++/* Compute the physical address of the PhysicalStart tag. We'll jump to this address once we've turned the MMU and caches off.
++*/
++ stmdb sp!, {r3}
++ ldr r0, =PhysicalStart
++ @bl OALVAtoPA
++ nop
++ ldmia sp!, {r3}
++
++/* r0 now contains the physical address of 'PhysicalStart'. r3 now contains the physical launch address.
++ Next, we disable the MMU, and I&D caches.
++*/
++
++ mov r1, #0x0078
++ mcr p15, 0, r1, c1, c0, 0
++
++/*
++ Jump to 'PhysicalStart'.
++*/
++
++ mov pc, r0
++ nop
++ nop
++ nop
++ nop
++
++PhysicalStart:
+ /*
+- mrc p15, 0, r0, c1, c0, 0
+- orr r0, r0, #0x1800
+- mcr p15, 0, r0, c1, c0, 0
+- CPWAIT
++ Flush the I&D TLBs.
+ */
+- mov pc, lr
++ mcr p15, 0, r2, c8, c7, 0 /* Flush the I&D TLBs */
++/* Jump to the physical launch address. This should never return...
++*/
++ mov pc, r3
++ nop
++ nop
++ nop
++ nop
++ nop
++ nop
++
++@------------------------------------------@
++@ Print_Hex @
++@------------------------------------------@
++
++
++ /* Subroutine to send a hex word (in r0) over the serial port */
++.globl print_hex
++ /* registers used r2, r3, r14(lr) */
++print_hex:
++ stmdb sp!, {r0,r2, r3, lr}
++ mov r2, r0
++ mov r3, #0x08
++ mov r0, #0x30
++ bl print_byte
++ mov r0, #0x78
++ bl print_byte
++prh1:
++ and r0, r2, #0xF0000000
++ mov r0, r0, lsr #28
++ add r0, r0, #0x30
++ cmp r0, #0x3A
++ addge r0, r0, #0x07
++ bl print_byte
++ mov r2, r2, lsl #4
++ subs r3, r3, #0x01
++ bne prh1
++
++ ldmia sp!, {r0,r2, r3, pc}
+
+
+ /****************************************************************************/
+@@ -337,7 +2408,7 @@
+
+ ldr r2, _armboot_start
+ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
+- sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
++ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
+ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
+
+@@ -403,96 +2474,236 @@
+
+ .align 5
+ undefined_instruction:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_undefined_instruction
++@ bl dump_reg
++ sub r0, r14,#0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, r13
++ bl print_hex
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, undef_msg
++ bl print_str
++ bl bdelay
++endless1:
++ b endless1
++
+
+ .align 5
+ software_interrupt:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_software_interrupt
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, soft_msg
++ bl print_str
++ bl bdelay
++endless2:
++ b endless2
+
+ .align 5
+ prefetch_abort:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_prefetch_abort
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, prefetch_msg
++ bl print_str
++ bl bdelay
++endless3:
++ b endless3
+
+ .align 5
+ data_abort:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_data_abort
++@ mov r3, r14
++ sub r0, r14, #0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++
++ sub r3, r3, #0x4
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, data_msg
++ bl print_str
++ bl bdelay
++endless4:
++ b endless4
+
+ .align 5
+ not_used:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_not_used
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, not_used_msg
++ bl print_str
++ bl bdelay
++endless5:
++ b endless5
+
+ #ifdef CONFIG_USE_IRQ
+
+ .align 5
+ irq:
+- get_irq_stack
+- irq_save_user_regs
+- bl do_irq
+- irq_restore_user_regs
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless6:
++ b endless6
+
+ .align 5
+ fiq:
+- get_fiq_stack
+- irq_save_user_regs /* someone ought to write a more */
+- bl do_fiq /* effiction fiq_save_user_regs */
+- irq_restore_user_regs
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless7:
++ b endless7
+
+-#else /* !CONFIG_USE_IRQ */
++#else
+
+ .align 5
+ irq:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_irq
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless8:
++ b endless8
+
+ .align 5
+ fiq:
+- get_bad_stack
+- bad_save_user_regs
+- bl do_fiq
+-
+-#endif /* CONFIG_USE_IRQ */
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless9:
++ b endless9
++
++
++#endif
++
++.align 4
++booting_progress:
++ .string "\r\n Booting is in progress.......\r\n"
++.align 4
++booting_fail:
++ .string "\r\n SDRAM MEMORY TEST :Failed \r\n"
++.align 4
++fail_address:
++ .string "\r\n Address : "
++.align 4
++expected_data:
++ .string "\r\n Expected Data : "
++.align 4
++actual_data:
++ .string "\r\n Actual Data : "
++.align 4
++undef_msg:
++ .string "\r\n Undefined instruction \r\n"
++.align 4
++soft_msg:
++ .string "\r\n Software interrupt never ends \r\n"
++.align 4
++prefetch_msg:
++ .string "\r\n Inside Prefetch abort loop\r\n"
++.align 4
++data_msg:
++ .string "\r\n inside the Data abort loop\r\n"
++.align 4
++not_used_msg:
++ .string "\r\n inside the not_used loop\r\n"
++.align 4
++irq_msg:
++ .string "\r\n Inside the irq exception loop\r\n"
++.align 4
++fiq_msg:
++ .string "\r\n Inside the fiq exception loop \r\n"
+
+ /****************************************************************************/
+-/* */
++/* */
+ /* Reset function: the PXA250 doesn't have a reset function, so we have to */
+-/* perform a watchdog timeout for a soft reset. */
+-/* */
++/* perform a watchdog timeout for a soft reset. */
++/* */
+ /****************************************************************************/
+
+ .align 5
+ .globl reset_cpu
+
+- /* FIXME: this code is PXA250 specific. How is this handled on */
+- /* other XScale processors? */
++ /* FIXME: this code is PXA250 specific. How is this handled on */
++ /* other XScale processors? */
+
+ reset_cpu:
+
+ /* We set OWE:WME (watchdog enable) and wait until timeout happens */
+
+- ldr r0, OSTIMER_BASE
++ ldr r0, =OSTIMER_BASE
+ ldr r1, [r0, #OWER]
+- orr r1, r1, #0x0001 /* bit0: WME */
++ orr r1, r1, #0x0001 /* bit0: WME */
+ str r1, [r0, #OWER]
+
+ /* OS timer does only wrap every 1165 seconds, so we have to set */
+- /* the match register as well. */
++ /* the match register as well. */
+
+- ldr r1, [r0, #OSCR] /* read OS timer */
++ ldr r1, [r0, #OSCR] /* read OS timer */
+ add r1, r1, #0x800 /* let OSMR3 match after */
+ add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
+ str r1, [r0, #OSMR3]
+
+ reset_endless:
+
++
+ b reset_endless
++
++
++ENTRY(pxa_cpu_standby)
++ ldr r0, =PSSR
++ mov r1, #(PSSR_PH | PSSR_STS)
++ mov r2, #PWRMODE_STANDBY
++@ mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
++@ ldr ip, [r3]
++ b 1f
++
++ .align 5
++1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
++ str r1, [r0] @ make sure PSSR_PH/STS are clear
++ mov pc, lr
+diff -Naur u-boot-2008.10_original/cpu/pxa/start.S_modified u-boot-2008.10/cpu/pxa/start.S_modified
+--- u-boot-2008.10_original/cpu/pxa/start.S_modified 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/start.S_modified 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,2657 @@
++@-------------------------------------------------------------@
++/* LED Blinking in and Getting Serial Port Message in Sirius */
++@-------------------------------------------------------------@
++
++#include <config.h>
++#include <version.h>
++#include </usr/include/linux/linkage.h>
++
++#define ASENTRY(x_) ENTRY(x_)
++#define _C_FUNC(x_) /**/x_/**/
++#define _C_LABEL(x_) /**/x_/**/
++#define DEBUG
++
++@#define CORE_104MHz
++@#define CORE_208MHz
++#define CORE_312MHz
++@#define CORE_416MHz
++@#define CORE_520MHz
++@#define RUN_MODE
++#define TURBO_MODE
++
++
++
++#define ENABLE_PRINT_BYTE 1
++#define PRINT_SDRAM_SIZE 1
++#define SDRAM_TEST_SKIP_HIGHER_DATALINES 0
++
++
++#define SDRAM_32bit 1
++#define SDRAM_16bit 0
++
++
++
++#define PWRMODE_IDLE 0x1
++#define PWRMODE_STANDBY 0x2
++#define PWRMODE_SLEEP 0x3
++#define PWRMODE_DEEPSLEEP 0x7
++#define PSSR 0x40F00004
++#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
++#define PSSR_STS (1 << 3) /* Standby Mode Status */
++#define UNCACHED_PHYS_0 0xff000000
++
++/* More handy macros. The argument is a literal GPIO number. */
++#define GPIO_bit(x) 1 << ((x) & 0x1f)
++
++
++.globl _start
++_start: b reset
++ ldr pc, _undefined_instruction
++ ldr pc, _software_interrupt
++ ldr pc, _prefetch_abort
++ ldr pc, _data_abort
++ ldr pc, _not_used
++ ldr pc, _irq
++ ldr pc, _fiq
++
++_undefined_instruction: .word undefined_instruction
++_software_interrupt: .word software_interrupt
++_prefetch_abort: .word prefetch_abort
++_data_abort: .word data_abort
++_not_used: .word not_used
++_irq: .word irq
++_fiq: .word fiq
++
++ .balignl 16,0xdeadbeef
++
++
++/*
++ * Startup Code (reset vector)
++ *
++ * do important init only if we don't start from RAM!
++ * - relocate armboot to ram
++ * - setup stack
++ * - jump to second stage
++ */
++
++_TEXT_BASE:
++ .word TEXT_BASE
++
++.globl _armboot_start
++_armboot_start:
++ .word _start
++
++/*
++ * These are defined in the board-specific linker script.
++ */
++.globl _bss_start
++_bss_start:
++ .word __bss_start
++
++.globl _bss_end
++_bss_end:
++ .word _end
++
++#ifdef CONFIG_USE_IRQ
++/* IRQ stack memory (calculated at run-time) */
++.globl IRQ_STACK_START
++IRQ_STACK_START:
++ .word 0x0badc0de
++
++/* IRQ stack memory (calculated at run-time) */
++.globl FIQ_STACK_START
++FIQ_STACK_START:
++ .word 0x0badc0de
++#endif
++
++
++
++
++
++
++/****************** STAGE7 - Uboot Relocation Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage5_uboot_relocation_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++/****************************************************************************/
++/* */
++/* the actual reset code */
++/* */
++/****************************************************************************/
++
++reset:
++ mrs r0,cpsr /* set the cpu to SVC32 mode */
++ bic r0,r0,#0x1f /* (superviser mode, M=10011) */
++ orr r0,r0,#0x13
++ msr cpsr,r0
++
++ /*
++ * we do sys-critical inits only at reboot,
++ * not when booting from ram!
++ */
++#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++ bl cpu_init_crit /* we do sys-critical inits */
++#endif
++
++#ifndef CONFIG_SKIP_RELOCATE_UBOOT
++relocate:
++ adr r0, _start /* r0 <- current position of code */
++ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
++ cmp r0, r1 /* don't reloc during debug */
++ beq stack_setup
++
++ /*reload the r0 and r1 before proceeding*/
++ adr r0, _start
++ ldr r1, _TEXT_BASE
++ ldr r2, _armboot_start
++ ldr r3, _bss_start
++ sub r2, r3, r2 /* r2 <- size of armboot */
++ add r2, r0, r2 /* r2 <- source end address */
++
++copy_loop:
++ ldmia r0!, {r3-r10} /* copy from source address [r0] */
++ stmia r1!, {r3-r10} /* copy to target address [r1] */
++ cmp r0, r2 /* until source end addreee [r2] */
++ ble copy_loop
++#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
++
++ /* Set up the stack */
++
++
++stack_setup:
++#if 0
++ mov r0, #'A'
++ bl print_byte
++#endif
++
++ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
++ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
++ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
++#ifdef CONFIG_USE_IRQ
++ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
++#endif
++ sub sp, r0, #12 /* leave 3 words for abort-stack */
++
++clear_bss:
++ ldr r0, _bss_start /* find start of bss segment */
++ ldr r1, _bss_end /* stop here */
++ mov r2, #0x00000000 /* clear */
++
++clbss_l:str r2, [r0] /* clear loop... */
++ add r0, r0, #4
++ cmp r0, r1
++ ble clbss_l
++#if 0
++ mov r0, #'D'
++ bl print_byte
++#endif
++ print_stage5_uboot_relocation_completed
++
++ ldr pc, _start_armboot
++_start_armboot: .word start_armboot
++
++/****************************************************************************/
++/* */
++/* CPU_init_critical registers */
++/* */
++/* - setup important registers */
++/* - setup memory timing */
++/* */
++
++/****************************************************************************/
++
++/* Interrupt-Controller base address */
++IC_BASE: .word 0x40d00000
++#define ICMR 0x04
++
++/* Reset-Controller */
++RST_BASE: .word 0x40f00030
++#define RCSR 0x00
++
++/* Operating System Timer */
++//OSTIMER_BASE: .word 0x40a00000
++#define OSTIMER_BASE 0x40a00000
++#define OSMR3 0x0C
++#define OSCR 0x10
++#define OWER 0x18
++#define OIER 0x1C
++
++
++
++/* Clock Manager Registers */
++#ifdef CFG_CPUSPEED
++CC_BASE: .word 0x41300000
++#define CCCR 0x00
++@cpuspeed: .word CFG_CPUSPEED @tharma
++
++#ifdef CORE_104MHz
++cpuspeed: .word 0x02000108 @ L = 8, 2N = 2, A = 1
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x0000000a @ B = 1, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++
++#ifdef CORE_208MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000110 @ L = 16, 2N = 2, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000110 @ L = 16, 2N = 2, A = 1
++#endif
++#ifdef RUN_MODE
++CLKCFG_VALUE: .word 0x00000002 @ B = 0, HT = 0, F = 1, T = 0
++#endif
++#ifdef TURBO_MODE
++CLKCFG_VALUE: .word 0x00000003 @ B = 0, HT = 0, F = 1, T = 1
++#endif
++#endif
++
++#ifdef CORE_312MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000190 @ L = 16, 2N = 3, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000190 @ L = 16, 2N = 3, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_416MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x00000210 @ L= 16, 2N = 4, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000210 @ L= 16, 2N = 4, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++#ifdef CORE_520MHz
++#ifdef MEMCLK104
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 0
++#else ifdef MEMCLK208
++cpuspeed: .word 0x02000290 @ L = 16, 2N = 5, A = 1
++#endif
++CLKCFG_VALUE: .word 0x0000000b @ B = 1, HT = 0, F = 1, T = 1
++#endif
++
++
++@#error "You have to define CFG_CPUSPEED!!"
++#endif
++
++
++
++
++
++ /* RS: ??? */
++ .macro CPWAIT
++ mrc p15,0,r0,c2,c0,0
++ mov r0,r0
++ sub pc,pc,#4
++ .endm
++
++
++
++#define GAFR2_L_ADDR 0x40E00064
++#define GAFR2_L_MASK_VALUE_FOR_GPIO71 0xFFFF3FFF
++#define GPDR2_ADDR 0x40E00014
++#define GPDR2_VALUE_FOR_GPIO71 0x00000080
++#define GPCR2_ADDR 0x40E0002C
++#define GPSR2_ADDR 0x40E00020
++
++
++/****************** BUZZER GPIO config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++
++.macro buzzer_gpio_config
++
++ ldr r0, =GAFR2_L_ADDR @Addr of GAFR2_L
++ ldr r1, [r0] @Get the value present in GAFR2_L
++ ldr r2, =GAFR2_L_MASK_VALUE_FOR_GPIO71
++ and r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =GPDR2_ADDR @Addr of GPDR2
++ ldr r1, [r0] @Get the value present in GPDR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++.endm
++
++
++
++#ifdef CONFIG_ESOM270
++/****************** BUZZER ON ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_on
++ ldr r0, =GPSR2_ADDR @Addr of GPSR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ str r2, [r0]
++.endm
++
++
++/****************** BUZZER OFF ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro esom270_buzzer_off
++ ldr r0, =GPCR2_ADDR @Addr of GPCR2
++ ldr r1, [r0] @Get the value present in GPCR2
++ ldr r2, =GPDR2_VALUE_FOR_GPIO71
++ orr r1, r1, r2
++ str r1, [r0]
++
++.endm
++#endif
++
++
++/************************* print_stage0_booting_in_progress ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_stage0_booting_in_progress
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'B'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'t'
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'i'
++ bl print_byte_without_stack
++
++ mov r0, #'n'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'p'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'o'
++ bl print_byte_without_stack
++
++ mov r0, #'g'
++ bl print_byte_without_stack
++
++ mov r0, #'r'
++ bl print_byte_without_stack
++
++ mov r0, #'e'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'s'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #'.'
++ bl print_byte_without_stack
++
++ mov r0, #' '
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE1 - Serial Port Init Completed ****************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage1_serial_port_init_completed
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++ mov r0, #'1'
++ bl print_byte_without_stack
++
++ mov r0, #'\r'
++ bl print_byte_without_stack
++
++ mov r0, #'\n'
++ bl print_byte_without_stack
++
++.endm
++
++
++/****************** STAGE2 - Stack Setup in Internal SRAM Completed ****
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage2_stack_setup_in_internal_sram_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE3 - Setting Cpuspeed Completed***************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage3_setting_cpuspeed_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++/****************** STAGE4 - Static ChipSelect Config Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage4_static_chip_select_config_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++/****************** STAGE6 - SDRAM Memory Test Completed**********
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++
++.macro print_stage6_sdram_memory_test_completed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++cpu_init_crit:
++ mov r11, lr
++ bl irq_masking
++ENTRY(return_from_c)
++ bl serial_port_init
++ print_stage1_serial_port_init_completed
++ /*Now initalize the SP before calling putstr or print_byte */
++ mov r0, #0x5c000000
++ add r0, r0, #0x8000
++ mov sp, r0
++ print_stage2_stack_setup_in_internal_sram_completed
++ bl setting_cpuspeed
++ print_stage3_setting_cpuspeed_completed
++ @buzzer_gpio_config
++ bl flash_config
++ print_stage4_static_chip_select_config_completed
++ bl sdram_config
++@No Need to test the SDRAM
++ @bl auto_detect_memory_test
++ mov pc, r11 @cpu_crit_init ends here
++
++
++
++
++/***********************************
++** Flash Config **
++** Registers used : r0,r1,lr **
++***********************************/
++
++MSC0_ADDR: .word 0x48000008
++MSC1_ADDR: .word 0x4800000c
++MSC2_ADDR: .word 0x48000010
++SA1110_ADDR: .word 0x48000064
++MECR_ADDR: .word 0x48000014
++MCMEM0_ADDR: .word 0x48000028
++MCMEM1_ADDR: .word 0x4800002c
++MCATT0_ADDR: .word 0x48000030
++MCATT1_ADDR: .word 0x48000034
++MCIO_0_ADDR: .word 0x48000038
++MCIO_1_ADDR: .word 0x4800003c
++FLYCNFG_ADDR: .word 0x48000020
++
++
++
++MSC0_VALUE: .word 0x7ff87ff8
++MSC1_VALUE: .word 0x7ff87ff8
++MSC2_VALUE: .word 0x7ff87ff8
++SA1110_VALUE: .word 0x00000000
++MECR_VALUE: .word 0x00000000
++
++@Minimun value ( default ) configuration
++/*
++MCMEM0_VALUE: .word 0x00000000
++MCMEM1_VALUE: .word 0x00000000
++MCATT0_VALUE: .word 0x00000000
++MCATT1_VALUE: .word 0x00000000
++MCIO_0_VALUE: .word 0x00000000
++MCIO_1_VALUE: .word 0x00000000
++*/
++
++@Maximum value configuration
++MCMEM0_VALUE: .word 0x000fcfff
++MCMEM1_VALUE: .word 0x000fcfff
++MCATT0_VALUE: .word 0x000fcfff
++MCATT1_VALUE: .word 0x000fcfff
++MCIO_0_VALUE: .word 0x000fcfff
++MCIO_1_VALUE: .word 0x000fcfff
++
++FLYCNFG_VALUE: .word 0x00010001
++
++flash_config:
++ stmdb sp!, {r0, r1, lr}
++
++ ldr r0, MSC0_ADDR
++ ldr r1, MSC0_VALUE
++ str r1, [r0]
++ ldr r1, [r0] @read it back
++
++ ldr r0, MSC1_ADDR
++ ldr r1, MSC1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MSC2_ADDR
++ ldr r1, MSC2_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, SA1110_ADDR
++ ldr r1, SA1110_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MECR_ADDR
++ ldr r1, MECR_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCMEM0_ADDR
++ ldr r1, MCMEM0_VALUE
++ str r1, [r0]
++
++ ldr r0, MCMEM1_ADDR
++ ldr r1, MCMEM1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT0_ADDR
++ ldr r1, MCATT0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCATT1_ADDR
++ ldr r1, MCATT1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_0_ADDR
++ ldr r1, MCIO_0_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, MCIO_1_ADDR
++ ldr r1, MCIO_1_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++
++ ldr r0, FLYCNFG_ADDR
++ ldr r1, FLYCNFG_VALUE
++ str r1, [r0]
++ ldr r1, [r0]
++ ldmia sp!, {r0, r1, pc}
++
++
++
++
++MDCNFG_ADDR: .word 0x48000000
++MDMRS_ADDR: .word 0x48000040
++MDMRSLP_ADDR: .word 0x48000058
++MDREFR_ADDR: .word 0x48000004
++MDMRS_VALUE: .word 0x00000032
++
++
++
++#ifdef SDRAM32
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x0ba80ba8
++ MDCNFG_VAL_EN: .word 0x0ba80bab
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x0bac0bac
++ MDCNFG_VAL_EN: .word 0x0bac0baf
++ #endif
++
++ #warning "SDRAM SIZE is 32MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26030 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x030 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6030
++ MDREFR_VAL_NOCLK: .word 0x208f6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe030
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c26060 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x060 for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6060
++ MDREFR_VAL_NOCLK: .word 0x208f6060
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe060
++ #endif
++
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06030 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x030 for memclk = 104Mhz. The DRI is 0x20 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6030
++ MDREFR_VAL_NOCLK: .word 0x208d6030
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de030
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06028 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x028 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6028
++ MDREFR_VAL_NOCLK: .word 0x208d6028
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de028
++ #endif
++ #endif
++#elif defined (SDRAM64)
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x0ba80bc8
++ MDCNFG_VAL_EN: .word 0x0ba80bcb
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x0bac0bcc
++ MDCNFG_VAL_EN: .word 0x0bac0bcf
++ #endif
++ #warning "SDRAM SIZE is 64MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif define(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++#elif defined (SDRAM128)
++ #if SDRAM_32bit
++ MDCNFG_VAL_DIS: .word 0x8ba80bd0
++ MDCNFG_VAL_EN: .word 0x8ba80bd3
++ #elif SDRAM_16bit
++ MDCNFG_VAL_DIS: .word 0x8bac0bd4
++ MDCNFG_VAL_EN: .word 0x8bac0bd7
++ #endif
++ #warning "SDRAM SIZE is 128MB"
++ #ifdef SDCLK_MEMCLK_BY_2
++ #warning "SDRAM CLK IS HALF OF MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEMCLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c26017 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x017 for memclk = 104Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6017
++ MDREFR_VAL_NOCLK: .word 0x208f6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe017
++
++ #elif defined(MEMCLK208)
++ #warning "MEMCLK is 208MHZ"
++ MDREFR_VAL_START: .word 0x20c2602E @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 208Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf602E
++ MDREFR_VAL_NOCLK: .word 0x208f602E
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe02E
++
++ #elif defined(MEMCLK91)
++ #warning "MEMCLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c26013 @bit17 K1DB2 = 1 -> sdram clock = memclk/2 bit 11-0 DRI = 0x02E for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cf6013
++ MDREFR_VAL_NOCLK: .word 0x208f6013
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208fe013
++ #endif
++ #elif defined(SDCLK_MEMCLK)
++ #warning "SDRAM CLK IS EQUALS TO MEM CLK"
++ #ifdef MEMCLK104
++ #warning "MEM CLK is 104MHZ"
++ MDREFR_VAL_START: .word 0x20c06017 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x017 for memclk = 104Mhz. The DRI is 0x17 because refresh rate is 10.1uS per row and 41ms per chip
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6017
++ MDREFR_VAL_NOCLK: .word 0x208d6017
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de017
++
++ #elif defined(MEMCLK91)
++ #warning "MEM CLK is 91MHZ"
++ MDREFR_VAL_START: .word 0x20c06014 @bit17 K1DB2 = 0 -> sdram clock = memclk bit 11-0 DRI = 0x014 for memclk = 91Mhz
++ MDREFR_VAL_SR_NOCLK: .word 0x20cd6014
++ MDREFR_VAL_NOCLK: .word 0x208d6014
++ MDREFR_VAL_PWRDWNEXIT: .word 0x208de014
++ #endif
++ #endif
++
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++
++
++
++
++LED_GREEN: .word GPIO_bit(16)
++LED_YELLOW: .word GPIO_bit(96)
++
++REG_GPCR: .word 0x40e00024
++REG_GPSR: .word 0x40e00018
++
++
++/****************** SDRAM config ***************************************
++ registers used - r0, r1, r2, r3
++***********************************************************************/
++sdram_config:
++ /*stack pointer is already set in SRAM */
++ stmdb sp!, {r0, r1, r2, r3, lr}
++ ldr r0, MDCNFG_ADDR
++ ldr r1, [r0]
++ ldr r2, =0xfffcfffc
++ and r1, r1, r2 @disable all banks
++ str r1, [r0]
++
++ @Config K0DB2, K0DB4 and DRI. SLFRSH=1, APD=0, K0RUN=1
++ ldr r0, MDREFR_ADDR
++ ldr r1, MDREFR_VAL_START
++ str r1, [r0]
++
++ @Enter Selfresfresh with ClkStop. K1RUN = 1, K2RUN=1, K1DB2=1 (MEMCLK/2), K2DB2 = 1
++ ldr r1, MDREFR_VAL_SR_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go out of self-refresh SLFRSH = 0 (Goes to PWRDWN)
++ ldr r1, MDREFR_VAL_NOCLK
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Go to PWRDWNX (powerdown exit)
++ @E1PIN = 1, K1RUN =1 (already set to 1)
++ ldr r1, MDREFR_VAL_PWRDWNEXIT
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++ @Now the SDRAM is in NOP mode
++
++ @configure the SDRAM with partitions disabled
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_DIS
++ str r1, [r0]
++
++ @delay for 200usec
++ bl bdelay
++
++
++ @Dummy Write and Read from SDRAM banks
++ mov r0, #0xa0000000
++ mov r1, #0xa0000000
++ str r1, [r0]
++ mov r2, #0x10
++loop:
++ add r1, r1, #0x04
++ str r1, [r0, #0x04]
++ sub r2, r2, #0x01
++ cmp r2, #0x00
++ bne loop
++
++ @enable sdram partion
++ ldr r0, MDCNFG_ADDR
++ ldr r1, MDCNFG_VAL_EN
++ str r1, [r0]
++
++ @Configure MRS
++ ldr r0, MDMRS_ADDR
++ ldr r1, MDMRS_VALUE
++ str r1, [r0]
++
++
++ ldmia sp!, {r0,r1,r2,r3,pc}
++
++
++
++
++/************************* print_string_booting_failed ****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++**********************************************************************/
++.macro print_string_booting_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'o'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'n'
++ bl print_byte
++
++ mov r0, #'g'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_sdram_test_failed ***********
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_sdram_test_failed
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'O'
++ bl print_byte
++
++ mov r0, #'R'
++ bl print_byte
++
++ mov r0, #'Y'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'S'
++ bl print_byte
++
++ mov r0, #'T'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'F'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'i'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++
++
++.endm
++
++
++
++
++
++
++/************************* print_string_address *********************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_address
++
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #'r'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'s'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++
++.endm
++
++
++/************************* print_string_expected_data ***************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_expected_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'E'
++ bl print_byte
++
++ mov r0, #'x'
++ bl print_byte
++
++ mov r0, #'p'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'e'
++ bl print_byte
++
++ mov r0, #'d'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++
++.endm
++
++
++/************************* print_string_actual_data *****************
++ registers used r0,r1,r2,lr
++ r0, - character to be print
++********************************************************************/
++.macro print_string_actual_data
++ mov r0, #'\r'
++ bl print_byte
++
++ mov r0, #'\n'
++ bl print_byte
++
++ mov r0, #'A'
++ bl print_byte
++
++ mov r0, #'c'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'u'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'l'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'D'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'t'
++ bl print_byte
++
++ mov r0, #'a'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #'\t'
++ bl print_byte
++
++ mov r0, #':'
++ bl print_byte
++
++ mov r0, #' '
++ bl print_byte
++
++.endm
++
++
++
++
++
++
++
++
++
++
++
++@---------------------------------------@
++@ Autodetect the SDRAM size @
++@---------------------------------------@
++
++@registers used: r0,,r1,r2,r3,r4,r5,r6,r7,r8,lr
++#ifdef SDRAM32
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x02000000
++#elif defined(SDRAM64)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x04000000
++#elif defined(SDRAM128)
++SDRAM_BASE: .word 0xa0000000
++SDRAM_SIZE: .word 0x08000000
++#else
++#error "You have to define the SDRAM SIZE (SDRAM32 or SDRAM64 or SDRAM128)"
++#endif
++
++SIZE_0M: .word 0x00000000
++SIZE_8M: .word 0x00800000
++SIZE_16M: .word 0x01000000
++SIZE_32M: .word 0x02000000
++SIZE_64M: .word 0x04000000
++SIZE_128M: .word 0x08000000
++SIZE_256M: .word 0x10000000
++
++
++auto_detect_memory_test:
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,lr}
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_0M
++ add r1, r1, r0
++ str r1, [r1]
++
++#if defined(SDRAM16) || defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++#if defined(SDRAM128) || defined (SDRAM256)
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ str r1, [r1]
++#endif
++
++check_sd16M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_16M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram16
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd32M
++#endif
++
++print_sdram16:
++ mov r8, #0x1000000 @16MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++
++#if defined(SDRAM32) || defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd32M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_32M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram32
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++ b check_sd64M
++#endif
++print_sdram32:
++ mov r8, #0x2000000 /*Move to r8 the size of SDRAM */ @32MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'3'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++#if defined(SDRAM64) || defined(SDRAM128) || defined (SDRAM256)
++check_sd64M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_64M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram64
++#if defined(SDRAM128) || defined (SDRAM256)
++ b check_sd128M
++#endif
++
++print_sdram64:
++ mov r8, #0x4000000 @64MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'4'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined(SDRAM128) || defined (SDRAM256)
++check_sd128M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_128M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram128
++#if defined (SDRAM256)
++ b check_sd256M
++#endif
++
++print_sdram128:
++ mov r8, #0x8000000 @128MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'1'
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'8'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++
++#if defined (SDRAM256)
++check_sd256M:
++ ldr r0, SDRAM_BASE
++ ldr r1, SIZE_256M
++ add r1, r1, r0
++ ldr r2, [r0]
++ cmps r2, r1
++ beq print_sdram256
++print_sdram256:
++ mov r8, #0x10000000 @256MB
++#if PRINT_SDRAM_SIZE
++ mov r0, #' '
++ bl print_byte
++
++ mov r0, #'2'
++ bl print_byte
++
++ mov r0, #'5'
++ bl print_byte
++
++ mov r0, #'6'
++ bl print_byte
++
++ mov r0, #'M'
++ bl print_byte
++
++ mov r0, #'B'
++ bl print_byte
++#endif
++ b decodercs
++#endif
++decodercs:
++
++#if 1
++test_mem:
++ /*; Data bus test */
++ /* Start the memory tester, hardcoded bank 0 & 1 for now */
++
++ ldr r7, SDRAM_BASE
++@ ldr r8, SDRAM_SIZE
++ add r6, r7, r8
++ mov r4, r7
++
++memoryload:
++ str r4, [r4]
++ add r4, r4, #0x4
++
++ cmp r4, r6
++ blt memoryload
++
++ mov r4, r7
++memorytest:
++ ldr r5, [r4]
++#if SDRAM_TEST_SKIP_HIGHER_DATALINES
++ ldr r7, =0x0000FFFF
++ and r5, r5, r7
++ and r4, r4, r7
++#endif
++ cmp r5, r4
++ bne memoryfail
++ add r4, r4, #0x4
++ cmp r4, r6
++ blt memorytest
++
++test_done:
++ mov r0, #0x0a
++ ldr r1, LED_YELLOW
++ bl led_blink_sp
++ bl bdelay
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++memoryfail:
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_on
++#endif
++ bl bdelay
++ print_string_booting_failed
++
++ print_string_sdram_test_failed
++ print_string_address
++
++ mov r0, r4 @address
++ bl print_hex
++ bl bdelay
++
++
++ print_string_expected_data
++
++ mov r0, r4 @expected data
++ bl print_hex
++ bl bdelay
++
++ print_string_actual_data
++
++ mov r0, r5 @actual data
++ bl print_hex
++ bl bdelay
++#ifdef CONFIG_ESOM270
++ esom270_buzzer_off
++#endif
++ mov r0, #0x0a
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++
++infinite_loop:
++ bl infinite_loop
++
++
++#endif
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,pc}
++
++
++
++
++
++
++
++
++
++
++
++
++
++/****************** led_blink_sp **************************
++ registers used r0,r1, r2
++ r0 - number of times to blink
++ r1 - led to blink
++******************************************************************/
++
++ENTRY(led_blink_sp)
++ stmdb sp!, {r0,r1,r2,lr}
++ cmp r1, #GPIO_bit(96)
++ beq yellow_led_blink_loop
++
++green_led_blink_loop:
++ @switch on the GREEN LED
++ ldr r2, GREEN_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the GREEN LED
++ ldr r2, GREEN_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne green_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++yellow_led_blink_loop:
++ @switch on the YELLOW LED
++ ldr r2, YELLOW_LED_GPCR
++ str r1, [r2]
++ bl bdelay_sp
++
++
++ @switch off the YELLOW LED
++ ldr r2, YELLOW_LED_GPSR
++ str r1, [r2]
++ bl bdelay_sp
++
++ sub r0, r0, #1
++ cmp r0, #0
++ bne yellow_led_blink_loop
++
++ ldmia sp!, {r0,r1,r2,pc}
++
++
++/******************************* bdelay_sp *************************
++ uses registers: r0, r1
++
++*******************************************************************/
++
++bdelay_sp:
++ stmdb sp!, {r0,r1,lr}
++ mov r0, #0x0 @ zero out r4
++loop_out:
++ mov r1, #0x0
++loop_in:
++ add r1, r1, #1 @ increment it
++ cmp r1, #0x0001000 @ compare against constant
++ bne loop_in @ if not equal, loop
++ add r0, r0, #1
++ cmp r0, #0x400
++ bne loop_out
++ ldmia sp!, {r0,r1, pc}
++
++
++@--------------------------------------------@
++@ IRQ Masking @
++@--------------------------------------------@
++irq_masking:
++ /* mask all IRQs */
++ ldr r0, IC_BASE
++ mov r1, #0x00
++ str r1, [r0, #ICMR]
++ mov pc, r14
++
++
++
++#if 1
++setting_cpuspeed:
++#if defined(CFG_CPUSPEED)
++
++ /* set clock speed */
++ ldr r0, CC_BASE
++ ldr r1, cpuspeed
++ str r1, [r0, #CCCR]
++ ldr r0, CLKCFG_VALUE
++ mcr p14, 0, r0, c6, c0, 0
++ CPWAIT
++#endif
++
++
++#endif
++ mov ip, lr
++@ bl lowlevel_init
++ bl econ_lowlevel_init
++ mov lr, ip
++
++/*To clear the RDH of PSSR Reg */
++
++ ldr r0, =0x40F00004
++ mov r1, #0x20
++ str r1, [r0]
++
++ mov pc, r14
++
++
++/******************************************
++ ** econ_lowlevel_init GPIO Configuration
++******************************************/
++GPSR0: .word 0x40e00018
++GPSR1: .word 0x40e0001c
++GPSR2: .word 0x40e00020
++GPSR3: .word 0x40e00118
++
++YELLOW_LED_GPSR: .word 0x40e00118
++YELLOW_LED_GPCR: .word 0x40e00124
++GREEN_LED_GPSR: .word 0x40e00018
++GREEN_LED_GPCR: .word 0x40e00024
++
++
++GPCR0: .word 0x40e00024
++GPCR1: .word 0x40e00028
++GPCR2: .word 0x40e0002c
++GPCR3: .word 0x40e00124
++
++GPDR0: .word 0x40e0000c
++GPDR1: .word 0x40e00010
++GPDR2: .word 0x40e00014
++GPDR3: .word 0x40e0010c
++
++GAFR0_L: .word 0x40e00054
++GAFR0_U: .word 0x40e00058
++GAFR1_L: .word 0x40e0005c
++GAFR1_U: .word 0x40e00060
++GAFR2_L: .word 0x40e00064
++GAFR2_U: .word 0x40e00068
++GAFR3_L: .word 0x40e0006c
++GAFR3_U: .word 0x40e00070
++
++
++GPSR0_VAL: .word 0x9a5f7e18
++GPSR1_VAL: .word 0x00100000
++GPSR2_VAL: .word 0x0c400000
++GPSR3_VAL: .word 0x00040c20
++
++GPCR0_VAL: .word 0x00200000
++GPCR1_VAL: .word 0x00000000
++GPCR2_VAL: .word 0x00080000
++GPCR3_VAL: .word 0x0018002e
++
++GPDR0_VAL: .word 0xdbdbf618
++GPDR1_VAL: .word 0xfcbf8b87
++GPDR2_VAL: .word 0x1ab1ffff
++GPDR3_VAL: .word 0x006e0440
++
++GAFR0_L_VAL: .word 0xa7800000
++GAFR0_U_VAL: .word 0x591a8053
++GAFR1_L_VAL: .word 0x699a555a
++GAFR1_U_VAL: .word 0xaaa5b8aa
++GAFR2_L_VAL: .word 0x5aaaaaaa
++GAFR2_U_VAL: .word 0xa909af06
++GAFR3_L_VAL: .word 0x55055003
++GAFR3_U_VAL: .word 0x00001405
++
++PSKTSEL_SET: .word 0x00008000
++econ_lowlevel_init:
++@ Configure the gpio pin:79 PSKTSEL as general gpio, output,value = high
++
++ ldr r0, GPSR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GPDR2
++ ldr r1, PSKTSEL_SET
++ str r1, [r0]
++
++ ldr r0, GAFR2_L
++ mov r1, #0x00
++ str r1, [r0]
++
++ mov pc, lr
++
++
++
++/* Delay Routine */
++@------------------------------------------------------@
++@ time delay subroutine @
++@ uses r9 and r10 registers @
++@------------------------------------------------------@
++
++
++bdelay:
++ mov r9, #0x0 @ zero out r4
++outloop:
++ mov r10, #0x0
++inloop:
++ add r10, r10, #1 @ increment it
++ cmp r10, #0x0001000 @ compare against constant
++ bne inloop @ if not equal, loop
++ add r9, r9, #1
++ cmp r9, #0x2000
++ bne outloop
++ mov pc, r14 @ return from subroutine
++
++
++
++
++
++
++
++
++
++@-------------------------------------------@
++@ Serial Port Initialization @
++@-------------------------------------------@
++
++serial_port_init:
++#ifdef CONFIG_STUART
++#warning "DEBUG UART IS STUART"
++
++/* Setting the GPIO46 and GPIO47 as input pin (STD_RXD) and output pin (STD_TXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E00010 @Addr of GPDR1
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x8000 @ GPIO47 = 1 ( bit15 ) GPIO46= 0 (bit14)for o/p and i/p respectively
++ str r1, [r0]
++
++/* Setting the GPIO46 and GPIO47 for alter.func af2 and af1 respectively */
++ ldr r0, =0x40E0005C @Addr of GAFR1_L
++ ldr r1, [r0] @Get the value present in GAFR1_L
++ orr r1, r1, #0x60000000 @AF47 = 0b01 , AF46 = 0b10
++ str r1, [r0]
++
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x700000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++#elif defined(CONFIG_FFUART)
++#warning "DEBUG UART IS FFUART"
++
++/* Setting the GPIO96 and GPIO16 as input pin (FFRXD) and output pin (FFTXD) respectively */
++@--------------------------------------------------------------@
++gpiosetup_serialport:
++
++ ldr r0, =0x40E0000C @Addr of GPDR0
++ ldr r1, [r0] @Get the value present in GPDR1
++ orr r1, r1, #0x10000 @ GPIO16 = 1 o/p
++ str r1, [r0]
++
++ ldr r0, =0x40E0010C @Addr of GPDR3
++ ldr r1, [r0] @Get the value present in GPDR1
++ bic r1, r1, #0x0001 @ GPIO96 = 0 i/p
++ str r1, [r0]
++
++/* Setting the GPIO16 and GPIO96 for alter.func af3 and af3 respectively */
++ ldr r0, =0x40E00058
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x40E0006c
++ ldr r1, [r0]
++ orr r1, r1, #0x00000003
++ str r1, [r0]
++
++
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000040 /* FFUART CLK ENABLE CKEN6 in CLK Enable Register */
++ str r1, [r0]
++
++uart_start:
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x100000 @ Standard UART register start addr
++
++ /* disable the UART */
++disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++
++#endif
++@#elif defined(CONFIG_BTUART)
++#if 1
++#warning " ADDITION UART IS BTUART"
++
++/* Setting the GPIO42 and GPIO43 as input pin (BT_RXD) and output pin (BT_TXD) respectively */
++@--------------------------------------------------------------@
++config_btuart:
++
++ ldr r0, =0x40e00010
++ ldr r1, [r0]
++ orr r1, r1, #0x0002800
++ str r1, [r0]
++
++ ldr r0, =0x40e00014
++ ldr r1, [r0]
++ orr r1, r1, #0x00300000
++ str r1, [r0]
++
++ ldr r0, =0x40e0005c
++ ldr r1, [r0]
++ orr r1, r1, #0x09900000
++ str r1, [r0]
++
++bt_uart_start:
++ ldr r0, =0x41300004 /* CLK ENABLE REGISTER CKEN */
++ ldr r1, [r0]
++ orr r1, r1, #0x00000080 /* STUART CLK ENABLE CKEN7 in CLK Enable Register */
++ str r1, [r0]
++
++
++ mov r1,#0x40000000 /* Base addr of UART */
++ add r1, r1, #0x200000 @ BTUART register start addr
++
++ /* disable the UART */
++bt_disbale_uart:
++ mov r2, #0x00
++ str r2, [r1, #0x04] @ UART1 Interrupt Enable Reg
++
++ /* no parity, 8 databits, 1 stopbit. */
++bt_databit:
++ mov r2, #0x83 @ 8N1
++ str r2, [r1, #0x0C] @ UART Line Control Reg
++
++bt_baudrate_setup: @Baudrate 115200
++ mov r2, #0x08
++@ mov r2, #0x60 @Baudrate 9600 for testing Bluetooth module
++ str r2, [r1, #0x00] /* DLL */
++ mov r2, #00
++ str r2, [r1, #0x04] /* DLH */
++bt_uart_unit_enable:
++ mov r2, #0x03 /* DLAB = 0 */
++ str r2, [r1, #0x0C]
++ mov r2, #0x40 /* UUE of IER = 1 */
++ str r2, [r1, #0x04]
++
++ mov pc, lr @ serial_port_init ends here
++
++#endif
++
++
++
++/**************************************************
++ Dumping registers r0 - r8
++**************************************************
++*/
++
++ENTRY(dump_reg)
++ stmdb sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
++
++ mov r0, r0
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r1
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r2
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r4
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r5
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r6
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r7
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r8
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r9
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r10
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r11
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r12
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r13
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r14
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++ mov r0, r15
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++ ldmia sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,pc}
++
++@-------------------------------------@
++@ Printing String @
++@-------------------------------------@
++
++/* registers used r2, lr */
++
++print_str:
++/*Save the return address */
++ stmdb sp!, {r2, lr}
++ mov r2, r0
++prs1:
++ ldrsb r0, [r2]
++ add r2, r2, #0x01
++ ands r0, r0, #0xFF
++ beq prs2
++ bl print_byte
++ b prs1
++
++prs2:
++ /* Return */
++ ldmia sp!, {r2, pc}
++
++ENTRY(nand_boot)
++ ldr r1, =0x04000000
++ mov pc, r1
++
++
++
++
++
++@----------------------------------@
++@ Printing Byte without stack @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte_without_stack)
++ /* Wait for room in the tx holding register */
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++
++check_without_stack:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check_without_stack
++send_byte_without_stack:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ mov pc, lr
++
++
++@----------------------------------@
++@ Printing Byte @
++@----------------------------------@
++
++/* registers used r1, r12 */
++
++ENTRY(print_byte)
++ /* Wait for room in the tx holding register */
++ stmdb sp!, {r0,r1, r12, lr}
++#if ENABLE_PRINT_BYTE
++ mov r1, #0x40000000
++#ifdef CONFIG_STUART
++#warning "print_byte will use STUART "
++ add r1, r1, #0x700000
++#elif defined(CONFIG_FFUART)
++#warning "print_byte will use FFUART "
++ add r1, r1, #0x100000
++#elif defined(CONFIG_BTUART)
++#warning "print_byte will use BTUART "
++ add r1, r1, #0x200000
++#endif
++check:
++ ldr r12, [r1, #0x14]
++ and r12, r12, #0x40 /* Check the TEMT of LSR Register */
++ cmp r12, #0x40
++ bne check
++send_byte:
++ str r0, [r1, #0x00] /* Write data in DHR Register */
++#endif
++ ldmia sp!, {r0, r1, r12, pc}
++
++@------------------------------------------@
++@ Print_Hex @
++@------------------------------------------@
++
++
++ /* Subroutine to send a hex word (in r0) over the serial port */
++.globl print_hex
++ /* registers used r2, r3, r14(lr) */
++print_hex:
++ stmdb sp!, {r0,r2, r3, lr}
++ mov r2, r0
++ mov r3, #0x08
++ mov r0, #0x30
++ bl print_byte
++ mov r0, #0x78
++ bl print_byte
++prh1:
++ and r0, r2, #0xF0000000
++ mov r0, r0, lsr #28
++ add r0, r0, #0x30
++ cmp r0, #0x3A
++ addge r0, r0, #0x07
++ bl print_byte
++ mov r2, r2, lsl #4
++ subs r3, r3, #0x01
++ bne prh1
++
++ ldmia sp!, {r0,r2, r3, pc}
++
++
++/****************************************************************************/
++/* */
++/* Interrupt handling */
++/* */
++/****************************************************************************/
++
++/* IRQ stack frame */
++
++#define S_FRAME_SIZE 72
++
++#define S_OLD_R0 68
++#define S_PSR 64
++#define S_PC 60
++#define S_LR 56
++#define S_SP 52
++
++#define S_IP 48
++#define S_FP 44
++#define S_R10 40
++#define S_R9 36
++#define S_R8 32
++#define S_R7 28
++#define S_R6 24
++#define S_R5 20
++#define S_R4 16
++#define S_R3 12
++#define S_R2 8
++#define S_R1 4
++#define S_R0 0
++
++#define MODE_SVC 0x13
++
++ /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
++
++ .macro bad_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++
++ ldr r2, _armboot_start
++ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
++ ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
++ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
++
++ add r5, sp, #S_SP
++ mov r1, lr
++ stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
++ mov r0, sp
++ .endm
++
++
++ /* use irq_save_user_regs / irq_restore_user_regs for */
++ /* IRQ/FIQ handling */
++
++ .macro irq_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++ stmdb r8, {sp, lr}^ /* Calling SP, LR */
++ str lr, [r8, #0] /* Save calling PC */
++ mrs r6, spsr
++ str r6, [r8, #4] /* Save CPSR */
++ str r0, [r8, #8] /* Save OLD_R0 */
++ mov r0, sp
++ .endm
++
++ .macro irq_restore_user_regs
++ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
++ mov r0, r0
++ ldr lr, [sp, #S_PC] @ Get PC
++ add sp, sp, #S_FRAME_SIZE
++ subs pc, lr, #4 @ return & move spsr_svc into cpsr
++ .endm
++
++ .macro get_bad_stack
++ ldr r13, _armboot_start @ setup our mode stack
++ sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
++
++ str lr, [r13] @ save caller lr / spsr
++ mrs lr, spsr
++ str lr, [r13, #4]
++
++ mov r13, #MODE_SVC @ prepare SVC-Mode
++ msr spsr_c, r13
++ mov lr, pc
++ movs pc, lr
++ .endm
++
++ .macro get_irq_stack @ setup IRQ stack
++ ldr sp, IRQ_STACK_START
++ .endm
++
++ .macro get_fiq_stack @ setup FIQ stack
++ ldr sp, FIQ_STACK_START
++ .endm
++
++
++/****************************************************************************/
++/* */
++/* exception handlers */
++/* */
++/****************************************************************************/
++
++ .align 5
++undefined_instruction:
++@ bl dump_reg
++ sub r0, r14,#0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, r13
++ bl print_hex
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, undef_msg
++ bl print_str
++ bl bdelay
++endless1:
++ b endless1
++
++
++ .align 5
++software_interrupt:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, soft_msg
++ bl print_str
++ bl bdelay
++endless2:
++ b endless2
++
++ .align 5
++prefetch_abort:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, prefetch_msg
++ bl print_str
++ bl bdelay
++endless3:
++ b endless3
++
++ .align 5
++data_abort:
++@ mov r3, r14
++ sub r0, r14, #0x8
++ bl print_hex
++ bl dump_reg
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++
++ sub r3, r3, #0x4
++ mov r0, r3
++ bl print_hex
++ mov r0, #0x20
++ bl print_byte
++ mov r0, #0xa
++ bl print_byte
++ mov r0, #0xd
++ bl print_byte
++
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ adr r0, data_msg
++ bl print_str
++ bl bdelay
++endless4:
++ b endless4
++
++ .align 5
++not_used:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, not_used_msg
++ bl print_str
++ bl bdelay
++endless5:
++ b endless5
++
++#ifdef CONFIG_USE_IRQ
++
++ .align 5
++irq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless6:
++ b endless6
++
++ .align 5
++fiq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless7:
++ b endless7
++
++#else
++
++ .align 5
++irq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, irq_msg
++ bl print_str
++ bl bdelay
++endless8:
++ b endless8
++
++ .align 5
++fiq:
++@ bl dump_reg
++ mov r0, #0xa
++ ldr r1, LED_GREEN
++ bl led_blink_sp
++ bl dump_reg
++ adr r0, fiq_msg
++ bl print_str
++ bl bdelay
++endless9:
++ b endless9
++
++
++#endif
++
++.align 4
++booting_progress:
++ .string "\r\n Booting is in progress.......\r\n"
++.align 4
++booting_fail:
++ .string "\r\n SDRAM MEMORY TEST :Failed \r\n"
++.align 4
++fail_address:
++ .string "\r\n Address : "
++.align 4
++expected_data:
++ .string "\r\n Expected Data : "
++.align 4
++actual_data:
++ .string "\r\n Actual Data : "
++.align 4
++undef_msg:
++ .string "\r\n Undefined instruction \r\n"
++.align 4
++soft_msg:
++ .string "\r\n Software interrupt never ends \r\n"
++.align 4
++prefetch_msg:
++ .string "\r\n Inside Prefetch abort loop\r\n"
++.align 4
++data_msg:
++ .string "\r\n inside the Data abort loop\r\n"
++.align 4
++not_used_msg:
++ .string "\r\n inside the not_used loop\r\n"
++.align 4
++irq_msg:
++ .string "\r\n Inside the irq exception loop\r\n"
++.align 4
++fiq_msg:
++ .string "\r\n Inside the fiq exception loop \r\n"
++
++/****************************************************************************/
++/* */
++/* Reset function: the PXA250 doesn't have a reset function, so we have to */
++/* perform a watchdog timeout for a soft reset. */
++/* */
++/****************************************************************************/
++
++ .align 5
++.globl reset_cpu
++
++ /* FIXME: this code is PXA250 specific. How is this handled on */
++ /* other XScale processors? */
++
++reset_cpu:
++
++ /* We set OWE:WME (watchdog enable) and wait until timeout happens */
++
++ ldr r0, =OSTIMER_BASE
++ ldr r1, [r0, #OWER]
++ orr r1, r1, #0x0001 /* bit0: WME */
++ str r1, [r0, #OWER]
++
++ /* OS timer does only wrap every 1165 seconds, so we have to set */
++ /* the match register as well. */
++
++ ldr r1, [r0, #OSCR] /* read OS timer */
++ add r1, r1, #0x800 /* let OSMR3 match after */
++ add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
++ str r1, [r0, #OSMR3]
++
++reset_endless:
++
++
++ b reset_endless
++
++
++ENTRY(pxa_cpu_standby)
++ ldr r0, =PSSR
++ mov r1, #(PSSR_PH | PSSR_STS)
++ mov r2, #PWRMODE_STANDBY
++@ mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
++@ ldr ip, [r3]
++ b 1f
++
++ .align 5
++1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
++ str r1, [r0] @ make sure PSSR_PH/STS are clear
++ mov pc, lr
+diff -Naur u-boot-2008.10_original/cpu/pxa/start.S_original u-boot-2008.10/cpu/pxa/start.S_original
+--- u-boot-2008.10_original/cpu/pxa/start.S_original 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/cpu/pxa/start.S_original 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,498 @@
++/*
++ * armboot - Startup Code for XScale
++ *
++ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
++ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
++ * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
++ * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
++ * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
++ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
++ * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/arch/pxa-regs.h>
++
++.globl _start
++_start: b reset
++ ldr pc, _undefined_instruction
++ ldr pc, _software_interrupt
++ ldr pc, _prefetch_abort
++ ldr pc, _data_abort
++ ldr pc, _not_used
++ ldr pc, _irq
++ ldr pc, _fiq
++
++_undefined_instruction: .word undefined_instruction
++_software_interrupt: .word software_interrupt
++_prefetch_abort: .word prefetch_abort
++_data_abort: .word data_abort
++_not_used: .word not_used
++_irq: .word irq
++_fiq: .word fiq
++
++ .balignl 16,0xdeadbeef
++
++
++/*
++ * Startup Code (reset vector)
++ *
++ * do important init only if we don't start from RAM!
++ * - relocate armboot to RAM
++ * - setup stack
++ * - jump to second stage
++ */
++
++_TEXT_BASE:
++ .word TEXT_BASE
++
++.globl _armboot_start
++_armboot_start:
++ .word _start
++
++/*
++ * These are defined in the board-specific linker script.
++ */
++.globl _bss_start
++_bss_start:
++ .word __bss_start
++
++.globl _bss_end
++_bss_end:
++ .word _end
++
++#ifdef CONFIG_USE_IRQ
++/* IRQ stack memory (calculated at run-time) */
++.globl IRQ_STACK_START
++IRQ_STACK_START:
++ .word 0x0badc0de
++
++/* IRQ stack memory (calculated at run-time) */
++.globl FIQ_STACK_START
++FIQ_STACK_START:
++ .word 0x0badc0de
++#endif /* CONFIG_USE_IRQ */
++
++
++/****************************************************************************/
++/* */
++/* the actual reset code */
++/* */
++/****************************************************************************/
++
++reset:
++ mrs r0,cpsr /* set the CPU to SVC32 mode */
++ bic r0,r0,#0x1f /* (superviser mode, M=10011) */
++ orr r0,r0,#0x13
++ msr cpsr,r0
++
++ /*
++ * we do sys-critical inits only at reboot,
++ * not when booting from RAM!
++ */
++#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++ bl cpu_init_crit /* we do sys-critical inits */
++#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
++
++#ifndef CONFIG_SKIP_RELOCATE_UBOOT
++relocate: /* relocate U-Boot to RAM */
++ adr r0, _start /* r0 <- current position of code */
++ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
++ cmp r0, r1 /* don't reloc during debug */
++ beq stack_setup
++
++ ldr r2, _armboot_start
++ ldr r3, _bss_start
++ sub r2, r3, r2 /* r2 <- size of armboot */
++ add r2, r0, r2 /* r2 <- source end address */
++
++copy_loop:
++ ldmia r0!, {r3-r10} /* copy from source address [r0] */
++ stmia r1!, {r3-r10} /* copy to target address [r1] */
++ cmp r0, r2 /* until source end address [r2] */
++ ble copy_loop
++#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
++
++ /* Set up the stack */
++stack_setup:
++ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
++ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
++ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
++#ifdef CONFIG_USE_IRQ
++ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
++#endif /* CONFIG_USE_IRQ */
++ sub sp, r0, #12 /* leave 3 words for abort-stack */
++
++clear_bss:
++ ldr r0, _bss_start /* find start of bss segment */
++ ldr r1, _bss_end /* stop here */
++ mov r2, #0x00000000 /* clear */
++
++clbss_l:str r2, [r0] /* clear loop... */
++ add r0, r0, #4
++ cmp r0, r1
++ ble clbss_l
++
++ ldr pc, _start_armboot
++
++_start_armboot: .word start_armboot
++
++
++/****************************************************************************/
++/* */
++/* CPU_init_critical registers */
++/* */
++/* - setup important registers */
++/* - setup memory timing */
++/* */
++/****************************************************************************/
++/* mk@tbd: Fix this! */
++#undef RCSR
++#undef ICMR
++#undef OSMR3
++#undef OSCR
++#undef OWER
++#undef OIER
++#undef CCCR
++
++/* Interrupt-Controller base address */
++IC_BASE: .word 0x40d00000
++#define ICMR 0x04
++
++/* Reset-Controller */
++RST_BASE: .word 0x40f00030
++#define RCSR 0x00
++
++/* Operating System Timer */
++OSTIMER_BASE: .word 0x40a00000
++#define OSMR3 0x0C
++#define OSCR 0x10
++#define OWER 0x18
++#define OIER 0x1C
++
++/* Clock Manager Registers */
++#ifdef CONFIG_CPU_MONAHANS
++# ifndef CFG_MONAHANS_RUN_MODE_OSC_RATIO
++# error "You have to define CFG_MONAHANS_RUN_MODE_OSC_RATIO!!"
++# endif /* !CFG_MONAHANS_RUN_MODE_OSC_RATIO */
++# ifndef CFG_MONAHANS_TURBO_RUN_MODE_RATIO
++# define CFG_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
++# endif /* !CFG_MONAHANS_TURBO_RUN_MODE_RATIO */
++#else /* !CONFIG_CPU_MONAHANS */
++#ifdef CFG_CPUSPEED
++CC_BASE: .word 0x41300000
++#define CCCR 0x00
++cpuspeed: .word CFG_CPUSPEED
++#else /* !CFG_CPUSPEED */
++#error "You have to define CFG_CPUSPEED!!"
++#endif /* CFG_CPUSPEED */
++#endif /* CONFIG_CPU_MONAHANS */
++
++ /* takes care the CP15 update has taken place */
++ .macro CPWAIT reg
++ mrc p15,0,\reg,c2,c0,0
++ mov \reg,\reg
++ sub pc,pc,#4
++ .endm
++
++cpu_init_crit:
++
++ /* mask all IRQs */
++#ifndef CONFIG_CPU_MONAHANS
++ ldr r0, IC_BASE
++ mov r1, #0x00
++ str r1, [r0, #ICMR]
++#else /* CONFIG_CPU_MONAHANS */
++ /* Step 1 - Enable CP6 permission */
++ mrc p15, 0, r1, c15, c1, 0 @ read CPAR
++ orr r1, r1, #0x40
++ mcr p15, 0, r1, c15, c1, 0
++ CPWAIT r1
++
++ /* Step 2 - Mask ICMR & ICMR2 */
++ mov r1, #0
++ mcr p6, 0, r1, c1, c0, 0 @ ICMR
++ mcr p6, 0, r1, c7, c0, 0 @ ICMR2
++
++ /* turn off all clocks but the ones we will definitly require */
++ ldr r1, =CKENA
++ ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
++ str r2, [r1]
++ ldr r1, =CKENB
++ ldr r2, =(CKENB_6_IRQ)
++ str r2, [r1]
++#endif /* !CONFIG_CPU_MONAHANS */
++
++ /* set clock speed */
++#ifdef CONFIG_CPU_MONAHANS
++ ldr r0, =ACCR
++ ldr r1, =(((CFG_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CFG_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
++ str r1, [r0]
++#else /* !CONFIG_CPU_MONAHANS */
++#ifdef CFG_CPUSPEED
++ ldr r0, CC_BASE
++ ldr r1, cpuspeed
++ str r1, [r0, #CCCR]
++ mov r0, #2
++ mcr p14, 0, r0, c6, c0, 0
++
++setspeed_done:
++
++#endif /* CFG_CPUSPEED */
++#endif /* CONFIG_CPU_MONAHANS */
++
++ /*
++ * before relocating, we have to setup RAM timing
++ * because memory timing is board-dependend, you will
++ * find a lowlevel_init.S in your board directory.
++ */
++ mov ip, lr
++ bl lowlevel_init
++ mov lr, ip
++
++ /* Memory interfaces are working. Disable MMU and enable I-cache. */
++ /* mk: hmm, this is not in the monahans docs, leave it now but
++ * check here if it doesn't work :-) */
++
++ ldr r0, =0x2001 /* enable access to all coproc. */
++ mcr p15, 0, r0, c15, c1, 0
++ CPWAIT r0
++
++ mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
++ CPWAIT r0
++
++ mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
++ CPWAIT r0
++
++ mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
++ CPWAIT r0
++
++ /* Enable the Icache */
++/*
++ mrc p15, 0, r0, c1, c0, 0
++ orr r0, r0, #0x1800
++ mcr p15, 0, r0, c1, c0, 0
++ CPWAIT
++*/
++ mov pc, lr
++
++
++/****************************************************************************/
++/* */
++/* Interrupt handling */
++/* */
++/****************************************************************************/
++
++/* IRQ stack frame */
++
++#define S_FRAME_SIZE 72
++
++#define S_OLD_R0 68
++#define S_PSR 64
++#define S_PC 60
++#define S_LR 56
++#define S_SP 52
++
++#define S_IP 48
++#define S_FP 44
++#define S_R10 40
++#define S_R9 36
++#define S_R8 32
++#define S_R7 28
++#define S_R6 24
++#define S_R5 20
++#define S_R4 16
++#define S_R3 12
++#define S_R2 8
++#define S_R1 4
++#define S_R0 0
++
++#define MODE_SVC 0x13
++
++ /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
++
++ .macro bad_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++
++ ldr r2, _armboot_start
++ sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
++ ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
++ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
++
++ add r5, sp, #S_SP
++ mov r1, lr
++ stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
++ mov r0, sp
++ .endm
++
++
++ /* use irq_save_user_regs / irq_restore_user_regs for */
++ /* IRQ/FIQ handling */
++
++ .macro irq_save_user_regs
++ sub sp, sp, #S_FRAME_SIZE
++ stmia sp, {r0 - r12} /* Calling r0-r12 */
++ add r8, sp, #S_PC
++ stmdb r8, {sp, lr}^ /* Calling SP, LR */
++ str lr, [r8, #0] /* Save calling PC */
++ mrs r6, spsr
++ str r6, [r8, #4] /* Save CPSR */
++ str r0, [r8, #8] /* Save OLD_R0 */
++ mov r0, sp
++ .endm
++
++ .macro irq_restore_user_regs
++ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
++ mov r0, r0
++ ldr lr, [sp, #S_PC] @ Get PC
++ add sp, sp, #S_FRAME_SIZE
++ subs pc, lr, #4 @ return & move spsr_svc into cpsr
++ .endm
++
++ .macro get_bad_stack
++ ldr r13, _armboot_start @ setup our mode stack
++ sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
++ sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
++
++ str lr, [r13] @ save caller lr / spsr
++ mrs lr, spsr
++ str lr, [r13, #4]
++
++ mov r13, #MODE_SVC @ prepare SVC-Mode
++ msr spsr_c, r13
++ mov lr, pc
++ movs pc, lr
++ .endm
++
++ .macro get_irq_stack @ setup IRQ stack
++ ldr sp, IRQ_STACK_START
++ .endm
++
++ .macro get_fiq_stack @ setup FIQ stack
++ ldr sp, FIQ_STACK_START
++ .endm
++
++
++/****************************************************************************/
++/* */
++/* exception handlers */
++/* */
++/****************************************************************************/
++
++ .align 5
++undefined_instruction:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_undefined_instruction
++
++ .align 5
++software_interrupt:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_software_interrupt
++
++ .align 5
++prefetch_abort:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_prefetch_abort
++
++ .align 5
++data_abort:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_data_abort
++
++ .align 5
++not_used:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_not_used
++
++#ifdef CONFIG_USE_IRQ
++
++ .align 5
++irq:
++ get_irq_stack
++ irq_save_user_regs
++ bl do_irq
++ irq_restore_user_regs
++
++ .align 5
++fiq:
++ get_fiq_stack
++ irq_save_user_regs /* someone ought to write a more */
++ bl do_fiq /* effiction fiq_save_user_regs */
++ irq_restore_user_regs
++
++#else /* !CONFIG_USE_IRQ */
++
++ .align 5
++irq:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_irq
++
++ .align 5
++fiq:
++ get_bad_stack
++ bad_save_user_regs
++ bl do_fiq
++
++#endif /* CONFIG_USE_IRQ */
++
++/****************************************************************************/
++/* */
++/* Reset function: the PXA250 doesn't have a reset function, so we have to */
++/* perform a watchdog timeout for a soft reset. */
++/* */
++/****************************************************************************/
++
++ .align 5
++.globl reset_cpu
++
++ /* FIXME: this code is PXA250 specific. How is this handled on */
++ /* other XScale processors? */
++
++reset_cpu:
++
++ /* We set OWE:WME (watchdog enable) and wait until timeout happens */
++
++ ldr r0, OSTIMER_BASE
++ ldr r1, [r0, #OWER]
++ orr r1, r1, #0x0001 /* bit0: WME */
++ str r1, [r0, #OWER]
++
++ /* OS timer does only wrap every 1165 seconds, so we have to set */
++ /* the match register as well. */
++
++ ldr r1, [r0, #OSCR] /* read OS timer */
++ add r1, r1, #0x800 /* let OSMR3 match after */
++ add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
++ str r1, [r0, #OSMR3]
++
++reset_endless:
++
++ b reset_endless
+diff -Naur u-boot-2008.10_original/drivers/mtd/nand/nand.c u-boot-2008.10/drivers/mtd/nand/nand.c
+--- u-boot-2008.10_original/drivers/mtd/nand/nand.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/mtd/nand/nand.c 2009-08-12 18:21:20.000000000 +0530
+@@ -67,7 +67,7 @@
+ if (nand_curr_device == -1)
+ nand_curr_device = i;
+ }
+- printf("%u MiB\n", size / 1024);
++ printf("%u MiB\n", size / 1024); // Commented by Tharma
+
+ #ifdef CFG_NAND_SELECT_DEVICE
+ /*
+diff -Naur u-boot-2008.10_original/drivers/net/Makefile u-boot-2008.10/drivers/net/Makefile
+--- u-boot-2008.10_original/drivers/net/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/net/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -25,6 +25,7 @@
+
+ LIB := $(obj)libnet.a
+
++COBJS-$(CONFIG_DRIVER_AX88796B) += regulus_ax88796b.o
+ COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
+ COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
+ COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
+diff -Naur u-boot-2008.10_original/drivers/net/regulus_ax88796b.c u-boot-2008.10/drivers/net/regulus_ax88796b.c
+--- u-boot-2008.10_original/drivers/net/regulus_ax88796b.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/drivers/net/regulus_ax88796b.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,1368 @@
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include <asm-arm/errno.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++#include "regulus_ax88796b.h"
++#include "regulus_uboot_skb.c"
++
++
++#define PXA_LAST_GPIO 127
++#define GPIO_IN 0x000
++#define GPIO_OUT 0x080
++#define GPIO_ALT_FN_1_IN 0x100
++#define GPIO_ALT_FN_1_OUT 0x180
++#define GPIO_ALT_FN_2_IN 0x200
++#define GPIO_ALT_FN_2_OUT 0x280
++#define GPIO_ALT_FN_3_IN 0x300
++#define GPIO_ALT_FN_3_OUT 0x380
++#define GPIO_MD_MASK_NR 0x07f
++#define GPIO_MD_MASK_DIR 0x080
++#define GPIO_MD_MASK_FN 0x300
++#define GPIO_DFLT_LOW 0x400
++#define GPIO_DFLT_HIGH 0x800
++
++
++
++/*
++ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
++ * and FCS/CRC (frame check sequence).
++ */
++
++#define ETH_ALEN 6 /* Octets in one ethernet addr */
++#define ETH_HLEN 14 /* Total octets in header. */
++#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
++#define ETH_DATA_LEN 1500 /* Max. octets in payload */
++#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
++#define ETH_FCS_LEN 4 /* Octets in the FCS */
++
++
++
++
++
++typedef unsigned long DWORD;
++typedef unsigned short WORD;
++typedef unsigned char BYTE;
++typedef unsigned char BOOLEAN;
++extern int pxa_gpio_mode(int);
++
++
++#define PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printk(args)
++#define printk(msg,args...) printf(msg, ## args)
++#define ECON_DEBUG 0
++#if ECON_DEBUG
++#define eprintk(msg,args...) printk(msg,## args)
++#else
++#define eprintk(msg,args...) do{}while(0)
++#endif
++
++#define CRITICAL_DEBUG 0
++#if CRITICAL_DEBUG
++#define cprintk(msg,args...) printk(msg,## args)
++#else
++#define cprintk(msg,args...) do{}while(0)
++#endif
++
++
++#define MAC_ADDDRESS_LENGTH 6
++#define MAC_ADDRESS_IN_NOR_FLASH 0x8000
++
++#define CONFIG_AX88796B_USE_MEMCPY 0
++#define CONFIG_AX88796B_8BIT_WIDE 0
++#define CONFIG_AX88796B_EEPROM_READ_WRITE 0
++
++#ifndef ENBTCR_IRQ_TYPE_PUSH_PULL
++#define ENBTCR_IRQ_TYPE_PUSH_PULL 0x20 /* IRQ Output is Push Pull Driver */
++#endif
++
++
++#ifdef AX88796B_BASE
++#undef AX88796B_BASE
++#define AX88796B_BASE PXA_CS4_PHYS
++#endif
++
++#if CONFIG_AX88796B_USE_MEMCPY
++#define FIFO_SEL_IS_A11 0
++#define FIFO_SEL_IS_A20 1
++#endif
++
++#if FIFO_SEL_IS_A11
++#warning "FIFO_SEL_IS_A11 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0xFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x0800
++ #endif
++
++#elif FIFO_SEL_IS_A20
++#warning "FIFO_SEL_IS_A20 is defined"
++ #ifdef NE_IO_EXTENT
++ #undef NE_IO_EXTENT
++ #define NE_IO_EXTENT 0x0FFFFFFF
++ #endif
++ #ifdef EN0_DATA_ADDR
++ #undef EN0_DATA_ADDR
++ #define EN0_DATA_ADDR 0x00100000
++ #endif
++
++#endif
++
++#define GPIO80_GPIO_OUT (80 | GPIO_OUT | GPIO_DFLT_HIGH)
++#define GPIO_FOR_ASIX_IRQ 74
++#define IRQ_EINT11 IRQ_GPIO(GPIO_FOR_ASIX_IRQ)
++#define GPIO_FOX_ASIX_IRQ_MD ( GPIO_FOR_ASIX_IRQ | GPIO_IN)
++#define IRQ_FALLING_EDGE 1
++
++#define mdelay(n) udelay((n)*1000)
++#define readb(a) (*(volatile unsigned char *)(a))
++#define readw(a) (*(volatile unsigned short *)(a))
++#define readl(a) (*(volatile unsigned int *)(a))
++
++#define writeb(v,a) (*(volatile unsigned char *)(a) = (v))
++#define writew(v,a) (*(volatile unsigned short *)(a) = (v))
++#define writel(v,a) (*(volatile unsigned int *)(a) = (v))
++
++
++/*
++ *
++ * Global variable declarations
++ *
++ */
++
++DWORD CS4_VIRT_BASE = AX88796B_BASE;
++struct ax_device ax_global;
++int media=0; // Media Mode(0=auto, 1=100full, 2=100half, 3=10full, 4=10half)
++unsigned char dev_addr[6];
++
++
++
++
++
++
++
++
++
++
++/*
++ *
++ * Function definitions
++ *
++ */
++void sirius_asix_gpio_initialize(void)
++{
++
++#define IMCR_GPIO_x (1<<10)
++#define ICLR_GPIO_x (1<<10)
++
++ pxa_gpio_mode(GPIO_FOX_ASIX_IRQ_MD);
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ GFER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#elif IRQ_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ GRER(GPIO_bit(GPIO_FOR_ASIX_IRQ)) |= GPIO_bit(GPIO_FOR_ASIX_IRQ);
++#endif
++ ICMR |= IMCR_GPIO_x;
++ ICLR &= ~(ICLR_GPIO_x);
++}
++
++
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++static inline u16 READ_FIFO (void *membase)
++{
++ return (readb (membase) | (((u16)readb (membase)) << 8));
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writeb ((u8)data , membase);
++ writeb ((u8)(data >> 8) , membase);
++}
++#else
++static inline u16 READ_FIFO (void *membase)
++{
++ return readw (membase);
++}
++
++static inline void WRITE_FIFO (void *membase, u16 data)
++{
++ writew (data, membase);
++}
++#endif
++
++
++
++static void load_macaddr (unsigned char *pMac)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Read the 12 bytes of station address PROM. */
++ {
++ struct {unsigned char value, offset; } program_seq[] =
++ {
++ {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
++ {ax_local->bus_width, EN0_DCFG}, /* Set wide access. */
++ {0x00, EN0_RCNTLO}, /* Clear the count regs. */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_IMR}, /* Mask completion irq. */
++ {0xFF, EN0_ISR},
++ {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
++ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
++ {0x0C, EN0_RCNTLO}, /* 12 bytes of station address */
++ {0x00, EN0_RCNTHI},
++ {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
++ {0x00, EN0_RSARHI},
++ {E8390_RREAD+E8390_START, E8390_CMD},
++ };
++
++ for (i = 0; i < sizeof (program_seq)/sizeof (program_seq[0]); i++)
++ writeb (program_seq[i].value, ax_base + program_seq[i].offset);
++ }
++
++ while (( readb (ax_base + EN0_SR) & 0x20) == 0);
++
++ for (i = 0; i < 6; i++) {
++ pMac[i] = (unsigned char) READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++
++}
++
++
++/*
++ * ======================================================================
++ * MII interface support
++ * ======================================================================
++ */
++#define MDIO_SHIFT_CLK 0x01
++#define MDIO_DATA_WRITE0 0x00
++#define MDIO_DATA_WRITE1 0x08
++#define MDIO_DATA_READ 0x04
++#define MDIO_MASK 0x0f
++#define MDIO_ENB_IN 0x02
++
++/* Generic MII registers. */
++
++#define MII_BMCR 0x00 /* Basic mode control register */
++#define MII_BMSR 0x01 /* Basic mode status register */
++#define MII_PHYSID1 0x02 /* PHYS ID 1 */
++#define MII_PHYSID2 0x03 /* PHYS ID 2 */
++#define MII_ADVERTISE 0x04 /* Advertisement control reg */
++#define MII_LPA 0x05 /* Link partner ability reg */
++#define MII_EXPANSION 0x06 /* Expansion register */
++#define MII_CTRL1000 0x09 /* 1000BASE-T control */
++#define MII_STAT1000 0x0a /* 1000BASE-T status */
++#define MII_ESTATUS 0x0f /* Extended Status */
++#define MII_DCOUNTER 0x12 /* Disconnect counter */
++#define MII_FCSCOUNTER 0x13 /* False carrier counter */
++#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
++#define MII_RERRCOUNTER 0x15 /* Receive error counter */
++#define MII_SREVISION 0x16 /* Silicon revision */
++#define MII_RESV1 0x17 /* Reserved... */
++#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
++#define MII_PHYADDR 0x19 /* PHY address */
++#define MII_RESV2 0x1a /* Reserved... */
++#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
++#define MII_NCONFIG 0x1c /* Network interface config */
++
++
++/* Basic mode control register. */
++#define BMCR_RESV 0x003f /* Unused... */
++#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
++#define BMCR_CTST 0x0080 /* Collision test */
++#define BMCR_FULLDPLX 0x0100 /* Full duplex */
++#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
++#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
++#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
++#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
++#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
++#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
++#define BMCR_RESET 0x8000 /* Reset the DP83840 */
++
++/* Basic mode status register. */
++#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
++#define BMSR_JCD 0x0002 /* Jabber detected */
++#define BMSR_LSTATUS 0x0004 /* Link status */
++#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
++#define BMSR_RFAULT 0x0010 /* Remote fault detected */
++#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
++#define BMSR_RESV 0x00c0 /* Unused... */
++#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
++#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
++#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
++#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
++#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
++#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
++#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
++#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
++
++/* Advertisement control register. */
++#define ADVERTISE_SLCT 0x001f /* Selector bits */
++#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
++#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
++#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
++#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
++#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
++#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
++#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
++#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
++#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
++#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
++#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
++#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
++#define ADVERTISE_RESV 0x1000 /* Unused... */
++#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
++#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
++#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
++
++#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
++ ADVERTISE_CSMA)
++#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
++ ADVERTISE_100HALF | ADVERTISE_100FULL)
++
++/* Link partner ability register. */
++#define LPA_SLCT 0x001f /* Same as advertise selector */
++#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
++#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
++#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
++#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
++#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
++#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
++#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
++#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
++#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
++#define LPA_PAUSE_CAP 0x0400 /* Can pause */
++#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
++#define LPA_RESV 0x1000 /* Unused... */
++#define LPA_RFAULT 0x2000 /* Link partner faulted */
++#define LPA_LPACK 0x4000 /* Link partner acked us */
++#define LPA_NPAGE 0x8000 /* Next page bit */
++
++#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
++#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
++
++/* Expansion register for auto-negotiation. */
++#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
++#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
++#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
++#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
++#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
++#define EXPANSION_RESV 0xffe0 /* Unused... */
++
++#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
++#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
++
++/* N-way test register. */
++#define NWAYTEST_RESV1 0x00ff /* Unused... */
++#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
++#define NWAYTEST_RESV2 0xfe00 /* Unused... */
++
++/* 1000BASE-T Control register */
++#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
++#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
++
++/* 1000BASE-T Status register */
++#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
++#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
++#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
++#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
++
++/* This structure is used in all SIOCxMIIxxx ioctl calls */
++struct mii_ioctl_data {
++ __u16 phy_id;
++ __u16 reg_num;
++ __u16 val_in;
++ __u16 val_out;
++};
++
++
++
++
++static void mdio_sync (void)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ int bits;
++ for (bits = 0; bits < 32; bits++) {
++ writeb (MDIO_DATA_WRITE1, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static void mdio_clear (void)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++
++ int bits;
++ for (bits = 0; bits < 16; bits++) {
++ writeb (MDIO_DATA_WRITE0, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_DATA_WRITE0 | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++static int mdio_read (int phy_id, int loc)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0xf6<<10)|(phy_id<<5)|loc;
++ int i, retval = 0;
++
++ mdio_clear ();
++ mdio_sync ();
++ for (i = 14; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 19; i > 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ retval = (retval << 1) | ((readb (ax_base + AX88796_MII_EEPROM) & MDIO_DATA_READ) != 0);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ return (retval>>1) & 0xffff;
++}
++
++static void mdio_write (int phy_id, int loc, int value)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
++ int i;
++
++ mdio_clear ();
++ mdio_sync ();
++ for (i = 31; i >= 0; i--) {
++ int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
++ writeb (dat, ax_base + AX88796_MII_EEPROM);
++ writeb (dat | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++ for (i = 1; i >= 0; i--) {
++ writeb (MDIO_ENB_IN, ax_base + AX88796_MII_EEPROM);
++ writeb (MDIO_ENB_IN | MDIO_SHIFT_CLK, ax_base + AX88796_MII_EEPROM);
++ }
++}
++
++
++static void do_set_multicast_list (void)
++{
++ void *ax_base = AX88796B_BASE;
++ int i;
++
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR);
++ writeb (E8390_NODMA + E8390_PAGE1, ax_base + E8390_CMD);
++ writeb (E8390_NODMA + E8390_PAGE0, ax_base + E8390_CMD);
++ writeb (E8390_RXCONFIG | 0x18, ax_base + EN0_RXCR);
++}
++
++
++void ax88796_PHY_init (void)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u16 advertise;
++
++ /* Enable AX88796B FOLW CONTROL */
++ writeb (ENFLOW_ENABLE, ax_base+EN0_FLOW);
++
++ advertise = mdio_read (0x10, MII_ADVERTISE) & ~ADVERTISE_ALL;
++
++ switch (ax_local->media) {
++ case MEDIA_AUTO:
++ PRINTK (DRIVER_MSG," The media mode is autosense.\n");
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++
++ case MEDIA_100FULL:
++ PRINTK (DRIVER_MSG," The media mode is forced to 100full.\n");
++ advertise |= ADVERTISE_100FULL | 0x400;
++ break;
++
++ case MEDIA_100HALF:
++ PRINTK (DRIVER_MSG," The media mode is forced to 100half.\n");
++ advertise |= ADVERTISE_100HALF;
++ break;
++
++ case MEDIA_10FULL:
++ PRINTK (DRIVER_MSG," The media mode is forced to 10full.\n");
++ advertise |= ADVERTISE_10FULL;
++ break;
++
++ case MEDIA_10HALF:
++ PRINTK (DRIVER_MSG," The media mode is forced to 10half.\n");
++ advertise |= ADVERTISE_10HALF;
++ break;
++ default:
++ advertise |= ADVERTISE_ALL | 0x400;
++ break;
++ }
++ mdio_write (0x10, MII_ADVERTISE, advertise);
++ mdio_write (0x10, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
++}
++
++
++
++static void ax_watchdog (unsigned long arg)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u8 status;
++ u16 bmcr, advertise;
++
++ status = readb (ax_base + EN0_SR);
++
++ eprintk("FUNC %s() : LINE %d : status is 0x%02X \n",__FUNCTION__,__LINE__,status);
++
++ if (ax_local->media_curr != status)
++ {
++
++ ax_local->media_curr = status;
++
++ if ((status & ENSR_LINK))
++ {
++ if (status & ENSR_SPEED_100) {
++ PRINTK (DRIVER_MSG, " Link mode : 100 Mb/s ");
++ } else {
++ PRINTK (DRIVER_MSG, " Link mode : 10 Mb/s ");
++ }
++
++ if (status & ENSR_DUPLEX_DULL) {
++ PRINTK (DRIVER_MSG, "Full Duplex.\n");
++ } else {
++ PRINTK (DRIVER_MSG, "Half Duplex.\n");
++ }
++
++ mdelay (200);
++ } else {
++ PRINTK (DRIVER_MSG, " Link down.\n");
++ }
++ }
++ return ;
++}
++
++
++
++
++
++
++
++static void ax_reset (void)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++
++ int count = 0;
++ readb (ax_base + EN0_RESET);
++
++
++ /* This check _should_not_ be necessary, omit eventually. */
++ while ((readb (ax_base+EN0_ISR) & ENISR_RESET) == 0)
++ {
++ if(count >20){
++ PRINTK (ERROR_MSG," ax_reset() did not complete.\n");
++ break;
++ }
++ else
++ {
++ mdelay(1);
++ count++;
++ }
++ }
++
++ writeb (ENISR_RESET, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++static void ax_init (int startp)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ int i;
++
++ /* Follow National Semi's recommendations for initing the DP83902. */
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD); /* 0x21 */
++ writeb (ax_local->bus_width, ax_base + EN0_DCFG);/* 8-bit or 16-bit */
++
++#if IRQ_FALLING_EDGE
++#warning "IRQ FALLING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active low \n");
++ /* Set AX88796B interrupt active low */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++
++#elif IRW_RISING_EDGE
++#warning "IRQ RISING EDGE is defined"
++ eprintk(" Set AX88796B interrupt active high \n");
++ /* Set AX88796B interrupt active high */
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, ax_base + E8390_CMD);
++ writeb ((ENBTCR_INT_ACT_HIGH | ENBTCR_IRQ_TYPE_PUSH_PULL), ax_base + EN0_BTCR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base + E8390_CMD);
++#endif
++
++ /* Clear the remote byte count registers. */
++ writeb (0x00, ax_base + EN0_RCNTLO);
++ writeb (0x00, ax_base + EN0_RCNTHI);
++
++ /* Set to monitor and loopback mode -- this is vital!. */
++ writeb (E8390_RXOFF, ax_base + EN0_RXCR); /* 0x20 */
++ writeb (E8390_TXOFF, ax_base + EN0_TXCR); /* 0x02 */
++
++ /* Set the transmit page and receive ring. */
++ writeb (NESM_START_PG, ax_base + EN0_TPSR);
++ writeb (NESM_RX_START_PG, ax_base + EN0_STARTPG);
++ writeb (NESM_RX_START_PG, ax_base + EN0_BOUNDARY);
++
++ ax_local->current_page = NESM_RX_START_PG + 1; /* assert boundary+1 */
++ writeb (NESM_STOP_PG, ax_base + EN0_STOPPG);
++
++ ax_local->tx_prev_ctepr = 0;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->tx_curr_page = NESM_START_PG;
++ ax_local->tx_stop_page = NESM_START_PG + TX_PAGES;
++
++ /* Clear the pending interrupts and mask. */
++ writeb (0xFF, ax_base + EN0_ISR);
++ writeb (0x00, ax_base + EN0_IMR);
++
++ /* Copy the station address into the DS8390 registers. */
++ writeb (E8390_NODMA + E8390_PAGE1 + E8390_STOP, ax_base+E8390_CMD); /* 0x61 */
++ writeb (NESM_START_PG + TX_PAGES + 1, ax_base + EN1_CURPAG);
++ for (i = 0; i < 6; i++)
++ {
++ writeb (dev_addr[i], ax_base + EN1_PHYS_SHIFT (i));
++ if (readb (ax_base + EN1_PHYS_SHIFT (i))!=dev_addr[i])
++ PRINTK (ERROR_MSG, "Hw. address read/write mismap %d\n",i);
++ }
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ if (startp)
++ {
++ /* Enable AX88796B TQC */
++ writeb ((readb (ax_base+EN0_MCR) | ENTQC_ENABLE), ax_base+EN0_MCR);
++
++ /* Enable AX88796B Transmit Buffer Ring */
++ writeb (E8390_NODMA+E8390_PAGE3+E8390_STOP, ax_base+E8390_CMD);
++ writeb (ENTBR_ENABLE, ax_base+EN3_TBR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_STOP, ax_base+E8390_CMD);
++
++ ax_local->media_curr = 0xFF;
++ ax88796_PHY_init ();
++ writeb (0xff, ax_base + EN0_ISR);
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+E8390_CMD);
++ writeb (E8390_TXCONFIG, ax_base + EN0_TXCR); /* xmit on. */
++
++ writeb (E8390_RXCONFIG, ax_base + EN0_RXCR); /* rx on, */
++ do_set_multicast_list (); /* (re)load the mcast table */
++ }
++
++}
++
++
++
++static int ax_open (void)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *membase = ax_local->membase;
++ int ret=0;
++
++ PRINTK (DEBUG_MSG, " ax88796B ei_open beginning ..........\n");
++ PRINTK (DEBUG_MSG, " membase %p\n\r", membase);
++
++ /* This can't happen unless somebody forgot to call ethdev_init(). */
++ if (ax_local == NULL)
++ {
++ PRINTK (ERROR_MSG, " ei_open passed a non-existent device!\n");
++ return -ENXIO;
++ }
++
++ ax_reset ();
++ ax_init (1);
++
++ return ret;
++}
++
++
++
++static int ax_close (void)
++{
++ PRINTK (DEBUG_MSG, " ax88796B ei_close beginning ..........\n");
++ ax_init (0);
++ PRINTK (DEBUG_MSG, " ax88796B ei_close end ..........\n");
++ return 0;
++}
++
++
++
++
++
++static void ax_block_output (int count, const unsigned char *buf, const int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ unsigned long m=0;
++
++ /* We should already be in page 0, but to be safe... */
++ writeb (E8390_PAGE0+E8390_START+E8390_NODMA, ax_base + E8390_CMD);
++ writeb (ENISR_RDC, ax_base + EN0_ISR);
++ /* Now the normal output. */
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (0x00, ax_base + EN0_RSARLO);
++ writeb (start_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RWRITE+E8390_START, ax_base + E8390_CMD);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0x7F8));
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ memcpy ((ax_base+EN0_DATA_ADDR), buf, ((count+ 7) & 0xFFFF8));
++ #endif
++#else
++ {
++ u16 i;
++ for (i = 0; i < count; i += 2) {
++ WRITE_FIFO (ax_base + EN0_DATAPORT, *((u16 *)(buf + i)));
++ }
++ }
++#endif
++ while ((readb(ax_base + EN0_ISR) & 0x40) == 0)
++ {
++ if (m >20) { /* 20ms */
++ PRINTK (ERROR_MSG, " timeout waiting for Tx RDC.\n");
++ ax_reset ();
++ ax_init (1);
++ break;
++ }
++ else
++ {
++ mdelay(1);
++ m++;
++ }
++ }
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++ return;
++}
++
++static void ax_trigger_send (unsigned int length, int start_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base+E8390_CMD);
++ writeb (length & 0xff, ax_base + EN0_TCNTLO);
++ writeb (length >> 8, ax_base + EN0_TCNTHI);
++ writeb (start_page, ax_base + EN0_TPSR);
++ writeb ((E8390_NODMA|E8390_TRANS|E8390_START), ax_base+E8390_CMD);
++}
++
++
++static int ax_start_xmit (void *buffer, int len)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ int send_length;
++ u8 ctepr=0, free_pages=0, need_pages;
++
++ /* check for link status */
++ eprintk("FUNC %s() : LINE %d : check for link status \n",__FUNCTION__,__LINE__);
++ if (!(readb (ax_base + EN0_SR) & ENSR_LINK))
++ {
++ eprintk("FUNC %s() : LINE %d : Link is not ready \n",__FUNCTION__,__LINE__);
++ return 0;
++ }
++ else
++ {
++ eprintk("FUNC %s() : LINE %d : Link is ready \n",__FUNCTION__,__LINE__);
++ }
++
++ send_length = ETH_ZLEN < len ? len : ETH_ZLEN;
++
++ writeb (0x00, ax_base + EN0_IMR);
++
++
++ need_pages = (send_length -1)/256 +1;
++ ctepr = readb (ax_base + EN0_CTEPR) & 0x7f;
++
++ if (ctepr == 0) {
++ if (ax_local->tx_curr_page == ax_local->tx_start_page && ax_local->tx_prev_ctepr == 0)
++ free_pages = TX_PAGES;
++ else
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page;
++ }
++ else if (ctepr < ax_local->tx_curr_page - 1) {
++ free_pages = ax_local->tx_stop_page - ax_local->tx_curr_page +
++ ctepr - ax_local->tx_start_page + 1;
++ }
++ else if (ctepr > ax_local->tx_curr_page - 1) {
++ free_pages = ctepr + 1 - ax_local->tx_curr_page;
++ }
++ else if (ctepr == ax_local->tx_curr_page - 1) {
++ if (ax_local->tx_full)
++ free_pages = 0;
++ else
++ free_pages = TX_PAGES;
++ }
++
++ if (free_pages < need_pages) {
++ PRINTK (DEBUG_MSG, "free_pages < need_pages\n\r");
++ ax_local->tx_full = 1;
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ return 1;
++ }
++
++ ax_block_output (send_length, buffer, ax_local->tx_curr_page);
++ ax_trigger_send (send_length, ax_local->tx_curr_page);
++ if (free_pages == need_pages) {
++ ax_local->tx_full = 1;
++ }
++ ax_local->tx_prev_ctepr = ctepr;
++ ax_local->tx_curr_page = ax_local->tx_curr_page + need_pages < ax_local->tx_stop_page ?
++ ax_local->tx_curr_page + need_pages :
++ need_pages - (ax_local->tx_stop_page - ax_local->tx_curr_page) + ax_local->tx_start_page;
++
++ writeb (ENISR_ALL, ax_base + EN0_IMR);
++ return 0;
++}
++
++
++
++
++static void ax_get_hdr (struct ax_pkt_hdr *hdr, int ring_page)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)hdr;
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (sizeof (struct ax_pkt_hdr), ax_base + EN0_RCNTLO);
++ writeb (0, ax_base + EN0_RCNTHI);
++ writeb (0, ax_base + EN0_RSARLO); /* On page boundary */
++ writeb (ring_page, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++ *(++buf) = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++
++ le16_to_cpus (&hdr->count);
++
++}
++
++
++static void ax_block_input (int count, struct sk_buff *skb, int ring_offset)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ u16 *buf = (u16 *)skb->data;
++ u16 i,m=0;;
++ unsigned char isr_data=0;
++
++ writeb (E8390_NODMA+E8390_PAGE0+E8390_START, ax_base+ E8390_CMD);
++ writeb (count & 0xff, ax_base + EN0_RCNTLO);
++ writeb (count >> 8, ax_base + EN0_RCNTHI);
++ writeb (ring_offset & 0xff, ax_base + EN0_RSARLO);
++ writeb (ring_offset >> 8, ax_base + EN0_RSARHI);
++ writeb (E8390_RREAD+E8390_START, ax_base + E8390_CMD);
++
++ while (( readb (ax_base+EN0_SR) & ENSR_DMA_READY) == 0);
++
++#if (CONFIG_AX88796B_USE_MEMCPY == 1)
++ {
++
++ #if FIFO_SEL_IS_A11
++ #warning "FIFO_SEL_IS_A11 is defined"
++
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & 0x7F8;
++ #elif FIFO_SEL_IS_A20
++ #warning "FIFO_SEL_IS_A20 is defined"
++ /* make the burst length be divided for 64-bit */
++ i = ((count - 2) + 7) & (0xFFFF8);
++ #endif
++
++ /* Read first 2 bytes */
++ *buf = READ_FIFO (ax_base + EN0_DATAPORT);
++
++ /* The address of ++buf should be agigned on 32-bit boundary */
++ memcpy (++buf, ax_base+EN0_DATA_ADDR, i);
++ }
++#else
++ {
++ for (i = 0; i < count; i += 2) {
++ *buf++ = READ_FIFO (ax_base + EN0_DATAPORT);
++ }
++ }
++#endif
++
++ while(1)
++ {
++ isr_data = readb(ax_base + EN0_ISR);
++ //cprintk("FUNC %s() : LINE %d : ISR Value is 0x%02X \n",__FUNCTION__,__LINE__,isr_data);
++ if((isr_data&ENISR_RDC)==ENISR_RDC)
++ {
++ break;
++ }
++ else
++ {
++ if (m>20)
++ { /* 20ms */
++ PRINTK (ERROR_MSG, " FUNC %s() : LINE %d : timeout waiting for Tx RDC. ISR Value is 0x%02X \n",__FUNCTION__,__LINE__,isr_data);
++ ax_reset ();
++ ax_init (1);
++ break;
++ }
++ else
++ {
++ m++;
++ mdelay(1);
++ }
++ }
++ }
++ eprintk("FUNC %s() : LINE %d : Ack intr \n",__FUNCTION__,__LINE__);
++
++
++ writeb (ENISR_RDC, ax_base + EN0_ISR); /* Ack intr. */
++}
++
++
++
++
++
++static void ax_receive (void *rxbuffer, int *prxbytes)
++{
++ struct ax_device *ax_local = (struct ax_device *) &ax_global;
++ void *ax_base = ax_local->membase;
++ unsigned char rxing_page, this_frame, next_frame;
++ unsigned short current_offset;
++ struct ax_pkt_hdr rx_frame;
++ int num_rx_pages = ax_local->stop_page - ax_local->rx_start_page;
++ while (1)
++ {
++ int pkt_len, pkt_stat;
++
++ /* Get the rx page (incoming packet pointer). */
++ writeb (E8390_NODMA+E8390_PAGE1, ax_base + E8390_CMD);
++ rxing_page = readb (ax_base + EN1_CURPAG);
++ writeb (E8390_NODMA+E8390_PAGE0, ax_base + E8390_CMD);
++
++ /* Remove one frame from the ring. Boundary is always a page behind. */
++ this_frame = readb (ax_base + EN0_BOUNDARY) + 1;
++ if (this_frame >= ax_local->stop_page)
++ this_frame = ax_local->rx_start_page;
++
++ if (this_frame != ax_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
++ PRINTK (RX_MSG, " mismatched read page pointers %2x vs %2x.\n",
++ this_frame, ax_local->current_page);
++
++ if (this_frame == rxing_page) { /* Read all the frames? */
++ break; /* Done for now */
++ }
++ current_offset = this_frame << 8;
++ ax_get_hdr (&rx_frame, this_frame);
++
++ pkt_len = rx_frame.count - sizeof (struct ax_pkt_hdr);
++ pkt_stat = rx_frame.status;
++ next_frame = this_frame + 1 + ((pkt_len+4)>>8);
++
++ /* Check for bogosity warned by 3c503 book: the status byte is never
++ written. This happened a lot during testing! This code should be
++ cleaned up someday. */
++ if (rx_frame.next != next_frame
++ && rx_frame.next != next_frame + 1
++ && rx_frame.next != next_frame - num_rx_pages
++ && rx_frame.next != next_frame + 1 - num_rx_pages) {
++ ax_local->current_page = rxing_page;
++ writeb (ax_local->current_page-1, ax_base+EN0_BOUNDARY);
++ PRINTK (ERROR_MSG, "error occurred! Drop this packet!!\n");
++ continue;
++ }
++
++ if (pkt_len < 60 || pkt_len > 1518)
++ {
++ PRINTK (RX_MSG, " bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
++ rx_frame.count, rx_frame.status,
++ rx_frame.next);
++ }
++ else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
++ {
++ struct sk_buff *skb;
++ skb = alloc_skb (pkt_len+2,0);
++ if (skb == NULL)
++ {
++ printk (" Couldn't allocate a sk_buff of size %d.\n", pkt_len);
++ break;
++ }
++
++ skb_reserve (skb, 2); /* IP headers on 16 byte boundaries */
++ skb_put (skb, pkt_len); /* Make room */
++
++ ax_block_input (pkt_len, skb, current_offset + sizeof (rx_frame));
++ memcpy(rxbuffer+(*(prxbytes)),skb->data,pkt_len);
++ *(prxbytes) += pkt_len;
++ dev_kfree_skb_any(skb);
++ if (pkt_stat & ENRSR_PHY)
++ {
++ }
++ }
++ else
++ {
++ PRINTK (ERROR_MSG, " bogus packet: status=%#2x nxpg=%#2x size=%d\n",
++ rx_frame.status, rx_frame.next, rx_frame.count);
++ /* NB: The NIC counts CRC, frame and missed errors. */
++ if (pkt_stat & ENRSR_FO)
++ {
++ }
++ }
++ next_frame = rx_frame.next;
++
++ /* This _should_ never happen: it's here for avoiding bad clones. */
++ if (next_frame >= ax_local->stop_page) {
++ PRINTK (ERROR_MSG, " next frame inconsistency, %#2x\n", next_frame);
++ next_frame = ax_local->rx_start_page;
++ }
++ ax_local->current_page = next_frame;
++ writeb (next_frame-1, ax_base+EN0_BOUNDARY);
++ }
++
++ return;
++}
++
++
++
++
++
++
++int regulus_ax88796b_init(void)
++{
++ volatile unsigned int msc2_data=0;
++ //volatile unsigned int ncs4_config_data = 0x7FF9; // Slower Device, Maximum ROM/SRAM Recovery Time, Maximum ROM Delay Next Access, Maximum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++#define CS4_RBUFF(x) ((x) <<15)
++#define CS4_RRR(x) ((x) <<12)
++#define CS4_RDN(x) ((x) <<8)
++#define CS4_RDF(x) ((x) <<4)
++#define CS4_RBW(x) ((x) <<3)
++#define CS4_RT(x) ((x) <<0)
++
++ volatile unsigned int ncs4_config_data = (CS4_RBUFF(0) | CS4_RRR(0) |CS4_RDN(3) | CS4_RDF(5) | CS4_RBW(1) |CS4_RT(1)); // Slower Device, Minimum ROM/SRAM Recovery Time, Minimum ROM Delay Next Access, Minimum ROM Delay First Access, 16bits ROM Bus Width, SRAM ROM type)
++
++ int reg0=0, ret=0,i=0;
++ volatile unsigned address = AX88796B_BASE;
++ struct ax_device *ax_local;
++ //printk("Configuring GPIO80 as GPIO and Drive Logic 1 on GPIO80 \n");
++ pxa_gpio_mode(GPIO80_GPIO_OUT);
++
++ //printk("Configuring GPIO80 as nCS4 \n");
++ pxa_gpio_mode(GPIO80_nCS_4_MD);
++
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Configuring the Memory Controller Register for nCS4 \n");
++ msc2_data = MSC2;
++ MSC2 = (ncs4_config_data & 0x0000FFFF) | (msc2_data & 0xFFFF0000);
++ //printk("FUNC %s() : LINE %d: MSC2 Value is 00x%08X \n",__FUNCTION__,__LINE__,MSC2);
++ //printk("Physical address of nCS4 is 0x%08X \n",PXA_CS4_PHYS);
++
++
++ reg0 = readb (address);
++ if (reg0 == 0xFF) {
++ ret = -ENODEV;
++ goto err_out;
++ }
++
++
++ //printk("FUNC %s() : LINE %d : Reading data from Page0 \n",__FUNCTION__,__LINE__);
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,E8390_CMD,(unsigned char) READ_FIFO(CS4_VIRT_BASE + E8390_CMD));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_CLDALO,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_CLDALO));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_CLDAHI,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_CLDAHI));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_BOUNDARY,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_BOUNDARY));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_TSR,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_TSR));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_NCR,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_NCR));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_FIFO,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_FIFO));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_ISR,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_ISR));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_CRDALO,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_CRDALO));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_CRDAHI,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_CRDAHI));
++ eprintk(" FUNC %s() : LINE %d: Address is 0x%02X . Data is 0x%02X \n",__FUNCTION__,__LINE__,EN0_RCNTLO,(unsigned char) READ_FIFO(CS4_VIRT_BASE + EN0_RCNTLO));
++
++
++
++ /* Do a preliminary verification that we have a 8390. */
++ {
++ int regd;
++ writeb (E8390_NODMA+E8390_PAGE1+E8390_STOP, address + E8390_CMD);
++ regd = readb (address + EN0_COUNTER0);
++ writeb (0xff, address + EN0_COUNTER0);
++ writeb (E8390_NODMA+E8390_PAGE0, address + E8390_CMD);
++ readb (address + EN0_COUNTER0); /* Clear the counter by reading. */
++ if (readb (address + EN0_COUNTER0) != 0) {
++ writeb (reg0, address);
++ writeb (regd, address + EN0_COUNTER0); /* Restore the old values. */
++ ret = -ENODEV;
++ goto err_out;
++ }
++ }
++
++ /* Reset card. Who knows what dain-bramaged state it was left in. */
++ {
++
++ int count=0;
++ readb (address + EN0_RESET);
++ while ((readb (address + EN0_ISR) & ENISR_RESET) == 0)
++ {
++
++ if (count >20)
++ {
++ PRINTK (ERROR_MSG, " not found (no reset ack).\n");
++ ret = -ENODEV;
++ goto err_out;
++ }
++ else
++ {
++ mdelay(1);
++ count++;
++ }
++ }
++ writeb (0xff, (address + EN0_ISR)); /* Ack all intr. */
++ }
++
++ ax_local = (struct ax_device *)&ax_global;
++
++ ax_local->membase = (void *)address;
++ ax_local->tx_start_page = NESM_START_PG;
++ ax_local->rx_start_page = NESM_RX_START_PG;
++ ax_local->stop_page = NESM_STOP_PG;
++ ax_local->media = media;
++#if (CONFIG_AX88796B_8BIT_WIDE == 1)
++ ax_local->bus_width = 0;
++#else
++ ax_local->bus_width = 1;
++#endif
++
++ load_macaddr (dev_addr);
++
++ /* Support for No EEPROM */
++ if(dev_addr[0] != 0x00)
++ {
++ get_mac_from_nor_flash(dev_addr);
++
++ printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ printk (" %2.2x", dev_addr[i]);
++ }
++ printk("\n");
++
++ if( (dev_addr[0] != 0x00))
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++
++ else if ((dev_addr[0] == 0) && (dev_addr[1] == 0) &&
++ (dev_addr[2] == 0) && (dev_addr[3] == 0) &&
++ (dev_addr[4] == 0) && (dev_addr[5] == 0) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++ else if ( (dev_addr[0] == 0xFF) && (dev_addr[1] == 0xFF) &&
++ (dev_addr[2] == 0xFF) && (dev_addr[3] == 0xFF) &&
++ (dev_addr[4] == 0xFF) && (dev_addr[5] == 0xFF) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++
++ }
++
++ else if ( (dev_addr[0] == 0) && (dev_addr[1] == 0) &&
++ (dev_addr[2] == 0) && (dev_addr[3] == 0) &&
++ (dev_addr[4] == 0) && (dev_addr[5] == 0) )
++ {
++
++ get_mac_from_nor_flash(dev_addr);
++
++ printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ printk (" %2.2x", dev_addr[i]);
++ }
++ printk("\n");
++ if( (dev_addr[0] != 0x00))
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++ else if ( (dev_addr[0] == 0) && (dev_addr[1] == 0) &&
++ (dev_addr[2] == 0) && (dev_addr[3] == 0) &&
++ (dev_addr[4] == 0) && (dev_addr[5] == 0) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++ else if ( (dev_addr[0] == 0xFF) && (dev_addr[1] == 0xFF) &&
++ (dev_addr[2] == 0xFF) && (dev_addr[3] == 0xFF) &&
++ (dev_addr[4] == 0xFF) && (dev_addr[5] == 0xFF) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++
++ }
++ else if ( (dev_addr[0] == 0xFF) && (dev_addr[1] == 0xFF) &&
++ (dev_addr[2] == 0xFF) && (dev_addr[3] == 0xFF) &&
++ (dev_addr[4] == 0xFF) && (dev_addr[5] == 0xFF) )
++ {
++
++ get_mac_from_nor_flash(dev_addr);
++
++ printk("MAC Address read from NOR flash is :");
++ for (i = 0; i < ETHER_ADDR_LEN; i++)
++ {
++ printk (" %2.2x", dev_addr[i]);
++ }
++ printk("\n");
++
++ if( (dev_addr[0] != 0x00))
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++ else if ( (dev_addr[0] == 0) && (dev_addr[1] == 0) &&
++ (dev_addr[2] == 0) && (dev_addr[3] == 0) &&
++ (dev_addr[4] == 0) && (dev_addr[5] == 0) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++ else if ( (dev_addr[0] == 0xFF) && (dev_addr[1] == 0xFF) &&
++ (dev_addr[2] == 0xFF) && (dev_addr[3] == 0xFF) &&
++ (dev_addr[4] == 0xFF) && (dev_addr[5] == 0xFF) )
++ {
++ printk("MAC Address read from NOR flash is INVALID \n");
++ dev_addr[0] = 0x00;
++ dev_addr[1] = 0x88;
++ dev_addr[2] = 0x88;
++ dev_addr[3] = 0x77;
++ dev_addr[4] = 0x99;
++ dev_addr[5] = 0x66;
++ }
++
++ }
++
++
++ printk(" MAC ADDRESS ");
++ for (i = 0; i < ETHER_ADDR_LEN; i++) {
++ printk (" %2.2x", dev_addr[i]);
++ }
++
++ printk("\n");
++
++ ax_init (0);
++ ax_open();
++ return 0;
++err_out:
++ return 1;
++
++}
++
++
++
++void get_mac_from_nor_flash(unsigned char *addr)
++{
++ int i=0;
++ unsigned char *mac_addr= (unsigned char *)addr;
++ memcpy(mac_addr,MAC_ADDRESS_IN_NOR_FLASH,MAC_ADDDRESS_LENGTH);
++}
++
++
++int eth_init (bd_t * bd)
++{
++ regulus_ax88796b_init();
++ return 0;
++}
++
++void eth_halt()
++{
++ return ;
++}
++
++/* Get a data block via Ethernet */
++extern int eth_rx (void)
++{
++ unsigned int *prxbytes,rxlen=0;
++ prxbytes=&rxlen;
++
++ ax_watchdog (0);
++ ax_receive (NetRxPackets[0],prxbytes);
++
++ /* Pass the packet up to the protocol layers. */
++ NetReceive(NetRxPackets[0], rxlen);
++
++ if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
++ printf ("packet too big!\n");
++
++
++ return (int) (rxlen);
++}
++
++/* Send a data block via Ethernet. */
++extern int eth_send (volatile void *packet, int length)
++{
++ ax_watchdog (0);
++ ax_start_xmit (packet,length);
++ return 0;
++}
++
++
+diff -Naur u-boot-2008.10_original/drivers/net/regulus_ax88796b.h u-boot-2008.10/drivers/net/regulus_ax88796b.h
+--- u-boot-2008.10_original/drivers/net/regulus_ax88796b.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/drivers/net/regulus_ax88796b.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,244 @@
++/* Generic AX88796B register definitions. */
++/* This file is part of AX88796B drivers, and is distributed
++ under the same license.*/
++
++#ifndef _ax88796_h
++#define _ax88796_h
++
++#define TX_PAGES 12
++#define Tx_page_size 256
++
++#define NE_IO_EXTENT 0xFFF
++
++#define NESM_START_PG 0x40 /* First page of TX buffer */
++#define NESM_RX_START_PG (NESM_START_PG + TX_PAGES) /* First page of RX buffer */
++
++#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
++
++#define ETHER_ADDR_LEN 6
++
++#define AX88796B_BASE 0x08000000
++
++/* The 796b specific per-packet-header format. */
++struct ax_pkt_hdr {
++ unsigned char status; /* status */
++ unsigned char next; /* pointer to next packet. */
++ unsigned short count; /* header + packet length in bytes */
++};
++
++/* Most of these entries should be in 'struct net_device' (or most of the
++ things in there should be here!) */
++/* You have one of these per-board */
++
++struct ax_device {
++ void *membase;
++ unsigned char bus_width;
++ unsigned char mcfilter[8];
++ unsigned char media;
++ unsigned char media_curr;
++ unsigned char tx_curr_page, tx_prev_ctepr, tx_curr_ctepr, tx_full;
++ unsigned char tx_start_page, tx_stop_page,rx_start_page, stop_page;
++ unsigned char current_page; /* Read pointer in buffer */
++};
++
++#define AX88796_WATCHDOG_PERIOD (3*HZ)
++
++//#define ei_status (*(struct ei_device *)(dev->priv))
++
++/* Some generic ethernet register configurations. */
++
++#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
++#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
++#define E8390_TXCONFIG 0x80 /* EN0_TXCR: Normal transmit mode */
++#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
++
++/* Register accessed at EN_CMD, the 8390 base addr. */
++#define E8390_STOP 0x01 /* Stop and reset the chip */
++#define E8390_START 0x02 /* Start the chip, clear reset */
++#define E8390_TRANS 0x04 /* Transmit a frame */
++#define E8390_RREAD 0x08 /* Remote read */
++#define E8390_RWRITE 0x10 /* Remote write */
++#define E8390_NODMA 0x20 /* Remote DMA */
++#define E8390_PAGE0 0x00 /* Select page chip registers */
++#define E8390_PAGE1 0x40 /* using the two high-order bits */
++#define E8390_PAGE2 0x80 /* Page 2 is invalid. */
++#define E8390_PAGE3 0xc0 /* Page 3 for AX88796B */
++
++#define EI_SHIFT(x) ((x) << 1)
++
++#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
++/* Page 0 register offsets. */
++#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
++#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
++#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
++#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
++#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
++#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
++#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */
++#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */
++#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */
++#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */
++#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */
++#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */
++#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */
++#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */
++#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */
++#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */
++#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */
++#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */
++#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */
++#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */
++#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */
++#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */
++#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */
++#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */
++#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */
++#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */
++#define EN0_DATAPORT EI_SHIFT(0x10)
++#define EN0_PHYID EI_SHIFT(0x10)
++#define AX88796_MII_EEPROM EI_SHIFT(0x14)
++#define EN0_BTCR EI_SHIFT(0x15) /* Buffer Type Configure Register */
++#define EN0_SR EI_SHIFT(0X17) /* AX88796B Status Register */
++#define EN0_FLOW EI_SHIFT(0x1a) /* AX88796B Flow control register */
++#define EN0_MCR EI_SHIFT(0X1b) /* Mac configure register */
++#define EN0_CTEPR EI_SHIFT(0x1c) /* Current TX End Page */
++#define EN0_VID0 EI_SHIFT(0x1c) /* VLAN ID 0 */
++#define EN0_VID1 EI_SHIFT(0x1d) /* VLAN ID 1 */
++#define EN0_RESET EI_SHIFT(0X1f) /* Issue a read to reset, a write to clear. */
++
++#define EN0_DATA_ADDR 0x0800
++
++#define ENVLAN_ENABLE 0x08
++
++/* Bits in EN0_ISR - Interrupt status register */
++#define ENISR_RX 0x01 /* Receiver, no error */
++#define ENISR_TX 0x02 /* Transmitter, no error */
++#define ENISR_RX_ERR 0x04 /* Receiver, with error */
++#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
++#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
++#define ENISR_COUNTERS 0x20 /* Counters need emptying */
++#define ENISR_RDC 0x40 /* remote dma complete */
++#define ENISR_RESET 0x80 /* Reset completed */
++#define ENISR_ALL (ENISR_RX | ENISR_TX | ENISR_RX_ERR | ENISR_TX_ERR | ENISR_OVER | ENISR_COUNTERS)/* Interrupts we will enable */
++
++
++/* Bits in EN0_DCFG - Data config register */
++#define ENDCFG_WTS 0x01 /* word transfer mode selection */
++#define ENDCFG_BOS 0x02 /* byte order selection */
++
++#define ENFLOW_ENABLE 0xc7 /* Flow Control Control Register */
++#define ENTQC_ENABLE 0x20 /* Enable TXQ */
++
++#define EN3_TBR EI_SHIFT(0x0d) /* Transmit Buffer Ring Control Register */
++#define ENTBR_ENABLE 0x01 /* Enable Transmit Buffer Ring */
++
++/* Page 1 register offsets. */
++#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */
++#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */
++#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */
++#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */
++#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */
++
++/* Bits in received packet status byte and EN0_RSR*/
++#define ENRSR_RXOK 0x01 /* Received a good packet */
++#define ENRSR_CRC 0x02 /* CRC error */
++#define ENRSR_FAE 0x04 /* frame alignment error */
++#define ENRSR_FO 0x08 /* FIFO overrun */
++#define ENRSR_MPA 0x10 /* missed pkt */
++#define ENRSR_PHY 0x20 /* physical/multicast address */
++#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
++#define ENRSR_DEF 0x80 /* deferring */
++
++/* Transmitted packet status, EN0_TSR. */
++#define ENTSR_PTX 0x01 /* Packet transmitted without error */
++#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
++#define ENTSR_COL 0x04 /* The transmit collided at least once. */
++#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
++#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
++#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
++#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
++#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
++
++/* Bits in buffer type configure register */
++#define ENBTCR_PME_INT_EN 0x40 /* PME interrupt enable */
++#define ENBTCR_INT_ACT_HIGH 0x10
++
++/* Bits in device status register, EN0_SR */
++#define ENSR_DMA_DONE 0x40 /* Remote DMA completed */
++#define ENSR_DMA_READY 0x20 /* Remote DMA ready */
++#define ENSR_DEV_READY 0x10 /* Device ready */
++#define ENSR_SPEED_100 0x04 /* PHY link at 100 Mb/s */
++#define ENSR_DUPLEX_DULL 0x02 /* PHY link at full duplex */
++#define ENSR_LINK 0x01 /* PHY link up */
++
++/* Power Management register offsets. */
++#define EN3_BM0 EI_SHIFT(0x01)
++#define EN3_BM1 EI_SHIFT(0x02)
++#define EN3_BM2 EI_SHIFT(0x03)
++#define EN3_BM3 EI_SH2IFT(0x04)
++#define EN3_BM10CRC EI_SHIFT(0x05)
++#define EN3_BM32CRC EI_SHIFT(0x06)
++#define EN3_BMOFST EI_SHIFT(0x07)
++#define EN3_LSTBYT EI_SHIFT(0x08)
++#define EN3_BMCD EI_SHIFT(0x09)
++#define EN3_WUCS EI_SHIFT(0x0a)
++#define EN3_PMR EI_SHIFT(0x0b)
++
++/* Bits in Wake up Control */
++#define ENWUCS_MPEN 0x01
++#define ENWUCS_WUEN 0x02
++#define ENWUCS_LINK 0x04
++
++/* Bits in PM Control */
++#define ENPMR_D1 0x01
++#define ENPMR_D2 0x02
++
++/* SMDK2440 Registers Definition */
++/* SMDK2440 default clocks: FCLK=400MHZ, HCLK=125MHZ, PCLK=62.5MHZ */
++#define CLKDIVN_125MHZ 0x0000000F /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define CAMDIVN_125MHZ 0x00000000 /* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
++#define UBRDIV0_125MHZ 0x00000023 /* Set UART Baud Rate divisor for 125MHZ HCLK */
++
++#define CLKDIVN_100MHZ 0x0000000D /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define CAMDIVN_100MHZ 0x00000000 /* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
++#define UBRDIV0_100MHZ 0x0000001B /* Set UART Baud Rate divisor for 100MHZ HCLK */
++
++#define CLKDIVN_50MHZ 0x0000000D /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define CAMDIVN_50MHZ 0x00000200 /* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
++#define UBRDIV0_50MHZ 0x0000000D /* Set UART Baud Rate divisor for 50MHZ HCLK */
++
++#define DEFAULT_100MHZ_BANKCON1 0x00000400
++#define DEFAULT_125MHZ_BANKCON1 0x00000510
++#define BURST_BANKCON1 0x0000040f
++
++/* EINTMASK Register Bit Definition */
++#define EINT11_MASK 0x00000800 /* Clear this bit to enable EINT11 interrupt */
++
++/* EXTINT1 Register Bit Definition */
++#define FLTEN11_HIGHLEVEL 0x00009000
++#define FLTEN11_LOWLEVEL 0x00008000 /* Enable EINT11 signal with noise filter */
++/* End of SMDK2440 Registers Definition */
++
++
++#define MEDIA_AUTO 0
++#define MEDIA_100FULL 1
++#define MEDIA_100HALF 2
++#define MEDIA_10FULL 3
++#define MEDIA_10HALF 4
++
++/* Debug Message Display Level Definition */
++#define DRIVER_MSG 0x0001
++#define INIT_MSG 0x0002
++#define TX_MSG 0x0004
++#define RX_MSG 0x0008
++#define INT_MSG 0x0010
++#define ERROR_MSG 0x0020
++#define WARNING_MSG 0x0040
++#define DEBUG_MSG 0x0080
++#define OTHERS_MSG 0x0100
++#define ALL_MSG 0x01FF
++#define NO_MSG 0x0000
++#define DEFAULT_MSG (DRIVER_MSG | ERROR_MSG)
++#define DEBUG_FLAGS DEFAULT_MSG
++
++#endif /* _8390_h */
+diff -Naur u-boot-2008.10_original/drivers/net/regulus_u-boot_compat.h u-boot-2008.10/drivers/net/regulus_u-boot_compat.h
+--- u-boot-2008.10_original/drivers/net/regulus_u-boot_compat.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/drivers/net/regulus_u-boot_compat.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,98 @@
++/*
++ * (C) Copyright 2003
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef _UBOOT_COMPAT_H__
++#define _UBOOT_COMPAT_H__
++
++
++#include <pci.h>
++#include <pci_ids.h>
++#include <common.h>
++#include <malloc.h>
++#include <net.h>
++
++#define __initdata
++#define __init
++#define __exit
++
++#define netif_stop_queue(x)
++#define netif_wake_queue(x)
++#define netif_running(x) 0
++#define unregister_netdev(x)
++#define remove_proc_entry(x,y)
++
++#define dev_addr enetaddr
++
++#define spin_lock_irqsave(x,y) y = 0;
++#define spin_lock_init(x)
++#define spin_lock(x)
++#define spin_unlock_irqrestore(x,y)
++#define spin_unlock(x)
++
++
++#define ENODEV 1
++#define EAGAIN 2
++#define EBUSY 3
++
++#define HZ CFG_HZ
++
++
++#define printk printf
++#define KERN_ERR
++#define KERN_WARNING
++#define KERN_INFO
++
++#define MOD_INC_USE_COUNT
++#define MOD_DEC_USE_COUNT
++
++
++#define kmalloc(x,y) malloc(x)
++#define kfree(x) free(x)
++#define GFP_ATOMIC 0
++
++#define pci_alloc_consistent(x,y,z) (void *)(*(dma_addr_t *)(z) = (dma_addr_t)malloc(y))
++#define pci_free_consistent(x,y,z,d) free(z)
++#define pci_dma_sync_single(x,y,z,d)
++#define pci_unmap_page(x,y,z,d)
++#define pci_unmap_single(x,y,z,d)
++#define pci_present() 1
++
++struct sk_buff
++{
++ u8 * data;
++ u32 len;
++ u8 * data_unaligned;
++};
++
++struct sk_buff * alloc_skb(u32 size, int dummy);
++void dev_kfree_skb_any(struct sk_buff *skb);
++void skb_reserve(struct sk_buff *skb, unsigned int len);
++void skb_put(struct sk_buff *skb, unsigned int len);
++
++#define dev_kfree_skb dev_kfree_skb_any
++#define dev_kfree_skb_irq dev_kfree_skb_any
++
++#define eth_copy_and_sum(dest,src,len,base) memcpy(dest->data,src,len);
++
++
++#endif /* _UBOOT_COMPAT_H__ */
+diff -Naur u-boot-2008.10_original/drivers/net/regulus_uboot_skb.c u-boot-2008.10/drivers/net/regulus_uboot_skb.c
+--- u-boot-2008.10_original/drivers/net/regulus_uboot_skb.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/drivers/net/regulus_uboot_skb.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,115 @@
++/*
++ * Definitions for the 'struct sk_buff' memory handlers in U-Boot.
++ *
++ * (C) Copyright 2003
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include "regulus_u-boot_compat.h"
++
++#define MAX_SKB 50
++
++static struct sk_buff *sk_table[MAX_SKB];
++
++
++struct sk_buff * alloc_skb(u32 size, int dummy)
++{
++ int i;
++ struct sk_buff * ret = NULL;
++
++ for (i = 0; i < MAX_SKB; i++)
++ {
++ if (sk_table[i])
++ {
++ /* Already allocated.
++ */
++ continue;
++ }
++
++ sk_table[i] = malloc(sizeof(struct sk_buff));
++ if (! sk_table[i])
++ {
++ printf("alloc_skb: malloc failed\n");
++ break;
++ }
++
++ memset(sk_table[i], 0, sizeof(struct sk_buff));
++ sk_table[i]->data = sk_table[i]->data_unaligned =
++ malloc(size + 16);
++ if (! sk_table[i]->data)
++ {
++ printf("alloc_skb: malloc failed\n");
++ free(sk_table[i]);
++ sk_table[i] = NULL;
++ break;
++ }
++
++ sk_table[i]->data += 16 - ((u32)sk_table[i]->data & 15);
++ sk_table[i]->len = size;
++
++ break;
++ }
++
++ if (i < MAX_SKB)
++ {
++ ret = sk_table[i];
++ }
++
++ if (! ret)
++ {
++ printf("Unable to allocate skb!\n");
++ }
++
++ return ret;
++}
++
++void dev_kfree_skb_any(struct sk_buff *skb)
++{
++ int i;
++
++ for (i = 0; i < MAX_SKB; i++)
++ {
++ if (sk_table[i] != skb)
++ {
++ continue;
++ }
++
++ free(skb->data_unaligned);
++ free(skb);
++ sk_table[i] = NULL;
++ break;
++ }
++
++ if (i == MAX_SKB)
++ {
++ printf("SKB allocation error!\n");
++ }
++}
++
++void skb_reserve(struct sk_buff *skb, unsigned int len)
++{
++ skb->data+=len;
++}
++
++void skb_put(struct sk_buff *skb, unsigned int len)
++{
++ skb->len+=len;
++}
+diff -Naur u-boot-2008.10_original/drivers/rtc/ds1307.c u-boot-2008.10/drivers/rtc/ds1307.c
+--- u-boot-2008.10_original/drivers/rtc/ds1307.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/rtc/ds1307.c 2009-08-12 18:21:20.000000000 +0530
+@@ -39,6 +39,7 @@
+
+ /*---------------------------------------------------------------------*/
+ #undef DEBUG_RTC
++//#define DEBUG_RTC 1
+
+ #ifdef DEBUG_RTC
+ #define DEBUGR(fmt,args...) printf(fmt ,##args)
+diff -Naur u-boot-2008.10_original/drivers/serial/usbtty.c u-boot-2008.10/drivers/serial/usbtty.c
+--- u-boot-2008.10_original/drivers/serial/usbtty.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/serial/usbtty.c 2009-08-12 18:21:20.000000000 +0530
+@@ -398,7 +398,11 @@
+ struct usb_endpoint_instance *endpoint =
+ &endpoint_instance[rx_endpoint];
+
++
++
++ TTYDBG(" Test whether a character is in the RX buffer \n");
+ /* If no input data exists, allow more RX to be accepted */
++ TTYDBG("If no input data exists, allow more RX to be accepted \n");
+ if(usbtty_input.size <= 0){
+ udc_unset_nak(endpoint->endpoint_address&0x03);
+ }
+@@ -419,14 +423,17 @@
+ struct usb_endpoint_instance *endpoint =
+ &endpoint_instance[rx_endpoint];
+
++ TTYDBG(" Read a single byte from the usb client port. Returns 1 on success, 0 \n");
+ while (usbtty_input.size <= 0) {
++ TTYDBG("usbtty_input.size is %d \n",usbtty_input.size);
+ udc_unset_nak(endpoint->endpoint_address&0x03);
+ usbtty_poll ();
+ }
+-
++ TTYDBG("Calling buf_pop() for getting a single char \n");
+ buf_pop (&usbtty_input, &c, 1);
++ TTYDBG("Calling udc_set_nak() \n");
+ udc_set_nak(endpoint->endpoint_address&0x03);
+-
++ TTYDBG("The Character read is %c \n",c);
+ return c;
+ }
+
+@@ -435,12 +442,14 @@
+ */
+ void usbtty_putc (const char c)
+ {
++ TTYDBG(" Output a single byte to the usb client port. \n");
+ buf_push (&usbtty_output, &c, 1);
+ /* If \n, also do \r */
+ if (c == '\n')
+ buf_push (&usbtty_output, "\r", 1);
+
+ /* Poll at end to handle new data... */
++ TTYDBG(" Poll at end to handle new data... \n");
+ if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {
+ usbtty_poll ();
+ }
+@@ -467,6 +476,7 @@
+ int maxlen = usbtty_output.totalsize;
+ int space, n;
+
++ TTYDBG(" Output a string to the usb client port - implementing flow control \n");
+ /* break str into chunks < buffer size, if needed */
+ while (len > 0) {
+ usbtty_poll ();
+@@ -531,6 +541,7 @@
+ sn, snlen, (ulong)(sizeof(serial_number) - 1));
+ snlen = sizeof(serial_number) - 1;
+ }
++
+ memcpy (serial_number, sn, snlen);
+ serial_number[snlen] = '\0';
+
+@@ -838,6 +849,7 @@
+ current_urb = next_urb (device_instance, endpoint);
+ /* TX data still exists - send it now
+ */
++ //TTYDBG(" TX data still exists - send it now \n");
+ if(endpoint->sent < current_urb->actual_length){
+ if(udc_endpoint_write (endpoint)){
+ /* Write pre-empted by RX */
+@@ -901,6 +913,7 @@
+ struct usb_endpoint_instance *endpoint =
+ &endpoint_instance[rx_endpoint];
+
++ //TTYDBG(" Test Print \n");
+ if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
+ unsigned int nb = 0;
+ char *src = (char *) endpoint->rcv_urb->buffer;
+@@ -909,6 +922,7 @@
+ if(rx_avail >= endpoint->rcv_urb->actual_length){
+
+ nb = endpoint->rcv_urb->actual_length;
++ TTYDBG(" nb is %d ,endpoint->rcv_urb->actual_length is %d \n");
+ buf_push (buf, src, nb);
+ endpoint->rcv_urb->actual_length = 0;
+
+@@ -932,9 +946,11 @@
+ case DEVICE_RESET:
+ case DEVICE_BUS_INACTIVE:
+ usbtty_configured_flag = 0;
++ TTYDBG("DEVICE_BUS_INACTIVE. usbtty_configured_flag is %d \n",usbtty_configured_flag);
+ break;
+ case DEVICE_CONFIGURED:
+ usbtty_configured_flag = 1;
++ TTYDBG("DEVICE_CONFIGURED. usbtty_configured_flag is %d \n",usbtty_configured_flag);
+ break;
+
+ case DEVICE_ADDRESS_ASSIGNED:
+@@ -982,26 +998,31 @@
+ void usbtty_poll (void)
+ {
+ /* New interrupts? */
++ //TTYDBG(" New interrupts? \n");
+ udc_irq();
+
+ /* Write any output data to host buffer
+ * (do this before checking interrupts to avoid missing one)
+ */
++ //TTYDBG(" Write any output data to host buffer .(do this before checking interrupts to avoid missing one) \n");
+ if (usbtty_configured ()) {
+ write_buffer (&usbtty_output);
+ }
+
+ /* New interrupts? */
++ //TTYDBG(" New interrupts? \n");
+ udc_irq();
+
+ /* Check for new data from host..
+ * (do this after checking interrupts to get latest data)
+ */
++ //TTYDBG(" Check for new data from host. (do this after checking interrupts to get latest data) \n");
+ if (usbtty_configured ()) {
+ fill_buffer (&usbtty_input);
+ }
+
+ /* New interrupts? */
++ //TTYDBG(" New interrupts? \n");
+ udc_irq();
+
+ }
+diff -Naur u-boot-2008.10_original/drivers/serial/usbtty.h u-boot-2008.10/drivers/serial/usbtty.h
+--- u-boot-2008.10_original/drivers/serial/usbtty.h 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/serial/usbtty.h 2009-08-12 18:21:20.000000000 +0530
+@@ -24,11 +24,13 @@
+ #ifndef __USB_TTY_H__
+ #define __USB_TTY_H__
+
+-#include "usbdcore.h"
++#include <usbdcore.h>
+ #if defined(CONFIG_PPC)
+-#include "usbdcore_mpc8xx.h"
+-#elif defined(CONFIG_ARM)
+-#include "usbdcore_omap1510.h"
++#include <usbdcore_mpc8xx.h>
++#elif defined(CONFIG_OMAP1510)
++#include <usbdcore_omap1510.h>
++#elif defined(CONFIG_PXA27X)
++#include <usbdcore_pxa27x.h>
+ #endif
+
+ #include <version_autogenerated.h>
+diff -Naur u-boot-2008.10_original/drivers/usb/Makefile u-boot-2008.10/drivers/usb/Makefile
+--- u-boot-2008.10_original/drivers/usb/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/drivers/usb/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -34,6 +34,7 @@
+ COBJS-y += usbdcore_ep0.o
+ COBJS-y += usbdcore_mpc8xx.o
+ COBJS-y += usbdcore_omap1510.o
++COBJS-$(CONFIG_PXA27X) += usbdcore_pxa27x.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+diff -Naur u-boot-2008.10_original/drivers/usb/usbdcore_pxa27x.c u-boot-2008.10/drivers/usb/usbdcore_pxa27x.c
+--- u-boot-2008.10_original/drivers/usb/usbdcore_pxa27x.c 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/drivers/usb/usbdcore_pxa27x.c 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,705 @@
++/*
++ * PXA27x USB device driver for u-boot.
++ *
++ * Copyright (C) 2007 Rodolfo Giometti <giome...@linux.it>
++ * Copyright (C) 2007 Eurotech S.p.A. <i...@eurotech.it>
++ * Copyright (C) 2008 Vivek Kutal <vivek.ku...@azingo.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++
++
++#include <common.h>
++#include <config.h>
++#include <asm/byteorder.h>
++#include <usbdcore.h>
++#include <usbdcore_ep0.h>
++#include <asm/arch/hardware.h>
++#include <usbdcore_pxa27x.h>
++
++/* number of endpoints on this UDC */
++#define UDC_MAX_ENDPOINTS 24
++
++static struct urb *ep0_urb;
++static struct usb_device_instance *udc_device;
++static int ep0state = EP0_IDLE;
++
++#ifdef USBDDBG
++static void udc_dump_buffer(char *name, u8 *buf, int len)
++{
++ usbdbg("%s - buf %p, len %d", name, buf, len);
++ print_buffer(0, buf, 1, len, 0);
++}
++#else
++#define udc_dump_buffer(name, buf, len) /* void */
++#endif
++
++static inline void udc_ack_int_UDCCR(int mask)
++{
++ USIR1 = mask | USIR1;
++}
++
++/*
++ * If the endpoint has an active tx_urb, then the next packet of data from the
++ * URB is written to the tx FIFO.
++ * The total amount of data in the urb is given by urb->actual_length.
++ * The maximum amount of data that can be sent in any one packet is given by
++ * endpoint->tx_packetSize.
++ * The number of data bytes from this URB that have already been transmitted
++ * is given by endpoint->sent.
++ * endpoint->last is updated by this routine with the number of data bytes
++ * transmitted in this packet.
++ */
++static int udc_write_urb(struct usb_endpoint_instance *endpoint)
++{
++ struct urb *urb = endpoint->tx_urb;
++ int ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++ u32 *addr32 = (u32 *) &UDCDN(ep_num);
++ u32 *data32 = (u32 *) urb->buffer;
++ u8 *addr8 = (u8 *) &UDCDN(ep_num);
++ u8 *data8 = (u8 *) urb->buffer;
++ unsigned int i, n, w, b, is_short;
++ int timeout = 2000; /* 2ms */
++
++ if (!urb || !urb->actual_length)
++ return -1;
++
++ n = MIN(urb->actual_length - endpoint->sent, endpoint->tx_packetSize);
++ if (n <= 0)
++ return -1;
++
++ usbdbg("write urb on ep %d", ep_num);
++#if defined(USBDDBG) && defined(USBDPARANOIA)
++ usbdbg("urb: buf %p, buf_len %d, actual_len %d",
++ urb->buffer, urb->buffer_length, urb->actual_length);
++ usbdbg("endpoint: sent %d, tx_packetSize %d, last %d",
++ endpoint->sent, endpoint->tx_packetSize, endpoint->last);
++#endif
++
++ is_short = n != endpoint->tx_packetSize;
++ w = n / 4;
++ b = n % 4;
++ usbdbg("n %d%s w %d b %d", n, is_short ? "-s" : "", w, b);
++ udc_dump_buffer("urb write", data8 + endpoint->sent, n);
++
++ /* Prepare for data send */
++ if (ep_num)
++ UDCCSN(ep_num) = UDCCSR_PC;
++
++ for (i = 0; i < w; i++)
++ *addr32 = data32[endpoint->sent/4 + i];
++ for (i = 0; i < b; i++)
++ *addr8 = data8[endpoint->sent + w*4 + i];
++
++ /* Set "Packet Complete" if less data then tx_packetSize */
++ if (is_short)
++ UDCCSN(ep_num) = ep_num ? UDCCSR_SP : UDCCSR0_IPR;
++
++ /* Wait for data sent */
++ while (!(UDCCSN(ep_num) & (ep_num ? UDCCSR_PC : UDCCSR0_IPR))) {
++ if (ep_num) {
++ if (timeout-- == 0)
++ return -1;
++ else
++ udelay(1);
++ };
++ }
++ endpoint->last = n;
++
++ if (ep_num) {
++ usbd_tx_complete(endpoint);
++ } else {
++ endpoint->sent += n;
++ endpoint->last -= n;
++ }
++
++ if ((endpoint->tx_urb->actual_length - endpoint->sent) <= 0) {
++ urb->actual_length = 0;
++ endpoint->sent = 0;
++ endpoint->last = 0;
++ }
++
++ if ((endpoint->sent >= urb->actual_length) && (!ep_num)) {
++ usbdbg("ep0 IN stage done");
++ if (is_short)
++ ep0state = EP0_IDLE;
++ else
++ ep0state = EP0_XFER_COMPLETE;
++ }
++
++ return 0;
++}
++
++static int udc_read_urb(struct usb_endpoint_instance *endpoint)
++{
++ struct urb *urb = endpoint->rcv_urb;
++ int ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++ u32 *addr32 = (u32 *) &UDCDN(ep_num);
++ u32 *data32 = (u32 *) urb->buffer;
++ unsigned int i, n, is_short ;
++
++ usbdbg("read urb on ep %d", ep_num);
++#if defined(USBDDBG) && defined(USBDPARANOIA)
++ usbdbg("urb: buf %p, buf_len %d, actual_len %d",
++ urb->buffer, urb->buffer_length, urb->actual_length);
++ usbdbg("endpoint: rcv_packetSize %d",
++ endpoint->rcv_packetSize);
++#endif
++
++ if (UDCCSN(ep_num) & UDCCSR_BNE)
++ n = UDCBCN(ep_num) & 0x3ff;
++ else /* zlp */
++ n = 0;
++ is_short = n != endpoint->rcv_packetSize;
++
++ usbdbg("n %d%s", n, is_short ? "-s" : "");
++ for (i = 0; i < n; i += 4)
++ data32[urb->actual_length/4 + i/4] = *addr32;
++
++ udc_dump_buffer("urb read", (u8 *) data32, urb->actual_length + n);
++ usbd_rcv_complete(endpoint, n, 0);
++
++ return 0;
++}
++
++static int udc_read_urb_ep0(void)
++{
++ u32 *addr32 = (u32 *) &UDCDN(0);
++ u32 *data32 = (u32 *) ep0_urb->buffer;
++ u8 *addr8 = (u8 *) &UDCDN(0);
++ u8 *data8 = (u8 *) ep0_urb->buffer;
++ unsigned int i, n, w, b;
++
++ n = UDCBCR0;
++ w = n / 4;
++ b = n % 4;
++
++ for (i = 0; i < w; i++) {
++ data32[ep0_urb->actual_length/4 + i] = *addr32;
++ ep0_urb->actual_length += 4;
++ }
++
++ for (i = 0; i < b; i++) {
++ data8[ep0_urb->actual_length + w*4 + i] = *addr8;
++ ep0_urb->actual_length++;
++ }
++
++ UDCCSR0 = UDCCSR0_OPC | UDCCSR0_IPR;
++ if (ep0_urb->actual_length == ep0_urb->device_request.wLength)
++ return 1;
++
++ return 0;
++}
++
++static void udc_handle_ep0(struct usb_endpoint_instance *endpoint)
++{
++ u32 udccsr0 = UDCCSR0;
++ u32 *data = (u32 *) &ep0_urb->device_request;
++ int i;
++
++ usbdbg("udccsr0 %x", udccsr0);
++
++ /* Clear stall status */
++ if (udccsr0 & UDCCSR0_SST) {
++ usberr("clear stall status");
++ UDCCSR0 = UDCCSR0_SST;
++ ep0state = EP0_IDLE;
++ }
++
++ /* previous request unfinished? non-error iff back-to-back ... */
++ if ((udccsr0 & UDCCSR0_SA) != 0 && ep0state != EP0_IDLE)
++ ep0state = EP0_IDLE;
++
++ switch (ep0state) {
++
++ case EP0_IDLE:
++
++ udccsr0 = UDCCSR0;
++ /* Start control request? */
++ if ((udccsr0 & (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE))
++ == (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE)) {
++
++ /* Read SETUP packet.
++ * SETUP packet size is 8 bytes (aka 2 words)
++ */
++ usbdbg("try reading SETUP packet");
++ for (i = 0; i < 2; i++) {
++ if ((UDCCSR0 & UDCCSR0_RNE) == 0) {
++ usberr("setup packet too short:%d", i);
++ goto stall;
++ }
++ data[i] = UDCDR0;
++ }
++
++ UDCCSR0 |= (UDCCSR0_OPC | UDCCSR0_SA);
++ if ((UDCCSR0 & UDCCSR0_RNE) != 0) {
++ usberr("setup packet too long");
++ goto stall;
++ }
++
++ udc_dump_buffer("ep0 setup read", (u8 *) data, 8);
++
++ if (ep0_urb->device_request.wLength == 0) {
++ usbdbg("Zero Data control Packet\n");
++ if (ep0_recv_setup(ep0_urb)) {
++ usberr("Invalid Setup Packet\n");
++ udc_dump_buffer("ep0 setup read",
++ (u8 *)data, 8);
++ goto stall;
++ }
++ UDCCSR0 = UDCCSR0_IPR;
++ ep0state = EP0_IDLE;
++ } else {
++ /* Check direction */
++ if ((ep0_urb->device_request.bmRequestType &
++ USB_REQ_DIRECTION_MASK)
++ == USB_REQ_HOST2DEVICE) {
++ ep0state = EP0_OUT_DATA;
++ ep0_urb->buffer =
++ (u8 *)ep0_urb->buffer_data;
++ ep0_urb->buffer_length =
++ sizeof(ep0_urb->buffer_data);
++ ep0_urb->actual_length = 0;
++ UDCCSR0 = UDCCSR0_IPR;
++ } else {
++ /* The ep0_recv_setup function has
++ * already placed our response packet
++ * data in ep0_urb->buffer and the
++ * packet length in
++ * ep0_urb->actual_length.
++ */
++ if (ep0_recv_setup(ep0_urb)) {
++stall:
++ usberr("Invalid setup packet");
++ udc_dump_buffer("ep0 setup read"
++ , (u8 *) data, 8);
++ ep0state = EP0_IDLE;
++
++ UDCCSR0 = UDCCSR0_SA |
++ UDCCSR0_OPC | UDCCSR0_FST |
++ UDCCS0_FTF;
++
++ return;
++ }
++
++ endpoint->tx_urb = ep0_urb;
++ endpoint->sent = 0;
++ usbdbg("EP0_IN_DATA");
++ ep0state = EP0_IN_DATA;
++ if (udc_write_urb(endpoint) < 0)
++ goto stall;
++
++ }
++ }
++ return;
++ } else if ((udccsr0 & (UDCCSR0_OPC | UDCCSR0_SA))
++ == (UDCCSR0_OPC|UDCCSR0_SA)) {
++ usberr("Setup Active but no data. Stalling ....\n");
++ goto stall;
++ } else {
++ usbdbg("random early IRQs");
++ /* Some random early IRQs:
++ * - we acked FST
++ * - IPR cleared
++ * - OPC got set, without SA (likely status stage)
++ */
++ UDCCSR0 = udccsr0 & (UDCCSR0_SA | UDCCSR0_OPC);
++ }
++ break;
++
++ case EP0_OUT_DATA:
++
++ if ((udccsr0 & UDCCSR0_OPC) && !(udccsr0 & UDCCSR0_SA)) {
++ if (udc_read_urb_ep0()) {
++read_complete:
++ ep0state = EP0_IDLE;
++ if (ep0_recv_setup(ep0_urb)) {
++ /* Not a setup packet, stall next
++ * EP0 transaction
++ */
++ udc_dump_buffer("ep0 setup read",
++ (u8 *) data, 8);
++ usberr("can't parse setup packet\n");
++ goto stall;
++ }
++ }
++ } else if (!(udccsr0 & UDCCSR0_OPC) &&
++ !(udccsr0 & UDCCSR0_IPR)) {
++ if (ep0_urb->device_request.wLength ==
++ ep0_urb->actual_length)
++ goto read_complete;
++
++ usberr("Premature Status\n");
++ ep0state = EP0_IDLE;
++ }
++ break;
++
++ case EP0_IN_DATA:
++ /* GET_DESCRIPTOR etc */
++ if (udccsr0 & UDCCSR0_OPC) {
++ UDCCSR0 = UDCCSR0_OPC | UDCCSR0_FTF;
++ usberr("ep0in premature status");
++ ep0state = EP0_IDLE;
++ } else {
++ /* irq was IPR clearing */
++ if (udc_write_urb(endpoint) < 0) {
++ usberr("ep0_write_error\n");
++ goto stall;
++ }
++ }
++ break;
++
++ case EP0_XFER_COMPLETE:
++ UDCCSR0 = UDCCSR0_IPR;
++ ep0state = EP0_IDLE;
++ break;
++
++ default:
++ usbdbg("Default\n");
++ }
++ USIR0 = USIR0_IR0;
++}
++
++static void udc_handle_ep(struct usb_endpoint_instance *endpoint)
++{
++ int ep_addr = endpoint->endpoint_address;
++ int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
++ int ep_isout = (ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
++
++ u32 flags = UDCCSN(ep_num) & (UDCCSR_SST | UDCCSR_TRN);
++ if (flags)
++ UDCCSN(ep_num) = flags;
++
++ if (ep_isout)
++ udc_read_urb(endpoint);
++ else
++ udc_write_urb(endpoint);
++
++ UDCCSN(ep_num) = UDCCSR_PC;
++}
++
++static void udc_state_changed(void)
++{
++ int config, interface, alternate;
++
++ UDCCR |= UDCCR_SMAC;
++
++ config = (UDCCR & UDCCR_ACN) >> UDCCR_ACN_S;
++ interface = (UDCCR & UDCCR_AIN) >> UDCCR_AIN_S;
++ alternate = (UDCCR & UDCCR_AAISN) >> UDCCR_AAISN_S;
++
++ usbdbg("New UDC settings are: conf %d - inter %d - alter %d",
++ config, interface, alternate);
++
++ usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
++ UDCISR1 = UDCISR1_IRCC;
++}
++
++void udc_irq(void)
++{
++ int handled;
++ struct usb_endpoint_instance *endpoint;
++ int ep_num, i;
++ u32 udcisr0;
++
++ do {
++ handled = 0;
++ /* Suspend Interrupt Request */
++ if (USIR1 & UDCCR_SUSIR) {
++ usbdbg("Suspend\n");
++ udc_ack_int_UDCCR(UDCCR_SUSIR);
++ handled = 1;
++ ep0state = EP0_IDLE;
++ }
++
++ /* Resume Interrupt Request */
++ if (USIR1 & UDCCR_RESIR) {
++ udc_ack_int_UDCCR(UDCCR_RESIR);
++ handled = 1;
++ usbdbg("USB resume\n");
++ }
++
++ if (USIR1 & (1<<31)) {
++ handled = 1;
++ udc_state_changed();
++ usbdbg("USB state changed \n");
++ }
++
++ /* Reset Interrupt Request */
++ if (USIR1 & UDCCR_RSTIR) {
++ udc_ack_int_UDCCR(UDCCR_RSTIR);
++ handled = 1;
++ usbdbg("Reset\n");
++ usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
++ } else {
++ if (USIR0)
++ usbdbg("UISR0: %x \n", USIR0);
++
++ if (USIR0 & 0x2)
++ USIR0 = 0x2;
++
++ /* Control traffic */
++ if (USIR0 & USIR0_IR0) {
++ handled = 1;
++ udc_handle_ep0(udc_device->bus->endpoint_array);
++ USIR0 = USIR0_IR0;
++ }
++
++ endpoint = udc_device->bus->endpoint_array;
++ for (i = 0; i < udc_device->bus->max_endpoints; i++) {
++ ep_num = (endpoint[i].endpoint_address) &
++ USB_ENDPOINT_NUMBER_MASK;
++ if (!ep_num)
++ continue;
++ udcisr0 = UDCISR0;
++ if (udcisr0 &
++ UDCISR_INT(ep_num, UDC_INT_PACKETCMP)) {
++ UDCISR0 = UDCISR_INT(ep_num,
++ UDC_INT_PACKETCMP);
++ udc_handle_ep(&endpoint[i]);
++ }
++ }
++ }
++
++ } while (handled);
++}
++
++/* The UDCCR reg contains mask and interrupt status bits,
++ * so using '|=' isn't safe as it may ack an interrupt.
++ */
++#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
++#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_UDE)
++
++static inline void udc_set_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
++}
++
++static inline void udc_clear_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
++}
++
++static void pio_irq_enable(int ep_num)
++{
++ if (ep_num < 16)
++ UDCICR0 |= 3 << (ep_num * 2);
++ else {
++ ep_num -= 16;
++ UDCICR1 |= 3 << (ep_num * 2);
++ }
++}
++
++/*
++ * udc_set_nak
++ *
++ * Allow upper layers to signal lower layers should not accept more RX data
++ */
++void udc_set_nak(int ep_num)
++{
++ /* TODO */
++}
++
++/*
++ * udc_unset_nak
++ *
++ * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
++ * Switch off NAKing on this endpoint to accept more data output from host.
++ */
++void udc_unset_nak(int ep_num)
++{
++ /* TODO */
++}
++
++int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
++{
++ return udc_write_urb(endpoint);
++}
++
++/* Associate a physical endpoint with endpoint instance */
++void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
++ struct usb_endpoint_instance *endpoint)
++{
++ int ep_num, ep_addr, ep_isout, ep_type, ep_size;
++ int config, interface, alternate;
++ u32 tmp;
++
++ usbdbg("setting up endpoint id %d", id);
++
++ if (!endpoint) {
++ usberr("endpoint void!");
++ return;
++ }
++
++ ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++ if (ep_num >= UDC_MAX_ENDPOINTS) {
++ usberr("unable to setup ep %d!", ep_num);
++ return;
++ }
++
++ pio_irq_enable(ep_num);
++ if (ep_num == 0) {
++ /* Done for ep0 */
++ return;
++ }
++
++ config = 1;
++ interface = 0;
++ alternate = 0;
++
++ usbdbg("config %d - interface %d - alternate %d",
++ config, interface, alternate);
++
++ ep_addr = endpoint->endpoint_address;
++ ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
++ ep_isout = (ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
++ ep_type = ep_isout ? endpoint->rcv_attributes : endpoint->tx_attributes;
++ ep_size = ep_isout ? endpoint->rcv_packetSize : endpoint->tx_packetSize;
++
++ usbdbg("addr %x, num %d, dir %s, type %s, packet size %d",
++ ep_addr, ep_num,
++ ep_isout ? "out" : "in",
++ ep_type == USB_ENDPOINT_XFER_ISOC ? "isoc" :
++ ep_type == USB_ENDPOINT_XFER_BULK ? "bulk" :
++ ep_type == USB_ENDPOINT_XFER_INT ? "int" : "???",
++ ep_size
++ );
++
++ /* Configure UDCCRx */
++ tmp = 0;
++ tmp |= (config << UDCCONR_CN_S) & UDCCONR_CN;
++ tmp |= (interface << UDCCONR_IN_S) & UDCCONR_IN;
++ tmp |= (alternate << UDCCONR_AISN_S) & UDCCONR_AISN;
++ tmp |= (ep_num << UDCCONR_EN_S) & UDCCONR_EN;
++ tmp |= (ep_type << UDCCONR_ET_S) & UDCCONR_ET;
++ tmp |= ep_isout ? 0 : UDCCONR_ED;
++ tmp |= (ep_size << UDCCONR_MPS_S) & UDCCONR_MPS;
++ tmp |= UDCCONR_EE;
++
++ UDCCN(ep_num) = tmp;
++
++ usbdbg("UDCCR%c = %x", 'A' + ep_num-1, UDCCN(ep_num));
++ usbdbg("UDCCSR%c = %x", 'A' + ep_num-1, UDCCSN(ep_num));
++}
++
++#define CONFIG_USB_DEV_PULLUP_GPIO 87
++//#define CONFIG_USB_DEV_PULLUP_GPIO 107
++
++/* Connect the USB device to the bus */
++void udc_connect(void)
++{
++ usbdbg("UDC connect");
++
++ /* Turn on the USB connection by enabling the pullup resistor */
++ set_GPIO_mode(CONFIG_USB_DEV_PULLUP_GPIO | GPIO_OUT);
++ GPSR(CONFIG_USB_DEV_PULLUP_GPIO) = GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO);
++}
++
++/* Disconnect the USB device to the bus */
++void udc_disconnect(void)
++{
++ usbdbg("UDC disconnect");
++
++ /* Turn off the USB connection by disabling the pullup resistor */
++ GPCR(CONFIG_USB_DEV_PULLUP_GPIO) = GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO);
++}
++
++/* Switch on the UDC */
++void udc_enable(struct usb_device_instance *device)
++{
++
++ ep0state = EP0_IDLE;
++ CKEN |= CKEN11_USB;
++
++ /* enable endpoint 0, A, B's Packet Complete Interrupt. */
++ UDCICR0 = 0x0000003f;
++ UDCICR1 = 0xa8000000;
++
++ /* clear the interrupt status/control registers */
++ UDCISR0 = 0xffffffff;
++ UDCISR1 = 0xffffffff;
++
++ /* set UDC-enable */
++ udc_set_mask_UDCCR(UDCCR_UDE);
++
++ udc_device = device;
++ if (!ep0_urb)
++ ep0_urb = usbd_alloc_urb(udc_device,
++ udc_device->bus->endpoint_array);
++ else
++ usbinfo("ep0_urb %p already allocated", ep0_urb);
++
++ usbdbg("UDC Enabled\n");
++}
++
++/* Need to check this again */
++void udc_disable(void)
++{
++ usbdbg("disable UDC");
++
++ udc_clear_mask_UDCCR(UDCCR_UDE);
++
++ /* Disable clock for USB device */
++ CKEN &= ~CKEN11_USB;
++
++ /* Free ep0 URB */
++ if (ep0_urb) {
++ usbd_dealloc_urb(ep0_urb);
++ ep0_urb = NULL;
++ }
++
++ /* Reset device pointer */
++ udc_device = NULL;
++}
++
++/* Allow udc code to do any additional startup */
++void udc_startup_events(struct usb_device_instance *device)
++{
++ /* The DEVICE_INIT event puts the USB device in the state STATE_INIT */
++ usbd_device_event_irq(device, DEVICE_INIT, 0);
++
++ /* The DEVICE_CREATE event puts the USB device in the state
++ * STATE_ATTACHED */
++ usbd_device_event_irq(device, DEVICE_CREATE, 0);
++
++ /* Some USB controller driver implementations signal
++ * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
++ * DEVICE_HUB_CONFIGURED causes a transition to the state
++ * STATE_POWERED, and DEVICE_RESET causes a transition to
++ * the state STATE_DEFAULT.
++ */
++ udc_enable(device);
++}
++
++/* Initialize h/w stuff */
++int udc_init(void)
++{
++ udc_device = NULL;
++ usbdbg("PXA27x usbd start");
++
++ /* Disable the UDC */
++ udc_clear_mask_UDCCR(UDCCR_UDE);
++
++ /* Disable clock for USB device */
++ CKEN &= ~CKEN11_USB;
++
++ /* Disable IRQs: we don't use them */
++ UDCICR0 = UDCICR1 = 0;
++
++ return 0;
++}
++
+diff -Naur u-boot-2008.10_original/examples/Makefile u-boot-2008.10/examples/Makefile
+--- u-boot-2008.10_original/examples/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/examples/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -37,6 +37,10 @@
+ endif
+ endif
+
++ifeq ($(BOARD),regulus)
++LOAD_ADDR = 0xa0300000
++endif
++
+ ifeq ($(ARCH),mips)
+ LOAD_ADDR = 0x80200000 -T mips.lds
+ endif
+diff -Naur u-boot-2008.10_original/Flash_881b_1_16.dat u-boot-2008.10/Flash_881b_1_16.dat
+--- u-boot-2008.10_original/Flash_881b_1_16.dat 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/Flash_881b_1_16.dat 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,88 @@
++/* Flash_891C_1_16.dat
++ Called from Jflash with Device ID = 0x891C
++*****************************************************************************
++ This is a flash data file required by JFlash. This file contains memory
++ map information and other particulars required to program the device.
++ This data file is a text file with specific format requirements.
++
++ The filename is constructed by the JFlash engine by the following
++ algorithm. This is so that the JFlash engine does not have to be
++ updated with new flash information. If the file was not found, then
++ the flash is either not supported or not released to the customer.
++
++ The algorithm is:
++
++ Flash_ + numeric ID + number of devices in parallel + bus width +.dat
++
++
++ Comment blocks can be defined using the old-style C comment blocks.
++ The difference is that the delimiter characters must have whitespace
++ on both sides.
++
++ Data may be string data, or numeric. String data is only allowed
++ at specific positions within this file. Numeric data can be decimal,
++ hexadecimal, or octal.
++ Decimal data is assumed, and HEX data may be denoted by a
++ preceding 'X' character.
++
++ Valid HEX data:
++ xA0000000
++ XA4090000
++ Xff
++
++ Valid OCTAL data:
++ o765
++ O123545
++
++*****************************************************************************
++*/
++ TE28F256P30B85 /* Designation for this memory type */
++ 1.0 /* Version number of this data file */
++ VLF0000001 /* Version lock code for compatibility to JTAG engine */
++/*
++*****************************************************************************
++*/
++ 5 /* Max Erase Time in seconds */
++ 16 /* Max Write Buffer */
++/*
++*****************************************************************************
++The flash blocks may be of different sizes throughout the flash device or
++may be all one size. The description of the flash for our purposes must
++identify where the erase and program regions are in the device. The simplest
++method would be to limit the description to allow up to 10 unique regions of
++similiar characteristics. In most cases, 10 regions will be too many, and
++these extra definition locations can be stubbed out by setting the region
++identifier as disabled. Regions are expected to be described in order so that
++the start address of the first region and the end address of the last region
++can be used to compute the total memory size.
++
++*****************************************************************************
++*/
++/*
++ reg # | enabled |# of | Block | Start | End |
++ | or |erase | size | Addr of | Addr of |
++ | disabled |blocks | | region | region |
++ | | |(words) | (bytes) | (bytes) |
++*/
++/* 0 */ /* enabled 254 X20000 X00000000 X1FDFFFF */
++/* 1 */ /* enabled 4 X8000 X1FE0000 X1FFFFFF */
++
++/* 0 */ enabled 4 X4000 X00000000 X1FFFF
++/* 1 */ enabled 127 X10000 X20000 XFFFFFF
++/* 2 */ disabled 0 X0 X0 X0
++/* 3 */ disabled 0 X0 X0 X0
++/* 4 */ disabled 0 X0 X0 X0
++/* 5 */ disabled 0 X0 X0 X0
++/* 6 */ disabled 0 X0 X0 X0
++/* 7 */ disabled 0 X0 X0 X0
++/* 8 */ disabled 0 X0 X0 X0
++/* 9 */ disabled 0 X0 X0 X0
++
++/*
++*********************************************************
++Alignment checkpoint - do not edit this value
++*********************************************************
++*/
++ 1111
++
++/* End of data */
+diff -Naur u-boot-2008.10_original/Flash_891c_1_16.dat u-boot-2008.10/Flash_891c_1_16.dat
+--- u-boot-2008.10_original/Flash_891c_1_16.dat 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/Flash_891c_1_16.dat 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,88 @@
++/* Flash_891C_1_16.dat
++ Called from Jflash with Device ID = 0x891C
++*****************************************************************************
++ This is a flash data file required by JFlash. This file contains memory
++ map information and other particulars required to program the device.
++ This data file is a text file with specific format requirements.
++
++ The filename is constructed by the JFlash engine by the following
++ algorithm. This is so that the JFlash engine does not have to be
++ updated with new flash information. If the file was not found, then
++ the flash is either not supported or not released to the customer.
++
++ The algorithm is:
++
++ Flash_ + numeric ID + number of devices in parallel + bus width +.dat
++
++
++ Comment blocks can be defined using the old-style C comment blocks.
++ The difference is that the delimiter characters must have whitespace
++ on both sides.
++
++ Data may be string data, or numeric. String data is only allowed
++ at specific positions within this file. Numeric data can be decimal,
++ hexadecimal, or octal.
++ Decimal data is assumed, and HEX data may be denoted by a
++ preceding 'X' character.
++
++ Valid HEX data:
++ xA0000000
++ XA4090000
++ Xff
++
++ Valid OCTAL data:
++ o765
++ O123545
++
++*****************************************************************************
++*/
++ TE28F256P30B85 /* Designation for this memory type */
++ 1.0 /* Version number of this data file */
++ VLF0000001 /* Version lock code for compatibility to JTAG engine */
++/*
++*****************************************************************************
++*/
++ 5 /* Max Erase Time in seconds */
++ 16 /* Max Write Buffer */
++/*
++*****************************************************************************
++The flash blocks may be of different sizes throughout the flash device or
++may be all one size. The description of the flash for our purposes must
++identify where the erase and program regions are in the device. The simplest
++method would be to limit the description to allow up to 10 unique regions of
++similiar characteristics. In most cases, 10 regions will be too many, and
++these extra definition locations can be stubbed out by setting the region
++identifier as disabled. Regions are expected to be described in order so that
++the start address of the first region and the end address of the last region
++can be used to compute the total memory size.
++
++*****************************************************************************
++*/
++/*
++ reg # | enabled |# of | Block | Start | End |
++ | or |erase | size | Addr of | Addr of |
++ | disabled |blocks | | region | region |
++ | | |(words) | (bytes) | (bytes) |
++*/
++/* 0 */ /* enabled 254 X20000 X00000000 X1FDFFFF */
++/* 1 */ /* enabled 4 X8000 X1FE0000 X1FFFFFF */
++
++/* 0 */ enabled 4 X4000 X00000000 X1FFFF
++/* 1 */ enabled 255 X10000 X20000 X1FFFFFF
++/* 2 */ disabled 0 X0 X0 X0
++/* 3 */ disabled 0 X0 X0 X0
++/* 4 */ disabled 0 X0 X0 X0
++/* 5 */ disabled 0 X0 X0 X0
++/* 6 */ disabled 0 X0 X0 X0
++/* 7 */ disabled 0 X0 X0 X0
++/* 8 */ disabled 0 X0 X0 X0
++/* 9 */ disabled 0 X0 X0 X0
++
++/*
++*********************************************************
++Alignment checkpoint - do not edit this value
++*********************************************************
++*/
++ 1111
++
++/* End of data */
+diff -Naur u-boot-2008.10_original/Flash_891C_1_16.dat u-boot-2008.10/Flash_891C_1_16.dat
+--- u-boot-2008.10_original/Flash_891C_1_16.dat 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/Flash_891C_1_16.dat 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,88 @@
++/* Flash_891C_1_16.dat
++ Called from Jflash with Device ID = 0x891C
++*****************************************************************************
++ This is a flash data file required by JFlash. This file contains memory
++ map information and other particulars required to program the device.
++ This data file is a text file with specific format requirements.
++
++ The filename is constructed by the JFlash engine by the following
++ algorithm. This is so that the JFlash engine does not have to be
++ updated with new flash information. If the file was not found, then
++ the flash is either not supported or not released to the customer.
++
++ The algorithm is:
++
++ Flash_ + numeric ID + number of devices in parallel + bus width +.dat
++
++
++ Comment blocks can be defined using the old-style C comment blocks.
++ The difference is that the delimiter characters must have whitespace
++ on both sides.
++
++ Data may be string data, or numeric. String data is only allowed
++ at specific positions within this file. Numeric data can be decimal,
++ hexadecimal, or octal.
++ Decimal data is assumed, and HEX data may be denoted by a
++ preceding 'X' character.
++
++ Valid HEX data:
++ xA0000000
++ XA4090000
++ Xff
++
++ Valid OCTAL data:
++ o765
++ O123545
++
++*****************************************************************************
++*/
++ TE28F256P30B85 /* Designation for this memory type */
++ 1.0 /* Version number of this data file */
++ VLF0000001 /* Version lock code for compatibility to JTAG engine */
++/*
++*****************************************************************************
++*/
++ 5 /* Max Erase Time in seconds */
++ 16 /* Max Write Buffer */
++/*
++*****************************************************************************
++The flash blocks may be of different sizes throughout the flash device or
++may be all one size. The description of the flash for our purposes must
++identify where the erase and program regions are in the device. The simplest
++method would be to limit the description to allow up to 10 unique regions of
++similiar characteristics. In most cases, 10 regions will be too many, and
++these extra definition locations can be stubbed out by setting the region
++identifier as disabled. Regions are expected to be described in order so that
++the start address of the first region and the end address of the last region
++can be used to compute the total memory size.
++
++*****************************************************************************
++*/
++/*
++ reg # | enabled |# of | Block | Start | End |
++ | or |erase | size | Addr of | Addr of |
++ | disabled |blocks | | region | region |
++ | | |(words) | (bytes) | (bytes) |
++*/
++/* 0 */ /* enabled 254 X20000 X00000000 X1FDFFFF */
++/* 1 */ /* enabled 4 X8000 X1FE0000 X1FFFFFF */
++
++/* 0 */ enabled 4 X4000 X00000000 X1FFFF
++/* 1 */ enabled 255 X10000 X20000 X1FFFFFF
++/* 2 */ disabled 0 X0 X0 X0
++/* 3 */ disabled 0 X0 X0 X0
++/* 4 */ disabled 0 X0 X0 X0
++/* 5 */ disabled 0 X0 X0 X0
++/* 6 */ disabled 0 X0 X0 X0
++/* 7 */ disabled 0 X0 X0 X0
++/* 8 */ disabled 0 X0 X0 X0
++/* 9 */ disabled 0 X0 X0 X0
++
++/*
++*********************************************************
++Alignment checkpoint - do not edit this value
++*********************************************************
++*/
++ 1111
++
++/* End of data */
+diff -Naur u-boot-2008.10_original/include/asm-arm/arch-pxa/pxa-regs.h u-boot-2008.10/include/asm-arm/arch-pxa/pxa-regs.h
+--- u-boot-2008.10_original/include/asm-arm/arch-pxa/pxa-regs.h 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/include/asm-arm/arch-pxa/pxa-regs.h 2009-08-12 18:21:20.000000000 +0530
+@@ -596,46 +596,69 @@
+ /*
+ * USB Device Controller
+ */
+-#ifndef CONFIG_CPU_MONAHANS
+-#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */
+-#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */
+-#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */
+-
+-#define UDCCR __REG(0x40600000) /* UDC Control Register */
+-#define UDCCR_UDE (1 << 0) /* UDC enable */
+-#define UDCCR_UDA (1 << 1) /* UDC active */
+-#define UDCCR_RSM (1 << 2) /* Device resume */
+-#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
+-#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
+-#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
+-#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
+-#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
+-
+-#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */
+-#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
+-#define UDCCS0_IPR (1 << 1) /* IN packet ready */
+-#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
+-#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
+-#define UDCCS0_SST (1 << 4) /* Sent stall */
+-#define UDCCS0_FST (1 << 5) /* Force stall */
+-#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
+-#define UDCCS0_SA (1 << 7) /* Setup active */
++#ifdef CONFIG_PXA27X
++#define UDCCR __REG(0x40600000) /* UDC Control Register */
++#define UDCCR_UDE (1 << 0) /* UDC enable */
++#define UDCCR_UDA (1 << 1) /* UDC active */
++#define UDCCR_RSM (1 << 2) /* Device resume */
++#define UDCCR_EMCE (1 << 3) /* Endpoint Memory
++onfiguration Error */
++#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to
++Active Configuration */
++#define UDCCR_RESIR (1 << 29) /* Resume interrupt request */
++#define UDCCR_SUSIR (1 << 28) /* Suspend interrupt request */
++#define UDCCR_SM (1 << 28) /* Suspend interrupt mask */
++#define UDCCR_RSTIR (1 << 27) /* Reset interrupt request */
++#define UDCCR_REM (1 << 27) /* Reset interrupt mask */
++#define UDCCR_RM (1 << 29) /* resume interrupt mask */
++#define UDCCR_SRM (UDCCR_SM|UDCCR_RM)
++#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
++#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host
++Negotiation Protocol Port Support */
++#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation
++Protocol Support */
++#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation
++Protocol Enable */
++#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable
++*/
++#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration
++Number */
++#define UDCCR_ACN_S 11
++#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number
++*/
++#define UDCCR_AIN_S 8
++#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate
++Interface Setting Number */
++#define UDCCR_AAISN_S 5
++
++#define UDCCS0 __REG(0x40600100) /* UDC Endpoint 0
++Control/Status Register */
++#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
++#define UDCCS0_IPR (1 << 1) /* IN packet ready */
++#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
++#define UDCCS0_DRWF (1 << 16) /* Device remote wakeup feature
++*/
++#define UDCCS0_SST (1 << 4) /* Sent stall */
++#define UDCCS0_FST (1 << 5) /* Force stall */
++#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
++#define UDCCS0_SA (1 << 7) /* Setup active */
++
+
+ /* Bulk IN - Endpoint 1,6,11 */
+-#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */
++#define UDCCS1 __REG(0x40600104) /* UDC Endpoint 1 (IN) Control/Status Register */
+ #define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */
+ #define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */
+
+ #define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
+ #define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
+-#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
++#define UDCCS_BI_FTF (1 << 8) /* Flush Tx FIFO */
+ #define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
+ #define UDCCS_BI_SST (1 << 4) /* Sent stall */
+ #define UDCCS_BI_FST (1 << 5) /* Force stall */
+ #define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
+
+ /* Bulk OUT - Endpoint 2,7,12 */
+-#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
++#define UDCCS2 __REG(0x40600108) /* UDC Endpoint 2 (OUT) Control/Status Register */
+ #define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
+ #define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */
+
+@@ -684,16 +707,16 @@
+ #define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
+
+ #define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */
+-#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */
+-#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */
++#define UFNRL __REG(0x40600014) /* UDC Frame Number Register Low */
++#define UBCR2 __REG(0x40600208) /* UDC Byte Count Reg 2 */
+ #define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */
+ #define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */
+ #define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */
+ #define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */
+ #define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */
+-#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */
+-#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */
+-#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */
++#define UDDR0 __REG(0x40600300) /* UDC Endpoint 0 Data Register */
++#define UDDR1 __REG(0x40600304) /* UDC Endpoint 1 Data Register */
++#define UDDR2 __REG(0x40600308) /* UDC Endpoint 2 Data Register */
+ #define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */
+ #define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */
+ #define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */
+@@ -708,7 +731,7 @@
+ #define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */
+ #define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */
+
+-#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */
++#define UICR0 __REG(0x40600004) /* UDC Interrupt Control Register 0 */
+
+ #define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
+ #define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
+@@ -719,7 +742,7 @@
+ #define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
+ #define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
+
+-#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */
++#define UICR1 __REG(0x40600008) /* UDC Interrupt Control Register 1 */
+
+ #define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
+ #define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
+@@ -730,7 +753,7 @@
+ #define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
+ #define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
+
+-#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */
++#define USIR0 __REG(0x4060000C) /* UDC Status Interrupt Register 0 */
+
+ #define USIR0_IR0 (1 << 0) /* Interrup request ep 0 */
+ #define USIR0_IR1 (1 << 1) /* Interrup request ep 1 */
+@@ -741,7 +764,7 @@
+ #define USIR0_IR6 (1 << 6) /* Interrup request ep 6 */
+ #define USIR0_IR7 (1 << 7) /* Interrup request ep 7 */
+
+-#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */
++#define USIR1 __REG(0x40600010) /* UDC Status Interrupt Register 1 */
+
+ #define USIR1_IR8 (1 << 0) /* Interrup request ep 8 */
+ #define USIR1_IR9 (1 << 1) /* Interrup request ep 9 */
+@@ -751,23 +774,243 @@
+ #define USIR1_IR13 (1 << 5) /* Interrup request ep 13 */
+ #define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */
+ #define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */
+-#endif /* ! CONFIG_CPU_MONAHANS */
++#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control
++Register0 */
++#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control
++Register1 */
++#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt
++for EP */
++#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete
++interrupt for EP */
++
++#define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
++#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */
++#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */
++#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */
++#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */
++#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */
++
++#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */
++#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */
++#define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
++#define UDCISR1_IRCC (1 << 31) /* IntEn - Configuration Change */
++#define UDCISR1_IRSOF (1 << 30) /* IntEn - Start of Frame */
++#define UDCISR1_IRRU (1 << 29) /* IntEn - Resume */
++#define UDCISR1_IRSU (1 << 28) /* IntEn - Suspend */
++#define UDCISR1_IRRS (1 << 27) /* IntEn - Reset */
++
++
++#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register
++*/
++#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt
++control */
++#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command
++recvd */
++#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt
++Rising Edge Interrupt Enable */
++#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt
++Falling Edge Interrupt Enable */
++#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising
++Edge Interrupt Enable */
++#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling
++Edge Interrupt Enable */
++#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising
++Edge Interrupt Enable */
++#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling
++Edge Interrupt Enable */
++#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid
++Rising Edge Interrupt Enable */
++#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid
++Falling Edge Interrupt Enable */
++#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP
++Detect Rising Edge Interrupt Enable */
++#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP
++Detect Falling Edge Interrupt Enable */
++#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising
++Edge Interrupt Enable */
++#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change
++Falling Edge Interrupt Enable */
++
++#define UDCCSN(x) __REG2(0x40600100, (x) << 2)
++#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status
++register - Endpoint 0 */
++
++#define UDCCSR0_SA (1 << 7) /* Setup Active */
++#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */
++#define UDCCSR0_FST (1 << 5) /* Force Stall */
++#define UDCCSR0_SST (1 << 4) /* Sent Stall */
++#define UDCCSR0_DME (1 << 3) /* DMA Enable */
++#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */
++#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */
++#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */
++
++#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register -
++Endpoint A */
++#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register -
++Endpoint B */
++#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register -
++Endpoint C */
++#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register -
++Endpoint D */
++#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register -
++Endpoint E */
++#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register -
++Endpoint F */
++#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register -
++Endpoint G */
++#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register -
++Endpoint H */
++#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register -
++Endpoint I */
++#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register -
++Endpoint J */
++#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register -
++Endpoint K */
++#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register -
++Endpoint L */
++#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register -
++Endpoint M */
++#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register -
++Endpoint N */
++#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register -
++Endpoint P */
++#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register -
++Endpoint Q */
++#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register -
++Endpoint R */
++#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register -
++Endpoint S */
++#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register -
++Endpoint T */
++#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register -
++Endpoint U */
++#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register -
++Endpoint V */
++#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register -
++Endpoint W */
++#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register -
++Endpoint X */
++
++#define UDCCSR_DPE (1 << 9) /* Data Packet Error */
++#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */
++#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */
++#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */
++#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */
++#define UDCCSR_FST (1 << 5) /* Force STALL */
++#define UDCCSR_SST (1 << 4) /* Sent STALL */
++#define UDCCSR_DME (1 << 3) /* DMA Enable */
++#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */
++#define UDCCSR_PC (1 << 1) /* Packet Complete */
++#define UDCCSR_FS (1 << 0) /* FIFO needs service */
++
++#define UDCBCN(x) __REG2(0x40600200, (x)<<2)
++#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */
++#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */
++#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */
++#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */
++#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */
++#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */
++#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */
++#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */
++#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */
++#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */
++#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */
++#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */
++#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */
++#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */
++#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */
++#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */
++#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */
++#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */
++#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */
++#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */
++#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */
++#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */
++#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */
++#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */
++
++#define UDCDN(x) __REG2(0x40600300, (x)<<2)
++#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */
++#define UDCDRA __REG(0x40600304) /* Data Register - EPA */
++#define UDCDRB __REG(0x40600308) /* Data Register - EPB */
++#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */
++#define UDCDRD __REG(0x40600310) /* Data Register - EPD */
++#define UDCDRE __REG(0x40600314) /* Data Register - EPE */
++#define UDCDRF __REG(0x40600318) /* Data Register - EPF */
++#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */
++#define UDCDRH __REG(0x40600320) /* Data Register - EPH */
++#define UDCDRI __REG(0x40600324) /* Data Register - EPI */
++#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */
++#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */
++#define UDCDRL __REG(0x40600330) /* Data Register - EPL */
++#define UDCDRM __REG(0x40600334) /* Data Register - EPM */
++#define UDCDRN __REG(0x40600338) /* Data Register - EPN */
++#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */
++#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */
++#define UDCDRR __REG(0x40600344) /* Data Register - EPR */
++#define UDCDRS __REG(0x40600348) /* Data Register - EPS */
++#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */
++#define UDCDRU __REG(0x40600350) /* Data Register - EPU */
++#define UDCDRV __REG(0x40600354) /* Data Register - EPV */
++#define UDCDRW __REG(0x40600358) /* Data Register - EPW */
++#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */
++
++#define UDCCN(x) __REG2(0x40600400, (x)<<2)
++#define UDCCRA __REG(0x40600404) /* Configuration register EPA */
++#define UDCCRB __REG(0x40600408) /* Configuration register EPB */
++#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */
++#define UDCCRD __REG(0x40600410) /* Configuration register EPD */
++#define UDCCRE __REG(0x40600414) /* Configuration register EPE */
++#define UDCCRF __REG(0x40600418) /* Configuration register EPF */
++#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */
++#define UDCCRH __REG(0x40600420) /* Configuration register EPH */
++#define UDCCRI __REG(0x40600424) /* Configuration register EPI */
++#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */
++#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */
++#define UDCCRL __REG(0x40600430) /* Configuration register EPL */
++#define UDCCRM __REG(0x40600434) /* Configuration register EPM */
++#define UDCCRN __REG(0x40600438) /* Configuration register EPN */
++#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */
++#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */
++#define UDCCRR __REG(0x40600444) /* Configuration register EPR */
++#define UDCCRS __REG(0x40600448) /* Configuration register EPS */
++#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */
++#define UDCCRU __REG(0x40600450) /* Configuration register EPU */
++#define UDCCRV __REG(0x40600454) /* Configuration register EPV */
++#define UDCCRW __REG(0x40600458) /* Configuration register EPW */
++#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */
++
++#define UDCCONR_CN (0x03 << 25) /* Configuration Number */
++#define UDCCONR_CN_S (25)
++#define UDCCONR_IN (0x07 << 22) /* Interface Number */
++#define UDCCONR_IN_S (22)
++#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */
++#define UDCCONR_AISN_S (19)
++#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */
++#define UDCCONR_EN_S (15)
++#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */
++#define UDCCONR_ET_S (13)
++#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */
++#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */
++#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */
++#define UDCCONR_ET_NU (0x00 << 13) /* Not used */
++#define UDCCONR_ED (1 << 12) /* Endpoint Direction */
++#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */
++#define UDCCONR_MPS_S (2)
++#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */
++#define UDCCONR_EE (1 << 0) /* Endpoint Enable */
++
++
++#define UDC_INT_FIFOERROR (0x2)
++#define UDC_INT_PACKETCMP (0x1)
++#define UDC_FNR_MASK (0x7ff)
++#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST)
++#define UDC_BCR_MASK (0x3ff)
+
+-#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
++#endif /* CONFIG_PXA27X */
+
+-/*
+- * USB Client Controller (incomplete)
+- */
+-#define UDCCR __REG(0x40600000)
+-#define UDCICR0 __REG(0x40600004)
+-#define UDCCIR0 __REG(0x40600008)
+-#define UDCISR0 __REG(0x4060000c)
+-#define UDCSIR1 __REG(0x40600010)
+-#define UDCFNR __REG(0x40600014)
+-#define UDCOTGICR __REG(0x40600018)
+-#define UDCOTGISR __REG(0x4060001c)
+-#define UP2OCR __REG(0x40600020)
+-#define UP3OCR __REG(0x40600024)
++#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
++
+
+ /*
+ * USB Host Controller
+diff -Naur u-boot-2008.10_original/include/common.h u-boot-2008.10/include/common.h
+--- u-boot-2008.10_original/include/common.h 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/include/common.h 2009-08-12 18:21:20.000000000 +0530
+@@ -675,6 +675,14 @@
+ int ftstc(int file);
+ int fgetc(int file);
+
++/*
++ * CONSOLE multiplexing.
++ */
++#ifdef CONFIG_CONSOLE_MUX
++#include <iomux.h>
++#endif
++
++
+ int pcmcia_init (void);
+
+ #ifdef CONFIG_STATUS_LED
+diff -Naur u-boot-2008.10_original/include/configs/regulus.h u-boot-2008.10/include/configs/regulus.h
+--- u-boot-2008.10_original/include/configs/regulus.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/include/configs/regulus.h 2010-02-11 14:03:21.000000000 +0530
+@@ -0,0 +1,515 @@
++/*
++ * (C) Copyright 2007
++ * Stefano Babic, DENX Gmbh, sbabic@denx.de
++ *
++ * (C) Copyright 2004
++ * Robert Whaley, Applied Data Systems, Inc. rwhaley@applieddata.net
++ *
++ * (C) Copyright 2002
++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * Configuation settings for the LUBBOCK board.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++#define CONFIG_PXA27X 1 /* This is an PXA27x CPU */
++#define REGULUS_CPU_NAME "PXA270"
++#define CONFIG_REGULUS 1 /* Board Name */
++#define LITTLEENDIAN 1 /* used by usb_ohci.c */
++#define __LITTLE_ENDIAN 1
++
++#define CONFIG_MMC 1
++#define BOARD_LATE_INIT 1
++//#define CONFIG_LCD 1
++#undef CONFIG_LCD
++#ifdef CONFIG_LCD
++#define CONFIG_CMD_BMP
++#define CONFIG_SHARP_REGULUS_LCD 1
++#define CFG_LOGO_CMAP_MODE 565
++#define CONFIG_BMP_16BPP 1
++#define LCD_BPP LCD_COLOR16
++#undef LCD_TEST_PATTERN
++//#define LCD_TEST_PATTERN 1
++//#define CONFIG_LCD_LOGO 1 /* print our logo on the LCD */
++#define CFG_WHITE_ON_BLACK 1
++#ifdef CONFIG_LCD_LOGO
++ #define CONFIG_LCD_INFO 1 /* ... and some board info */
++ #define CONFIG_SPLASH_SCREEN 1 /* ... with splashscreen support*/
++ #define CONFIG_LCD_INFO_BELOW_LOGO 1
++ #define CONFIG_LCD_DISPLAY_3P5_INCH_320_240
++ //#define CONFIG_LCD_DISPLAY_5P7_INCH_640_480
++ //#define CONFIG_LCD_DISPLAY_6P5_INCH_640_480
++ //#define CONFIG_CRT_DISPLAY_640_480
++#endif
++#else
++//#undef CONFIG_CMD_BMP
++#define CONFIG_LCD_DISPLAY_3P5_INCH_320_240
++//#define CONFIG_LCD_DISPLAY_5P7_INCH_640_480
++//#define CONFIG_LCD_DISPLAY_6P5_INCH_640_480
++//#define CONFIG_CRT_DISPLAY_640_480
++#endif
++
++
++#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++
++#define RTC /*This macro is used in lowlevel_init.S assembly file */
++
++/*
++ * SDRAM
++ *
++ */
++
++#define SDRAM128
++//#define SDRAM64
++//#define SDRAM32
++
++
++/*
++ *
++ * MEMCLK
++ *
++ */
++//#define MEMCLK208
++#define MEMCLK104
++//#define MEMCLK91
++
++/*
++ *
++ * SDCLK
++ *
++ */
++
++#define SDCLK_MEMCLK
++//#define SDCLK_MEMCLK_BY_2
++
++#ifdef MEMCLK208
++#undef SDCLK_MEMCLK
++#define SDCLK_MEMCLK_BY_2
++#elif defined(MEMCLK104)
++#undef SDCLK_MEMCLK_BY_2
++#define SDCLK_MEMCLK
++#endif
++
++
++/*
++ * ECON CAMERA
++ */
++#define ECON_CAMERA_ENABLE 1 // This macro is used for informing sdram memory size as 100MB instead of 128MB. The remaining 28MB is used by the CAMERA driver
++
++/*
++ * Size of malloc() pool
++ */
++#define CFG_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
++#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Hardware drivers
++ */
++
++/*
++ * select serial console configuration
++ */
++//#define CONFIG_SERIAL_MULTI
++//#define CONFIG_FFUART 1 /* we use FFUART on Conxs */
++//#define CONFIG_BTUART 1 /* we use BTUART on Conxs */
++#define CONFIG_STUART 1 /* we use STUART on Conxs */
++
++/* allow to overwrite serial and ethaddr */
++#define CONFIG_ENV_OVERWRITE
++
++#define CONFIG_BAUDRATE 115200
++
++#define CONFIG_DOS_PARTITION 1
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_MMC
++//#undef CONFIG_CMD_MMC
++#define CONFIG_CMD_FAT
++//#undef CONFIG_CMD_FAT
++#define CONFIG_CMD_IMLS
++//#undef CONFIG_CMD_IMLS
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_USB
++//#undef CONFIG_CMD_USB
++
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_DATE
++#define CONFIG_CMD_CACHE
++#define CONFIG_CMD_JFFS2
++#define CONFIG_CMD_EXT2
++#define CONFIG_CMD_NAND
++
++#define CONFIG_HARD_I2C 1
++#define CONFIG_RTC_DS1307 1
++#define CFG_I2C_SPEED 50000
++#define CFG_I2C_SLAVE 0x68 /* Dallas DS1338 RTC Chip's I2C SLAVE Address */
++#define CFG_I2C_RTC_ADDR 0x68 /* Dallas DS1338 RTC Chip's I2C SLAVE Address */
++#define CFG_I2C_INIT_BOARD 1
++
++/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
++
++#undef CONFIG_SHOW_BOOT_PROGRESS
++
++#define CONFIG_BOOTDELAY 2
++#define CONFIG_SERVERIP 192.168.0.89
++#define CONFIG_IPADDR 192.168.0.110
++#define CONFIG_BOOTCOMMAND "run boot_sd"
++#define CONFIG_NETDEV "eth0"
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_ETHADDR 00:12:33:55:cc:aa
++#if ECON_CAMERA_ENABLE
++#define CONFIG_BOOTARGS "console=ttyS2,115200 "\
++ " rw root=/dev/mtdblock4 rootfstype=jffs2 mem=100M"
++#else
++#define CONFIG_BOOTARGS "console=ttyS2,115200 "\
++ " rw root=/dev/mtdblock4 rootfstype=jffs2 mem=128M"
++#endif
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "boot_flash=" "bootm 0xC0000\0" \
++ "display_type=" "lcd3p5\0" \
++ "stdout=" "serial\0" \
++ "stderr=" "serial\0" \
++ "stdin=" "serial\0" \
++ "kgdb=" "off\0" \
++ "get_nor_kernel=" "cp.l c0000 a0000000 400000\0" \
++ "get_sd_kernel=" "mmcinit; fatload mmc 0 a0000000 uImage-2.6.25\0" \
++ "bootargs_nor=" "root=/dev/mtdblock4 rootfstype=jffs2\0" \
++ "bootargs_sd=" "root=/dev/mmcblk0p2 rootfstype=ext3 rootwait\0" \
++ "boot_nor=" "run get_nor_kernel; setenv bootargs $bootargs $bootargs_nor; bootm a0000000\0" \
++ "boot_sd=" "run get_sd_kernel; setenv bootargs $bootargs $bootargs_sd; bootm a0000000\0"
++
++
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++/* #define CONFIG_INITRD_TAG 1 */
++
++#if defined(CONFIG_CMD_KGDB)
++#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
++#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
++#endif
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CFG_HUSH_PARSER 1
++#define CFG_PROMPT_HUSH_PS2 "> "
++
++#define CFG_LONGHELP /* undef to save memory */
++#ifdef CFG_HUSH_PARSER
++#define CFG_PROMPT "REGULUS=> " /* Monitor Command Prompt */
++#else
++#define CFG_PROMPT "REGULUS=> " /* Monitor Command Prompt */
++#endif
++#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
++#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
++#define CFG_MAXARGS 16 /* max number of command args */
++#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
++#define CFG_DEVICE_NULLDEV 1
++
++#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */
++#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */
++
++#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CFG_LOAD_ADDR 0xa0000000 /* default load address */
++
++#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
++#define CFG_CPUSPEED 0x207 /* need to look more closely, I think this is Turbo = 2x, L=91Mhz */
++
++ /* valid baudrates */
++#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++#define CFG_MMC_BASE 0xF0000000
++
++/*
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++#endif
++
++/*
++ * Physical Memory Map
++ */
++#ifdef SDRAM128
++#warning "SDRAM128 is selected"
++#define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */
++#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB */
++#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */
++#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */
++#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */
++#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */
++#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */
++#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */
++
++#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
++
++#define CFG_DRAM_BASE 0xa0000000
++#define CFG_DRAM_SIZE 0x08000000
++#elif defined(SDRAM64)
++#warning "SDRAM64 is selected"
++#define CONFIG_NR_DRAM_BANKS 4 /* we have 2 banks of DRAM */
++#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */
++#define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */
++#define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 MB */
++#define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */
++#define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */
++#define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */
++#define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */
++
++#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
++
++#define CFG_DRAM_BASE 0xa0000000
++#define CFG_DRAM_SIZE 0x04000000
++#endif
++
++#define CFG_FLASH_BASE PHYS_FLASH_1
++
++
++/* JFFS Partition offset set */
++#define CFG_JFFS2_FIRST_BANK 0
++#define CFG_JFFS2_NUM_BANKS 1
++/* 2MB and 512K is reserved for u-boot and kernel */
++#define CFG_JFFS2_FIRST_SECTOR 24
++
++
++/*
++ * Board NAND Infomation
++ */
++#if 0
++#define CONFIG_JFFS2_DEV "nand0"
++#define CONFIG_JFFS2_NAND 1
++#define CONFIG_JFFS2_NAND_DEV 0 /* nand device jffs2 lives on */
++#define CONFIG_JFFS2_NAND_OFF 0 /* start of jffs2 partition */
++#define CONFIG_JFFS2_NAND_SIZE (512*1024*1024) /* size of jffs2 partition */
++#define CONFIG_MTD_NAND_ECC_JFFS2 1
++#define CONFIG_JFFS2_PART_SIZE (512*1024*1024)
++#define CONFIG_JFFS2_PART_OFFSET 0x00
++#endif
++
++#define CFG_NAND_ADDR 0x2C000000
++#define CFG_NAND_BASE CFG_NAND_ADDR
++#define CFG_MAX_NAND_DEVICE 1
++#define SECTORSIZE 2048
++#define ADDR_COLUMN 1
++#define ADDR_PAGE 2
++#define ADDR_COLUMN_PAGE 3
++#define NAND_ChipID_UNKNOWN 0x00
++#define NAND_MAX_FLOORS 1
++#define NAND_MAX_CHIPS 1
++
++#define REGULUS_NAND_CLE (1<<21) /* A21 -> Command Enable */
++#define REGULUS_NAND_ALE (1<<22) /* A22 -> Address Enable */
++
++#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | REGULUS_NAND_CLE) = (__u8)(d); } while(0)
++#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | REGULUS_NAND_ALE) = (__u8)(d); } while(0)
++#define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0)
++#define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr))
++
++/*
++ * GPIO settings
++ */
++#define CFG_GPSR0_VAL 0x00018000
++#define CFG_GPSR1_VAL 0x00000000
++#define CFG_GPSR2_VAL 0x400dc000
++#define CFG_GPSR3_VAL 0x00000000
++#define CFG_GPCR0_VAL 0x00000000
++#define CFG_GPCR1_VAL 0x00000000
++#define CFG_GPCR2_VAL 0x00000000
++#define CFG_GPCR3_VAL 0x00000000
++#define CFG_GPDR0_VAL 0x00018000
++#define CFG_GPDR1_VAL 0x00028801
++#define CFG_GPDR2_VAL 0x520dc000
++#define CFG_GPDR3_VAL 0x0001E000
++#define CFG_GAFR0_L_VAL 0x801c0000
++#define CFG_GAFR0_U_VAL 0x00000013
++#define CFG_GAFR1_L_VAL 0x6990100A
++#define CFG_GAFR1_U_VAL 0x00000008
++#define CFG_GAFR2_L_VAL 0xA0000000
++#define CFG_GAFR2_U_VAL 0x010900F2
++#define CFG_GAFR3_L_VAL 0x54000003
++#define CFG_GAFR3_U_VAL 0x00002401
++#define CFG_GRER0_VAL 0x00000000
++#define CFG_GRER1_VAL 0x00000000
++#define CFG_GRER2_VAL 0x00000000
++#define CFG_GRER3_VAL 0x00000000
++#define CFG_GFER0_VAL 0x00000000
++#define CFG_GFER1_VAL 0x00000000
++#define CFG_GFER2_VAL 0x00000000
++#define CFG_GFER3_VAL 0x00000020
++
++
++#define CFG_PSSR_VAL 0x20 /* CHECK */
++
++/*
++ * Clock settings
++ */
++#define CFG_CKEN 0x01FFFFFF /* CHECK */
++#define CFG_CCCR 0x02000290 /* 520Mhz */
++
++/*
++ * Memory settings
++ */
++
++#define CFG_MSC0_VAL 0x4df84df0
++#define CFG_MSC1_VAL 0x7ff87ff4
++#define CFG_MSC2_VAL 0xa26936d4
++#define CFG_MDCNFG_VAL 0x880009C9
++#define CFG_MDREFR_VAL 0x20ca201e
++#define CFG_MDMRS_VAL 0x00220022
++
++#define CFG_FLYCNFG_VAL 0x00000000
++#define CFG_SXCNFG_VAL 0x40044004
++
++/*
++ * PCMCIA and CF Interfaces
++ */
++#define CFG_MECR_VAL 0x00000001
++#define CFG_MCMEM0_VAL 0x00004204
++#define CFG_MCMEM1_VAL 0x00010204
++#define CFG_MCATT0_VAL 0x00010504
++#define CFG_MCATT1_VAL 0x00010504
++#define CFG_MCIO0_VAL 0x00008407
++#define CFG_MCIO1_VAL 0x0000c108
++
++#define CONFIG_DRIVER_AX88796B 1
++
++#define CONFIG_USB_OHCI_NEW 1
++#define CFG_USB_OHCI_BOARD_INIT 1
++#define CFG_USB_OHCI_MAX_ROOT_PORTS 3
++#define CFG_USB_OHCI_REGS_BASE 0x4C000000
++#define CFG_USB_OHCI_SLOT_NAME "trizepsiv"
++#define CONFIG_USB_STORAGE 1
++#define CFG_USB_OHCI_CPU_INIT 1
++
++/*
++ * FLASH and environment organization
++ */
++
++#define BASIC_BOOT_START_ADDR 0x00000000
++#define BASIC_BOOT_END_ADDR 0x00007FFF
++#define BASIC_BOOT_SIZE 0x00008000 //32KB
++
++#define MAC_ADDRESS_START_ADDR 0x00008000
++#define MAC_ADDRESS_END_ADDR 0x0000FFFF
++#define MAC_ADDRESS_SIZE 0x00008000 //32KB
++
++#define RSV_1_START_ADDR 0x00010000
++#define RSV_1_END_ADDR 0x00017FFF
++#define RSV_1_SIZE 0x00008000 //32KB
++
++#define RSV_2_START_ADDR 0x00018000
++#define RSV_2_END_ADDR 0x0001FFFF
++#define RSV_2_SIZE 0x00008000 //32KB
++
++#define U_BOOT_START_ADDR 0x00020000
++#define U_BOOT_END_ADDR 0x0009FFFF
++#define U_BOOT_SIZE 0x00080000 //512KB
++
++#define U_BOOT_ENV_START_ADDR 0x000A0000
++#define U_BOOT_ENV_END_ADDR 0x000BFFFF
++#define U_BOOT_ENV_SIZE 0x00020000 //128KB
++
++#define KERNEL_IMAGE_START_ADDR 0x000C0000
++#define KERNEL_IMAGE_END_ADDR 0x004BFFFF
++#define KERNEL_IMAGE_SIZE 0x00400000 //4MB
++
++#define ROOT_FILESYSTEM_START_ADDR 0x004C0000
++#define ROOT_FILESYSTEM_END_ADDR 0x017FFFFF
++#define ROOT_FILESYSTEM_SIZE 0x01340000 //19.25MB
++
++#define USER_APP_FLASH_START_ADDR 0x01800000
++#define USER_APP_FLASH_END_ADDR 0x01FFFFFF
++#define USER_APP_FLASH_SIZE 0x00800000 //8MB
++
++#define CFG_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER 1
++
++#define CFG_MONITOR_BASE 0
++#define CFG_MONITOR_LEN (BASIC_BOOT_SIZE+MAC_ADDRESS_SIZE+RSV_1_SIZE+RSV_2_SIZE+U_BOOT_SIZE)
++
++#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
++#define CFG_MAX_FLASH_SECT 4 + 255 /* max number of sectors on one chip */
++
++/* timeout values are in ticks */
++#define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */
++#define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */
++
++/* write flash less slowly */
++#define CFG_FLASH_USE_BUFFER_WRITE 1
++
++/* Flash environment locations */
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_ADDR (PHYS_FLASH_1 + CFG_MONITOR_LEN) /* Addr of Environment Sector */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment */
++#define CONFIG_ENV_SECT_SIZE 0x20000 /* Total Size of Environment Sector */
++
++
++#define __ADDERUSB__
++
++#if 0
++#define CONFIG_USB_DEVICE /* Include UDC driver */
++#define CONFIG_USB_TTY /* Bind the TTY driver to UDC */
++//#define CFG_USB_EXTC_CLK 0x02 /* Oscillator on EXTC_CLK 2 */
++//#define CFG_USB_BRG_CLK 0x04 /* or use Baud rate generator 0x04 */
++/* If you have a USB-IF assigned VendorID then you may wish to define
++ * your own vendor specific values either in BoardName.h or directly in
++ * usbd_vendor_info.h
++ */
++
++/*
++#define CONFIG_USBD_MANUFACTURER "e-con Systems"
++#define CONFIG_USBD_PRODUCT_NAME "Das U-Boot"
++#define CONFIG_USBD_VENDORID 0xFFFF
++#define CONFIG_USBD_PRODUCTID_GSERIAL 0xFFFF
++#define CONFIG_USBD_PRODUCTID_CDCACM 0xFFFE
++*/
++#endif
++
++
++
++/* Allow console in serial and other devices like LCD and USB at the same time */
++#define CONFIG_CONSOLE_MUX 1
++#define CFG_CONSOLE_IS_IN_ENV /* Console is in env */
++
++
++#endif /* __CONFIG_H */
+diff -Naur u-boot-2008.10_original/include/iomux.h u-boot-2008.10/include/iomux.h
+--- u-boot-2008.10_original/include/iomux.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/include/iomux.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,48 @@
++/*
++ * (C) Copyright 2008
++ * Gary Jennejohn, DENX Software Engineering GmbH, [EMAIL PROTECTED]
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ *This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef _IO_MUX_H
++#define _IO_MUX_H
++
++#include <devices.h>
++
++/*
++ * Stuff required to support console multiplexing.
++ */
++
++/*
++ * Pointers to devices used for each file type. Defined in console.c
++ * but storage is allocated in iomux.c.
++ */
++extern device_t **console_devices[MAX_FILES];
++/*
++ * The count of devices assigned to each FILE. Defined in console.c
++ * and populated in iomux.c.
++ */
++extern int cd_count[MAX_FILES];
++
++int iomux_doenv(const int, const char *);
++void iomux_printdevs(const int);
++device_t *search_device(int, char *);
++
++#endif /* _IO_MUX_H */
+diff -Naur u-boot-2008.10_original/include/lcd.h u-boot-2008.10/include/lcd.h
+--- u-boot-2008.10_original/include/lcd.h 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/include/lcd.h 2009-08-12 18:21:20.000000000 +0530
+@@ -77,7 +77,7 @@
+
+ extern vidinfo_t panel_info;
+
+-#elif defined CONFIG_PXA250
++#elif defined CONFIG_PXA250 || defined(CONFIG_PXA27X)
+ /*
+ * PXA LCD DMA descriptor
+ */
+@@ -307,7 +307,7 @@
+ #if LCD_BPP == LCD_MONOCHROME
+ # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
+ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+-#elif LCD_BPP == LCD_COLOR8
++#elif LCD_BPP == LCD_COLOR8 || LCD_BPP == LCD_COLOR16
+ # define COLOR_MASK(c) (c)
+ #else
+ # error Unsupported LCD BPP.
+diff -Naur u-boot-2008.10_original/include/usbdcore.h u-boot-2008.10/include/usbdcore.h
+--- u-boot-2008.10_original/include/usbdcore.h 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/include/usbdcore.h 2009-08-12 18:21:20.000000000 +0530
+@@ -44,7 +44,7 @@
+ #define usberr(fmt,args...) do{}while(0)
+ #endif
+
+-#if 0
++#if 1
+ #define usbdbg(fmt,args...) serial_printf("debug: %s(), %d: "fmt"\n",__FUNCTION__,__LINE__,##args)
+ #else
+ #define usbdbg(fmt,args...) do{}while(0)
+diff -Naur u-boot-2008.10_original/include/usbdcore_pxa27x.h u-boot-2008.10/include/usbdcore_pxa27x.h
+--- u-boot-2008.10_original/include/usbdcore_pxa27x.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/include/usbdcore_pxa27x.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,70 @@
++/*
++ * PXA27x register declarations and HCD data structures
++ *
++ * Copyright (C) 2007 Rodolfo Giometti <giome...@linux.it>
++ * Copyright (C) 2007 Eurotech S.p.A. <i...@eurotech.it>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++
++#ifndef __USBDCORE_PXA270X_H__
++#define __USBDCORE_PXA270X_H__
++
++#include <asm/byteorder.h>
++
++/* Endpoint 0 states */
++#define EP0_IDLE 0
++#define EP0_IN_DATA 1
++#define EP0_OUT_DATA 2
++#define EP0_XFER_COMPLETE 3
++
++
++/* Endpoint parameters */
++#define MAX_ENDPOINTS 4
++#define EP_MAX_PACKET_SIZE 64
++
++#define EP0_MAX_PACKET_SIZE 16
++#define UDC_OUT_ENDPOINT 0x02
++#define UDC_OUT_PACKET_SIZE EP_MAX_PACKET_SIZE
++#define UDC_IN_ENDPOINT 0x01
++#define UDC_IN_PACKET_SIZE EP_MAX_PACKET_SIZE
++#define UDC_INT_ENDPOINT 0x05
++#define UDC_INT_PACKET_SIZE EP_MAX_PACKET_SIZE
++#define UDC_BULK_PACKET_SIZE EP_MAX_PACKET_SIZE
++
++void udc_irq(void);
++/* Flow control */
++void udc_set_nak(int epid);
++void udc_unset_nak(int epid);
++
++/* Higher level functions for abstracting away from specific device */
++int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
++
++int udc_init(void);
++
++void udc_enable(struct usb_device_instance *device);
++void udc_disable(void);
++
++void udc_connect(void);
++void udc_disconnect(void);
++
++void udc_startup_events(struct usb_device_instance *device);
++void udc_setup_ep(struct usb_device_instance *device,
++ unsigned int ep, struct usb_endpoint_instance *endpoint);
++
++#endif
++
+diff -Naur u-boot-2008.10_original/include/wince.h u-boot-2008.10/include/wince.h
+--- u-boot-2008.10_original/include/wince.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/include/wince.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,450 @@
++#ifndef __WINCE_H__
++#define __WINCE_H__
++
++#define CE_DOFFSET (net->align_offset + ETHER_HDR_SIZE + IP_HDR_SIZE)
++
++/* Bin image parse results */
++
++#define CE_PR_EOF 0
++#define CE_PR_MORE 1
++#define CE_PR_ERROR 2
++
++
++
++
++#pragma pack(1)
++
++/* Edbg BOOTME packet structures */
++
++typedef struct
++{
++ unsigned int id; /* Protocol identifier ("EDBG" on the wire) */
++ unsigned char service; /* Service identifier */
++ unsigned char flags; /* Flags (see defs below) */
++ unsigned char seqNum; /* For detection of dropped packets */
++ unsigned char cmd; /* For administrative messages */
++ unsigned char data[1]; /* Cmd specific data starts here (format is determined by */
++ /* Cmd, len is determined by UDP packet size) */
++}
++eth_dbg_hdr;
++
++#define OFFSETOF(s,m) ((unsigned int)&(((s*)0)->m))
++#define EDBG_DATA_OFFSET (OFFSETOF(eth_dbg_hdr, data))
++
++typedef struct
++{
++ unsigned char versionMajor; // Bootloader version
++ unsigned char versionMinor; // Bootloader version
++ unsigned char macAddr[6]; // Ether address of device (net byte order)
++ unsigned int ipAddr; // IP address of device (net byte order)
++ char platformId[17]; // Platform Id string (NULL terminated)
++ char deviceName[17]; // Device name string (NULL terminated). Should include
++ // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
++ unsigned char cpuId; // CPU identifier (upper nibble = type)
++ // The following fields were added in CE 3.0 Platform Builder release
++ unsigned char bootmeVer; // BOOTME Version. Must be in the range 2 -> EDBG_CURRENT_BOOTME_VERSION, or
++ // remaining fields will be ignored by Eshell and defaults will be used.
++ unsigned int bootFlags; // Boot Flags
++ unsigned short downloadPort; // Download Port (net byte order) (0 -> EDBG_DOWNLOAD_PORT)
++ unsigned short svcPort; // Service Port (net byte order) (0 -> EDBG_SVC_PORT)
++
++} edbg_bootme_data;
++
++// Packet size
++
++#define BOOTME_PKT_SIZE (EDBG_DATA_OFFSET + sizeof(edbg_bootme_data))
++
++// WinCE .BIN file format signature
++
++#define CE_BIN_SIGN "B000FF\x0A"
++#define CE_BIN_SIGN_LEN 7
++
++
++typedef struct
++{
++ unsigned char sign[ CE_BIN_SIGN_LEN ];
++ unsigned int rtiPhysAddr;
++ unsigned int rtiPhysLen;
++}
++ce_bin_hdr;
++
++typedef struct
++{
++ unsigned int physAddr;
++ unsigned int physLen;
++ unsigned int chkSum;
++ unsigned char data[ 1 ];
++}
++ce_bin_entry;
++
++// CE ROM image structures
++
++#define ROM_SIGNATURE_OFFSET 0x40 // Offset from the image's physfirst address to the ROM signature.
++#define ROM_SIGNATURE 0x43454345 // Signature
++#define ROM_TOC_POINTER_OFFSET 0x44 // Offset from the image's physfirst address to the TOC pointer.
++#define ROM_TOC_OFFSET_OFFSET 0x48 // Offset from the image's physfirst address to the TOC offset (from physfirst).
++
++typedef struct
++{
++ unsigned int dllfirst; // first DLL address
++ unsigned int dlllast; // last DLL address
++ unsigned int physfirst; // first physical address
++ unsigned int physlast; // highest physical address
++ unsigned int nummods; // number of TOCentry's
++ unsigned int ramStart; // start of RAM
++ unsigned int ramFree; // start of RAM free space
++ unsigned int ramEnd; // end of RAM
++ unsigned int copyEntries; // number of copy section entries
++ unsigned int copyOffset; // offset to copy section
++ unsigned int profileLen; // length of PROFentries RAM
++ unsigned int profileOffset; // offset to PROFentries
++ unsigned int numfiles; // number of FILES
++ unsigned int kernelFlags; // optional kernel flags from ROMFLAGS .bib config option
++ unsigned int fsRamPercent; // Percentage of RAM used for filesystem
++ // from FSRAMPERCENT .bib config option
++ // byte 0 = #4K chunks/Mbyte of RAM for filesystem 0-2Mbytes 0-255
++ // byte 1 = #4K chunks/Mbyte of RAM for filesystem 2-4Mbytes 0-255
++ // byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255
++ // byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255
++
++ unsigned int drivglobStart; // device driver global starting address
++ unsigned int drivglobLen; // device driver global length
++ unsigned short cpuType; // CPU (machine) Type
++ unsigned short miscFlags; // Miscellaneous flags
++ void* extensions; // pointer to ROM Header extensions
++ unsigned int trackingStart; // tracking memory starting address
++ unsigned int trackingLen; // tracking memory ending address
++}
++ce_rom_hdr;
++
++// Win32 FILETIME strcuture
++
++typedef struct
++{
++ unsigned int loDateTime;
++ unsigned int hiDateTime;
++}
++ce_file_time;
++
++// Table Of Contents entry structure
++
++typedef struct
++{
++ unsigned int fileAttributes;
++ ce_file_time fileTime;
++ unsigned int fileSize;
++ char* fileName;
++ unsigned int e32Offset; // Offset to E32 structure
++ unsigned int o32Offset; // Offset to O32 structure
++ unsigned int loadOffset; // MODULE load buffer offset
++}
++ce_toc_entry;
++
++typedef struct
++{ /* Extra information header block */
++ unsigned int rva; /* Virtual relative address of info */
++ unsigned int size; /* Size of information block */
++}
++e32_info;
++
++#define ROM_EXTRA 9
++
++typedef struct
++{
++ unsigned short e32_objcnt; /* Number of memory objects */
++ unsigned short e32_imageflags; /* Image flags */
++ unsigned int e32_entryrva; /* Relative virt. addr. of entry point */
++ unsigned int e32_vbase; /* Virtual base address of module */
++ unsigned short e32_subsysmajor;/* The subsystem major version number */
++ unsigned short e32_subsysminor;/* The subsystem minor version number */
++ unsigned int e32_stackmax; /* Maximum stack size */
++ unsigned int e32_vsize; /* Virtual size of the entire image */
++ unsigned int e32_sect14rva; /* section 14 rva */
++ unsigned int e32_sect14size; /* section 14 size */
++ unsigned int e32_timestamp; /* Time EXE/DLL was created/modified */
++ e32_info e32_unit[ ROM_EXTRA ]; /* Array of extra info units */
++ unsigned short e32_subsys; /* The subsystem type */
++}
++e32_rom;
++
++
++
++// OS config msg
++
++#define EDBG_FL_DBGMSG 0x01 // Debug messages
++#define EDBG_FL_PPSH 0x02 // Text shell
++#define EDBG_FL_KDBG 0x04 // Kernel debugger
++#define EDBG_FL_CLEANBOOT 0x08 // Force a clean boot
++
++typedef struct
++{
++ unsigned char flags; // Flags that will be used to determine what features are
++ // enabled over ethernet (saved in driver globals by bootloader)
++ unsigned char kitlTransport; // Tells KITL which transport to start
++
++ // The following specify addressing info, only valid if the corresponding
++ // flag is set in the Flags field.
++
++ unsigned int dbgMsgIPAddr;
++ unsigned short dbgMsgPort;
++ unsigned int ppshIPAddr;
++ unsigned short ppshPort;
++ unsigned int kdbgIPAddr;
++ unsigned short kdbgPort;
++
++} edbg_os_config_data;
++
++
++
++// Driver globals structure
++// Used to pass driver globals info from RedBoot to WinCE core
++
++#define DRV_GLB_SIGNATURE 0x424C4744 // "DGLB"
++
++typedef struct
++{
++ unsigned int signature; // Signature
++ unsigned int flags; // Misc flags
++ unsigned int ipAddr; // IP address of device (net byte order)
++ unsigned int ipGate; // IP address of gateway (net byte order)
++ unsigned int ipMask; // Subnet mask
++ unsigned char macAddr[6]; // Ether address of device (net byte order)
++ edbg_os_config_data edbgConfig; // EDBG services info
++}
++ce_driver_globals;
++
++
++#pragma pack()
++
++
++
++typedef struct
++{
++ unsigned int rtiPhysAddr;
++ unsigned int rtiPhysLen;
++ unsigned int ePhysAddr;
++ unsigned int ePhysLen;
++ unsigned int eChkSum;
++
++ unsigned int eEntryPoint;
++ unsigned int eRamStart;
++ unsigned int eRamLen;
++ unsigned int eDrvGlb;
++
++ unsigned char parseState;
++ unsigned int parseChkSum;
++ int parseLen;
++ unsigned char* parsePtr;
++ int secion;
++
++ int dataLen;
++ unsigned char* data;
++
++ int binLen;
++ int endOfBin;
++
++ edbg_os_config_data edbgConfig;
++}
++ce_bin;
++
++
++
++
++
++
++
++
++// IPv4 support
++
++// Socket/connection information
++struct sockaddr_in {
++ IPaddr_t sin_addr;
++ unsigned short sin_port;
++ unsigned short sin_family;
++ short sin_len;
++};
++#define AF_INET 1
++#define INADDR_ANY 0
++
++
++
++
++
++
++
++
++
++typedef struct
++{
++ int verbose;
++ int link;
++ struct sockaddr_in locAddr;
++ struct sockaddr_in srvAddrSend;
++ struct sockaddr_in srvAddrRecv;
++ int gotJumpingRequest;
++ unsigned char secNum;
++ unsigned short blockNum;
++ int dataLen;
++ int align_offset;
++ int got_packet_4me;
++ unsigned char data[PKTSIZE_ALIGN];
++}
++ce_net;
++
++
++struct timeval {
++ long tv_sec; /* seconds */
++ long tv_usec; /* and microseconds */
++};
++
++
++
++// Default UDP ports used for Ethernet download and EDBG messages. May be overriden
++// by device in BOOTME message.
++
++#define EDBG_DOWNLOAD_PORT 980 // For downloading images to bootloader via TFTP
++#define EDBG_SVC_PORT 981 // Other types of transfers
++
++// Byte string for Id field (note - must not conflict with valid TFTP
++// opcodes (0-5), as we share the download port with TFTP)
++
++#define EDBG_ID 0x47424445 // "EDBG"
++
++// Defs for reserved values of the Service field
++
++#define EDBG_SVC_DBGMSG 0 // Debug messages
++#define EDBG_SVC_PPSH 1 // Text shell and PPFS file system
++#define EDBG_SVC_KDBG 2 // Kernel debugger
++#define EDBG_SVC_ADMIN 0xFF // Administrative messages
++
++// Commands
++
++#define EDBG_CMD_READ_REQ 1 // Read request
++#define EDBG_CMD_WRITE_REQ 2 // Write request
++#define EDBG_CMD_WRITE 3 // Host ack
++#define EDBG_CMD_WRITE_ACK 4 // Target ack
++#define EDBG_CMD_ERROR 5 // Error
++
++// Service Ids from 3-FE are used for user apps
++
++#define NUM_DFLT_EDBG_SERVICES 3
++
++// Size of send and receive windows (except for stop and wait mode)
++
++#define EDBG_WINDOW_SIZE 8
++
++// The window size can be negotiated up to this amount if a client provides
++// enough memory.
++#define EDBG_MAX_WINDOW_SIZE 16
++
++// Max size for an EDBG frame. Based on ethernet MTU - protocol overhead.
++// Limited to one MTU because we don't do IP fragmentation on device.
++
++#define EDBG_MAX_DATA_SIZE 1446
++
++// Defs for Flags field.
++#define EDBG_FL_FROM_DEV 0x01 // Set if message is from the device
++#define EDBG_FL_NACK 0x02 // Set if frame is a nack
++#define EDBG_FL_ACK 0x04 // Set if frame is an ack
++#define EDBG_FL_SYNC 0x08 // Can be used to reset sequence # to 0
++#define EDBG_FL_ADMIN_RESP 0x10 // For admin messages, indicate whether this is a response
++
++// Definitions for Cmd field (used for administrative messages)
++// Msgs from device
++
++#define EDBG_CMD_BOOTME 0 // Initial bootup message from device
++
++// Msgs from PC
++
++#define EDBG_CMD_SETDEBUG 1 // Used to set debug zones on device (TBD)
++#define EDBG_CMD_JUMPIMG 2 // Command to tell bootloader to jump to existing
++ // flash or RAM image. Data is same as CMD_OS_CONFIG.
++#define EDBG_CMD_OS_CONFIG 3 // Configure OS for debug ethernet services
++#define EDBG_CMD_QUERYINFO 4 // "Ping" device, and return information (same fmt as bootme)
++#define EDBG_CMD_RESET 5 // Command to have platform perform SW reset (e.g. so it
++ // can be reprogrammed). Support for this command is
++ // processor dependant, and may not be implemented
++ // on all platforms (requires HW mods for Odo).
++
++// Msgs from device or PC
++
++#define EDBG_CMD_SVC_CONFIG 6
++#define EDBG_CMD_SVC_DATA 7
++
++#define EDBG_CMD_DEBUGBREAK 8 // Break into debugger
++
++// Structures for Data portion of EDBG packets
++
++#define EDBG_MAX_DEV_NAMELEN 16
++
++// BOOTME message - Devices broadcast this message when booted to request configuration
++
++#define EDBG_CURRENT_BOOTME_VERSION 2
++
++//
++// Capability and boot Flags for dwBootFlags in EDBG_BOOTME_DATA
++// LOWORD for boot flags, HIWORD for capability flags
++//
++
++// Always download image
++
++#define EDBG_BOOTFLAG_FORCE_DOWNLOAD 0x00000001
++
++// Support passive-kitl
++
++#define EDBG_CAPS_PASSIVEKITL 0x00010000
++
++// Defs for CPUId
++
++#define EDBG_CPU_TYPE_SHX 0x10
++#define EDBG_CPU_TYPE_MIPS 0x20
++#define EDBG_CPU_TYPE_X86 0x30
++#define EDBG_CPU_TYPE_ARM 0x40
++#define EDBG_CPU_TYPE_PPC 0x50
++#define EDBG_CPU_TYPE_THUMB 0x60
++
++#define EDBG_CPU_SH3 (EDBG_CPU_TYPE_SHX | 0)
++#define EDBG_CPU_SH4 (EDBG_CPU_TYPE_SHX | 1)
++#define EDBG_CPU_R3000 (EDBG_CPU_TYPE_MIPS | 0)
++#define EDBG_CPU_R4101 (EDBG_CPU_TYPE_MIPS | 1)
++#define EDBG_CPU_R4102 (EDBG_CPU_TYPE_MIPS | 2)
++#define EDBG_CPU_R4111 (EDBG_CPU_TYPE_MIPS | 3)
++#define EDBG_CPU_R4200 (EDBG_CPU_TYPE_MIPS | 4)
++#define EDBG_CPU_R4300 (EDBG_CPU_TYPE_MIPS | 5)
++#define EDBG_CPU_R5230 (EDBG_CPU_TYPE_MIPS | 6)
++#define EDBG_CPU_R5432 (EDBG_CPU_TYPE_MIPS | 7)
++#define EDBG_CPU_i486 (EDBG_CPU_TYPE_X86 | 0)
++#define EDBG_CPU_SA1100 (EDBG_CPU_TYPE_ARM | 0)
++#define EDBG_CPU_ARM720 (EDBG_CPU_TYPE_ARM | 1)
++#define EDBG_CPU_PPC821 (EDBG_CPU_TYPE_PPC | 0)
++#define EDBG_CPU_PPC403 (EDBG_CPU_TYPE_PPC | 1)
++#define EDBG_CPU_THUMB720 (EDBG_CPU_TYPE_THUMB | 0)
++
++
++
++#endif
++
++
++int ce_bin_load(void* image, int imglen);
++int ce_is_bin_image(void* image, int imglen);
++void ce_bin_init_parser(void);
++int ce_bin_parse_next(void* parseBuffer, int len);
++void ce_init_bin(ce_bin* bin, unsigned char* dataBuffer);
++int ce_parse_bin(ce_bin* bin);
++int ce_lookup_ep_bin(ce_bin* bin);
++void ce_prepare_run_bin(ce_bin* bin);
++void ce_run_bin(ce_bin* bin);
++
++int ce_recv_frame(ce_net* net, int timeout);
++int ce_process_download(ce_net* net, ce_bin* bin);
++void ce_init_edbg_link(ce_net* net);
++void ce_process_edbg(ce_net* net, ce_bin* bin);
++
++int ce_recv_frame(ce_net* net, int timeout);
++int ce_process_download(ce_net* net, ce_bin* bin);
++void ce_init_edbg_link(ce_net* net);
++void ce_process_edbg(ce_net* net, ce_bin* bin);
++int ce_send_write_ack(ce_net* net);
++int ce_send_frame(ce_net* net);
++int ce_recv_packet(char *buf, int len, struct sockaddr_in *from, struct sockaddr_in *local, struct timeval *timeout);
++void ce_dump_block(unsigned char *ptr, int length);
+diff -Naur u-boot-2008.10_original/include/ymodem.h u-boot-2008.10/include/ymodem.h
+--- u-boot-2008.10_original/include/ymodem.h 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/include/ymodem.h 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,75 @@
++/* YMODEM support for bootldr
++ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
++ * Copyright (C) 2001 John G Dorsey
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * The author may be contacted via electronic mail at <john+@cs.cmu.edu>,
++ * or at the following address:
++ *
++ * John Dorsey
++ * Carnegie Mellon University
++ * HbH2201 - ICES
++ * 5000 Forbes Avenue
++ * Pittsburgh, PA 15213
++ */
++
++#if !defined(_YMODEM_H)
++#define _YMODEM_H
++
++#define PACKET_SEQNO_INDEX (1)
++#define PACKET_SEQNO_COMP_INDEX (2)
++
++#define PACKET_HEADER (3) /* start, block, block-complement */
++#define PACKET_TRAILER_CRC (2) /* CRC bytes */
++#define PACKET_TRAILER (1)
++#define PACKET_OVERHEAD_CRC (PACKET_HEADER + PACKET_TRAILER_CRC)
++#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
++#define PACKET_SIZE (128)
++#define PACKET_1K_SIZE (1024)
++
++#define FILE_NAME_LENGTH (255)
++#define FILE_SIZE_LENGTH (16)
++
++/* ASCII control codes: */
++#define SOH (0x01) /* start of 128-byte data packet */
++#define STX (0x02) /* start of 1024-byte data packet */
++#define EOT (0x04) /* end of transmission */
++#define ACK (0x06) /* receive OK */
++#define NAK (0x15) /* receiver error; retry */
++#define CAN (0x18) /* two of these in succession aborts transfer */
++#define CRC (0x43) /* use in place of first NAK for CRC mode */
++
++/* Iterations for delay loop, assumes caches on: */
++#define DELAY_UNIT (5000000) /*15000000*/
++#define AWAITKEY_UNIT (5000000)
++
++#define INITIAL_TIMEOUT (5) /*15*/
++#define CRC_TIMEOUT (3)
++#define NAK_TIMEOUT (10)
++
++/* Number of attempts at soliciting CRC mode from sender before falling
++ * back to arithmetic checksum:
++ */
++#define MAX_CRC_TRIES (5)
++
++/* Number of consecutive receive errors we will tolerate before giving
++ * up:
++ */
++#define MAX_ERRORS (5)
++
++extern unsigned int ymodem_receive(char *buf);
++
++#endif /* !define(_YMODEM_H) */
+diff -Naur u-boot-2008.10_original/lib_arm/board.c u-boot-2008.10/lib_arm/board.c
+--- u-boot-2008.10_original/lib_arm/board.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/lib_arm/board.c 2010-03-01 18:11:37.000000000 +0530
+@@ -38,6 +38,7 @@
+ * FIQ Stack: 00ebef7c
+ */
+
++
+ #include <common.h>
+ #include <command.h>
+ #include <malloc.h>
+@@ -47,6 +48,7 @@
+ #include <serial.h>
+ #include <nand.h>
+ #include <onenand_uboot.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
+
+ #ifdef CONFIG_DRIVER_SMC91111
+ #include "../drivers/net/smc91111.h"
+@@ -68,6 +70,9 @@
+ #define CONFIG_IDENT_STRING ""
+ #endif
+
++
++const char board_info_string[]="REGULUS Reference Platform Kit Rev-B";
++
+ const char version_string[] =
+ U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING;
+
+@@ -84,6 +89,270 @@
+ #include <i2c.h>
+ #endif
+
++#ifdef CONFIG_REGULUS
++extern int pxa_gpio_mode(int gpio_mode);
++int get_cpu_speed(void);
++int sdram_size_detect(void);
++extern void mdelay(int x);
++extern int set_core_frequency(int core_freq_value);
++extern int set_core_voltage(int core_volt_value);
++extern int do_unlock (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++
++#define CORE_FREQ_104M 104
++#define CORE_FREQ_208M 208
++#define CORE_FREQ_312M 312
++#define CORE_FREQ_416M 416
++#define CORE_FREQ_520M 520
++#define CORE_FREQ_624M 624
++
++#define CORE_VOLT_1P15V 115
++#define CORE_VOLT_1P25V 125
++#define CORE_VOLT_1P35V 135
++#define CORE_VOLT_1P45V 145
++#define CORE_VOLT_1P55V 155
++
++/*
++
++driver supports the following options, either via
++options=<OPTIONS> when modular or video=pxafb:<OPTIONS> when built in.
++
++For example:
++ modprobe pxafb options=mode:640x480-8,passive
++or on the kernel command line
++ video=pxafb:mode:640x480-8,passive
++
++mode:XRESxYRES[-BPP]
++ XRES == LCCR1_PPL + 1
++ YRES == LLCR2_LPP + 1
++ The resolution of the display in pixels
++ BPP == The bit depth. Valid values are 1, 2, 4, 8 and 16.
++
++pixclock:PIXCLOCK
++ Pixel clock in picoseconds
++
++left:LEFT == LCCR1_BLW + 1
++right:RIGHT == LCCR1_ELW + 1
++hsynclen:HSYNC == LCCR1_HSW + 1
++upper:UPPER == LCCR2_BFW
++lower:LOWER == LCCR2_EFW
++vsynclen:VSYNC == LCCR2_VSW + 1
++ Display margins and sync times
++
++color | mono => LCCR0_CMS
++ umm...
++
++active | passive => LCCR0_PAS
++ Active (TFT) or Passive (STN) display
++
++single | dual => LCCR0_SDS
++ Single or dual panel passive display
++
++4pix | 8pix => LCCR0_DPD
++ 4 or 8 pixel monochrome single panel data
++
++hsync:HSYNC
++vsync:VSYNC
++ Horizontal and vertical sync. 0 => active low, 1 => active
++ high.
++
++dpc:DPC
++ Double pixel clock. 1=>true, 0=>false
++
++outputen:POLARITY
++ Output Enable Polarity. 0 => active low, 1 => active high
++
++pixclockpol:POLARITY
++ pixel clock polarity
++ 0 => falling edge, 1 => rising edge
++
++
++
++LCD Display 3.5 Inch 240x320 resln:
++###################################
++LCLK = 104MHz, PCD=7, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(7+1)) = 6.5Mhz.
++pixelclock in seconds = 1/6.5Mhz = 0.153846*(10^-6) = 153846*(10^-12) = 153846 picoseconds
++
++insmod pxafb.ko options=mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 5.7 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++LCD Display 6.5 Inch 640x480 resln:
++###################################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single
++
++CRT Display 640x480 resln:
++##########################
++LCLK = 104MHz, PCD=1, PCDDIV=0, So pixelclock = LCLK/(2*(PCD+1)) = 104*(10^6)/(2*(1+1)) = 26Mhz.
++pixelclock in seconds = 1/26Mhz = 0.038461*(10^-6) = 38461*(10^-12) = 38461 picoseconds
++
++insmod pxafb.ko options=mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single
++*/
++#if ECON_CAMERA_ENABLE
++#define BOOTARGS_FOR_LCD3P5 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD3P2 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++#define BOOTARGS_FOR_LCD4P3 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:480x272-16,pixclock:76923,left:2,right:2,upper:2,lower:2,hsynclen:41,vsynclen:10,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD5P7 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD6P5 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_CRT "console=ttyS2,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++#define KGDB_BOOTARGS_FOR_LCD3P5 "console=ttyS0,115200 rw mem=100M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD3P2 "console=ttyS0,115200 rw mem=100M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:1,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD4P3 "console=ttyS2,115200 rw mem=100M video=pxafb:mode:480x272-16,pixclock:76923,left:2,right:2,upper:2,lower:2,hsynclen:41,vsynclen:10,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD5P7 "console=ttyS0,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD6P5 "console=ttyS0,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_CRT "console=ttyS0,115200 rw mem=100M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single kgdbwait"
++#else
++#define BOOTARGS_FOR_LCD3P5 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD3P2 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++#define BOOTARGS_FOR_LCD4P3 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:480x272-16,pixclock:76923,left:2,right:2,upper:2,lower:2,hsynclen:41,vsynclen:10,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD5P7 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_LCD6P5 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single"
++#define BOOTARGS_FOR_CRT "console=ttyS2,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single"
++#define KGDB_BOOTARGS_FOR_LCD3P5 "console=ttyS0,115200 rw mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD3P2 "console=ttyS0,115200 rw mem=128M video=pxafb:mode:240x320-16,pixclock:153846,left:59,right:17,upper:0,lower:4,hsynclen:14,vsynclen:8,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:1,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD4P3 "console=ttyS2,115200 rw mem=128M video=pxafb:mode:480x272-16,pixclock:76923,left:2,right:2,upper:2,lower:2,hsynclen:41,vsynclen:10,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD5P7 "console=ttyS0,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:81,right:81,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_LCD6P5 "console=ttyS0,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:7,right:1,upper:19,lower:19,hsynclen:5,vsynclen:3,hsync:0,vsync:0,dpc:0,outputen:1,pixclockpol:0,color,active,single kgdbwait"
++#define KGDB_BOOTARGS_FOR_CRT "console=ttyS0,115200 rw mem=128M video=pxafb:mode:640x480-16,pixclock:38461,left:49,right:49,upper:37,lower:17,hsynclen:64,vsynclen:3,hsync:1,vsync:1,dpc:0,outputen:1,pixclockpol:1,color,active,single kgdbwait"
++#endif
++
++/*************************************************************************************************************/
++/*enable LCD controller */
++#ifndef CONFIG_LCD
++#define LCD_ENABLE
++#else
++#undef LCD_ENABLE
++#endif
++
++#ifdef LCD_ENABLE
++extern void select_lcd(unsigned int Cx, unsigned int Cy, unsigned int Device);
++
++void show_lcd()
++{
++#if 0
++#ifdef CONFIG_SHARP_LCD_320_240
++ select_lcd(240,320,35);
++#elif defined(CONFIG_OPTREX_LCD_640_480)
++ select_lcd(640,480,57);
++#elif defined(CONFIG_LCD_640_480)
++ select_lcd(640,480,64);
++#elif defined(CONFIG_LCD_800_480)
++ select_lcd(640,480,84);
++#endif
++#else
++
++ char *s=NULL;
++ char *s1=NULL;
++ s1 = getenv ("kgdb");
++ if((s1==NULL)||(strcmp(s1,"off")==0)&&(strcmp(s1,"on")!=0))
++ {
++ s = getenv ("display_type");
++ //printf("display_type is %s \n",s);
++ if(s==NULL)
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p5")==0)
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p2")==0)
++ {
++ select_lcd(240,320,32);
++ setenv("bootargs",BOOTARGS_FOR_LCD3P2);
++ }
++ else if(strcmp(s,"lcd4p3")==0)
++ {
++ select_lcd(480,272,43);
++ setenv("bootargs",BOOTARGS_FOR_LCD4P3);
++ }
++ else if(strcmp(s,"lcd5p7")==0)
++ {
++ select_lcd(640,480,57);
++ setenv("bootargs",BOOTARGS_FOR_LCD5P7);
++ }
++ else if(strcmp(s,"lcd6p5")==0)
++ {
++ select_lcd(640,480,65);
++ setenv("bootargs",BOOTARGS_FOR_LCD6P5);
++ }
++ else if(strcmp(s,"crt")==0)
++ {
++ select_lcd(640,480,64);
++ setenv("bootargs",BOOTARGS_FOR_CRT);
++ }
++ else
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",BOOTARGS_FOR_LCD3P5);
++ }
++ }
++ else if(strcmp(s1,"on")==0)
++ {
++ s = getenv ("display_type");
++ //printf("display_type is %s \n",s);
++ if(s==NULL)
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p5")==0)
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ else if(strcmp(s,"lcd3p2")==0)
++ {
++ select_lcd(240,320,32);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P2);
++ }
++ else if(strcmp(s,"lcd4p3")==0)
++ {
++ select_lcd(480,272,43);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD4P3);
++ }
++ else if(strcmp(s,"lcd5p7")==0)
++ {
++ select_lcd(640,480,57);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD5P7);
++ }
++ else if(strcmp(s,"lcd6p5")==0)
++ {
++ select_lcd(640,480,65);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD6P5);
++ }
++ else if(strcmp(s,"crt")==0)
++ {
++ select_lcd(640,480,64);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_CRT);
++ }
++ else
++ {
++ select_lcd(240,320,35);
++ setenv("bootargs",KGDB_BOOTARGS_FOR_LCD3P5);
++ }
++ }
++#endif
++
++}
++
++
++#endif // LCD_ENABLE
++#endif // CONFIG_REGULUS
++
++
++
++
+ /*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+@@ -171,6 +440,163 @@
+ return (0);
+ }
+
++
++#ifdef CONFIG_REGULUS
++int get_cpu_speed(void)
++{
++#define TURBO_MODE (1 << 0)
++#define CCCR_2N_MASK (0xF << 7)
++ int i=0;
++ int cccr_2N_value=0,L_value=0;
++ volatile unsigned int cccr_read_data=0;
++ int cpu_speed = 0;
++
++ cccr_read_data = CCCR;
++ //printf ("cccr_read_data is 0x%08X \n",cccr_read_data);
++ cccr_2N_value = (((cccr_read_data & CCCR_2N_MASK)>>7));
++ L_value = cccr_read_data & CCCR_L_MASK;
++
++ if(L_value <=2)
++ {
++ L_value = 1;
++ }
++ else if(L_value >2 && L_value<=0x1E)
++ {
++ L_value = L_value;
++ }
++ else
++ {
++ //printf("L_value is a resererved value \n");
++ }
++
++ /* read control register */
++ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
++
++ /* read CLKCFG register */
++ asm ("mrc p14, 0, %0, c6, c0, 0":"=r" (i));
++
++ //printf("CLKCFG Data is 0x%08X \n",i);
++
++ if(((i & TURBO_MODE) == TURBO_MODE) && (L_value >7) &&(cccr_2N_value >2))
++ {
++
++ cpu_speed = (13 * L_value *cccr_2N_value)/2;
++ //printf("TURBO MODE \n");
++ }
++ else
++ {
++ cpu_speed = 13 * L_value;
++ //printf("RUN MODE \n");
++ }
++
++ return cpu_speed;
++}
++
++
++int sdram_size_detect(void)
++{
++#ifdef SDRAM128
++#warning "SDRAM128 defined"
++#define MAX_SDRAM_SIZE SZ_128M
++return 128;
++#elif defined(SDRAM64)
++#warning "SDRAM64 defined"
++#define MAX_SDRAM_SIZE SZ_64M
++return 64;
++#endif
++
++#define SDRAM_BASE 0xa0000000
++#define SZ_0M 0x00000000
++#define SZ_1M 0x100000
++#define SZ_2M 0x200000
++#define SZ_4M 0x400000
++#define SZ_8M 0x800000
++#define SZ_16M 0x1000000
++#define SZ_32M 0x2000000
++#define SZ_64M 0x4000000
++#define SZ_128M 0x8000000
++#define SZ_256M 0x10000000
++//#define dprintf printf
++#define dprintf do{}while(0);
++ int sdram_size=0;
++ volatile unsigned int *sdram_addr = (unsigned int *)SDRAM_BASE;
++ volatile unsigned char *addr = (unsigned char *)SDRAM_BASE;
++
++
++ // Write Data as 0x00000000 AT Address 0xA0000000
++ *sdram_addr = SZ_0M;
++
++
++ // Is size 16MB ?
++ dprintf("Is size 16MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_16M;
++ *sdram_addr = SDRAM_BASE + SZ_16M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_16M))
++ {
++ sdram_size = 16;
++ dprintf("SDRAM size is 16MB \n");
++ }
++ // Is size 32MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 32MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_32M;
++ *sdram_addr = SDRAM_BASE + SZ_32M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_32M))
++ {
++ sdram_size = 32;
++ dprintf("SDRAM size is 32MB \n");
++ }
++ // Is size 64MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 64MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_64M;
++ *sdram_addr = SDRAM_BASE + SZ_64M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_64M))
++ {
++ sdram_size = 64;
++ dprintf("SDRAM size is 64MB \n");
++ }
++ // Is size 128MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 128MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_128M;
++ *sdram_addr = SDRAM_BASE + SZ_128M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_128M))
++ {
++ sdram_size = 128;
++ dprintf("SDRAM size is 128MB \n");
++ }
++ // Is size 256MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 256MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_256M;
++ *sdram_addr = SDRAM_BASE + SZ_256M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_256M))
++ {
++ sdram_size = 256;
++ dprintf("SDRAM size is 256MB \n");
++ }
++ } // end of size 256MB
++ } // end of size 128MB
++ } // end of size 64MB
++ } // end of size 32 MB
++
++ return sdram_size;
++
++}
++
++#endif /* CONFIG_REGULUS */
++
++
+ /*
+ * WARNING: this code looks "cleaner" than the PowerPC version, but
+ * has the disadvantage that you either get nothing, or everything.
+@@ -275,7 +701,7 @@
+ init_fnc_t **init_fnc_ptr;
+ char *s;
+ #if !defined(CFG_NO_FLASH) || defined (CONFIG_VFD) || defined(CONFIG_LCD)
+- ulong size;
++ ulong size,flash_size;
+ #endif
+ #if defined(CONFIG_VFD) || defined(CONFIG_LCD)
+ unsigned long addr;
+@@ -294,6 +720,9 @@
+
+ monitor_flash_len = _bss_start - _armboot_start;
+
++ printf(" \n %s \n",board_info_string);
++
++
+ for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+ if ((*init_fnc_ptr)() != 0) {
+ hang ();
+@@ -302,7 +731,12 @@
+
+ #ifndef CFG_NO_FLASH
+ /* configure available FLASH banks */
++ //printf(" FUNC : %s() LINE : %d : configure available FLASH banks \n",__FUNCTION__,__LINE__);
+ size = flash_init ();
++ //printf(" FUNC : %s() LINE : %d : Formatting the size of Flash in terms of Mbytes \n",__FUNCTION__,__LINE__);
++ flash_size = size/(1024*1024);
++ //printf(" FUNC : %s() LINE : %d : Displaying the size of Flash in terms of Bytes \n",__FUNCTION__,__LINE__);
++
+ display_flash_config (size);
+ #endif /* CFG_NO_FLASH */
+
+@@ -355,6 +789,30 @@
+ /* initialize environment */
+ env_relocate ();
+
++ /* conveying the partitions of flash memory */
++
++#if 0
++ printf("\n MTD PARTIIONS IN FLASH MEMORY: \n");
++ printf(" ----------------------------------------------------------------------------------\n");
++ printf(" PARTITION NO NODE-NAME PARTITION-NAME START-ADDR END-ADDR SIZE \n");
++ printf(" ----------------------------------------------------------------------------------\n");
++ printf(" 0 mtdblock0 BASIC-BOOT 0x00000000 0x0001ffff 0x00020000 \n");
++ printf(" 1 mtdblock1 UBOOT 0x00020000 0x0005ffff 0x00040000 \n");
++ printf(" 2 mtdblock2 UBOOT-PARAMS 0x00060000 0x0007ffff 0x00020000 \n");
++ printf(" 3 mtdblock3 KERNEL 0x00080000 0x0027ffff 0x00200000 \n");
++ printf(" 4 mtdblock4 ROOTFS 0x00280000 0x00ffffff 0x00D80000 \n");
++ printf(" 5 mtdblock5 FLASH2 0x01000000 0x01ffffff 0x01000000 \n");
++ printf(" 6 mtdblock6 FLASH 0x00000000 0x01ffffff 0x02000000 \n");
++ printf(" ----------------------------------------------------------------------------------\n");
++#endif
++
++
++/*enable the LCD controller */
++#ifdef LCD_ENABLE
++ show_lcd();
++#endif
++
++
+ #ifdef CONFIG_VFD
+ /* must do this after the framebuffer is allocated */
+ drv_vfd_init();
+@@ -413,6 +871,14 @@
+ /* enable exceptions */
+ enable_interrupts ();
+
++#ifdef CONFIG_REGULUS
++ // Calling the do_unlock() for unlocking all the sectors in the NOR Flash Memory
++ //printf(" FUNC : %s() LINE : %d : Unlocking all the sectors in the NOR Flash Memory \n",__FUNCTION__,__LINE__);
++ //set_core_voltage(CORE_VOLT_1P45V);
++ do_unlock(NULL,0,1,NULL);
++#endif
++
++
+ /* Perform network card initialisation if necessary */
+ #ifdef CONFIG_DRIVER_TI_EMAC
+ extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
+@@ -454,6 +920,23 @@
+ reset_phy();
+ #endif
+ #endif
++
++
++#ifdef CONFIG_REGULUS
++ set_core_voltage(CORE_VOLT_1P45V);
++ set_core_frequency(CORE_FREQ_520M);
++#endif
++
++#if 0
++ printf("########################################################### \n");
++ printf("DETECTED SDRAM MEMORY SIZE : %dMB \n",sdram_size_detect());
++ printf("SDRAM MEMORY TEST : SUCCESS \n");
++ printf("DETECTED NOR FLASH MEMORY SIZE : %dMB \n",flash_size);
++ printf("PROCESSOR RUNNING FREQUENCY : %dMHz \n",get_cpu_speed());
++ printf("########################################################### \n");
++#endif
++
++
+ /* main_loop() can return to retry autoboot, if so just run it again. */
+ for (;;) {
+ main_loop ();
+diff -Naur u-boot-2008.10_original/lib_arm/board.c_modified u-boot-2008.10/lib_arm/board.c_modified
+--- u-boot-2008.10_original/lib_arm/board.c_modified 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/lib_arm/board.c_modified 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,793 @@
++/*
++ * (C) Copyright 2002-2006
++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++ *
++ * (C) Copyright 2002
++ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
++ * Marius Groeger <mgroeger@sysgo.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++/*
++ * To match the U-Boot user interface on ARM platforms to the U-Boot
++ * standard (as on PPC platforms), some messages with debug character
++ * are removed from the default U-Boot build.
++ *
++ * Define DEBUG here if you want additional info as shown below
++ * printed upon startup:
++ *
++ * U-Boot code: 00F00000 -> 00F3C774 BSS: -> 00FC3274
++ * IRQ Stack: 00ebff7c
++ * FIQ Stack: 00ebef7c
++ */
++
++#include <common.h>
++#include <command.h>
++#include <malloc.h>
++#include <devices.h>
++#include <version.h>
++#include <net.h>
++#include <serial.h>
++#include <nand.h>
++#include <onenand_uboot.h>
++#include <asm-arm/arch-pxa/pxa-regs.h>
++
++#ifdef CONFIG_DRIVER_SMC91111
++#include "../drivers/net/smc91111.h"
++#endif
++#ifdef CONFIG_DRIVER_LAN91C96
++#include "../drivers/net/lan91c96.h"
++#endif
++
++DECLARE_GLOBAL_DATA_PTR;
++
++ulong monitor_flash_len;
++
++#ifdef CONFIG_HAS_DATAFLASH
++extern int AT91F_DataflashInit(void);
++extern void dataflash_print_info(void);
++#endif
++
++#ifndef CONFIG_IDENT_STRING
++#define CONFIG_IDENT_STRING ""
++#endif
++
++const char version_string[] =
++ U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING;
++
++#ifdef CONFIG_DRIVER_CS8900
++extern void cs8900_get_enetaddr (uchar * addr);
++#endif
++
++#ifdef CONFIG_DRIVER_RTL8019
++extern void rtl8019_get_enetaddr (uchar * addr);
++#endif
++
++#if defined(CONFIG_HARD_I2C) || \
++ defined(CONFIG_SOFT_I2C)
++#include <i2c.h>
++#endif
++
++extern int pxa_gpio_mode(int gpio_mode);
++int get_cpu_speed(void);
++int sdram_size_detect(void);
++#define BEEP_ENABLE 1
++#define BEEP_DISABLE 0
++extern void mdelay(int x);
++
++#define CORE_FREQ_104M 104
++#define CORE_FREQ_208M 208
++#define CORE_FREQ_312M 312
++#define CORE_FREQ_416M 416
++#define CORE_FREQ_520M 520
++#define CORE_FREQ_624M 624
++
++#define CORE_VOLT_1P15V 115
++#define CORE_VOLT_1P25V 125
++#define CORE_VOLT_1P35V 135
++#define CORE_VOLT_1P45V 145
++#define CORE_VOLT_1P55V 155
++
++extern int set_core_frequency(int core_freq_value);
++extern int set_core_voltage(int core_volt_value);
++
++extern int do_unlock (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++
++
++
++
++
++/*
++ * Begin and End of memory area for malloc(), and current "brk"
++ */
++static ulong mem_malloc_start = 0;
++static ulong mem_malloc_end = 0;
++static ulong mem_malloc_brk = 0;
++
++static
++void mem_malloc_init (ulong dest_addr)
++{
++ mem_malloc_start = dest_addr;
++ mem_malloc_end = dest_addr + CFG_MALLOC_LEN;
++ mem_malloc_brk = mem_malloc_start;
++
++ memset ((void *) mem_malloc_start, 0,
++ mem_malloc_end - mem_malloc_start);
++}
++
++void *sbrk (ptrdiff_t increment)
++{
++ ulong old = mem_malloc_brk;
++ ulong new = old + increment;
++
++ if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
++ return (NULL);
++ }
++ mem_malloc_brk = new;
++
++ return ((void *) old);
++}
++
++
++/************************************************************************
++ * Coloured LED functionality
++ ************************************************************************
++ * May be supplied by boards if desired
++ */
++void inline __coloured_LED_init (void) {}
++void inline coloured_LED_init (void) __attribute__((weak, alias("__coloured_LED_init")));
++void inline __red_LED_on (void) {}
++void inline red_LED_on (void) __attribute__((weak, alias("__red_LED_on")));
++void inline __red_LED_off(void) {}
++void inline red_LED_off(void) __attribute__((weak, alias("__red_LED_off")));
++void inline __green_LED_on(void) {}
++void inline green_LED_on(void) __attribute__((weak, alias("__green_LED_on")));
++void inline __green_LED_off(void) {}
++void inline green_LED_off(void)__attribute__((weak, alias("__green_LED_off")));
++void inline __yellow_LED_on(void) {}
++void inline yellow_LED_on(void)__attribute__((weak, alias("__yellow_LED_on")));
++void inline __yellow_LED_off(void) {}
++void inline yellow_LED_off(void)__attribute__((weak, alias("__yellow_LED_off")));
++
++/************************************************************************
++ * Init Utilities *
++ ************************************************************************
++ * Some of this code should be moved into the core functions,
++ * or dropped completely,
++ * but let's get it working (again) first...
++ */
++
++static int init_baudrate (void)
++{
++ char tmp[64]; /* long enough for environment variables */
++ int i = getenv_r ("baudrate", tmp, sizeof (tmp));
++ gd->bd->bi_baudrate = gd->baudrate = (i > 0)
++ ? (int) simple_strtoul (tmp, NULL, 10)
++ : CONFIG_BAUDRATE;
++
++ return (0);
++}
++
++static int display_banner (void)
++{
++ printf ("\n\n%s\n\n", version_string);
++ debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
++ _armboot_start, _bss_start, _bss_end);
++#ifdef CONFIG_MODEM_SUPPORT
++ debug ("Modem Support enabled\n");
++#endif
++#ifdef CONFIG_USE_IRQ
++ debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
++ debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
++#endif
++
++ return (0);
++}
++
++
++
++int get_cpu_speed(void)
++{
++#define TURBO_MODE (1 << 0)
++#define CCCR_2N_MASK (0xF << 7)
++ int i=0;
++ int cccr_2N_value=0,L_value=0;
++ float N_value = 0;
++ volatile unsigned int cccr_read_data=0;
++ int cpu_speed = 0;
++
++ cccr_read_data = CCCR;
++ //printf ("cccr_read_data is 0x%08X \n",cccr_read_data);
++ cccr_2N_value = (((cccr_read_data & CCCR_2N_MASK)>>7));
++
++ if(cccr_2N_value <=2)
++ {
++ N_value = 1;
++ }
++ else if(cccr_2N_value >2)
++ {
++ N_value = (cccr_2N_value /2.0);
++ }
++
++ L_value = cccr_read_data & CCCR_L_MASK;
++ if(L_value <=2)
++ {
++ L_value = 1;
++ }
++ else if(L_value >2 && L_value<=0x1E)
++ {
++ L_value = L_value;
++ }
++ else
++ {
++ printf("L_value is a resererved value \n");
++ }
++
++ /* read control register */
++ asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
++
++ /* read CLKCFG register */
++ asm ("mrc p14, 0, %0, c6, c0, 0":"=r" (i));
++
++ //printf("CLKCFG Data is 0x%08X \n",i);
++
++ if(((i & TURBO_MODE) == TURBO_MODE) && (L_value >7))
++ {
++ cpu_speed = 13 * L_value * N_value;
++ //printf("TURBO MODE \n");
++ }
++ else
++ {
++ cpu_speed = 13 * L_value;
++ //printf("RUN MODE \n");
++ }
++
++ return cpu_speed;
++}
++
++
++int sdram_size_detect(void)
++{
++#ifdef SDRAM128
++#warning "SDRAM128 defined"
++#define MAX_SDRAM_SIZE SZ_128M
++return 128;
++#elif defined(SDRAM64)
++#warning "SDRAM64 defined"
++#define MAX_SDRAM_SIZE SZ_64M
++return 64;
++#endif
++
++#define SDRAM_BASE 0xa0000000
++#define SZ_0M 0x00000000
++#define SZ_1M 0x100000
++#define SZ_2M 0x200000
++#define SZ_4M 0x400000
++#define SZ_8M 0x800000
++#define SZ_16M 0x1000000
++#define SZ_32M 0x2000000
++#define SZ_64M 0x4000000
++#define SZ_128M 0x8000000
++#define SZ_256M 0x10000000
++//#define dprintf printf
++#define dprintf do{}while(0);
++ int sdram_size=0;
++ volatile unsigned int *sdram_addr = (unsigned int *)SDRAM_BASE;
++ volatile unsigned char *addr = (unsigned char *)SDRAM_BASE;
++
++
++ // Write Data as 0x00000000 AT Address 0xA0000000
++ *sdram_addr = SZ_0M;
++
++
++ // Is size 16MB ?
++ dprintf("Is size 16MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_16M;
++ *sdram_addr = SDRAM_BASE + SZ_16M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_16M))
++ {
++ sdram_size = 16;
++ dprintf("SDRAM size is 16MB \n");
++ }
++ // Is size 32MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 32MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_32M;
++ *sdram_addr = SDRAM_BASE + SZ_32M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_32M))
++ {
++ sdram_size = 32;
++ dprintf("SDRAM size is 32MB \n");
++ }
++ // Is size 64MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 64MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_64M;
++ *sdram_addr = SDRAM_BASE + SZ_64M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_64M))
++ {
++ sdram_size = 64;
++ dprintf("SDRAM size is 64MB \n");
++ }
++ // Is size 128MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 128MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_128M;
++ *sdram_addr = SDRAM_BASE + SZ_128M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_128M))
++ {
++ sdram_size = 128;
++ dprintf("SDRAM size is 128MB \n");
++ }
++ // Is size 256MB ?
++ else if((*sdram_addr) == SZ_0M)
++ {
++ dprintf("Is size 256MB ? \n");
++ sdram_addr = SDRAM_BASE + SZ_256M;
++ *sdram_addr = SDRAM_BASE + SZ_256M;
++ sdram_addr = SDRAM_BASE;
++ if((*sdram_addr) == (SDRAM_BASE + SZ_256M))
++ {
++ sdram_size = 256;
++ dprintf("SDRAM size is 256MB \n");
++ }
++ } // end of size 256MB
++ } // end of size 128MB
++ } // end of size 64MB
++ } // end of size 32 MB
++
++ return sdram_size;
++
++}
++
++
++
++
++/*
++ * WARNING: this code looks "cleaner" than the PowerPC version, but
++ * has the disadvantage that you either get nothing, or everything.
++ * On PowerPC, you might see "DRAM: " before the system hangs - which
++ * gives a simple yet clear indication which part of the
++ * initialization if failing.
++ */
++static int display_dram_config (void)
++{
++ int i;
++
++#ifdef DEBUG
++ puts ("RAM Configuration:\n");
++
++ for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
++ printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
++ print_size (gd->bd->bi_dram[i].size, "\n");
++ }
++#else
++ ulong size = 0;
++
++ for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
++ size += gd->bd->bi_dram[i].size;
++ }
++ puts("DRAM: ");
++ print_size(size, "\n");
++#endif
++
++ return (0);
++}
++
++#ifndef CFG_NO_FLASH
++static void display_flash_config (ulong size)
++{
++ puts ("Flash: ");
++ print_size (size, "\n");
++}
++#endif /* CFG_NO_FLASH */
++
++#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
++static int init_func_i2c (void)
++{
++ puts ("I2C: ");
++ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
++ puts ("ready\n");
++ return (0);
++}
++#endif
++
++/*
++ * Breathe some life into the board...
++ *
++ * Initialize a serial port as console, and carry out some hardware
++ * tests.
++ *
++ * The first part of initialization is running from Flash memory;
++ * its main purpose is to initialize the RAM so that we
++ * can relocate the monitor code to RAM.
++ */
++
++/*
++ * All attempts to come up with a "common" initialization sequence
++ * that works for all boards and architectures failed: some of the
++ * requirements are just _too_ different. To get rid of the resulting
++ * mess of board dependent #ifdef'ed code we now make the whole
++ * initialization sequence configurable to the user.
++ *
++ * The requirements for any new initalization function is simple: it
++ * receives a pointer to the "global data" structure as it's only
++ * argument, and returns an integer return code, where 0 means
++ * "continue" and != 0 means "fatal error, hang the system".
++ */
++typedef int (init_fnc_t) (void);
++
++int print_cpuinfo (void); /* test-only */
++
++init_fnc_t *init_sequence[] = {
++ cpu_init, /* basic cpu dependent setup */
++ board_init, /* basic board dependent setup */
++ interrupt_init, /* set up exceptions */
++ env_init, /* initialize environment */
++ init_baudrate, /* initialze baudrate settings */
++ serial_init, /* serial communications setup */
++ console_init_f, /* stage 1 init of console */
++ display_banner, /* say that we are here */
++#if defined(CONFIG_DISPLAY_CPUINFO)
++ print_cpuinfo, /* display cpu info (and speed) */
++#endif
++#if defined(CONFIG_DISPLAY_BOARDINFO)
++ checkboard, /* display board info */
++#endif
++#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
++ init_func_i2c,
++#endif
++ dram_init, /* configure available RAM banks */
++ display_dram_config,
++ NULL,
++};
++
++void start_armboot (void)
++{
++ init_fnc_t **init_fnc_ptr;
++ char *s;
++#if !defined(CFG_NO_FLASH) || defined (CONFIG_VFD) || defined(CONFIG_LCD)
++ ulong size,flash_size;
++#endif
++#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
++ unsigned long addr;
++#endif
++
++ /* Pointer is writable since we allocated a register for it */
++ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
++ /* compiler optimization barrier needed for GCC >= 3.4 */
++ __asm__ __volatile__("": : :"memory");
++
++ memset ((void*)gd, 0, sizeof (gd_t));
++ gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
++ memset (gd->bd, 0, sizeof (bd_t));
++
++ gd->flags |= GD_FLG_RELOC;
++
++ monitor_flash_len = _bss_start - _armboot_start;
++
++ for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
++ if ((*init_fnc_ptr)() != 0) {
++ hang ();
++ }
++ }
++
++#ifndef CFG_NO_FLASH
++ /* configure available FLASH banks */
++ //printf(" FUNC : %s() LINE : %d : configure available FLASH banks \n",__FUNCTION__,__LINE__);
++ size = flash_init ();
++ //printf(" FUNC : %s() LINE : %d : Formatting the size of Flash in terms of Mbytes \n",__FUNCTION__,__LINE__);
++ flash_size = size/(1024*1024);
++ //printf(" FUNC : %s() LINE : %d : Displaying the size of Flash in terms of Bytes \n",__FUNCTION__,__LINE__);
++
++ display_flash_config (size);
++#endif /* CFG_NO_FLASH */
++
++#ifdef CONFIG_VFD
++# ifndef PAGE_SIZE
++# define PAGE_SIZE 4096
++# endif
++ /*
++ * reserve memory for VFD display (always full pages)
++ */
++ /* bss_end is defined in the board-specific linker script */
++ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
++ size = vfd_setmem (addr);
++ gd->fb_base = addr;
++#endif /* CONFIG_VFD */
++
++#ifdef CONFIG_LCD
++ /* board init may have inited fb_base */
++ if (!gd->fb_base) {
++# ifndef PAGE_SIZE
++# define PAGE_SIZE 4096
++# endif
++ /*
++ * reserve memory for LCD display (always full pages)
++ */
++ /* bss_end is defined in the board-specific linker script */
++ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
++ size = lcd_setmem (addr);
++ gd->fb_base = addr;
++ }
++#endif /* CONFIG_LCD */
++
++ /* armboot_start is defined in the board-specific linker script */
++ mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
++
++#if defined(CONFIG_CMD_NAND)
++ puts ("NAND: ");
++ nand_init(); /* go init the NAND */
++#endif
++
++#if defined(CONFIG_CMD_ONENAND)
++ onenand_init();
++#endif
++
++#ifdef CONFIG_HAS_DATAFLASH
++ AT91F_DataflashInit();
++ dataflash_print_info();
++#endif
++
++ /* initialize environment */
++ env_relocate ();
++
++#ifdef CONFIG_VFD
++ /* must do this after the framebuffer is allocated */
++ drv_vfd_init();
++#endif /* CONFIG_VFD */
++
++#ifdef CONFIG_SERIAL_MULTI
++ serial_initialize();
++#endif
++
++ /* IP Address */
++ gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
++
++ /* MAC Address */
++ {
++ int i;
++ ulong reg;
++ char *s, *e;
++ char tmp[64];
++
++ i = getenv_r ("ethaddr", tmp, sizeof (tmp));
++ s = (i > 0) ? tmp : NULL;
++
++ for (reg = 0; reg < 6; ++reg) {
++ gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
++ if (s)
++ s = (*e) ? e + 1 : e;
++ }
++
++#ifdef CONFIG_HAS_ETH1
++ i = getenv_r ("eth1addr", tmp, sizeof (tmp));
++ s = (i > 0) ? tmp : NULL;
++
++ for (reg = 0; reg < 6; ++reg) {
++ gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
++ if (s)
++ s = (*e) ? e + 1 : e;
++ }
++#endif
++ }
++
++ devices_init (); /* get the devices list going. */
++
++#ifdef CONFIG_CMC_PU2
++ load_sernum_ethaddr ();
++#endif /* CONFIG_CMC_PU2 */
++
++ jumptable_init ();
++
++ console_init_r (); /* fully init console as a device */
++
++#if defined(CONFIG_MISC_INIT_R)
++ /* miscellaneous platform dependent initialisations */
++ misc_init_r ();
++#endif
++
++ /* enable exceptions */
++ enable_interrupts ();
++
++#ifdef CONFIG_REGULUS
++ // Calling the do_unlock() for unlocking all the sectors in the NOR Flash Memory
++ //printf(" FUNC : %s() LINE : %d : Unlocking all the sectors in the NOR Flash Memory \n",__FUNCTION__,__LINE__);
++ //set_core_voltage(CORE_VOLT_1P45V);
++ do_unlock(NULL,0,1,NULL);
++#endif
++
++
++ /* Perform network card initialisation if necessary */
++#ifdef CONFIG_DRIVER_TI_EMAC
++extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
++ if (getenv ("ethaddr")) {
++ davinci_eth_set_mac_addr(gd->bd->bi_enetaddr);
++ }
++#endif
++
++#ifdef CONFIG_DRIVER_CS8900
++ cs8900_get_enetaddr (gd->bd->bi_enetaddr);
++#endif
++
++#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
++ if (getenv ("ethaddr")) {
++ smc_set_mac_addr(gd->bd->bi_enetaddr);
++ }
++#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
++
++ /* Initialize from environment */
++ if ((s = getenv ("loadaddr")) != NULL) {
++ load_addr = simple_strtoul (s, NULL, 16);
++ }
++#if defined(CONFIG_CMD_NET)
++ if ((s = getenv ("bootfile")) != NULL) {
++ copy_filename (BootFile, s, sizeof (BootFile));
++ }
++#endif
++
++#ifdef BOARD_LATE_INIT
++ board_late_init ();
++#endif
++#if defined(CONFIG_CMD_NET)
++#if defined(CONFIG_NET_MULTI)
++ puts ("Net: ");
++#endif
++ eth_initialize(gd->bd);
++#if defined(CONFIG_RESET_PHY_R)
++ debug ("Reset Ethernet PHY\n");
++ reset_phy();
++#endif
++#endif
++
++
++ printf(" Booted Successfully!!! \n");
++#ifdef CONFIG_REGULUS
++ set_core_voltage(CORE_VOLT_1P45V);
++ set_core_frequency(CORE_FREQ_520M);
++#endif
++ printf("########################################################### \n");
++ printf("DETECTED SDRAM MEMORY SIZE : %dMB \n",sdram_size_detect());
++ printf("SDRAM MEMORY TEST : SUCCESS \n");
++ printf("DETECTED NOR FLASH MEMORY SIZE : %dMB \n",flash_size);
++ printf("PROCESSOR RUNNING FREQUENCY : %dMHz \n",get_cpu_speed());
++ printf("########################################################### \n");
++
++
++
++ /* main_loop() can return to retry autoboot, if so just run it again. */
++ for (;;) {
++ main_loop ();
++ }
++
++ /* NOTREACHED - no way out of command loop except booting */
++}
++
++void hang (void)
++{
++ puts ("### ERROR ### Please RESET the board ###\n");
++ for (;;);
++}
++
++#ifdef CONFIG_MODEM_SUPPORT
++static inline void mdm_readline(char *buf, int bufsiz);
++
++/* called from main loop (common/main.c) */
++extern void dbg(const char *fmt, ...);
++int mdm_init (void)
++{
++ char env_str[16];
++ char *init_str;
++ int i;
++ extern char console_buffer[];
++ extern void enable_putc(void);
++ extern int hwflow_onoff(int);
++
++ enable_putc(); /* enable serial_putc() */
++
++#ifdef CONFIG_HWFLOW
++ init_str = getenv("mdm_flow_control");
++ if (init_str && (strcmp(init_str, "rts/cts") == 0))
++ hwflow_onoff (1);
++ else
++ hwflow_onoff(-1);
++#endif
++
++ for (i = 1;;i++) {
++ sprintf(env_str, "mdm_init%d", i);
++ if ((init_str = getenv(env_str)) != NULL) {
++ serial_puts(init_str);
++ serial_puts("\n");
++ for(;;) {
++ mdm_readline(console_buffer, CFG_CBSIZE);
++ dbg("ini%d: [%s]", i, console_buffer);
++
++ if ((strcmp(console_buffer, "OK") == 0) ||
++ (strcmp(console_buffer, "ERROR") == 0)) {
++ dbg("ini%d: cmd done", i);
++ break;
++ } else /* in case we are originating call ... */
++ if (strncmp(console_buffer, "CONNECT", 7) == 0) {
++ dbg("ini%d: connect", i);
++ return 0;
++ }
++ }
++ } else
++ break; /* no init string - stop modem init */
++
++ udelay(100000);
++ }
++
++ udelay(100000);
++
++ /* final stage - wait for connect */
++ for(;i > 1;) { /* if 'i' > 1 - wait for connection
++ message from modem */
++ mdm_readline(console_buffer, CFG_CBSIZE);
++ dbg("ini_f: [%s]", console_buffer);
++ if (strncmp(console_buffer, "CONNECT", 7) == 0) {
++ dbg("ini_f: connected");
++ return 0;
++ }
++ }
++
++ return 0;
++}
++
++/* 'inline' - We have to do it fast */
++static inline void mdm_readline(char *buf, int bufsiz)
++{
++ char c;
++ char *p;
++ int n;
++
++ n = 0;
++ p = buf;
++ for(;;) {
++ c = serial_getc();
++
++ /* dbg("(%c)", c); */
++
++ switch(c) {
++ case '\r':
++ break;
++ case '\n':
++ *p = '\0';
++ return;
++
++ default:
++ if(n++ > bufsiz) {
++ *p = '\0';
++ return; /* sanity check */
++ }
++ *p = c;
++ p++;
++ break;
++ }
++ }
++}
++#endif /* CONFIG_MODEM_SUPPORT */
+diff -Naur u-boot-2008.10_original/Makefile u-boot-2008.10/Makefile
+--- u-boot-2008.10_original/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -43,6 +43,8 @@
+
+ HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
+ sed -e 's/\(cygwin\).*/cygwin/')
++ARCH=arm
++CROSS_COMPILE=/usr/local/arm/4.0.0/usr/bin/arm-linux-
+
+ export HOSTARCH HOSTOS
+
+@@ -135,7 +137,7 @@
+
+ # load ARCH, BOARD, and CPU configuration
+ include $(obj)include/config.mk
+-export ARCH CPU BOARD VENDOR SOC
++export ARCH CPU BOARD VENDOR SOC LOGO_BMP
+
+ ifndef CROSS_COMPILE
+ ifeq ($(HOSTARCH),$(ARCH))
+@@ -2715,7 +2717,6 @@
+ #########################################################################
+ ## XScale Systems
+ #########################################################################
+-
+ actux1_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm ixp actux1
+
+@@ -2770,6 +2771,9 @@
+ pxa255_idp_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm pxa pxa255_idp
+
++regulus_config : unconfig
++ @$(MKCONFIG) $(@:_config=) arm pxa regulus
++
+ trizepsiv_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm pxa trizepsiv
+
+diff -Naur u-boot-2008.10_original/net/net.c u-boot-2008.10/net/net.c
+--- u-boot-2008.10_original/net/net.c 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/net/net.c 2009-08-12 18:21:20.000000000 +0530
+@@ -287,6 +287,7 @@
+ NetLoop(proto_t protocol)
+ {
+ bd_t *bd = gd->bd;
++ int econ_count = 0; // Added by econ on July20, 2007
+
+ #ifdef CONFIG_NET_MULTI
+ NetRestarted = 0;
+@@ -551,6 +552,19 @@
+ #ifdef CONFIG_NET_MULTI
+ NetRestarted = 1;
+ #endif
++ if(econ_count != 1 )
++ {
++ econ_count = 1;
++ // printf("%s %s %d : goto restart \n",__FILE__,__FUNCTION__,__LINE__);
++ // goto restart;
++ goto end_of_Netloop;
++ }
++ else
++ {
++ // printf(" Go to end_of_Netloop \n");
++ goto end_of_Netloop;
++ }
++
+ goto restart;
+
+ case NETLOOP_SUCCESS:
+@@ -572,6 +586,12 @@
+ return (-1);
+ }
+ }
++//Added by econ on July20, 2007
++end_of_Netloop:
++ // printf(" Failed to get the file for the serverip \n");
++ return -1;
++
++
+ }
+
+ /**********************************************************************/
+diff -Naur u-boot-2008.10_original/tools/logos/denx1.bmp u-boot-2008.10/tools/logos/denx1.bmp
+--- u-boot-2008.10_original/tools/logos/denx1.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/denx1.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,14 @@
++BM²<\0\0\0\0\0\0²\0\0\0(\0\0\0 \0\0\0`\0\0\0\x01\0\b\0\0\0\0\0\0<\0\0m\v\0\0m\v\0\0\x1f\0\0\0\x1f\0\0\05I5\0CVC\0PbP\0^n^\0kzk\0yy\0\0\0¡«¡\0¯·¯\0¼Ã¼\0ÊÏÊ\0×Û×\0åçå\0òóò\03ºÿ\0A¿ÿ\0OÄÿ\0\Èÿ\0jÍÿ\0wÑÿ\0
Öÿ\0Ûÿ\0 ßÿ\0®äÿ\0»èÿ\0Éíÿ\0×òÿ\0äöÿ\0òûÿ\0ÿÿÿ\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x01\x04\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\0\0\x04\x03\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e
++\0 \x1e\x1e\x1e\x1e\x1e\x1e\x01\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0
++\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\f\0\0\0\0\0\x03\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0\0\0\0\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e
++\0\x04\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\r\0\x05\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\0\x04\x1e\x1e\x1e\x1e\a\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\x04\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\b\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\r\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0 \x1e\x1e\x1e\x1e\x1e
++\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x03\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x03\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x0e\0\x02\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\x02\x01\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\f\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e
++\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\f\x1e\x1e\x1e\v\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\x1e\x1e\x1e\x1e\x1e\a\0
++\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e \0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\x05\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x1e\a\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0
++\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\b\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x05\0\0\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x1e\x1e\x1e\x1e\x1e\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\0\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\x1e\x1e\x1e\x1e\x1e\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\x0e\x02\0\x1e\x1e\x1e\b\0\x1e\a\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\f\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x05\0\0\0\r\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\0 \x1e\x1e\0\0\x1e\x1e\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\a\a\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\x05\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\x1e\x1e\x1e\0\0\x1e\0\0\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\x06\x1e\x1e\x1e\x1e\x06\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\0 \0\0\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\0\r\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x02\0\0\x04\x04\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\0\x04\x04\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\v\x1e\x1e\x1e\x1e\a\0\0\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x03\x04\x03\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\x1e\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\b\0\0\a\x04\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\a\v\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\x04\0\x01\x04
++\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\a\a
++\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e^[\x16\x1a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x16\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e
++\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x19\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x10\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e^[\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1c\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1d\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x10\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1d\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\x1e\x1e\x1e \x02\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\v\x1e\x1e\v\x06\0\0\0\0\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1d\x16\x12\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x12\x17\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\r\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\b\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1d\x1e\x1e\x1e\x1e\x1e\x11\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x14\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\r\0\0\0\0\0\0\0\0\0\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1d\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\r\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\b\0\0\0\0\0\0\0\0\r\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x12\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x10\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x11\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x13\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x13\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x10\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x12\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\0\0\0\0\0\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x13\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\r\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\0\0\0\0\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x02\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x01\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x11\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e^[\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x18\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x19\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0
++\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x06\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x01\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\x0e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\0\x04\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0e\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e
++\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\f\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\x05\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e \0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e^[\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x14\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\0\0\0\0\0\0\0\0\0\x04\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\a\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\v\x1e
++\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\v\x1e\v\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1d\x19\x13\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x13\x1a\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x12\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x12\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x18\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x10\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f^[\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1d\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\x1e\a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\b\x1e\x1e\x1e\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \x1e\x1e\x1e\x1e\x1e\x1e\x1e\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x04\0\0\0\0\0\0\0\0\0\0\0\0\b\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\b\0\0\0\0\0\0\0\0\0\0\0\0\x02\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e \0\0\0\0\0\0\0\0\0\0\0\0\0\b\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x0f\x0f\x0f\x0f\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x18\x0f\x0f\x0f\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\x01\0\0\0\0\x04\x0e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\x04\0\0\0\0\0\a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\x04\0\0\0\0\0\x04\f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1a\x0f\x0f\x12\x1a\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x19\x0f\x0f\x0f\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\0\0\0\0\0\0\0\0\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\v\v\v\v\v\v\v\v\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/econbutterfly_565.bmp u-boot-2008.10/tools/logos/econbutterfly_565.bmp
+--- u-boot-2008.10_original/tools/logos/econbutterfly_565.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/econbutterfly_565.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,14 @@
++BMHX\x02\0\0\0\0\0F\0\0\08\0\0\0ð\0\0\0@\x01\0\0\x01\0\x10\0\x03\0\0\0\x02X\x02\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0\0ø\0\0à\a\0\0\x1f\0\0\0\0\0\0\0·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·l·t·l·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·l·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·l·t·t·l·t·t·l·t·l·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·l·t·l·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·l·l·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·l·t·l·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·l·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·l·l·t·t·l·t·t·t·t·t·t·l·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·l·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·l·t·t·t·ty¼ÆýÖüÎú¥·t·t·l·t·t·t·t·l·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l·t·t·t·t·l·l·t·t·t·t·l·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·l·t·t·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·l·l·t·t·t·l·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·l·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·l·t·t·t·t·l·t·t·t·t·t·t·t·t·l·l·t·t·t·t·t;®~ïÿ÷¿÷=ßú¥øt·l·t·t·t·t·t·l·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·l¸t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t¸t·t·t·t·t·t¸t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t·t¸t·t·t¸t·t·t·t·t¸t·t·t¸t·l·t·t·t¸t·t·t·t·t·t·l·t·l·tø|;®¾÷ÿÿÿÿÿÿ~ç|¾¹ø|¸t·t·l·t·t¸t·t·t¸t·t·t·t·t¸t·t¸t·l·t¸l·t·t¸t·l·t·t·t·t·l·t·t·t·t·l·t·l·t·l·l·t·t·t·t·t·t·t·t·t·t·t¸t·t·t·t·t·t·t·t·t·t·t·t·t·t¸t·l·t¸t·t·t·t·l·t·t·t·t¸t·t·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·t·t·l·t·t·t·t·t·t·l¸t¸t·t·t·l·t·t·t·t·t·t·t·t·t·t·t·t¸t·t¸t·t¸t·t¸t·t·t·t·t·t·t¸t·t·t·t·t·t·t·l·t·t·t·t¸t·t·t·t¸t¸t¸t¸t·t·t·t¸t¸t·l¸t·t·t¸t·t·t·t¸t·t·l¸t·t·l·t¸t·t¸t¸t·t¸t·t¸t·t·t¸t¸t·t¸t·t·t¸t·t·t¸t¸l·t¸t·t¸t¸t·t¸t·t·t¸t¸t·t·t¸l¸t¸t·t·l·t·t¸t¸l·t·l·l·t·t·l·t·l·t¸t·t·t·t¸t·tøt;®¾÷ÿÿÿÿÿÿÿÿÿ÷~ç;®ø|øt·t¸t¸t·t·t·t·t·t¸t·t·t¸t¸l¸t·t·t¸t·t¸t·l·t·l·t¸t¸l·t¸t·t·t¸l¸l¸t·t·l·t·t¸l·t·t·t·t·t·t·t¸t¸t·t·t·t·l·t¸t·t¸t¸t·t¸t·t·t·t¸t·t·t·t·t·t¸l·t¸t¸t·l·t·t·t·t¸t¸t·t·t·t·t¸t·t·t¸t¸t¸t¸t¸t·t¸l¸t¸t¸l¸t·t¸t·l¸t¸t¸t·t¸t·t·t·t·l¸t·t·t·l·t¸t·t·t¸t·t¸t¸t·t¸t¸t¸t·t·t¸t¸t¸t·t¸t·t¸t·l·t¸t·t·t¸l¸t·t¸l¸t¸t¸t·t¸t¸t¸t¸l¸t¸l·t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t·t¸t¸t¸l¸t¸t¸t¸l·t¸t¸t¸t¸t¸t¸t·t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t·t¸t·t¸t·t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸l¸t·tøtû¥ÿ÷ÿÿÿÿÿÿÿÿÿÿ¿÷~ç;®øt¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l·l¸t·t¸t¸t·t¸t·t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t·t¸t¸t¸t¸t·t¸t¸t¸t¸t¸t¸t·t·t¸t¸t·t¸t¸t·l¸l·t·t¸t¸l·t¸t¸t·l¸t¸t·t¸t¸t·t¸t¸t¸t¸t·t¸t¸t¸t¸t¸t¸t¸t·t·t·t¸t·t¸t¸t·t¸t·t¸t¸t¸t¸t¸t¸l¸t¸t¸t·t·t¸l·t¸l¸t¸t¸t·t¸t¸l·t·t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t·t¸t¸t¸t·t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸l¸l¸tøtº~ïÿÿÿÿÿÿÿÿÿÿÿÿ¿÷üÎ9
¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸t¸t¸t¸l¸l¸t¸l¸l¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸l¸t¸t¸t¸t¸l¸t¸tøtº~çÿÿÿÿÿÿÿÿÿÿÿÿ¿÷=ß8}øt9
y8}¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸l¸tøt9
=ßÿÿÿÿÿÿÿÿÿÿÿÿ¿÷¼ÆyûýÖ~ç¼Æº8}øt¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸l¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t8}¼Æ¿÷ÿÿÿÿÿÿÿÿÿÿ¿÷|¾¼Æ¾ïÿ÷ÿ÷¿÷~ç¼Æºø|øt¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸l¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸tøtº~çÿÿÿÿÿÿÿÿÿÿÿ÷¾ï¿÷ÿÿÿÿÿÿÿÿÿ÷¾ïýκøtøt¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸l¸t¸t¸l¸l¸t¸t¸t¸l¸l¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸l¸t¸l¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸tøt9}|¾¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~ç;®8}¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸l¸t¸l¸t¸t¸l¸t¸t¸l¸t¸t¸tøl¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸tøt¸tøt¸t¸t¸tøtøl¸t¸tøt¸t¸tøt¸t¸t¸t¸l¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸l¸l¸tøløt¸tøt¸t¸t¸t¸t¸tøl¸t¸t¸t¸t¸t¸t¸t¸t¸t¸tøtøt¸tøt¸t¸tøt¸l¸t¸t¸tøt¸l¸tøt¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t9}yýÖÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ïû¥øtøt¸tøt¸tøtøt¸t¸t¸t¸t¸t¸t¸t¸t¸tøt¸t¸tøt¸løt¸t¸tøt¸t¸t¸t¸t¸t¸t¸l¸t¸t¸løt¸tøtøt¸t¸t¸l¸tøt¸t¸t¸t¸l¸t¸t¸tøt¸t¸tøt¸t¸t¸tøt¸løl¸t¸t¸t¸t¸t¸t¸t¸t¸tøt¸tøløl¸løt¸l¸t¸tøløt¸t¸t¸t¸t¸l¸t¸t¸tøt¸t¸tøt¸t¸l¸løløt¸t¸t¸t¸t¸t¸t¸tøt¸t¸t¸t¸t¸t¸løt¸tøt¸t¸t¸t¸tøt¸t¸t¸t¸tøt¸t¸l¸tøt¸tøt¸t¸løt¸tøt¸t¸t¸t¸t¸l¸t¸t¸tøt¸tøt¸tøtøt¸t¸l¸t¸tøt¸t¸l¸t¸t¸t¸t¸t¸t¸tøtøt¸l¸t¸t¸t¸t¸tøl¸t¸løt¸tøt¸t¸tøtøt¸løt¸t¸t¸t¸tøtøt¸t¸t¸t¸tøt¸t¸t¸tøt¸t¸l¸tøtøtøt¸tøt¸t¸l¸t¸løt¸t¸l¸t¸tøt¸t¸tøtøt9}º=ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷¼Î9}øt¸t¸t¸løtøtøt¸tøt¸t¸t¸t¸t¸t¸t¸l¸t¸løt¸t¸t¸t¸t¸tøt¸tøt¸tøtøt¸t¸t¸t¸tøt¸t¸tøt¸t¸t¸tøl¸tøl¸t¸t¸tøtøt¸t¸tøløtøl¸tøt¸l¸t¸t¸t¸tøl¸tøtøtøtøtøt¸l¸t¸t¸t¸t¸t¸tøt¸tøtøt¸tøløløt¸t¸l¸løtøtøtøt¸tøt¸t¸l¸t¸t¸t¸t¸tøl¸løtøt¸tøt¸t¸tøt¸t¸tøt¸t¸tøl¸l¸tøtøløt¸tøl¸t¸t¸løløt¸t¸løtøtøt¸tøt¸løtøt¸tøt¸t¸tøt¸t¸tøt¸t¸t¸t¸t¸tøl¸l¸tøløl¸tøt¸t¸tøtøtøløtøtøtøt¸t¸tøt¸tøt¸tøt¸t¸løt¸t¸t¸t¸løtøtøtøtøt¸tøl¸tøtøtøt¸t¸t¸tøt¸løl¸tøt¸t¸tøtøt¸tøtøtøtøtøtøtøtøtøtøløløt¸t¸t¸tøt¸tøt9
{¶¾ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¾ï|¾9}øtøt¸t¸tøtøtøtøtøt¸løt¸t¸t¸løtøtøtøtøl¸t¸tøt¸t¸tøt¸t¸t¸tøtøtøt¸tøt¸tøt¸tøtøtøt¸løtøtøt¸tøt¸tøt¸t¸tøt¸løt¸tøt¸tøløl¸l¸tøtøtøtøtøt¸t¸tøtøtøt¸t¸tøtøtøt¸tøtøtøt¸løtøtøt¸t¸tøt¸t¸tøtøt¸t¸t¸l¸tøtøtøt¸tøt¸l¸løt¸løt¸t¸l¸tøt¸tøt¸t¸t¸løtøt¸t¸t¸t¸løt¸t¸løtøtøl¸tøtøt¸t¸tøtøt¸t¸tøtøløtøtøløtøtøløtøt¸tøtøt¸tøtøtøtøtøt¸l¸tøløtøtøløtøtøtøtøløt¸t¸løløtøløtøt¸tøtøtøtøt¸løløl¸t¸t¸tøt¸tøtøtøtøtøtøløtøløl¸tøtøtøløtøløtøløtøt¸tøløt¸tøt¸tøtøtøtøløt¸t¸løt¸tøtù|9}9
;¶>ßÿÿÿÿÿÿÿ÷¿÷¿÷¿÷ÿÿ¿÷¿÷¿÷¾ï~ç|¾9}øtøløtøløtøtøt¸t¸tøtøløtøtøløtøtøtøtøløtøtøt¸løtøtøløt¸løløt¸tøtøtøtøtøtøl¸løløtøtøt¸l¸tøtøtøløt¸tøtøløtøtøl¸t¸t¸tøt¸tøtøtøtøl¸løt¸tøtøtøtøtøt¸tøt¸tøtøl¸tøt¸tøtøtøtøtøtøtøtøtøtøtøtøl¸t¸tøtøtøløt¸t¸tøtøtøløtøtøtøtøtøl¸tøl¸tøtøtøløt¸t¸løtøt¸tøtøt¸tøtøt¸tøtøt¸tøt¸tøtøtøløtøtøløtøtøtøtøtøtøtøtøt¸tøtøtøtøtøløtøtøtøtøløtøtøløtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøtøtøtøtøløløløtøtøtøtøtøtøløtøtøtøtøtøtøløl¸tøtøtøtøtøtøtøtøtyzû¥;®ýξïÿÿÿÿÿÿ~çüÎ;®{¶|¾|¾¼¾;®û¥y9}øtøtøtøtøtøtøtøløløløtøtøt¸tøtøtøl¸løtøtøtøt¸løtøtøtøt¸tøtøtøtøt¸tøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøtøtøtøløløtøtøt¸løtøtøtøtøtøt¸tøtøløtøt¸tøtøløtøtøtøtøtøløtøløløløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøløtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløløtøtøløløløtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøløtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøløtù|z;®ýÖ~ç~ï¾÷ÿ÷ÿÿÿÿÿÿ¿÷~ç¼Æû¥9
øtù|ù|ù|øtøtøtøtøtøtøtøtøtøtøløløtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøløtøløløtøtøtøløtøtøløtøtøtøløløløløtøtøtøtøtøtøløtøløtøløtøtøtøtøtøløløløtøtøtøløtøløtøtøtøløtøløløtøtøløtøtøtøtøløløtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøløtøtøtøtøtøtøløløtøtøtøtøløtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøløløtøtøtøtøtøtøtøtøløløtøtøtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøløløløtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøt9};®>ß¾÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷¼Æ{¶;®øtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøløløtøtøtøtøløtøtøtøtøtøtøtøtøløtøløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøløtøtøløtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøløløløtøtøtøtøløtøtøtøtøtøtøløløløtøtøtøløtøløtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøt9}|¶~ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷¼Æºù|øtøtøtøtøløtøtøtøtøtøløløtøtøtøtøtøtøtøløløtøtøtøtøløtøløløtøløtøtøløtøtøtøtøtøtøtøtøløtøløtøtøtøtøløløtøtøtøtøtøløtøløtøtøtøtøtøtøtøløløtøtøtøløtøtøtøtøløtøløtøløtøløløtøtøløtøtøløtøtøtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøløtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøty
|¾~ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ï¼Æzøtøtøtøtøløløtøtøtøløløløtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøløløløtøtøtøtøtøtøtøløløtøtøtøtøtøløløtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøløtøløtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøløtøløtøløtøtøtøløtøløtøtøtøløtøtøtøtøtøtøtøtøløløløtøtøtøtøtøløtøtøtøløtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøløløløly
¼¾¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷=ßû¥9}øtøtøtøtøtøtøtøtøløtøtøløtøtøtøløtøtøtøtøtøløtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøløtøtøløløtøtøtøløtøtøløtøtøtøtøtøløtøtøtøtøløtøtøtøtøtøtøtøtøløtøtøtøløløløtøtøtøtøtøløtøtøløløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøtøløtøløtøtøtøtøtøtøtøtøløløtøtøløtøtøtøtøtøløløløtøløtøtøtøtøløtøløtøtøtøtøtøløløløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøløtøtøtøtøløtøtøløtøtøtøtøtøløtøtøtøtøtøtøt{¶¾ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~ï¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ïû¥9}øtøløtøløtøtøtøtøtøtøløtøtøløtøløløløtøtøtøtøtøløtøløtøtøløtøtøtøløtøløtøtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøløløløtøløtøløtøtøtøtøtøtøtøtøløtøtøløtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøløtøløtøtøtøtøtøtøløløtøtøløløløtøtøtøløtøtøløløtøtøtøtøtøtøtøtøløtøløtøtøtøløtøtøløtøtøtùtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøtøtøtøtøtøløløtøtøtøtøtøløløløtøløtøtøløtøløløløtøtøtùtøtøtøtøtùløtøtøtøtøtøtøløtøtøtùtøtøtøtøtº=×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¾ï;®~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷=ߺùtøtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøtøløtøløtøløtøløtøtøtøløtøtøtøløtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtølùtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøløtøtøløtøtøløløtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtølùløtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøtùtølùtølùtùtølùtøtøtùtøtùtøløtøtùtùtøtùtùlùtùtøtùtøtøtøløtøtøtùtølùtùtùtøtùtùtùtùtøtùtølùlùløtøtøtølùtùløtùtùlùtùtølølùtùtølùløtøtøtølùtùtùtøtøløtùtùtùtùtz=×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ýκýÎÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ýÎ9}ùtùlùlùtùtøtøtølùtøløtøtøtøtølùtùtøtùlùtùlølùtøtùtøløtøtøløløtølølølùlùtøtølùtøtøløløtøtùtøtùlùtùløtøtùtøtøtøløtøtøtøløtùtølùtùtùtøtùtøtøtùløløtøtøtøtùtøtùtøløtøtùtùtøtøtùtøtøtøtøtølùtùtøtøløtøtøløtøtùtùtùtøtùløtùtøløløtùtøtølùtùlølùtùtøtùløtùtøtøtøtùtùtølùtøløløtøtøløtùtøtùtøtùtùtùtùtùlùtùtùtùtùtùløtùtùtùlùtùtùtùtùtùtùtøtùtùtùlùløtùlùtùtùtùtùløtùtùlùtøtùtùlùtùtùtùtùlùtùtùtùtùlùtùlùlùtøtùtùtùtùtùtùtùlùtùlùtùtùtùlùtùløtùtùtølùtùtº¼Æ~ç~ç¾ï¾ï¾ï¿÷¾ï=ßû9}|¶¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~çºùtøtùtùtùtùtùlùtølùlùtùtùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùlùtùløtùtùtùlùtùtùlùtùtøtùlùtùtùtùtùtùtùtùtùtølùtùtùlùtùtùløtùløtùtùlùtùtùlùlùtùtùtùlùtùlùtùtùlùlùlùtùtùlùtùlùlùtùtùtùlùtùtùtùtùtùlùtùtùlùtùlùtùtølùtùlùtùtùtùtùtùtùtùlùtøtùtùlùtùløtùtølùtùtùtùtùtùlùtøtùtùtùtøtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùlùlùlùtùlùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùlùlùlùtùtùtùtùlùtùlùtùtùtùtùlùt9}ºz»;®|¶<¶º9}ùtº=׿÷¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ~ïzùtùtùtùtùtùtùtùlùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùtùtùtùtùtùlùlùtùlùtùtùlùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùlùlùtùtùtùtùtùtùtùlùtùtùtùtùlùtùlùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùlùtùtùtùtùtùlùtùtùlùtùtùtùtùlùtùlùtùtùtùtùtùtùtùlùlùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùtùlùtùlùtùtùtùlùtùtùlùtùtùlùtùtùtùlùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùt9}9}ùtùtùt9}û¼ÆýÎýÖ~ç~ç¾ï¾ï>ß¼¾z
ùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùlùlùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùlùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùlùlùtùtùlùtùtùtùlùlùtùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùtùt9}9
zzº»ºº9}ùtùlùtùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùlùtùtùtùtùlùtùtùtùlùtùtùtùlùtùlùlùtùtùlùtùtùlùlùtùtùlùtùtùtùlùtùlùtùtùtùlùlùlùtùtùlùtùlùtùlùtùlùtùtùlùtùtùlùlùtùlùtùtùtùtùtùlùlùtùtùlùtùtùtùlùtùtùtùlùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùtùlùlùlùtùtùlùlùtùtùlùtùlùtùlùtùlùtùlùtùlùtùlùtùtùlùtùtùtùlùtùtùtùlùtùtùtùlùlùlùtùtùtùlùtùtùtùlùtùtùtùtùlùlùlùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùtùtùtùtùlùtùlùtùtùlùlùlùlùlùtùtùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùlùlùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùlùtùtùlùlùlùtùlùlùtùlùtùtùtùtùtùtùtùlùtùtùtùlùtùlùtùlùlùtùlùlùtùtùtùtùtùtùlùlùtùlùlùtùlùtùtùlùtùtùtùlùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùlùtùtùlùtùlùtùtùtùlùtùlùlùtùtùtùtùtùtùlùtùtùlùlùtùlùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùtùlùtùlùlùtùlùtùlùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùtùlùtùlùlùlùtùlùtùtùlùtùtùlùtùtùlùtùtùtùtùlùtùtùtùtùlùtùtùlùlùlùtùlùtùtùlùtùlùtùtùtùtùtùlùtùlùtùlùlùtùlùtùtùtùtùlùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùlùtùlùtùlùtùlùtùtùtùtùlùlùlùtùtùtùtùlùlùtùtùtùlùtùtùtùtùlùlùlùtùtùtùtùlùtùlùtùlùtùtùtùtùtùlùlùtùlùtùtùtùtùtùlùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùlùlùlùtùlùlùtùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùlùtùtùtùtùlùtùlùtùtùtùtùlùlùlùtùlùtùtùtùtùtùlùtùtùtùtùlùlùtùlùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùtùtùlùlùlùlùlùtùtùlùlùtùtùtùtùlùtùlùtùtùlùtùlùtùtùlùtùtùlùlùtùtùtùlùtùlùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùlùlùtùlùtùlùtùtùtùlùtùtùtùlùtùlùlùtùtùtùtùlùlùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùlùtùtùtùtùlùtùlùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùlùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùlùlùtùlùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùlùlùlùlùlùlùtùtùtùtùlùlùlùtùtùtùtùtùlùtùtùtùlùlùlùlùtùtùtùlùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùtùtùtùlùtùtùlùtùlùtùtùtùtùlùlùtùtùtùtùlùtùtùlùtùtùtùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùlùlùtùlùlùtùtùtùlùlùtùtùlùtùtùtùtùlùtùlùtùtùtùtùtùlùtùtùlùtùtùlùtùlùlùtùlùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùtùtùtùtùtùtùtùlùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùlùlùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùtùlùtùtùlùtùtùtùlùtùlùtùlùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùlùtùlùlùtùlùlùtùlùtùtùtùtùlùtùtùtùlùlùtùlùtùlùtùlùtùlùtùtùlùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùlùlùlùlùtùtùlùtùlùtùtùlùlùtùtùtùlùlùtùtùtùtùtùtùtùlùtùlùtùlùlùtùtùtùtùtùtùlùtùtùtùtùlùtùlùtùtùlùtùlùtùtùtùlùtùlùtùtùlùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùlùtùlùlùtùlùtùlùlùtùtùtùlùtùtùtùtùtùlùlùtùlùtùtùtùtùlùtùlùtùtùtùtùtùtùlùtùlùlùtùlùtùlùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùtùlùlùtùlùlùlùtùlùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùlùtùlùtùtùlùtùtùtùtùlùtùtùtùtùlùlùtùlùtùlùtùtùtùlùtùtùtùtùtùtùlùtùtùtùlùtùtùtùlùlùlùtùtùtùlùlùtùtùtùlùlùtùtùtùtùtùlùlùtùtùtùlùlùtùtùlùtùlùlùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùlùtùtùlùtùlùtùtùlùtùlùtùtùtùtùtùlùlùlùtùlùtùtùlùtùlùlùlùlùtùtùlùtùtùtùlùtùtùlùtùlùtùlùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùlùtùtùtùtùtùlùlùlùlùtùtùtùlùlùtùtùtùtùlùtùtùtùlùtùtùtùtùtùlùlùtùtùtùlùlùlùtùtùlùtùtùtùlùtùtùtùlùtùlùtùlùlùlùtùlùtùlùlùtùtùtùtùlùtùlùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùtùlùlùtùtùtùtùtùlùlùtùlùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùlùlùtùlùtùtùtùlùlùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùlùtùtùlùtùlùtùtùlùtùlùlùtùtùtùtùtùtùlùlùtùtùtùtùtùlùtùlùlùlùtùlùtùlùtùlùlùtùtùtùlùlùtùtùtùtùtùlùlùlùtùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùtùlùtùtùtùlùlùlùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùlùlùtùlùlùlùtùtùtùtùtùtùtùlùtùlùtùlùlùlùlùtùtùtùtùtùlùtùlùlùtùtùlùtùtùtùlùtùlùlùlùlùtùtùtùlùtùlùtùtùtùlùtùlùlùtùlùtùtùlùlùlùtùtùtùlùlùlùlùlùlùlùlùtùtùlùtùtùtùtùtº|¾|¾ûùlùlùtùtùtùtùtùtùtùlùtùtùtùtùlùtùlùlùtùtùlùtùlùlùtùtùlùtùlùtùlùtùtùlùtùtùtùtùtùlùtùtùlùtùlùtùtùtùtùlùtùtùlùtùtùlùtùtùtùtùtùtùlùtùlùlùlùlùtùtùtùtùtùtùlùtùtùlùtùtùtùtùtùl:}ºz:}9uùlùlùlùtùtùtùlùtùtùtùtùtùtùtùlùtùtùlùtùtùtùlùtùlùtùlùlùtùlùlùtùtùlùtùlùtùlùtùlùtùlùtùtùtùtùtùtùlùlùtùtùtùlùtùlùtùtùtùlùlùlùtùlùtùtùtùtùtùlùtùtùlùlùtùtùtùlùlùtùtùlùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùlùtùlùlùtùtùtùlùtùtùtùlùtùtùlùtùtùlùtùtùtùtùlùlùlùlùlùlùlùtùlùtùlùtùlùlùtùlùtùlùlùtùtùtùtùtùtùtùtùtùt¼¾¾ï¿÷=×ûùtùlùlùtùtùlùlùlùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùlùlùlùtùlùtùtùtùlùtùtùlùtùtùlùlùtùtùtùtùlùlùtùlùlùtùlùlùtùlùtùtùtùtùtùtùtùtùlùlùlùtùtùlùt:}|¶~ß~ç½Æûzùtùtùtùlùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùlùtùtùtùlùtùtùlùlùtùtùlùtùlùtùlùtùlùlùlùlùtùlùlùtùtùlùlùlùlùtùtùlùlùtùtùtùtùtùtùtùtùlùtùtùlùtùlùlùtùtùlùlùtùtùtùtùlùtùtùtùlùlùlùlùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùtùtùlùlùtùlùlùtùtùtùtùtùtùtùtùtùtùtz>ßÿÿÿÿ¿÷½Æ:
ùlùtùtùtùtùtùtùlùlùtùtùtùtùtùtùlùlùtùlùlùlùtùlùtùlùtùtùtùlùtùtùlùtùlùtùtùtùtùtùtùlùtùlùtùtùlùtùtùtùtùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùlùtùlùtùtùtùtùtùl:}ýÖÿÿÿÿÿÿ~ïýÎ;¦:}ùtùtùtùtùlùlùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùlùtùlùtùlùtùtùtùlùtùtùlùtùlùtùlùtùtùlùtùlùlùtùtùtùtùlùtùlùlùlùtùlùtùlùlùtùtùtùlùlùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùlùtùlùtùtùtùtùlùtùtùlùtùtùtùtùlùtùtùtùtùlùtùtùtùtùlùtùtùlùtùlùtùlùtùtùlùtùtùtùlùlùlùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùt<®¾ïÿÿÿÿÿÿ~ç;¦9uùlùlùlùtùlùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùlùtùlùlùlùtùtùtùlùtùtùtùlùtùtùlùlùtùtùtùtùtùlùtùtùtùlùtùlùtùtùlùtùtùlùtùlùlùtùlùtùlùtùtùlùtùlùtùtùtùtùlùlùlùlùlùlùtùlùt:u|¾ÿÿÿÿÿÿÿÿÿÿ=×z
:u:}:}ùtùtùtùtùtùlùlùtùtùtùlùtùtùlùlùtùlùlùtùlùlùtùtùlùtùlùtùtùtùtùlùtùtùtùlùlùtùlùlùtùtùlùtùlùtùtùlùtùtùlùtùlùlùtùlùtùlùtùlùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùlùlùlùlùtùtùtùlùtùtùlùtùtùlùlùtùtùtùtùtùtùlùtùtùtùlùtùlùlùlùtùtùtùtùtùlùlùtùtùtùlùtùlùtùlùtùtùlùlùtùlùlùtùtùtùlùlùtùtùtùl:}½Æÿ÷ÿÿÿÿÿÿÿÿ=×»ùtùlùtùtùtùlùtùtùtùtùlùlùlùlùtùlùlùtùtùlùtùtùtùlùtùtùtùtùtùlùlùtùtùtùlùtùtùtùtùtùlùtùlùtùlùlùlùtùtùtùtùtùtùlùtùtùtùlùlùtùlùlùtùtùtùtùtùlùtùtùtùlùlùlùlùtùlùlùtùtútû~çÿÿÿÿÿÿÿÿ~ç»<®½Æ|¾û¥:}:uùtùtùtùtùtùlùlùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùlùlùtùtùlùlùtùtùlùlùtùtùlùlùlùtùtùtùtùtùlùlùtùtùtùlùtùtùtùtùlùlùtùtùtùtùlùtùlùlùtùtùlùtùtùtùtùtùtùtùlùtùlùlùtùtùtùtùtùtùtùtùtùlùtùtùtùlùlùlùtùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùlùtùtùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùlùlùtútz=×ÿ÷ÿÿÿÿÿÿÿÿ¿÷ýÎz
ùtùtùlùtùtùlùlùtùtùtùtùtùtùtùtùlùtùlùlùtùtùlùtùlùtùtùlùtùtùlùtùtùtùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùlútútùtútútùlútùtùtútútùtùtùtùtùtùtùtùtútùt:u|¾ÿÿÿÿÿÿÿÿ~ïýÆ~ßÿÿ¿÷~çýÖ<®z
ùtùtúlùlùtúlútútùtùtùtútùtùtùlútútùlútúlùtúlùtútútùtùlùtútùtùlùtùlùtùtúlútúlùtúlùlúlùtùlùtùtúlùtùlútútúlùtùtútúlúlùlùtútùtúlúlùtùtútútùlúlútùlùtùtútùtùlùtùtùtùtùlúlúlùtútùtùlùtútùtútútútúlùlùlùlùtúlútùlúlúlùtútúlùtútútúlùlútùlútùtùtúlúlùtùlúlútùlùtùtúlùtùtùtùlútùtúlútútz~çÿÿÿÿÿÿÿÿÿÿÿÿ¾ï|¶:uútùlùlùlúlútùtútùtútúlùtùtútútùlùtùtùtùtùtùlútùlútùlúlùtúlútùlùlùlùlútùlùlútútútùlùlùtùtùlùtúlútútùtútútùtùtútútúlúlúlútúlútúlútútútútútútútútúlúlútùtútútùlùt:u»ýο÷ÿÿÿÿÿ÷¿÷ÿ÷ÿÿÿÿÿÿÿ÷ÿÿ½Æ:}útúlùtùtùlútúlùlùtùtúlúlútúlùlútúlúlúlúlúlútútútútúlútútúlútútútútùlúlútúlútúlútúlútùtútútúlútúlútútútútùtùlútútùtútùtúlútúlúlútútúlúlùtúlútúlútúlútútúlùlúlútútútúlútútútùlúlútútùtútútúlútútúlútúlúlùtútútútùtútútùlútútútùtútútùlúlútúlùtùtùtùlútútúlútútútùtúlùlútùlútút»¾ïÿÿÿÿÿÿÿÿÿÿÿÿ¿÷½Æ:}útúlúlúlútútùtútúlútútúlútútútútútútúlútúlútùlútùtútúlúlúlúlútúlútúlúlútúlúlútúlútútúlùtùlútúlùtútútútútúlútútútútútútúlúlútúlútúlútútúlúlúlúlúlúlúl:u{
z}{
:u:uz
|¶~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýλútútútúlútúlúlútútútútútútútútútúlútúlútúlútúlútútúlúlúlútútútútútútútúlútútútútúlútútúlútútútútútúlúlúlúlúlúlútútútútútúlútúlútútúlútúlútúlútútúlúlútútútútútútúlútúlúlúlútútútúlútútútúlútútúlúlútútúlútúlútútúlúlútútúlútútúlúlútúlútútútútúlútúlútúlútúlútútútúlútútúl:u»¾ïÿÿÿÿÿÿÿÿÿÿÿÿ¿ï½¾:}útútútútútútútútútúlútúlútútúlútúlúlútúlútúlúlútútúlútúlúlútúlútútútúlútúlútútútútútúlúlúlútúlútútúlútúlúlútútútútútúlútútútúlútútútútútúlútútútúl:}<®>×>ßýÎýÆ<¦<¦ýÆ~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ýÎûútútúlúlúlútúlútútúlútúlútútúlúlúlútútúlútúlútútúlútútúlúlútútútútútúlúlútútútúlútútútúlútútútúlúlúlúlúlútúlútútútúlúlúlútútúlúlúlúlútútúlútútútúlúlúlúlútútúlútútútúlútútútúlúlútútútúlúlútútúlútúlútúlútútútútútúlútúlútúlútútútútúlúlúlútútútúlúlútútútútúlútútútútútúlúlút»~çÿÿÿÿÿÿÿÿÿÿ¿÷~ç»:u:u:uútúlútútútútútútútútúlútútútútútútútútúlúlútútúlúlútúlúlútúlúlúlúlútútútútúlútúlúlútúlútúlútútútútúlútútútúlúlúlúlútútútútútútútúlútútútútúlút:}ýÎÿÿÿÿÿÿ¿÷ÿÿ~ç~ç¿÷ÿÿÿÿ¿÷¿ï¿÷¿÷¿ïýÖ|®:}úlúlúlútútúlúlútútútútútúlútútútútútútútúlúlútúlútúlútúlúlúlúlútútúlúlúlúlútúlúlúlútútútútútúlútútútúlúlútúlútútúlútútútúlútúlútútútúlúlúlútútútúlúlúlútútútútúlúlútútútútúlútútútúlútútútútútúlúlútúlútútúlútúlúlúlútúlútútútúlútútúlútúlútútútúlútútúlútútútúlútúlúlútútúlút:u»>ßÿ÷ÿÿÿÿÿÿÿÿ¿÷|¶»ü<®û:}útútútútúlúlútúlútútútútútúlútútúlútútútútútútútútútútútúlútútútútútútúlútútúlútútútútútútútúlútútútútúlútúlútútúlúlútútútúlútútútútúlútútút:u½¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>ß|¶<®|®<®û:}:uútútútútútúlútútútúlúlútútúlúlútúlútútútútútúlúlúlútúlúlúlútútútúlúlúlúlútútútúlútútútútútútúlútútútúlútúlúlúlútútútúlútútúlútútútúlúlútúlútútútúlúlútútúlútúlúlútúlútúlútútútútútútúlútútútútúlútútútúlútútútútúlútúlútútútútúlútútúlútútútútútútútútúlútútútútútúlúlúlúlútútút:u{
½¾ÿÿÿÿÿÿÿÿÿÿ¿÷>ß>ß¾ï¿ï¿ï<®:}útútútúlúlúlútútútútútútútútúlútúlútúlútútútútúlúlúlúlútútútútúlútúlútútúlútúlútútúlútúlútútútúlúlúlúlútúlútútúlútúlúlútúlúlútútúlútúlúlúlút{
ýÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>×{:u:}:u:uútútútútúlútútúlúlútúlútútútútútútúlúlútúlútútútútútúlútúlúlútúlútúlúlútúlútútúlútúlútútútútúlúlúlúlúlúlútútútútútúlútúlútútútútútúlúlútúlúlútúlútútútúlúlútútútútútútúlútútúlúlútúlúlútúlútútúlúlúlúlútútúlútúlúlútútúlúlúlútúlútútútúlútútútúlútúlútútútútútútúlúlútúlútútútútútútút:}<¦¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¾ï<¦:uútúlútúlútúlúlúlúlútútútútútútúlútútúlútútútúlútúlúlútútútútútúlúlútúlútúlúlútúlúlútútútúlútúlúlútúlútútútútúlúlútútúlútútúlúlúlútútútúlút:uü>׿÷ÿÿÿÿÿ÷ÿÿÿÿÿÿ~çû:uútúlúlútútútútútútúlútútúlúlútútútútútútútútúlúlútútúlúlútúlúlúlútútúlútútútútútúlútúlúlúlútúlútúlútúlútútúlúlútútútúlúlúlútúlútútútúlúlútúlúlúlúlúlúlútúlútúlútútútúlútútúlútúlúlúlúlúlútúlútútútúlútútúlútútúlútúlúlúlútútúlúlúlútúlútúlútútútúlútúlútúlútúlútútútútútúlútútútút:u:u{}:u:u:}û~ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷>ßû:uútútútútúlútútúlúlútútútúlútúlúlúlútútútútúlútútúlúlútúlútútútúlútútútúlútúlúlútútúlúlútúlútúlútúlúlútútúlúlúlútútútútútúlúlútúlútútúlútúlútü~ç~ç>ß>ß¿÷ÿÿÿÿ¿÷½¾:}útútútútúlúlútútúlútútúlúlúlúlútúlúlúlútútútúlúlútúlútútútúlútútútútútúlútútútútúlútútútútútútúlútútúlútútútúlúlúlútúlútútúlútúlútútútúlútútútútútútúlúlúlútútútútútútúlúlútútútúlútútúlútúlútútúlútúlútútútútútútútútútúlútúlútúlútútútútúlúlútútútútútútútúlúlúlúlútútút:u:}:}»»û»»»»<®>×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷½Æ{
:uútúlútútúlútúlútúlúlúlútútútútútútútúlútútúlútúlútútútútútútútúlútútútútúlútútútútútúlúlúlútútútútúl:uúlúlúlútútútúlútúlútútúlúlúlútúlútút:u»ü{
ýοïÿÿÿÿÿÿýÎ:}úlúlúlút:múl:uútútútúlútúlúlútúlúlúlút:m:m:múlútútúl:uútútúlúlúlútútút:uút:múlúlút:múlúlútúl:uúlúlúlúlúlútútútúlútútúlúlútútútúlúlútútúlúlút:uútútútúlútútúlútút:uútúlútúlúlúlútúlútúlútútútútútúlúlúlútút:múlútúlútútúlútútútúlúl:uútútútút:mútúl:uúlúlúlúlúl:uúlútút:u:}»|¶>×~ç~ç~ï~ï~ç>×ýÆ>×¾ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ï<®:uút:u:múlútútútúlúlút:uútútútútúlút:uúlútútút:uúlútúlútút:mútúlútútút:m:uútútútúlútútút:uút:m:u:u:u:uút:uúl:u:mútút:u:m:m:mút:m:uúlút:m:mútútúl:u»>ßÿÿÿÿÿÿÿÿ~ç{útútútúl:m:mútúlút:uútúlúlút:múl:u:uúl:mútúl:m:uúl:u:uúl:uútúlúlút:uútút:uúlútúlúlúl:uútútút:u:múl:uúlúl:u:m:mútút:uútúlút:mút:mútútút:m:uútútúl:u:m:uúl:m:uúl:uúlútúl:u:u:múl:uútút:u:u:múl:uútút:múl:uútútúl:uútútúl:u:u:u:múl:u:múl:uút:múl:múlútút:u:mútúlúl:uúl:u»½¾~ç¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿ÷ÿ÷¿÷ÿÿÿÿÿÿÿÿ¿÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>×{
útúl:uúlúlúl:múlúlúl:mút:mútútút:uúlúlútúlútúl:m:mút:u:m:múl:m:uútút:m:uúlút:mútúl:m:uúlútúlúlúlúl:m:m:m:uúlút:uúlútút:u:uúl:uút:m:m:uútúlútút:u{
þÖÿ÷ÿÿÿÿÿÿ>ß»út:uúl:m:uúlúlútút:u:uút:u:múlúl:u:u:uúl:u:mútút:uúlúl:mútút:m:mút:uúlúl:u:u:uút:u:m:uútúl:uúlútút:mút:uúl:m:múl:u:múl:uútút:uút:mút:mútúl:múl:u:u:u:múlút:u:m:uút:múl:m:u:m:uútúlúlúl:u:m:uút:u:uút:m:múlút:u:mútúlút:uút:m:u:uút:uútútúl:u:múlút:uútút:m:m:uút:uúl}¶>ß¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~ç>×>׿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ï<¦:u:mút:uúl:u:múlútúlúl:uúlúl:m:múl:u:m:mút:u:m:u:m:mútút:uút:uút:u:m:m:u:mút:mút:múlútúl:m:m:m:m:u:u:u:u:u:mút:u:uút:u:u:m:u:u:mút:u:u:mút:mút:u:u<®¾ïÿÿÿÿÿ÷>ß{
úl:u:uúl:u:u:m:m:u:m:uúl:u:m:u:u:uúl:m:m:u:m:u:m:u:u:u:u:u:u:m:u:m:mút:u:u:mútúl:u:mút:m:u:u:uútúl:m:m:u:u:mútúl:u:m:mút:u:u:u:uúl:m:m:u:m:uút:u:mút:u:uút:u:m:m:m:m:m:m:u:mútúl:u:m:m:m:u:u:m:m:m:u:u:u:mútút:u:u:u:m:m:u:m:u:m:m:u:u:mút:m:m:u:m:u:m:u:uút:u:m:uü~çÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ç>ß½Æ<¦üýÎ~ï¿÷ÿ÷ÿÿÿÿÿÿ¾ïü:u:u:u:m:u:u:u:u:u:u:u:m:uúl:mútút:u:u:u:múl:u:u:m:m:uút:u:m:m:u:m:m:uút:u:uút:m:m:m:m:m:m:u:m:u:m:u:u:m:u:m:m:u:u:u:u:u:m:u:m:u:u:u:m:m:u:m:u:m:u:u<®¿ïÿÿÿÿ½Æ:}:m:m:u:m:m:u:u:m:u:u:u:m:m:u:m:m:m:u:u:u:u:u:u:u:u:u:u:m:u:m:m:u:m:u:u:m:u:m:u:u:m:u:m:u:m:m:m:m:m:m:u:m:m:m:m:m:m:m:m:m:m:m:u:u:u:u:m:u:u:u:u:u:m:u:u:u:u:m:u:u:u:m:u:m:u:u:u:u:u:m:u:m:u:m:u:u:u:u:u:u:u:u:u:u:m:m:u:u:u:m:m:m:m:m:u:u:m:u:u:u:m:m:m:m:m:m:u:m:u»~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷|¶½Æü;}{}»½¾ýÎ>ß~ç>ß½¾»:u:m:m:m:m:u:u:m:m:m:u:u:m:m:u:u:u:m:u:u:u:m:u:u:m:u:u:m:m:m:m:u:m:u:m:m:u:u:m:u:u:u:u:m:u:u:u:u:u:m:u:m:m:u:u:m:m:u:u:m:u:m:u:m:m:m:m:u:m:u:u:m:m:m{}½¾~ï¾ï<®:u:u:m:u:m:u:m:m:m:m:u:u:u:m:u:m:m:m:u:u:u:u:u:m:u:u:u:u:m:u:u:u:m:u:m:m:u:u:m:u:m:u:u:m:m:m:u:u:m:m:u:m:m:m:m:m:m:u:u:u:u:u:m:m:u:u:u:u:u:u:u:m:u:m:m:m:u:u:m:m:m:u:m:m:u:m:m:m:m:m:m:u:m:u:u:u:m:m:u:m:u:m:u:u:u:m:u:u:m:u:u:m:u:u:u:m:u:m:u:u:m:m:m:m:m:m:u:m:m:m;uü~ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿ¿÷>ß»{}:u:u:u;}{
»»»
;};u:u:u:u:m:u:u:m:m:u:m:u:m:m:m:u:u:u:m:m:m:u:u:u:m:u:u:u:u:m:u:u:m:u:m:m:m:m:u:u:m:m:u:m:m:u:u:u:u:m:u:u:u:m:m:u:u:u:u:m:m:m:m:u:u:m:m:u:u:u:m:u:m:m:u:u:u}¶|¶»:u:m:m:u:u:m:m:m:m:m:m:u:m:u:u:u:u:m:m:u:u:u:u:u:m:m:u:u:m:u:u:u:u:u:u:m:u:u:m:m:u:m:u:m:u:u:u:m:u:u:u:u:u:u:u:u:m:u:m:m:m:u:u:u:m:m:u:u:m:m:u:u:m:m:u:u:u:m:m:u:m:m:u:m:u:m:m:u:m:m:m:m:u:u:u:u:m:u:m:m:u:m:m:m:u:u:u:m:m:m:m:m:m:m:u:m:u:u:u:u:m:m:m:u:m:u:u:u:u:m:m;u»½Æ~ç¿÷ÿ÷ÿÿÿÿÿÿ¿÷~ß~çÿÿÿÿÿÿÿÿÿÿ¿ï|®{}:u:m:m:m:u:u:u:u:u:u:m:u:m:u:u:m:m:m:m:m:m:m:m:m:u:u:u:m:u:u:m:u:m:m:u:u:u:m:u:m:m:u:u:u:u:m:u:u:u:m:m:u:u:u:u:m:u:m:u:m:m:u:u:m:m:m:m:m:u:u:m:u:u:u:m:m:u:u:u:u:u:u:u:m:m:m;}{}:m:u:u:m:m:m:u:m:u:m:m:m:u:m:m:m:u:m:m:m:u:u:m:m:u:u:u:m:m:m:m:m:u:u:m:u:m:m:m:u:m:m:u:m:u:m:m:u:u:u:m:m:u:m:m:u:u:m:u:m:u:m:m:u:u:u:u:u:m:m:m:m:u:u:m:m:u:u:m:m:m:u:u:u:u:m:u:u:m:m:m:u:u:m:m:u:u:u:u:u:m:u:u:u:u:u:u:u:u:m:m:u:m:u:u:m:m:m:m:u:u:u:m:m:u:m:m:u:u:u:u:m:m;u;u»½Æ~ß¿÷ÿ÷¾ï>×<¦>ßÿÿÿÿÿÿÿÿÿÿÿÿ~ç»;u:u:u:u:u:u:u:u:u:m:u:m:u:m:m:u:u:u:u:m:u:m:u:m:u:u:u:u:m:m:u:u:m:u:u:m:u:u:u:u:u:u:u:u:m:u:u:m:m:m:u:u:u:u:u:m:m:u:u:u:u:m:m:u:u:m:m:u:u;u:m;m:u;m:u:u:m;u:m;u:u:m:m:u;u:u;m:u:m;m:u:u:m:u:m:u:u:m:m:m;u:m:u;m:u:u:m;u:m;u:m;u:u;u:u:u:u:u:u:u;m:u:m:u;m:m:u:u:u;u;m:m;u:m;u:m:m:m;u:u:u;u:m:m:u:u;m;m:u;u:m:m;u:m:m:m;u:u:m:u;u:u;u;m:m;m:m:u:u:u;u;m;u:m:m:u:u:u:u:m;u;m;m:u:u:m:m:u:u:u:m:u:u;u:u;m:m;u:u:m:u:u:m:u;u:m;u:m:m:m:u:u;m:u:u:u;u;u:u:u:u;m;u:u{}ü½¾>×½¾»»
~ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¾{}:m:m:m;m:m:u:m;u;m:u:u:m;m:m:m:u:m:m:m:m;m:u:u:u:u:u:m:m:m:m:m;m:m:u:u:u:m;u:u:u:u:m:m:m:m:m:m:m;u:m:u:m;m:m:m:u;m;u;u:m;m;m;m;m;m;u;u;u:u;u;m;m;u;m;m:m;m;m;m;u:m;u;m;u;m:m;u;m;m;u;m:m;m;m;u;u;m;u;m;m;u:m:u;u;u:u;m:u;u;u;m;m;u;m;m;u;m:m;m;m:u;m;u:u;u:u:m;m:u;m;u;m;m;u;u:u;u;m;u;m;u:m:m;u:u;u;u;u;m:m;m:u;m;u;u;u;u;u:m;u:m:m;u:m;m:u;u;u;u;m;m:m:u;u;u;u;u;m:m;u;m;m;m:u;u;u:m;m;u:m:u;m:u:m:u;m:u;m;m:u;m;u;u;m;m;u:m;u;m;u;m;m:u;u:m;u;u:m;m;u;m;u:u;m;u{}{}{};u»~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾ïü;u;m;m:u;u;m;u:m;m;m;m:u:u:m;u;u;u:u:m;m;u;m:u:m;m;u;u;u;m:m:u;m;m;u;m:u;u;m:m;m:u:u:u;u;u;m;m;m;m;u;u:u;m;u;u:u;m;m;m;u;m;m;m;m;u;u;u;u;m;u;m;u;m;m;m;m;m;m;m;m;u;m;m;u;m;m;u;u;u;m;m;m;u;u;u;u;u;m;m;u;m;u;u;u;u;m;u;u;u;m;u;m;u;u;m;m;u;u;u;m;m;u;m;u;u;m;u;u;u;u;u;u;u;m;u;u;m;u;u;u;m;u;u;m;m;u;m;u;u;u;m;u;m;m;m;m;u;u;m;m;u;m;u;u;u;m;m;u;u;m;m;u;m;m;m;u;m;m;m;u;m;m;m;m;u;m;m;u;m;u;m;m;u;m;u;u;u;u;u;m;m;m;m;m;u;u;m;m;u;u;m;u;m;u;u;m;m;u;m;m;u;m;m;u;m;u;u;u;u»>׿÷ÿÿÿÿÿÿÿÿÿÿÿÿ¿÷}®;u;u;u;u;u;m;m;u;u;u;m;m;m;m;m;u;u;u;u;m;m;m;m;u;u;m;u;u;m;u;u;u;u;u;u;m;m;u;m;u;u;m;m;u;u;m;m;u;m;m;u;m;m;m;u;m;u;u;u;m;u;m;m;m;m;m;m;u;m;u;m;u;u;m;m;m;m;m;m;m;m;u;u;u;m;m;u;m;u;u;m;u;m;u;m;m;m;u;u;u;u;m;m;u;m;m;u;u;u;u;m;u;u;u;u;u;m;m;u;u;m;u;m;m;u;m;m;u;m;u;m;m;m;u;m;u;m;u;u;m;u;u;u;u;u;u;u;u;m;m;u;u;m;u;m;u;u;u;u;u;u;m;m;m;m;m;m;u;u;u;u;m;m;m;m;u;u;m;u;m;m;m;u;u;m;u;m;u;u;m;u;m;u;m;u;m;m;m;m;u;m;u;u;m;m;u;u;m;u;u;m;m;u;m;m;m;m;u;m;m;u;u;m;m;m;m;m;u;m;}|®>ß¿÷ÿÿÿÿÿÿÿÿÿÿÿÿýÎ{};u;u;m;m;u;u;u;m;m;u;m;u;u;m;m;u;m;u;u;m;m;u;u;u;u;u;m;u;u;m;u;u;u;u;u;u;m;u;m;m;m;u;m;u;u;m;m;u;u;m;m;u;u;m;u;m;m;u;m;m;m;u;u;u;u;u;u;u;u;u;m;m;m;m;m;u;m;u;m;u;u;m;u;m;m;m;u;u;u;u;m;u;m;m;u;m;m;m;m;u;m;u;u;u;m;u;u;m;m;m;m;m;u;u;m;u;m;m;u;m;u;u;u;u;m;u;u;m;u;u;u;u;m;u;m;m;u;u;u;u;u;m;u;u;m;m;m;u;m;u;m;m;m;u;u;m;u;u;u;m;m;u;m;u;m;u;m;m;m;m;m;u;m;u;u;m;m;m;u;m;m;m;m;u;u;u;u;u;u;m;u;u;u;m;m;m;u;m;u;m;m;u;u;u;u;m;m;m;u;u;u;u;m;u;m;m;m;m;u;u;u;u;m;u;m;m;u;m;u{}ü½Æ¿ïÿ÷ÿÿÿÿÿÿÿÿ>×{
;u;u;m;m;m;u;m;m;u;u;u;m;m;m;m;u;u;u;m;m;u;m;m;u;m;m;m;u;u;m;u;m;m;u;m;m;u;m;m;u;u;u;u;u;m;m;u;m;u;m;u;m;m;m;u;m;m;u;u;u;u;m;u;m;u;m;u;u;u;u;m;u;u;m;u;u;u;m;m;u;u;m;u;u;u;u;m;u;m;m;m;m;u;u;m;u;m;m;u;m;u;m;m;m;u;u;u;m;u;u;m;m;m;u;u;u;m;u;m;u;u;m;m;u;u;m;u;u;m;m;u;u;u;u;m;u;u;m;m;m;m;u;m;m;u;u;m;m;m;m;u;u;u;m;u;m;m;u;u;u;u;u;u;m;u;m;u;u;u;u;m;u;u;m;m;m;u;m;m;u;m;u;m;m;u;u;u;m;u;u;m;m;u;m;u;u;m;m;m;u;m;m;m;m;m;m;m;m;u;m;m;m;u;m;m;m;m;u;u;m;u;m;m;u;u;u;m;m;u;u;u»
üþÎ~ç¿÷ÿ÷¿÷ýÎ{};u;u;m;m;u;m;m;u;u;m;u;m;m;u;m;m;m;m;u;u;m;m;u;u;m;m;u;u;u;u;u;u;u;m;u;m;m;m;m;u;m;m;u;m;m;u;m;m;u;m;m;u;m;u;u;m;u;u;m;u;m;u;u;u;u;m;m;m;m;m;u;m;u;u;m;m;m;m;u;u;u;u;u;m;m;u;u;m;u;m;u;u;m;m;m;m;m;m;m;u;m;u;u;u;u;m;m;u;u;u;u;u;u;u;m;u;m;m;m;u;u;u;m;u;u;m;u;u;u;u;m;m;u;u;m;m;m;m;m;m;m;m;u;u;u;u;m;u;u;u;u;m;u;m;u;m;u;m;m;u;u;m;u;u;m;u;m;u;u;m;u;u;m;u;u;u;u;m;m;m;u;m;u;u;m;u;u;m;m;u;m;m;m;m;u;m;m;u;m;m;m;u;m;u;u;u;u;m;u;m;u;u;u;m;m;m;u;u;u;m;m;m;u;m;u;m;m;m;u;u;u;u;u;uü½¾ýÎþÎü;u;u;u;m;u;m;m;m;u;u;u;u;u;u;u;u;u;m;u;m;u;m;m;m;u;m;u;u;u;u;m;u;u;m;u;u;u;m;m;m;m;u;u;u;u;u;u;u;m;u;u;m;u;u;m;m;u;u;u;m;m;m;u;u;u;m;m;u;u;m;m;m;m;u;m;m;m;m;u;m;u;m;m;m;m;u;m;m;u;u;u;m;m;m;u;m;u;m;m;m;m;u;u;m;u;u;u;u;u;m;m;m;u;m;u;m;m;u;m;m;u;m;m;m;u;m;u;u;m;u;m;u;m;m;u;m;m;u;u;u;m;u;u;u;m;u;m;m;u;m;m;u;m;m;u;m;u;u;m;m;m;u;u;u;m;m;m;m;m;m;u;u;m;u;u;m;m;m;u;u;m;u;m;u;m;m;u;m;m;m;m;u;m;m;u;m;u;m;u;u;u;u;m;m;m;m;m;m;u;u;m;m;m;m;u;u;m;m;u;u;u;u;u;m;m;u;m;u;u;m;u;m;u;u;u;u{}{}{}{u;u;u;m;u;u;u;u;u;m;u;m;u;u;u;u;u;m;u;u;u;m;u;u;u;u;u;u;m;m;u;m;u;m;m;u;m;m;u;m;u;u;m;m;m;u;u;m;u;u;u;u;u;m;u;u;u;m;m;u;u;m;u;u;m;u;m;u;u;m;u;m;u;m;m;m;m;m;m;u;u;u;m;u;m;u;m;m;u;u;u;m;m;u;u;u;m;m;u;u;u;m;m;u;m;u;u;m;m;u;u;m;u;u;m;m;u;u;m;m;m;m;m;m;m;u;u;m;u;m;m;m;u;m;u;u;u;u;m;m;m;m;u;u;m;u;u;m;u;u;m;u;u;u;m;u;m;u;m;m;u;u;m;m;u;u;m;m;m;u;m;m;m;m;u;m;u;u;u;m;m;m;u;u;m;m;u;u;u;m;u;m;m;m;u;u;m;u;m;u;u;m;m;u;u;m;m;m;u;m;m;m;u;u;u;m;u;m;u;u;m;m;u;m;u;m;m;u;u;u;m;m;m;m;m;m;u;u;u;u;u;u;m;m;m;m;u;m;u;m;u;m;u;u;u;u;u;m;m;m;u;m;u;u;m;m;m;u;u;u;m;u;m;m;u;u;m;u;m;u;u;m;u;m;m;m;m;u;u;m;m;u;m;m;u;u;u;m;m;m;u;m;u;u;m;m;m;m;u;m;u;u;m;m;u;u;u;u;m;u;u;m;u;m;u;u;m;m;m;m;u;u;m;u;u;m;u;m;m;m;u;m;u;m;m;u;m;u;m;u;u;u;m;m;u;m;u;m;u;m;m;m;m;u;m;u;u;m;u;m;m;m;u;m;m;m;m;m;u;u;u;m;u;u;m;u;u;m;m;m;m;m;u;u;m;m;u;u;m;u;m;m;m;m;m;m;u;u;m;m;u;u;m;u;m;u;m;u;u;u;u;u;m;m;m;m;m;u;m;u;m;m;m;u;m;m;m;m;u;u;m;u;u;u;u;m;m;m;u;u;m;u;m;m;m;u;m;m;u;u;u;m;m;u;u;u;u;u;u;m;u;u;m;m;m;u;m;m;m;u;m;m;u;m;m;m;m;m;u;u;m;u;u;m;u;m;m;u;u;m;m;m;m;m;m;u;m;u;m;u;u;u;m;u;m;u;u;u;u;m;m;m;m;u;m;m;u;m;m;u;u;u;m;m;m;u;m;u;u;m;u;u;u;m;u;m;u;u;m;u;m;u;u;u;u;u;u;u;m;m;m;u;u;u;u;u;m;m;m;u;m;m;u;u;m;m;m;m;u;u;m;m;u;u;m;u;m;m;m;m;m;m;u;m;m;m;m;u;m;u;u;u;u;u;u;m;m;u;m;m;m;m;m;m;u;m;m;u;m;m;u;m;u;m;u;u;m;m;m;m;m;u;u;m;m;u;m;m;u;m;m;u;m;m;m;m;u;u;m;u;u;u;u;m;m;u;m;u;m;m;u;u;u;m;u;m;u;m;m;u;m;m;m;u;m;m;m;m;m;m;m;u;u;m;m;m;m;u;u;m;m;u;u;m;m;m;u;u;u;u;m;u;u;m;m;u;m;m;u;m;m;u;m;u;u;m;m;m;m;u;u;m;u;u;u;u;u;u;u;u;m;m;m;u;m;u;m;m;m;m;u;m;u;u;m;m;m;m;m;m;u;m;u;m;u;u;m;m;u;u;m;u;m;u;u;u;u;m;m;m;u;u;m;m;m;m;u;u;m;m;m;m;m;m;m;u;m;u;m;m;u;m;u;m;m;m;u;u;m;m;m;u;m;m;u;u;u;m;m;m;u;u;m;m;u;m;u;m;m;m;u;m;m;m;u;m;u;m;m;m;m;m;m;m;u;m;u;u;m;m;u;u;m;u;u;m;m;m;u;u;u;u;m;m;m;m;u;u;m;u;m;u;m;m;m;m;u;u;m;m;m;u;u;m;u;u;m;m;m;m;m;u;u;u;m;m;u;m;u;u;u;m;m;m;m;u;u;m;u;u;u;m;m;u;u;m;m;m;m;m;m;m;m;m;u;m;m;m;m;u;u;m;u;m;m;u;m;m;m;u;u;m;u;u;m;m;m;u;m;u;u;u;u;u;m;u;u;m;u;u;m;m;m;m;m;m;m;u;m;u;u;m;u;u;u;m;u;m;m;m;u;m;m;u;m;m;m;m;m;u;u;u;m;m;u;u;u;u;m;m;u;m;u;u;u;m;m;m;m;u;u;m;m;m;m;m;u;u;m;u;u;u;m;m;m;u;u;m;m;u;m;u;m;m;m;m;m;u;m;m;m;u;u;m;m;u;u;u;u;u;m;m;u;m;m;m;m;m;m;u;u;m;m;u;m;u;m;u;m;u;u;u;m;m;u;u;u;u;u;m;m;u;m;m;m;m;m;u;m;m;m;u;m;m;m;m;m;m;u;u;m;m;m;m;m;m;m;u;m;m;m;m;u;m;m;m;u;u;m;m;m;u;m;m;m;m;m;m;u;u;u;u;u;m;m;m;m;u;u;u;u;u;m;m;m;u;m;u;u;m;m;m;m;m;u;u;m;m;u;u;m;m;m;m;m;m;u;m;u;u;u;m;m;m;m;u;m;m;u;m;m;u;m;u;m;m;m;u;u;m;m;u;m;u;u;u;m;m;u;u;m;u;m;u;m;u;m;m;m;m;m;u;u;u;u;m;u;u;m;m;u;m;u;u;m;u;u;u;u;m;u;m;u;m;m;m;m;m;m;u;m;u;m;u;u;m;u;u;u;m;m;u;m;m;m;m;m;u;u;u;m;m;u;u;m;m;u;u;u;m;u;m;m;m;m;u;m;u;u;m;u;m;u;u;m;u;m;u;u;m;m;m;m;u;u;m;m;u;m;m;u;m;m;m;m;u;u;u;u;u;u;u;m;u;u;m;m;m;u;m;u;u;m;u;m;m;u;m;m;m;u;m;u;u;u;m;m;m;m;u;u;u;m;u;u;m;m;u;m;m;m;u;m;m;m;u;m;u;u;m;u;u;m;u;u;u;u;m;u;u;m;m;u;m;m;m;u;u;m;m;m;m;m;m;u;m;u;m;m;u;u;m;m;m;u;u;u;m;m;m;u;u;m;m;m;m;m;m;m;u;u;u;u;m;m;u;u;m;m;m;u;u;m;m;m;u;u;u;u;m;m;m;m;u;u;m;u;m;m;m;m;m;u;m;m;m;u;u;u;m;u;u;m;u;m;m;m;u;u;m;u;u;m;u;m;u;u;u;m;u;m;m;u;u;m;m;u;u;u;m;m;m;m;m;m;u;u;u;m;u;m;m;m;u;u;m;m;m;m;u;m;m;u;m;u;u;u;u;m;m;u;u;u;u;m;m;u;m;m;m;m;u;u;m;u;u;u;m;m;m;m;m;m;m;m;m;m;m;u;u;m;m;m;m;u;m;m;u;u;u;u;u;m;m;m;u;m;u;u;u;m;u;u;m;u;u;m;m;m;m;m;m;m;m;u;m;m;u;m;m;u;m;m;m;m;m;u;m;u;u;m;m;u;m;u;u;m;m;u;u;m;m;m;u;u;u;m;u;m;m;m;m;u;u;m;u;u;u;m;u;u;m;m;m;m;u;m;u;m;u;m;u;u;u;m;u;u;m;u;m;m;m;u;m;u;u;m;u;m;u;u;u;u;m;u;u;m;u;m;m;m;m;u;m;m;u;m;u;m;m;m;m;m;m;u;m;m;m;m;m;u;m;m;u;m;m;u;u;m;m;m;u;m;m;m;u;u;m;m;m;m;m;u;u;u;u;u;m;u;u;u;u;m;u;m;u;m;m;m;u;m;u;m;u;m;u;u;u;m;u;u;u;m;u;u;m;u;m;m;m;m;u;m;m;u;m;u;u;m;m;m;u;m;m;m;m;m;m;m;m;m;u;u;m;m;m;m;m;m;m;u;m;m;u;u;m;u;u;m;u;m;m;m;u;u;m;m;u;u;m;u;m;u;u;m;u;m;m;u;u;u;u;m;u;m;m;m;u;m;u;m;u;u;u;m;m;m;m;u;m;m;m;m;u;m;u;m;m;u;m;u;m;u;m;m;m;m;m;u;m;m;u;m;m;m;m;m;m;u;m;u;m;u;u;m;u;u;m;u;u;u;m;u;m;u;m;u;u;u;u;u;u;u;m;m;u;u;u;m;u;m;m;m;m;m;m;m;u;u;m;m;m;m;m;u;m;m;u;m;u;m;m;u;m;m;m;u;u;m;m;m;u;u;m;m;m;u;u;m;m;m;u;m;m;m;u;u;m;u;m;u;m;u;m;u;u;m;m;u;m;m;u;m;m;u;u;m;m;u;u;m;u;m;m;m;m;u;m;m;u;u;m;u;m;m;m;u;m;u;u;u;m;m;m;m;u;u;m;u;m;m;m;m;u;u;m;u;u;m;u;m;m;m;u;u;m;m;m;m;u;m;m;u;u;m;m;m;u;m;m;m;m;u;m;m;m;u;m;m;u;u;u;m;u;u;u;m;m;m;m;u;u;u;m;m;u;u;u;u;m;m;m;u;m;u;m;m;u;m;u;m;m;m;u;u;m;m;m;m;u;m;m;m;m;m;u;m;m;u;m;m;m;m;u;m;m;u;m;m;u;m;m;m;m;m;u;m;m;u;m;m;u;m;m;u;m;u;m;u;m;m;u;u;m;u;u;u;m;m;u;m;m;u;u;m;m;m;u;m;m;u;u;m;u;m;m;m;m;m;u;u;m;u;u;m;m;m;u;m;m;m;m;u;m;u;u;m;m;u;u;u;u;u;m;u;u;m;m;m;m;u;m;u;m;m;u;u;m;m;u;u;m;u;u;m;u;m;m;m;m;u;m;m;u;m;u;u;m;u;m;u;u;u;m;u;m;m;u;u;u;m;m;u;u;u;u;u;u;m;m;m;m;m;m;m;m;u;m;m;u;m;m;m;m;u;m;m;m;m;m;m;u;u;m;u;u;u;m;m;m;m;m;u;m;u;u;u;m;m;m;m;m;m;u;m;m;m;m;m;u;u;u;m;u;m;m;u;m;m;m;u;m;u;m;m;m;m;u;m;m;m;u;u;m;u;u;m;m;m;u;u;m;u;m;u;m;u;m;m;m;u;u;u;u;m;u;m;u;m;u;u;m;m;u;m;u;m;m;m;u;u;u;m;u;u;m;u;m;m;m;m;u;m;u;m;m;m;u;m;m;u;u;m;u;u;m;u;m;m;u;m;u;u;m;m;u;u;u;m;m;m;u;m;m;m;m;u;m;m;u;m;m;u;m;m;m;u;m;u;u;m;m;u;m;m;m;m;u;u;m;u;m;u;u;m;u;u;u;u;m;u;u;u;m;m;m;m;u;m;u;m;u;u;u;m;u;m;m;m;u;u;m;m;m;m;m;u;u;m;u;m;m;u;m;u;u;m;u;m;u;m;u;u;m;u;m;u;m;m;m;u;u;u;m;m;u;u;u;u;m;u;m;u;m;u;m;m;u;u;m;m;m;u;m;m;u;m;m;u;m;m;m;u;m;m;u;u;u;u;m;m;m;m;m;m;u;u;m;m;m;m;m;m;m;u;m;u;u;u;m;m;u;u;m;u;m;m;u;m;m;u;m;u;u;u;m;u;u;m;m;u;m;u;u;u;m;m;m;m;u;m;m;u;u;m;u;u;m;m;m;u;m;u;m;m;u;m;u;u;u;u;m;u;u;m;u;m;m;m;u;u;m;m;u;u;u;m;m;u;m;u;m;m;u;u;u;u;m;u;u;u;m;m;u;m;m;m;m;m;m;u;m;m;u;u;m;u;m;m;u;u;u;m;u;m;u;u;m;m;m;u;u;m;u;u;m;u;u;u;m;m;m;m;u;m;u;u;m;m;u;m;u;m;m;m;u;u;u;u;u;u;u;u;u;u;m;u;m;u;m;m;u;u;m;u;m;m;m;m;m;u;u;m;u;u;u;u;m;m;m;u;u;m;m;m;u;m;m;m;m;m;u;u;m;m;m;m;u;u;u;m;m;m;u;m;u;m;m;u;m;m<u;m;m;u;u;m;m;u;m;m<u;u<m;m<m;m;u;u;u;m;u;u;m;m<u;u;m;m;m<m;m;m<u;m;m;u;m;u;u;m;m;u;u;m;u;m;u;m;m<u;u;m;m;u<m;m;m;u;m;u;m;m;m;u;m;m<m;m;u;m;m;u;m;u;m;m;m<m;u;u;m;u;m;m;u;m;u;m;u;u<u;m;u;m;u;m;m;m;u<m;u;u;u;m;m;u;u;m;m<u;u;m;m;m;m;m;u;u;m;u;u;m;m;m;u;u;u;u<m<m;u<u;m;u;u<m<u;u;u;m;u<m;m;m;m<m;m;m;m;u;u;m;u;u;m;u;m;m;m;m;u;u;u<u;m;m;u;m;m;u;m;u;u;m;u;m;u;m;m;m;m;u;m;u;m;m;u;u;m;m;m;m;m;u<u;m;m;u;m;m;m;u;m;m;u;u;u;u;u;m;m;m;m;m;m;m;m;m;u;m;u;m;m;m;u;u;m;m;m;m;u;m;m;m;m;m<m<u<m<u;m;m;u;m;u;u<u;m;m;u;u;m;u<u;u<u<u;m<u<m<m<m;m<m<m;m;m<m<m;m<m<u;m<u;m;u;u;u;m<m;m<m<u;u;u<u;u;u<m<u<u;u<m<m;m;m;m<u<m<u;u<m;m<u<u<m;u;m;m<m<u;u;u<m<m;u;m<m<u<m<m<u;m<m<m;m<m;m<m<m;u<m<m;m;m;u;u<m;m;u<u<m<m<u<m;m<u;u<m;m;u;m<m<u<m;m;u<u<u;m<u<m;u;m;u<m;m<m<u;u;m;m<m;m<m<u<m<m<m;m;u;u<m<m;u<m;u<m<u<m;u<m<m<m<m<m<u;m<u;m;u<m<m<m<m;u;u<m<u<u;u<u<m<m<m;m;u<m;u<u;m<m<m;u;m<u<u;u<m<m;m<m<u;m<m<m;m;u;m<u<u<u;m<m<m;m<m;u;m<u;m;m<m;m;m;u;u;m<m;u;u<m<m;u<m;m;u<u<m<u<u<u<m<m;m;u<u<u<u<m<u<u<m<m<m<m<m<u<m<m<u<u<u<m<m<u<m<u<m<m<m<m<u<u<m<u<m<m<u<u<u<m<m<m<m<u<m<m<m<m<m<m<m<u<u<m<m<m<m<m<u<m<u<u<m<u<m<m<m<u<m<m<m<m<m<u<m<u<u<m<m<m<m<m<u<u<m<m<m<m<u<m<m<u<u<u<u<u<m<u<u<u<u<u<m<u<m<u<u<m<m<u<m<m<m<m<u<m<m<m<m<u<m<m<u<m<u<m<m<u<u<u<m<m<m<u<u<m<u<m<u<m<m<u<m<m<u<u<m<u<m<u<m<m<u<m<m<u<m<u<u<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<m<u<u<m<u<m<u<m<m<m<u<u<u<m<m<m<m<m<u<m<m<m<u<m<m<m<m<u<u<m<m<m<m<m<u<u<m<m<u<m<m<u<m<u<m<u<u<m<m<m<m<u<u<m<m<u<u<u<m<m<m<m<m<m<m<u<m<m<m<m<u<m<m<m<u<u<m<m<u<m<m<u<m<m<m<u<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<m<u<m<m<m<u<u<m<m<m<m<m<m<m<u<m<u<u<u<m<m<u<u<m<m<m<m<m<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<u<u<u<m<u<m|u|}¼
<u<u<m<m<m<m<m<m<m<m<u<m<u<u<m<m<u<m<u<m<u<m<m<u<m<m<u<u<u<m<m<m<m<m<m<m<u<m<m<u<u<u<m<u<u<m<m<m<u<m<m<m<m<u<m<m<u<m<u<m<m<m<m<m<m<m<u<u<u<u<m<m<m<u<m<m<u<m<m<u<m<m<m<u<m<m<u<m<m<m<u<m<m<u<m<u<m<u<m<m<u<m<m<u<m<m<m<m<m<u<u<m<u<m<u<u<m<u<m<m<m<u<m<m<m<u<u<m<m<m<m<u<u<m<m<m<m<m<m<m<m<m<u<m<m<m<u<m<u<m<m<u<m<m<m<u<m<m<m<m<m<u<m<m<m<m<m<m<u<u<m<m<u<m<m<m<u<u<m<m<m<m<m<m<u<m<m<u<u<m<m<u<u<m<u<m<u<u<m<u<m<m<u<u<m<m<u<u<m<m<m<u<u<u<m<u<m<m<u<m<m<m<m<m<m<m<m<m<m<u<m<m<m<u<m|u¼
¾¾\x7fçþÆý<m<m<u<m<m<m<m<u<u<m<m<m<u<m<u<m<m<u<m<m<m<u<m<u<u<m<m<m<m<m<u<m<m<u<m<m<m<m<m<m<u<m<m<u<m<m<m<m<m<m<m<m<m<u<u<m<u<m<m<u<m<m<u<m<m<u<m<m<u<u<m<m<u<m<u<m<u<u<u<u<m<m<m<u<m<m<m<m<m<m<u<u<u<m<m<m<m<u<u<u<m<m<m<m<u<m<u<m<u<m<m<m<u<m<u<m<m<m<u<m<u<m<m<m<u<m<m<m<u<u<m<u<m<u<u<u<m<m<u<m<m<u<m<u<u<u<m<u<m<m<m<u<m<m<m<m<m<m<m<m<u<m<m<u<u<u<m<m<u<u<m<m<m<m<m<m<m<u<m<m<u<u<m<m<m<u<u<u<m<m<u<u<m<m<m<m<m<m<m<u<u<u<u<m<m<m<u<m<m<u<m<m<m<u<u<m<m<m<m<u<m<u<m<m<m<m<m<m<m<m<m<m<u|u=¦¿ïÿ÷ÿÿ¿ï½¾<u<m<m<m<m<u<m<u<u<u<u<m<m<u<u<m<m<m<u<m<m<m<u<m<m<m<u<m<m<m<m<m<u<u<m<u<m<m<u<m<m<u<u<m<u<u<m<m<u<u<m<u<m<u<u<m<m<m<m<u<m<m<m<u<u<u<u<m<u<u<u<u<m<m<u<m<m<m<m<u<m<m<m<u<u<m<m<m<m<m<u<m<u<u<m<u<m<m<u<m<m<u<m<m<u<m<m<u<m<m<m<m<m<m<u<m<m<u<m<m<u<u<m<u<u<m<m<m<m<m<m<u<m<m<m<m<m<m<u<u<m<u<m<u<m<m<m<m<m<u<m<u<u<m<m<m<u<u<m<u<m<m<m<m<m<m<u<m<m<m<u<m<m<m<u<u<u<m<u<m<u<u<m<m<u<m<m<u<m<u<m<m<u<u<m<u<m<m<u<m<u<m<u<m<m<m<u<m<u<u<m<u<m<u<m<u<u<u<u<m<m<m<m<m<m<u<u<u<u<m<m<u|}=¦~ßÿÿÿÿÿÿÿ÷¾¾¼}<u<m<u<m<m<m<m<m<u<u<m<u<m<u<m<m<m<u<m<m<m<u<u<m<m<u<u<u<m<u<m<m<m<m<u<m<u<u<m<m<u<m<m<u<m<m<m<m<m<u<m<m<m<u<u<m<m<m<u<m<m<m<m<m<m<m<u<m<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<u<m<m<m<m<m<m<m<m<m<m<u<m<m<u<u<m<m<m<m<m<m<m<u<m<u<m<m<m<m<m<u<m<m<m<u<m<m<u<m<u<u<m<u<m<m<m<m<m<m<u<u<m<m<m<u<m<u<u<m<u<m<m<m<u<m<u<m<m<m<m<u<u<u<m<m<u<m<m<m<m<u<u<m<m<m<m<u<m<m<u<m<u<m<m<m<u<m<m<m<m<m<u<u<m<m<m<m<m<u<m<u<m<m<m<m<m<m<u<u<u<m<u<m<m<m<m<u<m<u<u<m<m<m<m<m<u<u<m<u<m<m<m<u<u|u|u¼þÆ¿ïÿ÷ÿÿÿÿÿÿÿ÷>Ï|}<m<m<m<m<m<m<m<m<u<m<m<u<m<m<u<m<u<u<m<u<m<u<m<m<u<u<u<u<m<u<m<u<m<m<m<m<m<u<m<u<u<m<m<m<u<m<m<u<m<m<u<m<m<m<m<u<m<m<m<m<m<u<u<m<m<u<u<m<m<m<m<m<m<m<m<m<m<u<u<m<m<m<u<u<m<m<m<m<m<m<u<m<u<m<m<u<u<m<u<u<u<m<m<m<m<m<m<m<m<m<m<m<m<m<u<m<u<m<u<m<u<m<u<m<u<u<m<u<m<u<m<u<m<m<u<m<m<m<u<m<m<m<m<m<m<u<m<m<u<m<m<m<u<m<u<m<m<m<m<m<u<m<m<m<m<m<u<m<u<u<u<m<u<m<m<m<m<u<u<u<m<m<m<m<u<u<m<u<m<m<m<u<u<u<u<u<m<m<m<u<u<m<m<m<m<u<m<m<u<m<m<u<u<m<m<u<m<m<m<m<m<u<m<m<m<m<m<u|uýþοïÿÿÿÿÿÿÿÿÿÿÿÿþÎ|}|u<u<m<u<u<m<u<u<u<u<m<m<u<m<m<m<m<u<m<u<m<m<u<m<m<m<m<m<m<u<m<m<u<m<m<u<m<m<m<m<m<m<m<u<u<u<u<u<m<u<u<m<m<m<u<u<u<u<u<m<m<m<u<u<u<m<u<u<u<u<m<u<m<m<m<u<u<u<m<m<m<u<m<m<u<m<m<u<m<u<u<m<m<m<m<m<u<m<m<m<m<m<m<m<m<m<u<u<m<m<m<m<m<m<m<m<m<u<u<m<m<m<m<u<u<m<m<m<m<m<u<m<m<m<m<m<m<m<m<m<m<m<m<m<m<u<m<m<m<m<u<m<u<m<m<u<m<m<m<m<m<u<m<m<m<m<m<u<u<m<m<u<m<u<m<m<u<u<u<u<m<u<u<u<m<m<m<m<m<m<m<u<m<m<u<m<u<m<m<u<m<m<u<u<m<m<u<u<u<u<m<m<u<m<m<m<u<m<m<m<m<u<u<m<u<m<u|u¼
>×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>Ï|}<u<u<m<m<m<m<m<m<m<m<m<m<m<u<m<m<u<m<m<u<m<m<m<m<m<m<m<u<m<m<m<m<m<u<m<m<m<m<m<m<m<m<m<u<m<m<u<m<m<m<u<m<m<m<m<m<m<u<u<m<u<m<u<m<m<u<u<u<m<m<u<m<m<m<m<m<m<m<m<m<u<m<u<m<m<m<m<m<m<m<u<m<u<m<m<u<u<m<m<m<u<m<m<m<m<u<u<m<u<u<m<u<m<u<u<m<m<m<m<u<m<m<m<m<m<m<u<m<u<u<m<u<m<m<m<m<u<m<m<m<m<m<m<m<u<m<m<m<m<m<u<u<m<m<u<u<m<m<m<u<u<m<m<u<m<m<m<u<m<m<u<m<m<u<m<m<m<m<u<u<u<m<u<u<m<m<m<m<m<m<m<m<m<m<m<u<m<u|m|u<u<m<m<m<m<m|m<m<m<u<m<u<u<m<u<m<m<m<m<u<u<u<m|u<m<m<m|uý~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷þƼ}<u<m<u<m<u<u<m<m<u<m|m<m<u<m<u<m<u<m<m<m<u<m|m<u<m|m<m<m<m<m<m<u|m<m<u<m<m<u<m<u<m<m<m<u<u<m<m<u<m<m<u<m<m<u<m|m<m<u<m<m<u<m<m|m<m<u|u|u<m<m<u|m<u<m<u<u<m<m<m<u<u<u|m<m<m|m|m<m<m|m<m<u<m<u|m<m<m<u<u<m<m<m<m|m<m<m<u|m<m<m<m<u<m<m<u<m<m<m<m<u<m<m<m<u<u<m<m<m<m<u<m<m<m<u<u<m|m<u<m<m<u<m<m<u<m<m<m<m<m<u<m<u<m|m<u<m<u|m<m|m<u<u<u<m<m|m<m<u|m|m<m<u<m<m<u<m|u<m|u<m|m<m<u<m<m<m<m<u<m<m<m<u<u<m|m|m<m|m<u<m<m<m<u<m<m<m|m<m<m<m<m<u<m<m<m|m|u<u<m|m<m<u<u|m|u|u|u|uý\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷þÆ|}<u|m<u|m|u<m<m<m<m<m<m<m<u<m|u|m<m|u|m<u|m<m<u<m<m|m<m|m<u<u<m<m<m<u<m|m<u|m|m<m<u<m<u|m<m|u|u<m<u|m|m|m<u<m<u|u<m<m<m<m|u<m<u|u<m<m<u<u<m<m|u<u|m|m<u<m|m<m<u<m<u|m|m<u|m<m<m|m<m|u|m|u<u<m|m|u|u<m<u<m<m|m<m|m<u<m|u|u<m|u<m<u<m|u<m<m<u<m<m<m<m<m<m|m<u<m<m<u<u|m<m|u<m|u<m|m<m<m|m<m<m<u<u<m<m<m|m<u<m<m|m|m|u<m|u|u|m<u|m<m<u|m|m<u<u|m|u<m<m|u<m<m|m<m|m<m|m<u<m|m|m|m|m<u<m<m<m<u<u|m|u<m<m<u<u<u<m|m|u<m|m|m|m<m<u|m|m<m|u<u<m|m<m<u|u|m|m|m|u<m|u|m|u|}}¦~¶=½
½
>×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~¶|u|u<m<m|m|u|m|m<m<u|u<u|u|m|m|u<m|u|m<u|m<u<m|m|m|u|u<m|m|m|u<m<u|u<m|u<m<m|u|u|u|m<u|u|u|m<m<u|m<u<m<u|u<m<m|m<m<u|m|m|m|m<m<m|u|m|m<m|u<m|m|m<u<m<u|m|m<m|u|m|m|m|m|m<m|u<u<m|u<u|u|m<u<u|m<m|u<u<m<m|u|m|m|m|u|m|m|m|m|m<m|m<u|m|u<m|m|m<m|m<m<m|m<m<u|m|m<m|m|m|m|u<m<m<m|u|u<m<u<m|u<m<m<m<m<u|u|m<u<m<u<m|u|m|m<u|m|m<m|u<m|m<u|u<m|m|u<m<m|u|m<m<u|u<m|u|m|m<m<m<u|m|m|u|u|m|m|m|m|m|m|u|m|m<m|m<u<m|u|u|m|m<m|m|u|m|u|m|m|m|m<m|m|u|u|m|u<m|m|u|m|u|}=þÆ\x7fç¿÷¿ï>×=¦~¶ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç=|u<m<m<m|u|m|m|m|m|u|m<u|u|u|m|m|m|m|m|m|u<m<m|m|m<m|u|m|u|m|u|m|m|m|m|u|m|m<u<m|m<m|u|u|m|m|u<u<m|m|u|m|u|u<u|m|m|m|m|m|m|m|u|u|m<u|m<m<m|m|m|m<m|u<m|m|m|u|m|u|u|u<m<m<u<m|u|m|m|m<m|m|u|m|m|u<u|u|u<m|m|m|u|m|m|m<u|u<u|u|u|m|m|u|m|u|u<m|m|u|u|u|u|m|u|m<m|m|u|m|m|m|m|u|m|m|u<m<m<m<u|m<m|m|m<m|u|u|m<m|m|u|m<m<m|m<u|m|u|m|m|m|m|u|m|m|m|u|m<u|m|u|m|m|m|m|m|m|u|u|m|m|u<u|m|m|u|u|m|m|m|m|m|m|m<m|m|m|m|u|u|m|u|u|u|u|m|m|u|m|m|m|m|m|m|m|m|u|m|u|u|}=>×ÿ÷ÿÿÿÿÿÿÿ÷\x7fç>׿÷ÿÿÿÿÿÿÿÿÿÿÿ÷þÎ|}|u|m|u|m|m|m|u|m|m|m|m|m|m|u|m<u|u|m|m|m<u|m|m|u|m|m|m|m|m|u|m|u|m|m<m|m|m|u|u|u|m<m|m|m|m|u|m<m|u|m|m|m|m|u|m|m|m|u|m|m|u|m|m|u|m|m|m|u|m|m|u|m|u|m|m|m|m|m<m|m|m|m|m|m|u|m|m|m|u|m<m|m|m|m|m|m|m|m|u<u|m|m|u|u|m|u|u|u|m|m|m|u|m|m|m|m|m|u|m|m<m|m|m|m|m|m|m|u|u|m|m|m|m|m|m|m|m|m|m<m<m|m|m|u|m|u|u|m|m|m|m|u|u|m|m|m|m|m|m|m|m|m|m|m|u|m|u|m|u|m|u|m|m|u|m|u|m|m|m|m|m|m|u|m|u|m|u|m|u|u|m|m|m|u|m|m|m|u|m|m|u|m|m|m|u|u|m|u|m|m|m|m|m|u|m|u|m|m|u|u½}¾¶¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿ¿ï}¦|u|u|m|m|u|m|u|u|m|m|m|m|m|u|m|m|m|m|m|u|m|m|m|m|m|m|m|u|m|m|u|u|m|m|u|m|m|u|m|u|m|m|u|u|u|m|m|m|m|u|m|m|m|m|m|m|u|m|m|u|m|m|u|m|m|m|m|u|u|u|m|m|m|m|m|m|m|m|m|m|u|u|m|m|m|m|m|m|m|m|m|m|m|m|m|m|u|m|m|u|m|u|m|m|m|u|m|u|m|m|m|u|m|u|m|m|m|m|m|m|m|m|m|u|u|m|u|m|u|u|m|m|m|m|m|m|m|m|u|m|m|m|m|m|m|u|m|u|u|u|u|m|m|m|m|u|m|m|m|m|u|m|u|m|m|u|u|m|m|m|m|m|u|m|m|m|m|m|u|u|m|u|m|m|u|m|m|m|u|u|m|m|m|m|u|m|u|m|m|m|m|m|m|m|m|u|u|m|m|m|m|u|u|m|m|m|m|m|m|u½}¾¶¿çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷þν
½}|u|m|m|m|u|u|u|u|m|m|m|m|u|m|m|u|u|m|u|u|m|m|m|m|m|u|u|m|u|m|m|u|m|m|u|u|m|m|m|m|u|m|m|u|m|m|m|m|m|m|u|u|m|u|u|m|u|m|m|u|u|m|m|m|m|u|m|m|u|m|u|u|m|m|u|m|m|u|u|m|u|m|m|m|m|m|m|m|m|m|m|u|m|u|m|m|u|m|m|m|m|u|m|m|m|m|u|m|m|u|u|m|u|m|m|m|u|m|m|u|u|u|u|u|m|u|u|m|u|m|u|u|u|m|m|u|m|m|m|m|m|u|m|m|m|u|u|m|m|u|m|m|m|u|m|m|u|m|m|m|m|m|m|m|u|u|u|u|u|m|m|m|m|u|m|m|m|m|m|m|m|m|m|m|u|m|m|m|u|m|u|m|m|u|u|m|m|m|u|m|u|u|u|u|u|m|m|m|m|m|m|u|u|m|u|u|m|u½}¾¶¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~ß=½}|u|m|m|u|m|m|u|m|u|m|u|m|m|m|u|m|m|m|m|u|m|m|m|m|u|m|m|m|m|m|u|m|m|m|u|u|m|m|m|u|m|m|m|u|u|m|m|m|m|m|m|m|u|u|m|m|m|m|m|m|m|u|u|m|m|u|u|u|m|u|m|m|m|m|m|u|m|m|m|m|m|m|u|m|m|m|u|m|u|m|m|m|m|m|m|u|m|u|m|u|m|u|u|m|m|m|m|u|m|m|m|m|m|m|m|u|u|u|m|m|m|u|m|m|m|m|u|m|m|m|u|u|u|m|m|u|m|u|m|m|u|m|m|m|m|m|m|m|m|m|m|u|m|m|m|m|u|u|m|m|m|u|m|m|m}m|m|m|m}m|m|m|m|u|u|m|u|m|u}m|m|m|u|m}m|m|m|u|m|m|m|m|m|m|m|m}u|m|m|m|u|m}u|m|m|m|m|m|m|m|u|u|u|m|m|m|m|u|uý~ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ï~®½}}u|m}u|m|m|m|m|m|m|m|u|m|m|u|m|u|m|m|m|m}m|m|m|m}m|m|m|m}u|m|u|m|m|m}u|m|m|m|m|m|u|m|m|m|m|m|u|u|u|m|m|u|m|m|m|m|u}m|m|m|m|m|u|m|m|m|m}m|u|u|m|u|u|u|u|m|m|u|u|m|m|m}u|u|m|m|u|m|m|m}m|m}m|u|m|m}m|m|u}u|u|m|m|m|m|m|m|m|m|m|m|u|u|u|m}u|m|u|m}u|u|u|m|m|u|m|u|m|m|u|m|m}m}m}m|m|m|u}m|m}m|u|u|m|u|m|m|u|m|m|u|u|u|m|m|m|u|u|m|u|u|m}m}u|m}u|m}m}m}u|m|u}u|m}u|u|m|m|u|m}m|m|m|m}m}m|m|m}m}m}m}m}m|m|m}m}m|u|u}u|u|m}m}m|u|m}m|m}u|m}m|u}m}u}u}u|m}m}m}u=¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷~ß~®½
}}}u}}}u|m|m}u}m}u}m}m|m|m|m}m}m}m|m}u}m}m}m|m|m}u|u|m|m}u}m|m}m}m}m}u}u|m|m|m|m}u}u}u}m}u|m|m|u}m|m}m}u|u|m|u|m|m}u}m}m}u}m}u|u|u|u|m|m|u}m|m}m}u}m|m|u|u|m}m|m}m}u}m|u}m|u}m|u|m|m}m}m|u}u}m|m}m}u}m|u|m}m}m|m}m|m}u}m}u}u|m|u|m|u}m}m}u}m|m}u}u}m|m}u|m}m}u|m}m}u}m}m|m}m|u}m|m|u|m|m|m|u}m|u}m|m}m}m}m}m}u}u|m|m}m|m|u|u}m}m|m}u}m}u}m}m}u}u|m}m}m}m}u}u|m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m|u}u}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}uý>׿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿ÷ÿ÷ÿÿÿÿÿÿÿÿÿÿ\x7fç¾¾=ý½½}½}}u}u}u}u}u}m}m}m}m}u}m}m}u}u}m}m}m}m}m}u}m}m}m}u}u}m|u}u}m}u|u}u}u|m|m}u}u}m}m}u}m}m}m}m}m}u}m}m}m}u}u}m}m}u}m}m}u}u}u}m}m}u}m}u}m}m}m}m}m}u}u}u}m}m}u}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}u}m}u}m}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}u}m}u}m|m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}u}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}u}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}u}u}m}m}uý¾¶>Ï\x7fß\x7fç\x7fç\x7fß\x7fßþÆþÎþ¾¾¾¿ïÿÿÿÿÿÿ¿÷¿ï\x7fç\x7fß>×þξ¶=½
}u}u}u}m}m}m}u}m}m}u}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}m}m}m}u}u}m}m}u}m}m}m}m}m}u}m}u}u}m}u}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}u}u}m}m}u}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}u}m}u}m}m}u}m}m}m}u}u}u}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}u}u}u½}½
ýýý½}½
½
¾¾\x7fß\x7fßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿÷¿ï>ß~®½}}u}u}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}u}m}m}m}u}m}m}m}u}m}m}u}m}m}m}u}m}u}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}u}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}u}u}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}u}m}u}m}u}u}m}m}m}u}m}m}m}m}m}u}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}u}m}m}u}u}u}u}u}u}uý¾¶¾¶>׿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ïþ¾ý}u}u}m}u}m}m}u}u}u}m}m}m}m}m}m}m}m}u}m}m}u}u}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}u}m}u}m}m}u}m}m}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}u}u}m}u}m}u}u}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}u}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}u}m}u}m}m}m}u}m}u}m}m}m}m}u}u}m}m}m}m}m}u}m}u}m}m}u}m}m}u}u}u}m}m}m}u}u}m}u}u}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}u}m}m}m}m}u}m}m}u}uý~®\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷>×=}u}m}m}u}m}u}u}m}u}m}u}m}m}m}m}u}u}u}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}u}m}m}u}m}m}u}u}u}m}u}m}m}m}m}u}m}m}u}u}u}m}u}m}m}m}u}u}u}m}m}u}u}u}m}u}u}m}m}u}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}u}m}u}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}u}u}m}u}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}m}m}u}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}u}m}m}u}u}m}u}u}m}m}u}m}m}m}m}m}m}u½}¾¾¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fß=½}}m}m}u}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}m}u}m}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}u}m}m}u}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u½
¾¾¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>ß>¦}m}m}u}m}u}u}u}m}m}m}u}m}m}u}m}u}m}m}u}u}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}u}m}u}u}m}u}u}m}m}m}u}m}m}m}u}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}u}m}u}u}u}m}u}m}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}u}m}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}u}m}u}m}m}m}u}m}u}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}u}m}u}m}u}m}m}u}m}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}u½
þÆ¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>×½}}u}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}m}u}m}m}m}m}m}m}m}u}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}u}m}m}m}m}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}u}u}u}u}m}m}m}m}m}m}u}m}m}m}m}m}u}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}u}m}u}u}u}u}m}m}u}m}u}m}u~®¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\x7fß¾¾¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>×½
}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}u}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}u}u}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}m}u}m}m}u}u}u}m}u}m}m}m}m}u>\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷þ¾ý?׿÷ÿÿÿÿÿÿÿÿÿÿÿ÷ÿ÷¿ï?ß~®}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}u}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}u}u}u}m}u}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}m}u}m}u}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}u}m}m}u}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}u}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}m}u½}>Ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷¾¶½}>?ß¿÷¿÷¿÷\x7fç>Ïþƾ¶¾¶}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}u}u}u}m}m}m}u}u}m}m}m}m}u}m}u}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}u}u}u}m}m}u}m}m}u}m}m}u}m}m}m}u}m}m}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}m}u}u}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}u}m}u}m}m}m}m}m}u}m}m}m}uþ\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\x7fçþ}u}u>¾¶¾¶>þ½
}u}m}m}m}m}u}u}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}u}u}m}m}m}m}u}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}u}m}m}m}u}u}u}m}m}u}m}u}m}m}u}m}m}m}m}u}m}m}m}u}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}m}u}m}m}u}m}m}u}u}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}u}m}u}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}u}m}m}m}m}uþ¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿÷¿ï¾¾½}}u}u}u}u}u}u}u}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}u}m}u}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}u}m}u}m}m}m}u}m}m}m}m}u}u}m}u}m}m}m}m}uþ>׿ïÿ÷¿÷¿÷\x7fç\x7fß?×¾¶>¾
}m}m}m}u}m}m}u}u}u}m}m}m}m}u}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}u}u}u}m}m}m}m}u}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}u}u}m}m}u}u}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m½uþ
~®~®¾¶>>þ½}½u}u}u}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}u}u}u}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}u}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}u}m}m}u}u}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}u}m}m}u}u}m}m}m}u}m}u}u}u}m}m}m}m}m}u}u}u}u}u}u}u}u}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}u}u}m}m}m}m}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}u}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}u}m}u}m}m}m}m}m}u}u}u}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}u}m}u}m}m}m}u}m}m}m}m}u}m}m}u}m}u}m}m}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}u}m}m}u}m}u}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}m}u}m}u}m}m}u}m}m}m}m}u}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}u}m}m}m}m}u}m}m}m}m}u}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}u}m}m}u}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m~m~m}m}u}u}m}m}m}m}u~m}m~u}m}m~m}m}u~m}m}m~u}m}u~m}m}m}m}m}m}u}m~m}m}u}u}m}m~m}m}m}m~m}m}m~m}m}u~m~u}m}m}m}m}m}m}u}m}u}m}m}m}u~m}u}m}m}m}m~u}u}m}u~u}m~m}m}m}m}m}m}m}m~m}m}m}m}u}m}m}m}u}m}m}m~m}m}m}m~m}m}m}m}m}m~u~m}m}m~m}m~m}u}m}m~m}m}m}m}m~m}m}m}m~m}m}m~m}m~m}m}m}u~u}m}m}u~u~m}m}m~m}m~m}m~u}m}m}m}u}m~m}m}m}u}m}m}m~m}m}m}m~m}m}m}m~m}m~m}u}m}m}m}m}m}u}m}u}m}m~m}m~m}m~u}m~u~u}m}m}m~m}m}m}m}m}m}m}m}m}m}m}u}m}u}m~u}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m~m}m}u}m}m}m}m~m}m~m}m}m}u}m~m~m}m}m}u}m~u~u}m~m}m}m}m~m~m~m}u~m~m}m}m~m}m}m~m}m}m~m~m}m~m}m}m}m~m~m}m~m~m~u}m}m~m}m}m}u~m}m~m}m~m~m}m~u~m}m~u}m}m~m}m~m}m~m}m}m~m}m~m~m}m~m}m}m~m~m~u}m}m}m~u~m~m~u}m}m}m}m~u~m}m}m~m~m}m~m}m}m}m~m~m}m}m}u~m}m~m~m~m}m~m}u}m}m~m~m}u}m~m}m}u~m~m~u}m~m}m}u}m}u~m}m}u~m}m}u}m~m~m}m}m~m~u~m}m~m~m~m~u~m}m}m~m}m}m}m}u~m~m}m~m}m}m~m}u}u}m}m~m}m}m~m~m}m~m~m~m}m~m~u}m~m~m}m}m~m}u~m}m~u~m~m~u~m}m}m}m~m}m}u}m~m~m~m~m~u~m}m~m}m~m~m}m~u~m~u~m~m}m~m~m}m}m~u~m}m~m}m~m~m}m~m}m}m~m~m}m}m}m~u~m~m~m~m~u~m~u~m}m~m~m~m~m~m}m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~u~m}u~u~u~u~m~m~m~m~m~u~m~m~u~m~u~u~m~m~u~m~m~m~m~u~m~m}m~m~m~m~m~m~m~m~m}m~m~m~m~m~m~m~m~u~u~m~m~m~u~m~m~m~u~u~m~m~u~m~m~m~u~m~m}m}m~m~u~m~m~m~u~m~m~m~m~m~m~m}u~m~m~m~u~m~u~u~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m}m~m~u~u~m}u~u~m}m~m~m~m~m~m~m~u~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m}m~m~m~m~m~u~u~m}m~m~m~m~m~m}m~m~m~m~m~m~m~m}m~m~m~u~u~m~m~u~m~m~m~m~m}m~m~m~m~u~m~m~m~m~m~m~m~m}m~m~m~m~m~m~m}m~m~u~m}m~m~m~u~m~m}m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~u~m~u~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~u~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~u~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~u~u~m~u~m~u~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~u~u~m~m~m~m~u~m~m~m~u~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~u~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~u~m~u~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~u~m~u~m~m~u~m~m~m~u~m~m~m~m~u~u~m~m~m~m~m~m~u~m~u~u~m~m~m~m~m~m~u~u~m~m~m~u~m~u~m~m~u~m~u~m~u~u~m~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~u~m~m~u~m~u~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~u~u~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~u~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~u~u~m~m~u~u~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~u~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~u~u~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~u~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~mÀ\0~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~u~u~m~m~m~u~m~m~m~m~u~m~m~m~m~m~u~m~m~u~u~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~u~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~u~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~u~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m\x1f\0~m~u~m~m~u~m~m~m~m~m~u~m~m~m~m~m~u~u\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~u~mA\x02A\x02A\x02A\x02A\x02~m~m~m~u~m~m~u~m~m~m~m~m~mà Á ~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~u~m~u~m~m~m~m~u~u~m~u~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~u~m~m~m~m~m~m~m~m~m~m~mrÁ \x01s~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m\x1e\0\x1f\0~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~u~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~m~m~m~m~m~m~m~uq
C\x1aJK~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~u~m~u~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~u~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m\x1f\0\x1d\0~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~m~m~m~u~m~m~m~u~m~mD\x1aÁ F3~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~u~m~u~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m¾m~m~m~m~m¼~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~m~m~m~m~mòÁ\x01@\x02B\x12~m¾m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m¾m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m¾m~u~m~m~m~m~m~m~m~m~m~m~m~m~m¾m~m~m~m¾m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m¾m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m¾m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m¾m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m¾m~m~m¾m~m~m¾m~m~u~m~m~m~m¾m~m~m~m~m\\b\x1e\0\b~m~m~m¾u~m~m~m~m~m~m~u\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m~mA\x02A\x02A\x02A\x02A\x02~m~m~m~m~m~m~m~m~m¾m\x01À\x01"~m~m~m~m~m~m~m~m~m~m¾m~m~m~m¾m~m~m~m~m~m~m~m~m~m~m~m~m~m¾m~m¾m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m¾u~m~m~m¾m~m~m~m~m~m~m~u~m~m~m¾m~m~m¾m~m~m~m~m~m¾m~m~m~m~m~m~m~m¾u¾m~m¾m~m¾m~m~m¾m~m¾u~m~m~m¾u~m¾m~m~m~m~m¾m~m¾m¾m~u~m~m~m~m~m¾m~m~m~m~m~m~m~m~m~m~u¾m~m¾m~m~m~m~m~m~m¾m¾m~m~m~m~m¾m~m~m~m¾m~m~m¾m~m~m~m~m¾m~m~m~m~m~m¾m~m¾u~m~m¾m¾m~m¾m~u¾m~m~m~u~m~m~m¾m~m~m~m~m¾m~m~m~m~m~u~m~m~u~m¾m~m~m~u~m~m~m~m~u~m~m\x1f\0\x1f\0\x1f\0~m¾m~m~m¾m~m~m~m¾m¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m~mA\x02A\x02A\x02A\x02A\x02~m~m~u¾m¾m~m~u~m¾m¾mr,\¾m~m~m~m~m~m¾m~m~m~m~m~m~u~m¾m¾m~m~m~uA\x02¾m~mA\x02A\x02~m¾uA\x02A\x02¾m¾mA\x02~m~mA\x02~m~m~m~m~mA\x02A\x02~m~mA\x02~m¾m~u~mA\x02~uA\x02~u~mA\x02¾m¾mA\x02A\x02A\x02~m~m~m¾m~mA\x02A\x02A\x02¾mA\x02~m~uA\x02~mA\x02¾mA\x02A\x02A\x02~m~m~mA\x02A\x02A\x02¾u¾mA\x02A\x02A\x02¾m~mA\x02A\x02A\x02~m¾mA\x02A\x02A\x02~m~mA\x02A\x02A\x02¾m¾m¾m~m~mA\x02¾mA\x02¾m~m~mA\x02A\x02¾m¾mA\x02~m~mA\x02~m¾mA\x02A\x02A\x02~m~m~m~u¾m~m¾m¾m¾m~m~m~m~m¾m¾m¾m~m~m¾m¾m~m¾m~m¾m¾m~m¾m~m¾m¾m~m¾m¾m¾m~m~m~m~m¾m~m¾m¾m~m~m~m~m¾m~u~m~m¾u~m¾m~m¾m~m¾m¾m¾m~m~u¾m¾m¾m¾m¾m~m~m¾m¾m~m~m~m~mJ\x1f\0\b~m¾m~m~u~m~m~m~m¾m¾m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m¾mA\x02A\x02A\x02A\x02A\x02~m~m~m¾m¾m~m~m\0
++\0
++~m~m~m¾m~m~m¾m¾m¾m¾m¾m~m~m~m~m¾m¾m¾m¾m¾m~m~uA\x02¾mA\x02¾m¾mnTA\x02~m~mA\x02¾mA\x02~m¾mA\x02¾m~m~m~mA\x02~m~mA\x02~mA\x02¾m¾m~m~uA\x02~mA\x02~m~mA\x02~mA\x02¾m~m¾m~m~m~m¾mA\x02~u~m¾m~mA\x02¾m¾mA\x02~mA\x02¾mA\x02¾m~mA\x02~uA\x02~m~m~m~mA\x02¾m¾mA\x02¾mA\x02¾m¾mA\x02~mA\x02~m¾m¾m~mA\x02¾m¾mA\x02~m¾m~m¾mA\x02A\x02~mA\x02A\x02~mA\x02~m¾mA\x02¾mA\x02~m¾mA\x02¾mA\x02~m¾mA\x02~m~m~m~m¾m¾m¾m~m~m¾m¾m~m~m¾m¾m~m~m~m~m~m~m~m¾m~m¾m~m~m¾m~m¾m~m¾m~m¾m¾m~m~m~m¾u~m~m¾m¾m¾m~m~m~m¾m¾m~m~m~m¾m¾m¾m¾m¾u¾m¾u¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m~m¾m¾m~m¾m~m¾m~m¾m!\x1e\0\x19[¾m~m¾m¾u~m¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾mA\x02A\x02A\x02A\x02A\x02~m¾m¾m~m¾m¾m\0
++\0
++\0
++\0
++¾m¾m¾m¾m~m¾m¾m¾m~m¾m~m~m~m¾m¾m¾m~m~m¾m~m¾mA\x02¾mA\x02~m~m¾mA\x02¾m¾mA\x02¾mA\x02¾m~mA\x02¾m¾m¾m~mA\x02¾m¾mA\x02~mA\x02¾m¾m¾u¾uA\x02~mA\x02¾m~mA\x02¾mA\x02A\x02A\x02A\x02~m¾m¾m¾mA\x02A\x02A\x02A\x02~mA\x02¾m~mA\x02~mA\x02¾mA\x02~u¾uA\x02¾mA\x02A\x02A\x02A\x02¾mA\x02¾m¾mA\x02~mA\x02¾m¾mA\x02~mA\x02A\x02A\x02A\x02~mA\x02¾m¾mA\x02¾m¾m~m¾mA\x02~mA\x02¾mA\x02¾mA\x02¾m~mA\x02¾mA\x02¾m¾mA\x02~mA\x02~m¾uA\x02¾m¾u~m~m~m~u¾m¾u~m¾m~m¾m¾m¾m~m¾m¾m~m¾m~m~m~m~u~m¾m~m~m¾u¾}?þ~m¾u¾m¾m¾m¾m¾m~m¾m¾m¾m~m¾m¾u~m¾m¾m~m¾m¾m¾m¾m~m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾u¾m¾m¾u¾m~m¾m¾m~m¾m~m~mz\x1f\0\x1f\0\x1f\0Ús¾m¾m¾m~m¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾mA\x02A\x02A\x02A\x02A\x02~m¾m¾m~m¾m¾m\0
++\0
++\0
++\0
++¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m~m~mA\x02¾mA\x02¾m~m,LA\x02¾u¾mA\x02~mA\x02¾m~mA\x02¾m~m¾m¾mA\x02¾m¾mA\x02¾mA\x02¾u¾u¾m¾mA\x02¾mA\x02¾m¾mA\x02~mA\x02¾m¾mA\x02¾m¾m¾m¾uA\x02û¾mA\x02~mA\x02¾m~mA\x02~mA\x02¾mA\x02¾m¾uA\x02~mA\x02¾m¾mA\x02~mA\x02¾m¾mA\x02~mA\x02¾m~mA\x02¾mA\x02¾m¾mA\x02¾uA\x02¾m¾mA\x02¾m¾m¾mA\x02A\x02~mA\x02~mA\x02~mA\x02¾m¾mA\x02¾mA\x02¾m¾mA\x02~mA\x02¾m¾mA\x02¾m¾m¾m¾m~m~m~m¾m¾m¾m¾m¾m~m¾m¾m¾m~m¾m~u¾m~m¾m¾m¾u¾m¾uþÿÆ¿ï¿ï?Ͼ}¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m~m¾m~m¾m¾m¾m¾u¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾mz|\x1f\0\x1f\0\x1f\0J¾m¾m¾m¾m¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m¾mA\x02A\x02A\x02A\x02A\x02~m¾m~m¾m¾m¾m\a3\0
++\0
++¾m~m¾m¾u~m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾mA\x02¾m¾mA\x02A\x02¾m¾mA\x02A\x02¾m¾mA\x02A\x02A\x02¾m¾m¾m~m¾m¾mA\x02A\x02¾uA\x02A\x02A\x02¾m¾mA\x02A\x02A\x02A\x02A\x02A\x02¾m¾m¾mA\x02A\x02¾m¾m~m¾m¾m¾mA\x02A\x02¾m¾mA\x02A\x02A\x02¾mA\x02A\x02~mA\x02A\x02A\x02¾m¾m¾mA\x02A\x02¾m¾m¾mA\x02A\x02A\x02¾m¾mA\x02A\x02A\x02~m~mA\x02A\x02¾m¾m¾mA\x02A\x02A\x02¾m¾m¾mA\x02~m~ms
¾m~mA\x02¾mA\x02A\x02¾m¾ms
A\x02¾mA\x02¾m¾mA\x02A\x02A\x02¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾}??×ÿ÷ÿÿÿÿ\x7fß?¾m¾m¾m~m¾m¾u~m¾m¾m¾m¾m¾m~m¾m¾u¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m\x1a\x19\x1f\0]\b¾m¾m¾m¾m¾m¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾mA\x02A\x02A\x02A\x02A\x02¾m¾mA\x02A\x02A\x02ñ
¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02¾m¾m¾m¾uA\x02¾mA\x02¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾uA\x02¾m¾m¾m¾mA\x02¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾mA\x02¾m¾u¾m¾mA\x02¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾uÿ
¿¶¿ïÿÿÿÿÿÿÿÿ¿ï?¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m\x1f\0\x1f\0\x1f\0;¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾mA\x02A\x02A\x02A\x02A\x02¾mA\x02A\x02A\x02A\x02A\x02¾m¾m¿m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¿m¾m¾mA\x02¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02A\x02¿m¾m¾mA\x02¿mA\x02¾m¾u¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾u¾m¾m¾m¾mA\x02¾u¾u¾m¿m¾m¾m¾m¾m¾m¾m¾m¾mA\x02¾m¾u¾m¾mA\x02¾m¾m¾m¾u¾m¾m¾m¾m¾mA\x02¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾mA\x02¿m¾m¾m¾mA\x02¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾u??Ï¿ïÿ÷ÿÿÿÿÿÿÿÿ¿ï?¾u¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾u¾m¿m¾m¾m¾m¾m¾m¿m¾m¾m¾m¿u¾m¾m¾m¾m¾m¾m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾mA\x02A\x02A\x02A\x02A\x02¾mA\x02A\x02A\x02A\x02A\x02¿m¾u¾m¿u¾m¾m¾m¾m¾m¾m¿m¿m¾m¾m¾m¾m¾m¾m¿m¿m¿m¿m¾m¿m¾m¿m¾m¾m¾m¾m¿m¿m¾m¾u¾m¿m¾m¾m¿m¾m¿m¾m¾m¾m¾m¿m¾m¿m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¿m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾u¾m¾m¾m¿m¿m¾m¿m¾m¾m¿m¿m¿m¾m¾m¿m¿m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¿m¾m¾m¾m¾m¾m¾m¿m¾m¿m¾m¾m¿m¾m¾m¾m¾m¾m¿m¾m¾m¿m¾m¾m¾m¿m¾m¿m¿m¾m¿m¾m¾m¿m¾m¾m¾m¾m¿m¾m¾m¿m¾m¾m¿m¾m¾m¾m¾u¾m¿m¾m¿m¿m¾u??×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿ¿ï?¿u¿m¾m¾u¾m¾m¾m¾m¿u¾m¾m¾m¾m¾m¾m¿m¾m¾m¿m¿m¾m¿m¿m¿m¿u¾m¿m¾m¾m¾m¾m¾m¿m¾m¿m¿m¿u¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¾m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02¾mA\x02A\x02A\x02A\x02A\x02¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿u¾m¿m¿m¾m¿u¿m¾m¿m¾m¿m¿m¾m¿m¿m¾m¿m¿m¿m¿m¾m¾m¾m¿m¾m¿m¿m¾m¿m¿m¾m¾m¿m¿m¿m¾u¾m¿m¿m¿m¿m¿m¾m¾m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¾m¾m¿m¿m¿m¿m¿u¾m¾m¿u¾m¿m¾m¾m¾m¿m¿m¿m¿m¾m¾m¿m¿m¿m¿m¿m¾m¿m¿m¾m¿m¾m¾m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¾m¾m¾m¿m¾m¿m¿m¿u¿m¾m¿m¿m¾m¿m¿m¿m¿m¾m¾m¾m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¾m¿m¿m¾m¾m¾u¿¶¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç?¿u¿m¿m¿m¿m¿m¾m¿m¿m¿m¾m¾m¿m¿m¾m¿u¿m¿m¿m¾m¿u¿m¿m¿m¿m¿m¿m¾m¿m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿u¿m¿m¿u¿m¾m¿m¿m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02¿m2
A\x02A\x02A\x02°t¿m¿m¿m¿m¿m¾m¿u¾m¿m¿m¿m¿m¿m¿m¿m¿m¾m¾m¾m¿m¿m¿m¾m¿m¿m¿u¿m¿m¿m¿m¾m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¾m¾m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¾m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿u¿m¿m¿m¾m¿m¿u¿m¾m¿m¿m¾m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¾u¿u¾m¾m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿u¿u¿u¿}¿u¾uÿ¶¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fßÿ¾u¿m¿m¿m¿m¿m¿m¿m¿m¾m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02¿m¿m¿mð|¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿}\x7fÿÆ¿¶?¿}\x7f¦¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?׿}¿u¿m¿m¿m¿m¿m¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m?T?T¿m¿m¿u¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u?ÿ¾\x7fß¿ï¿÷\x7fç¿®\x7f¿çÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿ¾¿}¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿u¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿd\x1f\0\x1f\0\x1f\x19¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u??Ï¿÷ÿÿÿÿÿÿÿÿ¿ï\x7fß¿çÿÿÿÿÿÿÿÿÿÿÿÿ¿ï?¿u¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m?T\x1f\0ßK¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿ
¿¶\x7fçÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÆÿ
¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m\x1f\x19ß!¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿}¿¶¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç?ÿ}¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿uA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿mÿd_2_!_!ß:?m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1fC_!_!ß:?m¿m¿m¿m¿\\x1f*_!\x1f*ßK¿m¿m¿m_Kß:¿m¿m¿m¿m_K_K¿m¿m¿m¿m¿m¿m¿m¿mÿdß:_!_!_!\x1fC?m¿m¿m¿m¿m¿m2\x1f\0ÿd¿m¿m¿m¿mKß!_!\x1f*ßK¿u¿m¿mßKß!_!¿\¿m¿m_Kß!_!\x1f*ßK¿m¿m¿mß:K¿m¿u¿m?Tß:¿m¿m¿mÿdß:ÿd¿m¿mÿd_2_!_!\x1fCÿd¿m¿m¿m¿m¿m¿m¿m¿u¿u\x7f¦\x7fçÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ç\x7f¦ÿ}¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x10¿m¿mB\x12A\x02A\x02A\x02\0
++A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1fC_\bß\x10ß:\x1f*ß\x10_\bÿd¿m¿m¿m¿m¿m¿m¿mÿdß\x10_\b22_\b_\b?m¿mß:\x1f\0_!ß:_!\x1f\0_2¿m¿m_!\x1f\0¿m¿m¿m¿m_!_!¿m¿m¿m¿m¿m¿m¿mß:\x1f\0ß\x10_2ß:2ß\x10_\b¿\¿m¿m¿m¿m_\b\x1f\0\x1fC¿m¿m¿mß!\x1f\0_!ß:_!\x1f\0ß:¿m¿m_\b_\bß:¿m?m\x1f\x19\x1f\0\x1f*ß:_!\x1f\02¿m¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m¿\\x1f\0_\b_2_2_\b_\b?m¿m¿m¿m¿m¿m¿m¿u¿}?×ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ÿ¾ÿ
¿}¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m?m\x1f\0_\b?m¿m¿m?m\x1f\0_2¿m¿m¿m¿m¿m¿m¿m2\x1f\0ßK¿m¿m?m\x1f\0ß:?m\x1f\0\x1f\x19¿m¿m¿m2\x1f\0?m¿m_!\x1f\0¿m¿m¿m¿u_!_!¿m¿m¿m¿m¿m¿m?T\x1f\0_!?m¿m¿m¿m?m_\bß!¿m¿m¿m?T\x1f\0\x1f\0_!¿m¿m?m\x1f\0\x1f\x19¿m¿m¿m\x1f\x19_\b¿m¿m\x1f\0_!¿m¿m2\x1f\0ß:¿m¿m¿m_2\x1f\0?m¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m_2\x1f\0ßK¿m¿mßK\x1f\0\x1fC¿m¿m¿m¿m¿m¿m¿mÿ
ÿ¾¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\x7fß\x7f¦¿}¿u¿u¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mK\x1f\0ß:¿m¿m¿m¿m¿\¿m¿m¿m¿m¿u¿m¿m¿mß\x10_\b¿m¿m¿m¿m\x1f*KK\x1f\0\x1fC¿m¿m¿m¿\\x1f\0_K¿m_!\x1f\0¿m¿m¿m¿m_!_!¿m¿m¿m¿m¿m¿m\x1f*\x1f\0?T¿m¿m¿m¿m¿mß:\x1f\0?T¿m¿m\x1f*\x1f\0\x1f*\x1f\0ÿd¿m?mK?T¿m¿m?mß\x10\x1f\0¿m¿m\x1f\0_!¿m¿mß\x10_\b?m¿m¿m¿m?mÿd¿m¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m¿\ß:¿m¿m¿m\x1fC\x1f\0ß:¿m¿m¿m¿m¿u¿m¿m¿uÿ
ÿÆ¿ï¿÷¿÷ÿ÷ÿÿ¿÷ÿ÷¿ï¿÷ÿ÷ÿ÷ÿÿÿÿÿÿ\x7fç¿¶?ÿ
ÿ}ÿ}¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mß:\x1f\0\x1fC?T?T?T?T?T¿\¿m_!_!_!_!K¿m\x1f\0_!¿m¿m¿m¿m¿m¿mß:\x1f\0?T¿m¿m¿m¿m\x1f\0ß:¿m_!\x1f\0¿m¿m¿m¿m_!_!¿m¿m¿m¿m¿m¿mKß:¿m¿m¿m¿m¿m¿m\x1f*\x1f\0?T¿m¿\_\bß!¿\\x1f\0\x1f*¿m¿u¿m?mKß!\x1f\0\x1f\02¿m¿m\x1f\0_!¿m¿m\x1f\0\x1f\x19?T?T?T?T?T?T?m¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m¿m¿m¿\_2ß\x10\x1f\0_\bÿd¿m¿m¿m¿m¿m¿m¿m¿u¿uÿ}?\x7f¦ÿ¾ÿ¾ÿÆÿ¾¿®¿¶¿®ÿ¾¿ïÿÿÿÿÿÿ¿÷¿ç?×ÿÆ¿¶\x7f¦ÿ
¿}¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mß:\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0_!¿mß:ß:ß:ß:?T¿m\x1f\0_!¿m¿m¿m¿m¿m¿mß:\x1f\0?T¿m¿m¿m¿m\x1f\0ß:¿m_!\x1f\0¿m¿m¿m¿m_!_!¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿdßKß!\x1f\02¿m¿m\x1f*\x1f\0ßK¿m\x1f\x19_\b?m¿mK\x1f\0\x1f\0ß\x102¿\¿m¿m¿m\x1f\0_!¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0?T¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m?m\x1f\x19\x1f\0\x1f\0ß!K?m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u¿u¿u¿u¿}¿u¿u¿}??Ç?×\x7fßÿ÷ÿÿÿÿÿÿÿÿÿ÷ÿ÷ÿ÷¿ï\x7fçÿ¾?¿}¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mßK\x1f\0?T¿m¿m¿m¿m_!\x1f*¿m¿m¿m¿m¿m¿m¿m\x1f\x19_\b¿m¿m¿m¿mK¿m_K\x1f\0\x1fC¿m¿m¿m¿\\x1f\0K¿m_!\x1f\0¿m¿m¿m¿m_!_!¿m¿m¿m¿m¿m¿m¿m¿m¿m2ß\x10\x1f\0\x1f\0\x1f\0ß!¿m¿m¿m_\bß\x10¿m¿mß:\x1f\0K¿m_\b\x1f\0?T¿m¿m¿m¿m¿m¿m\x1f\0_!¿m¿u\x1f\x19_!¿m¿m¿m¿m?T\x1f\0ÿd¿m\x1f\0_!¿m¿m¿mß:\x1f\0¿m¿m¿m?T\x1f\0?T¿m\x1fC\x1f\0ß!?m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u¿uÿ
\x7f¦¿¶\x7fßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷\x7fç¿¶ÿ¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿd\x1f\0ß!¿m¿m¿m¿\\x1f\0K¿m¿m¿m¿m¿m¿m¿m\x1f*\x1f\0?T¿m¿mßK\x1f\0Kÿd\x1f\0_!¿m¿m¿mß:\x1f\0ÿd¿m_!\x1f\0K¿m¿m¿mß\x10ß!¿m¿m¿m¿m¿m¿m¿m?Tß\x10\x1f\0\x1f\0_!2ßK¿m¿m¿m?T\x1f\0\x1f*¿m¿m¿\\x1f\0\x1f*¿m\x1f\0_!¿m¿mK_\bßK¿m¿m\x1f\0_!¿m¿m\x1f*\x1f\0¿\¿m¿m¿mß!ß\x10¿m¿m\x1f\0\x1f\0ÿd¿m¿m_!\x1f\0ßK¿m¿mK\x1f\0?T¿mß:\x1f\0?T¿m¿mß\x10_!¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿uÿÿÆ¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷?Ïÿ
¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\01¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mK_\b_!ß:\x1f*\x1f\0\x1f\x19¿m¿m¿m¿m¿m¿m¿m¿mÿdß\x10_\b22\x1f\0\x1f\x19?m¿mß:\x1f\0_!ß:_!\x1f\02¿m¿m_!\x1f\0\x1f\x19\x1f*ß:\x1f\x19\x1f\0K¿m¿m¿m¿m¿m¿m?m_\b_\bK¿m¿m¿m¿m¿m¿m¿m\x1f*_\b?T¿m¿m¿m_!_\b¿m\x1f*\x1f\0\x1f*ß:_\b_\bÿd¿m_!\x1f\0_\b_!¿m?m_!_\b2ß:ß\x10\x1f\0ßK¿m¿m\x1f\0ß\x10\x1f\x19ß:ß!\x1f\0_!ß\x102ß:_\b_\b¿m¿mÿd\x1f\0ß\x10ß:ß!\x1f\02¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u\x7f\x7fßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷?Ïÿ¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿd\x1f*_!ß!\x1fC¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m?m\x1fC_!_!ß:?m¿m¿m¿m¿\\x1f*_!\x1f*ßK¿m¿m¿mKß:?m2_!ß!ßK¿m¿m¿m¿m¿m¿m¿m?T\x1f\0ß:¿m¿m¿m¿m¿m_22¿m\x1fCK¿m¿m¿m¿m¿\ß:ÿd?mKß!_!2?m¿m¿mß:\x1f\0ß\x10ß:¿m¿m¿mK_!_!2¿\¿m¿m¿mß:K¿\ß!_!\x1f*?mÿd\x1f*_!\x1f*¿\¿m¿m¿m¿\2_!ß!ßK¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u\x7f¦\x7fßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷?Ï?¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÿd\x1f\0_!¿m¿m¿m¿m¿\\x1f\0\x1fC¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0_!¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿}\x7f¦\x7fçÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ÿÆ¿}¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿u\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m2\x1f\0_2?T?TK\x1f\x19_\bÿd¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0_!¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u\x7f\x7fçÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ïÿ¾\x7fçÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\x7fß?¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mßK\x1f\x19\x1f\0\x1f\0_\b\x1f*ÿd¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿mÿdßK¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿uÿ
?Ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç\x7f¿¶¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿÷?Ïÿ
¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿mA\x02A\x02A\x02A\x02A\x02¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u\x7f¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?×ÿ}ÿ
?׿÷ÿ÷¿÷ÿ÷\x7fç\x7fß\x7fß?×ÿÆ¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿uÿ¶¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿ï¿¶¿u¿u?¿¶ÿÆ¿¶\x7f?ÿ
ÿ
¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿mr¿m¿mA\x02A\x02A\x02¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m;\x1f\0\x1f\0\x1f\0¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿}\x7f¦¿ïÿ÷ÿÿÿÿÿ÷ÿ÷¿ï¿ï\x7fçÿ¾ÿ
¿u¿m¿u¿u¿u¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿mÀ\x01À\x01Æ2¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿u¿m¿m¿m\\b\x1f\0\x1a\x19¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿uÿ
¿¶?×?Ï?×ÿÆÿ¾¿¶?ÿ¿}¿u¿m¿m¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿mD"\0\x02\x01\x02\x03\x12¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿mJ\x1f\0\x1f\0\x1f\0z¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿uÿ}ÿ
¿}ÿ}¿u¿u¿u¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿mlÀ\x01Á\x01Ë[¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿mÚs\x1f\0\x1f\0\x1f\0z¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿u¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿u¿u¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿mY[\x1e\0)¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mÈ:\0\x02\a;¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\b\x1f\0J¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m \0\x02\x02\x1a¿m¿m¿m¿m¿m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\x1f\0\x1f\0\x1f\0¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿mÅ*@\x02r¿m¿m¾m¿m¾m¿m¿m¿m¿m¿mA\x02A\x02A\x02A\x02A\x02A\x02¿m¿m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m\b\x1e\0\\b¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¾m¿u¿m¿m¿m¿m¾m¿m¿m¾m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¾m¿u¿m¿m¿m¾m¾m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¾m¿m¿m¿m¾u¿m¿u¾m¿m¿m¿m¿m¿m¿u¿m¿m¿m¿m¿m¿m¾m¿m¾m¿m¾m¿m¿u¿m¿m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¿m¿u¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿u¾m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¿m¿m¿m¿m¿m¿m¾m¿m¿u¿m¿m¾m¿u¿m¾m¿m¿u¿m¿m¿m¾m¾m¾u¾m¾m¾m¿m¿m¿m¿m¿m¾m¿m¾m¿m¿m¾m¿mA\x02A\x02A\x02A\x02A\x02A\x02¾m¿u\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¿m¾m¾m¾u¿m¿m¿m¾m¿m¿m¿m¾m¿m¿m¾m¾m¿m¿m¾u¿m¾m¿m¿m¾m¾m¿m¿u¾m¿u¿m¾m¾m¿u¾m¾m¿m¿m¿m¾m¾m¾m¿m¾m¿m¾m¿m¿m¿m¾m¿m¿m¾m¾m¾m¿m¿m¾m¾m¿m¾m¾m¾m¿m¿m¿m¿m¿m¿m¿u¿u¿m¿m¾m¾m¾u¾m¿m¿m¾m¿m¾m¾m¾m¾m¿m¾m¾m¿m¿m¾m¿m¾m¾m¿m¾m¿m¾m¿m¾m¿u¾m¿m¿m¿m¿m¿m¾m¾m¾m¿m¾m¿m¿m¾u¿m¾m¾m¿m¿m¿m¾m¾m¾m¿m¾m¿m¾m¿m¿m¿m¿m¾m¿m¿m¿m¾m¾m¿m¾m¿m¿m¾m¿m¿m¿m¿m¾m¿m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¿m¿m¾m¾u¿m¾m¿m¾m¾m¿m¿m¾m¾m¿m¾m¾m¿m¾m¾m¾m¾m¾m¿m¿m¿m¿m¾m¿m¿m¾m¾m¿m¾m¾u¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¿m¾m¿m¾m¾m¾m¾m¾mD" ¿m¿m¿m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾u¿mA\x02A\x02A\x02A\x02A\x02A\x02¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾m¿m¾m¿m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m»\x1f\0]\b¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¿m¾m¾u¾u¿m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾m¿m¿m¿m¾m¾m¿u¾m¾m¾m¾u¿m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾m¿m¿m¾m¿m¿m¿m¿m¾m¾m¿m¿m¾u¾m¿m¿m¿m¾m¾m¿m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¿m¿m¿m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¿m¿m¿m¾m¿m¾m¿m¾m¿m¿u¿m¾m¾m¿m¾m¿m¾m¾m¿m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¿m¿m¾m¿m¾m¾m¿m¾m¾m¿m¿m¿m¾m¾m¾m¿m¿m¿m¾m¾m¾m¾m¾m¾m¾u¿m¿m¿m¿m¿m¾m¾m¾m¾m¿m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾u¾m¾m¾m¾m¾m\a;E*¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02A\x02A\x02A\x02A\x02A\x02¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m\x1e\0\b¾m¾m¿m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾u¿m¾m¾m¾m¾u¿m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¿u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¿m¾m¾m¾m¾u¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾u¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾mA\x02A\x02A\x02A\x02A\x02A\x02¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾m¾u¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾u¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾u¾m¾m~m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾mÀ\0¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾u¾m¾mA\x02A\x02A\x02A\x02A\x02A\x02¾m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾m~m¾m¾m~m¾m¾u~m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m\x1f\0¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m~m~m¾m¾m¾m~m¾m¾m¾m¾m¾m¾u¾m¾m¾m~m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~u¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾u¾m¾u¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾u¾m~u¾m~m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾u¾m¾m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾u¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m~m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m~m¾m~m¾m¾m~u¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m~m¾m¾u¾m¾m¾m¾m¾m¾m¾u¾m¾m~m~m¾m¾m¾m¾mA\x02A\x02A\x02A\x02A\x02A\x02¾m¾m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾u~m~m¾m¾m¾u¾m¾m~m¾m¾m¾m¾m¾m¾m¾m~u¾m¾m¾u~u¾m¾m¾u¾m¾m¾m¾m~u¾m~m~m¾m~m¾m~m¾m¾m~m~m¾m~u¾m¾m¾m~m¾m¾m¾m~m¾m¾m¾m¾m~m¾m¾m¾m¾m~m~m¾m~m¾m¾m¾m¾m¾m¾m¾m¾u¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m~m¾m~m¾m¾m¾m¾m¾m¾m~m~m¾m¾m~u¾m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m~m¾m¾u¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m~m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m~m¾m~u¾m¾m¾m¾u¾m~m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m¾m~m¾m¾u¾m¾m~m¾m¾m~m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m~m¾m¾m¾m¾m¾m~m¾m¾m¾m~u~u¾m~m¾m~m¾m~m¾u¾m~m¾m¾m¾m~m~m¾m~m¾m~m¾u¾m~m~mA\x02Á\x01A\x02A\x02A\x02B\x1a~m~m\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0~m¾m¾m¾m¾m¾m¾m~m¾m¾u¾m~m~m~m¾m~m¾m~m~m¾u¾m¾m¾u~m~m~m¾m¾u¾m¾m~m¾m~m~m~m~m¾m¾m¾m¾m¾m¾m¾m~m¾m¾m¾m~u~m¾m~m~m~m~u¾m¾m~m¾m¾m¾m~m~m~m¾m~m~m¾m¾m¾m~u~m~m~m¾m¾m¾m~m~u¾m~u~m¾u~m~m¾m¾m¾m~m¾m~m~m¾m~m~m¾m~m~m¾m¾m¾m¾m¾m~m~m¾m~m¾m~m¾m~m~m~m¾m¾m¾m¾m~m¾m~m~m~m¾m~m~m¾m~m¾m¾m¾m¾m¾m~m~m~m¾m~m~m~m¾m¾m¾m¾m~m¾m~u¾u¾m~m¾m~m¾m~m~m¾m¾m¾m¾m¾m~m~m¾m~m~m¾m¾m¾m¾m~m¾m¾m¾m¾m¾m¾m¾m¾m¾m~m¾m~m¾m¾m¾m~m¾m~u¾m~m~m~m¾m¾m~u¾m¾m~m~m~u~m¾m~m~m¾u¾m~m~u~m~m¾m¾m¾m~m¾m~u~m¾u~m¾m¾m¾m¾m~m¾m~m¾m¾m¾m¾m~m¾m¾m~m~m~m¾m~m~m¾m~m¾m~m~m¾m¾m¾m~m¾m¾m~m~m¾m~u¾m¾u~m~u~m¾m~m~m~u~m~m~u~m~m¾m~m~m~m¾m~m~m~m~m¾m¾m~m¾m~m~m¾m¾m¾m~m~m¾u¾m~m¾m¾u¾m~m~m~m~m~m~m¾m¾m~m~m¾m~m~m¾m¾m~m¾m~m~m¾m~m~m~m~u¾m¾m~m~m¾m¾u~m~m¾m¾m¾m¾m~m¾m~m~m¾m~m~m~m~m¾m~m~m¾m~m~m¾m~m~m¾m~m~m¾m~m¾m¾m~m~m~u~m~m~m¾m¾m¾m¾m¾m~m¾m¾u¾m~m~m~m~m~m¾m~m¾m~m¾m¾m~m¾m~m~m~u¾m¾m¾m¾m~m¾m~m~m¾m~m~m~m~m¾m~m¾m¾m¾m~m¾m¾m~m~m~m~m~m¾m¾m~m¾m~m~m¾m~m¾m¾m¾m¾m~m¾m¾m~m~m¾m¾m~u¾m¾m~m~m~m~m~m~m~m~m~m~m¾m¾m~m¾m¾m~m~m~m¾m~m¾m~m¾m~m~m¾u¾m~m¾m¾m~m¾m~m¾m¾m~m¾m¾m~m~u¾m¾m¾m~m~u~m¾m~m~m~m~u¾m~u~m~m¾m~m~m~m~m¾m~m~m¾m~m~m~m¾m~m¾m~m~m~m~m~u~m¾m~m~m~m~m~m¾m~m¾m~m~m~m¾u~m~m~u~m~m~m¾u¾m¾m~m~m¾m¾m~m~m¾m~m¾m~m~m¾m~m~m~m¾m¾m¾m~m¾m¾m¾m~m¾m~m¾m~m¾u~u~u~m¾m~m~m¾m¾m¾m~m~m¾m~m¾m~m¾m~m~u~m~m~m~m¾m~m¾m¾m¾m~m~m¾m~m¾m¾m~m~m~m~m¾m¾m¾m¾u~m¾m~m¾m~m~m¾m¾m~u~u¾m~m~m¾m~m¾m~u~m¾m¾m~m~m~m~m¾m~m~m~u~u~m~m~m~m~m¾m~m~m¾m~m~m~m~m~m¾m~m~m~m¾m~m~m~m~u¾m~m¾u~m~m~m¾m¾m~u~m¾m¾m~m¾m¾m~u~m¾m~m~m~m~m~m¾m~m~m~m~m~m¾m~m~m~m~m~m~m~m¾m~m~u¾u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u¾m¾u~m~u~m¾m~m~m¾m~m~u~m~m¾m~m~m~m~m~m~m~m~m~u~m~m~u~m~m¾m~m~m~m~m~m~m~m¾m~m~m~u~m¾m~m~m~m¾m~u~u¾m~u~m~m¾m~m¾m~m~m¾m~m~u¾m~m~m~m~m~m~m¾u~m~m~m~m~m¾m~m~m~m~m~m~m~m¾m~m~m~m~m~m~m~u¾m¾m~m~m~m~m~m~m~u~m~m~m~u~m~m¾m~m~m~m~u~m~m¾u~m~m¾m~m~m¾m~m~m~m~m~m~m¾m~m~m~m~m~m¾m~u¾m~m~m~m~m~u¾m~m¾m~m~m~m~m~m¾m~m¾m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m¾m¾u~u~m~m~m¾m~m~m¾u~m~m~m~m¾m~m~m~m¾m~m¾m~m~m~u~m~m~m¾m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m¾m~u~m¾m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m¾m~m~m~m¾m~m¾m~m~m~m~m~m~m~u~m¾m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m¾m~m~u~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m¾m~m~m~u~m~m~u~m~m~m~m~u~m~u~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m~m~u~m~u~m~m~m~m~m~m~m~m~u~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~u~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~mþ
þ¾}~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m¾u¾}þ
>¿®\x7fß¿ç\x7fß¿¶~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~u~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u¾}~ÿÎ\x7fç¿ïÿÿÿÿ¿ï¿¶~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~u~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~u~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m¾u¾}¾
¾}¾u¾u~¦\x7fçÿ÷ÿÿÿÿÿÿÿÿ¿ï~¦¾}~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~u~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u¾u¾
>¾¶?ÏÿÆ>¾
ÿÆ¿÷ÿÿÿÿÿÿÿÿÿÿ¿çþ¾u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~u~m~m~m~u~m~u~m~u~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~u~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m¾uþ
~¦?Ï\x7fç¿ï¿÷¿÷\x7fß>?Ï¿÷ÿÿÿÿÿÿÿÿ¿÷?Ͼ}~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m¾uþ
ÿÆ¿ïÿÿÿÿÿÿÿÿÿÿÿ÷\x7fß\x7fçÿ÷ÿÿÿÿÿÿÿÿ¿ï~¾u~m~m~m~m~m~u~m~m~u~m~u~m~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~u~m~m~u~m~u~m~m~m~u~m~m~m~m~u~m~m~m~u~m~m~u~m~u~m~m~m~u~m~m~m~u~u~m~m~u~m~u~m~u~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~u~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~u~m~u~m~u~u~m~m~m~u~m~m~m~m~m~m¾}¾®¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿ÷ÿÿÿÿÿÿÿÿ¿÷?×þ
~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~u~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~u~u~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~u~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~u~m~m~u~m~u~u~m~m~m~m~m~m~m~m~u~u~m~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~u~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m¾}~¦¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\x7fßþ~u~m~m~m~m~m~u~m~m~m~m~u~m~m~u~m~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~u~m~m~u~m~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~m~m~m~u~m~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~u~u~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~u~m~m~u~m~m~u~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~u¾u¾}¾¶\x7fß¿ïÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷?×>¾}~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~u~m~m~m~m~u~m~u~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~u~m~m~u~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~u~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~m~u~m¾uþ¾¶?Ï\x7fß\x7fç¿ïÿ÷ÿÿÿÿÿÿ¿÷?Ï>¾}~u~u~u~m~u~m~m~u~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~u~u~m~m~m~m~u~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m~m~m~m~u~m~m~u~u~m~m~m~m~m~m~m~m~m~m~m~m~u~m~m~m~m~u~m~m~m~m~m~m~m~m~m~m~m~m~m~u~u~m~m~u~m~m~m~m~m~m~u~u~m~m~m~m~m~m~m~m~u}m~m~m~u}u~u~m~m~m~m~m~m~m~m}u~m~m~m}u~m~m}m~m~m~u}u~m~u}m~m~u~m}m}m}m}m~m~m~m~m~m~m}u~m}m~m}m~m~m~u~m~m}u}m}m~u~m~m~u~u}m~m~m~m~m~m}m~u~m~u~u~m~m~u~m~m~m~u~m~u~m~m}m~m}m~m~m~m~m~m~m~m~u~m~m~u~m~m~m~m~u~m~m}m}m~u~u}u¾}þ~¦þ¾\x7fßÿ÷ÿÿÿÿ?ß>~u~m~u~u~m~m~m~m}m~u~m}u~u~u~m~m~m~m~m~m~m~m~u~m~m~m}u~u~m~m~u}m~m~m}u~m~m~m~m}m~m~m~m~m~m~m~m~u~m~u~m~u~m~m~m~m}u~m~m~m~m}m~m~u~m~u~m}m}m~m~m~m~m~m~u~m~m~m~u~m~m~m~m}m~m~u~u~m~m~m~m~m~m~m~u~m~m~m~m~m~m~u~m}m~m~m~m~u~m~m~m~m~m~m~m}m~m~m~m~m~m~m}m~m}m}m~m}m}u~m}u}m~m~m~u}m~m~m}m}u}m}m~m~m~u}m}m~m~m}m~m}m}m~m}u}m}m~m~m~u}m~m~m~u~u}m}m~m}m~m}m}m~u~u~m}m~m}m~m}m}m~u}u}m}m~u}m}u}m}u}m}m}m~m~m}u}m}m~m~m~m~m}u~m~m}m~u}m~m~m~m~m}m~m~m}u}m~m}m}u~m}m}m~m~m~m~m}u~m}m}u¾uþþÆ?׿ïÿÿÿÿ\x7fß~®þ
¾}~u}m}m~m}u~m~m}m}u}m~u}m~m~m}m}m~m}m}u}m~m}m~m}m~m~m}m~m~m~u~m~m}m~m~u~m~m}m}m}m~m~m}m}u}u}m~m}m}m}m~u}m~m~m}m}m}m~u~m}m~m~m}u}m~m~m~u~m}m~m~m}m~u}m~m~m}m}m}m}m~m~m}m~u~m}m~m}m}m}u~m}m~m}m~m~m~m~m}m~u~m~m}u}m~u~m~m}m~m}u~m}m}m~m}u~m~m}m}m~u}m~m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m~m}m}m}m~m}m}m}m~m}m}m}m}m}m~u}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m~m}m}m}m}m}m}m}m}m}m~m}m}u}m}m}m}m}u}m}m}u~u}m}m}m~u}u}m}m}m}m}m}m~m}m~m}u}m}m~m}m}m~m}u}m}m}m}m}m}m}m}m}m}m}m¾u¾
~®?׿÷ÿÿÿÿ¿÷\x7fçþÎ~þ
}u}m}m}m}m}u}m}m~m~m~m}m}m}u~m}m~m}u}m~m}m}m}m~u}m}m}u}m~u~m}m}m}m}u}u}m~m}m~m~m}m}m}m}m}m}u~m~m}m}m}m~m}m~m}m}m~m}m~m}m~m~m}u}m~m}m}u}m}m}m~m}m~u}m}m}m}u}m~u}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u~m}m}m}m}m}m}m~m}m}m}u}m}m}m}m}m}m}m~m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}u}m}m}m}m}m}u}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}u½}>þÆ\x7fç¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ\x7fçþÆþ}u}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}u}u}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}u}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}u}u}u}m}u}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}u}u}m}u}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}u}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}u}m}m}uþþ¾¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷?×þ¾u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}u}m}m}m}u}m}m}m}u}m}m}u}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}m}m}m}u}u}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m½u>?׿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÆþ
}u}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}u}m}u}m}m}u}u}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}u¾
>Ï¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿ï¿÷ÿÿÿÿÿÿÿÿÿÿ¿ï¾¶}u}m}m}m}m}m}m}m}m}m}u}m}m}u}u}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}m}u}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}u}m}u}m}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m½u>¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fß¾¾\x7fçÿÿÿÿÿÿÿÿÿÿÿÿ\x7fßþ}m}m}m}m}u}u}m}m}m}m}m}u}m}u}m}m}u}m}m}u}u}u}m}m}m}u}u}m}u}u}u}m}m}u}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}u}m}m}m}m}u}u}u}m}u}m}m}m}m}m}m}m}m}m}u}u}m}u}m}m}m}m}m}m}u}u}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}u}m}m}u}u}u}m}u}m}m}m}m}m}m}m}u}u}u}m}m}m}m}m}u}m}u}m}m}m}u}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u½
þοïÿÿÿÿÿ÷ÿ÷ÿ÷¿ï¾¾þ?ß¿÷ÿÿÿÿÿÿÿÿÿÿ¿÷¾¶½}}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}u}m}u}m}u}u}m}m}m}u}m}m}m}m}m}u}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}u}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}u}m}m}u}m}m}m}u}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u½
>¦¾¶þÆ>×\x7fß\x7fçþÆþ½}~®\x7fß¿ï¿÷ÿ÷ÿÿÿÿÿ÷þν
}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}u}m}u}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}u}m}u}m}u}u}m}u}m}m}m}m}m}m}m}u}m}u}u}u}m}m}m}u}m}m}u}m}u}m}m}u}u}m}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}u}m}u}u}m}u}u}m}m}m}u}m}m}m}u}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}u}u½}½
½
½
½
½}}u}u½}>~®¾¶¾¾þÎ?×>×>½}}m}m}u}m}u}m}m}m}m}u}m}m}u}m}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}u}u}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}m}m}u}m}m}m}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}u}m}u}m}m}u}u}m}m}m}u}m}m}m}m}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}u}u}m}m}u}m}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}u}m}m}u}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}u}u}m}m}m}u}m}m}u}m}m}u}m}u}m}m}u}m}m}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}u}u}m}m}m}m}u}m}m}m}u}m}u}m}m}m}u}m}u}m}m}u}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}u}m}u}m}u}m}m}u}m}m}u}u}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}u}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u½
½
½
}u}m}m}m}m}m}m}m}u}m}m}u}u}m}u}m}m}u}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}u}u}u}m}u}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}u}m}u}u}m}u}m}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}u}m}m}u}m}m}u}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}u}u}u}u}m}m}m}m}m}m}u}m}m}m}m}m}u}m}u}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}u}m}u}u}u}u}m}m}u}m}u}m}m}m}m}u}m}u}m}u}u}m}u}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}u}m}m}u}u}u}m}u~¦\x7fß>Ï>½}}m}m}u}m}u}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}u}u}u}m}m}u}m}m}u}m}m}u}m}m}m}u}m}m}m}m}u}m}m}m}m}u}m}u}u}m}m}m}m}m}u}u}u}u}m}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}u}u}m}m}u}m}m}m}m}m}m}m}u}u}m}u}m}m}m}u}m}m}u}u}u}m}u}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}u}m}u}m}m}m}m}m}m}u}u}u}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}u}u½}>ßÿ÷ÿ÷¿ï¾¶ý}u}m}m}m}u}u}m}m}m}m}m}m}m}m}m}u}m}m}u}u}u}u}u}m}u}m}u}m}m}u}m}m}m}m}u}m}m}m}u}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}m}u}m}m}m}m}u}m}m}u}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}u}m}m}u}u}m}m}u}m}m}u}m}m}u}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}u}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}u}m}m}m}m}m}m}u}m}m}u}m}m}u}m}m}m}m}m}m}m}u}u}m}m}u½}þÎÿÿÿÿÿÿ¿ïþÆý}m}m}m}m}m}m}u}u}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}u}m}u}m}m}m}m}u}u}m}m}u}m}m}m}m}u}m}u}u}m}m}m}m}m}m}u}m}m}m}m}u}u}u}m}m}m}m}u}m}u}m}m}m}u}m}m}u}m}u}m}m}m}u}m}u}m}u}m}m}m}u}m}u}m}m}uþÆ¿÷ÿÿÿÿÿÿ¿ï¾¶}}}m}m}m}m}u}u}m}m}m}m}m}u}u}m}m}m}u}u}m}m}m}m}m}m}u}m}m}u}u}u}u}m}m}m}m}u}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}m}u}m}u}u}u}u}m}m}m}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}u}m}m}m}m}u}u}m}m}m}u}m}u}m}u}u}m}u}m}m}m}m}u}m}m}u}u}m}u}u}m}m}m}u}m}m}m}u}u}m}m}m}m}m}u}m}m}m}u}u}u}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}u}u}u}m}m}m}m}m}m}u}m}m}u}u}m}m}m}u}u}u}m}u}u>¦ÿ÷ÿÿÿÿÿÿÿÿ¾¶}u}u}u}m}u}m}m}u}m}u}m}m}m}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}u}m}m}u}m}m}m}m}m}u}m}m}m}m}m}m}u}u}u}u}m}m}u}m}m}m}m}m}u}m}m}m}u}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u}m}m}u}m}m}m}m}u}m}m}u}m}m}m}m}u}m}m}u}m}u}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}u}m}m}m}m}m}m}m}u}u}m}u}m}m}m}m}m}m}m}u}u}m}u}m}m}m}u}m}m}u}m}u}u}m}u}m}m}m}m}m}m}m}u}m}m}m}m}u}u}u}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}u}m}m}m}m}m}m}m}m}u}m}u}m}m}m}m}m}m}u}m}m}uý~¦~®ý½
}u}uý>×ÿÿÿÿÿÿ¿ï}¦~®¾¶=½
}m}u}m}m}m}m}m}m}m}m}m}m}m}m}m}u}u}m}m}m}m}m}m}u}m}m}u}m}u}u}m}m}m}u}u}m}m}m}u}u}m}u}m}m}m}u}u}m}u}m}m}m}m}m}u}u}m}m}u}m}m}m}u}m}m}m}m}m}m}u}m}m}m}m}u}u}u}u}m}u}m}u}m}m}m}m}m}m}m}m}u}m}m}m}m}m}u}m}u}m}m}m}u}u}m}u}u}m}m}u}m}m}u}u}m}m}u}u}m}m}u}m}u}m}m}m}u}u}u}m}m}u}m}m}u}m}u}u}u}m}u}m}m}m}m}u}m}m}u}m}m}u}u}m}m}u}m}m}m}m}m}m}m}m}m}m}u}u}m}m}u}m}m}m}u}m}m}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m}u}m}m}u}u}u}m}u}m}u}m}m}m}u}m}m}m}m}m}u}u}u}m}m}m}u}u}u¾¶ÿÿ¿ï\x7fçþÆý½}=þο÷ÿÿÿÿ¿÷\x7fß\x7fçÿ÷\x7fç¾¾½
}u}u}m}m}m}m}u}u}m}m}u}u}m}m}m}u}m}m}m}m}m}m}m}m}m}u}m}m}m}m}m}m}m}u}m}m}m}m}m}m}u|m}m}m}m}m}m|m}m}u}u}u}m}m}m}m}m}m}u}m}u}m}m}m}m}u}m}m}m}u}m}m}m}m}m}m}m}m|m|m}u}m}m}m}m}m}m}m|m}m|m|u}u}m}m}u}m}m}u}m}m}m}u}m}m}m}m}u}u}m}m}m}m}m}m}u}u}m}u}m}m}u}u}m}m}m}m}u|u|m}u}m}m}m}m}m}m|m}u}m}m}m}m}m}u}m}u}m}m}m}m}m}m}m}u}u}u}m}m}u}u}m}m}m}u}m}u}u}u}m}m}m}m|m}m}m|m}m}m}m}m}m}m}m}u}u}m}u}m}u}m|u|m}m|m}m|u|m|u}m|m|m}m}m}m}u|m}m|m}u|m|m|m|m}m}m|m}m|u|m}uþ¾ÿ÷ÿÿÿÿ¿÷\x7fç~®¾¾>׿÷ÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿ¿ïþν
}u}m}m}m}m}m}m}m}m}m}u|m|m|m}m|m}m}u|m|m|m}m}u|m}m}m|m|m}u}m}m|u}m}m|m|u}m|u|u|m}u|m}m|u|m}m|m|m}u}m|m}u|m}m}u}m}m}m}m|m}u|m}u}u|m|m}m}m}m}m}m}m|m}m|u}m}u}u}m|m}m|m|m|m|u|m}m}m|m}m}m|u|m}m|m}u|m}u}u|m|m}m|m}u}m}m|m|m|m}m}m}u|u}m}u}m}m}m}m|m|m}u}u|m|u}m}m|u|m|m|u|m|u|m|u|m}m|m|u}u|u}m|m}m|m}u|u}m|u}m|m}m}u|m|m}m|u}m|u}m|m}m}u}m|m|m|m}u|m}m|u}m}u}m|m}m}m|m|m}m}m}m|u|m|m|m|m|m|m|u|m|m|m|m|u|m|m|m|u|m|m|m}m|m|m|m|m|m|m|m|u|m|u|m|m|m}m|m}m}u=¿ïÿÿÿÿÿÿÿÿ¿ï\x7fß¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>×½|m|m|u}u|m|m|u}m|u|m|m}u|m|m|m|u|u}m|m|u|u|u|m|u}m|m|m|u|m|m|m|u|m|m}u|u|m|m|m|u|m|u|m|u|m|m}m|m|m|m}u|m|u}u|m|m|m}u|m|u|m|m|m|m|m|u|u|u|u|m|u|m}u|m|m|u|u|m|m|u|m|m|u|m|u|m|m|u|u|m|m}m|m|u|m|m|m|m}m|m}m|m|m|u|m|m}u|m}m|m|m|m|u|m|m|m|u|m|m|m|m}m}m|u|m|m|m|u|u|m|m|u|u|m|u|u|m}m|m|m|u|m|m}m|u|m|m|m}m|u|m|m|u|m|m|m|m|m|m|u|u|m|m|m|m|m|m|u|u|u|u|m}u|m|u|m|m|m|m|u|u|m}m|m|u|m|m|m|u|m|u|m|m|u|m|m|m|m|m|m|m|u|m|u|m|m|m|u|u|m|m|m|m|m|m|u|u|m|mý>Ïÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿ÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ï=¦|u|m|m|m|m|m|m|u|m|m|m|u|u|u|u|m|m|m|m|u|m|u|m|m|m|u|m|m|m|u|u|m|m|m|m|m|m|m|m|m|m|m|m|m|u|m|m|u|m|m|m|u|m|m|u|u|u|u|m|m|u|m|m|m|u|m|m|m|m|u|u|m|u|m|m|m|m|m|u|m|u|m|m|m|m|m|u|m|u|m|m|m|m|m|u|m|m|m|u|u|m|m|m|m|m|m|m|m|m|u|u|m|m|m|m|u|m|u|u|m|u|u|m|u|m|m|m|u|u|u|m|m|m|m|u|m|u|u|m|m|u|u|m|m|m|m|m|m|m|m|m|m|m|u|m|u|u|m|m|m|u|m|u|m|u|m|m|u|u|m|u|m|m|u|m|u|u|m|u|u|m|m|u|u|m|m|m|m|u|m|m|m|u|u|m|m|u|m|m|m|u|u|m|u|m|m|u|m|m|u|u|m|m|m|m|m|m|m|u|u~¶¿ïÿÿÿÿÿÿÿÿÿÿÿÿ¿÷þÆþÆ>ß¿ï¿÷¿÷¿ï¿ï>ß¾¾ý|m|m|m|u|u|m|u|u|m|m|m|m|m|m|u|m|u|m|u|u|u|m|u|m|m|m|u|m|m|m|m|m|m|u|u|m|m|u|m|m|u|u|m|m|m|m|m|m|u|m|m|m|m|u|m|m|m|m|m|m|u|u|u|u|u|m|m|m|m|u|m|u|m|m|u|m|m|m|m|m|m|m|m|m|m|m|m|m|m|m|m|m|u|m|m|u|u|u|m|m|m|u|m|m|m|m|m|m|m|u|m|u|u|u|m|m|m|m|m|m|m|u|m|m|u|m|m|m|m|m|m|m|m|m|m|m|m|m|m|m|m|u|m|m|u|u|m|m|m|m|u|m|u|m|m|u|m|m|u|m|m|u|m|m|m|m|m|m|m|u|m|m|m|m|m|m|m|u|m|m|u|u|m|m|m|u|u|u|m|m|m|m|m|m|m|u|m|m|m|u|m|m|m|m|m|m|m|u|u|m|m|m|m|m|u|u|m|u|m|m½
>׿ï¿÷¿÷ÿÿÿÿÿÿ¿ï=¦|}ý=¦}®¾¶}¦=½
|m|m|m|u|m|m|m|u|m|m|u|m|m|m|m|m|m|m|m|u|u|m|u|m|m|u|u|m|m|m|m|m|m|m|m|u|m|u|u|u|m|m|m|u|m|m|u|m|m|m|m|u|m|m|u|m|m|u|u|m|m|m|m|u|m|m|m|u|u|m|u|m|m|u|m|u|u|m|m|m|u|m|m|m|m|m|m|u|m|m|m|u|m|m|m|m|m|m|m|m|m|u|u|m|m|m|u|u|m|m|m|u|m|u|m|m|m|u|m|m|u|u|m|m|m|u|m|m|m|m|m|m|m|m|u|m|u|m|m|m|u|m|u|u|u|u|m|m|m|m|m|u|m|u|u|m|u|u|m|m|u|m|m|u|m|u|m|m|m|u|m|m|m|u|m|m|m|m|m|m|m|m|u|m|m|u|u|m|m|m<m|m|u|m|u|m|m|m|m|m|m|m|m|m|m|m|m|m|m|u|u|m|m|m|m|u|u|m|m|u|u|m|u½=¦=¦>×ÿ÷ÿÿÿÿ¿ï=|u|u|u|u|u|u|m|u|m|m|u<m|m|m|m|u|u|m|u|u|u|u|m|u|u|u|m|m|m|u|m|u|m|m|m|m|u|m|u|u|m|m|m|m|m|m|u|m|m|m<u|m|m|m|u|u|m|u|m|u<m|u|m<m|m|m|u|u|m|m|m|m|u|m|m|m|u|m|u|u|m|m|m|m|u<m|m|m|m|m|u|m|u|u|m|u|u|m|u<m|u|m|m<m|m|m|u<u|m<m<u|m|u<m|m|m|u|m|m|m|m|u|m|u|m|u|u|m|m|m|u|m|u|m|u|m|m|m|m|m|m|u|m|m|u|m|m<m|m|m|m|m|m|m<m|u<m|m|m<u|m|u|m|m|m<m|m|m|u|u|m|m|u|u|m|u|m|m|m|m|m|m|u|u|m|m|m|m|m|m|m|u|m|u|m|m<u|m|m<u<u<m<m|m|m|m|m<m|m<m|u|m|m<m<m|m|u|m|m<m|m|u|m<m<m|u<u|m|m|u|m<m|u}¦~ßÿ÷ÿÿÿÿ¿ï}®|u|m<u|m|m<u<m|m|m|m|m|m|m|u<m|u|u|m|u|m|u|m|u<m<m<m|m|m|m<u<m|m|m|m<m|u|u|u|m|m<u<u<m<u|m<m|u|m|u<m|u|m<m|m<m|u|u|m|m|m|m<m|m|u|m|u|u<u|m|m|m<m|u|u|u|m|m<u|u|m|u<m|u<u<m|u|m|u|u|m|u<u|u<m|m|m<m<u<m|u|u|m|m|m<m|u<m|m|u|u|m|m|m<m|m<u|m<m<u|u<m|u|m|m|m|m<m|m<u|m|m|m|m|m<m|m|u|m|u|u|m|m|m|m|m<m<m|m|m|m|u<m|m|m<m<m<m|m|u|m|u|u<m|m|m|m<m<u|u|m|m|m|m<m<u|m|m|m|m|m|m|m|u|m|m<u<u|u|m<m<m|m|m<m<m|m|m|m<m<m<u|m|m<m<u|u|m|m|m|m<m|m|m<m|m|u|u|m|m<m<m|u<m|m<m<m<m<u<m<u|m|m¼}þÆÿ÷ÿÿÿÿÿÿ¿÷=¦|u<u<m|m|u|u<m|u|m<m<m<u|m|m<m|m<m|m|u<u<u|m<u|u<m|m|u|m|u|m|m<u|u<u|u<m<m|m|m|m|m<m|m<m|m<u|m|u|m|u<m<m|u|u<m|m|m<m|m|m|m|m|m<m|u|u<m|m|u<u<m<m|u|u|m|m|m<m<m|m<m|u<m|u<m<m|m|m|u|m<m<m<u<u|m|m<m<u|m|m|u<u|u<m<m<m|u|u<m<m|m<m<u<m|m|m<m<m<m<m<m<m|u<m|m|m<m<m<m<m<m|m<m|u|m<m<m|u|m<m<u|m|m|m|u|u<u|u|m<m<m<m<u|m<m|u|m|m<m|m|m|m<u|u|m|m|m<u|u<m<m<u|m|m|m<m<m|u|m<m<m|m|m<m<m|u|u<m<m<m|m<u<m|m<m|m<m|m|m<m<m<u<u<m<m<m|m<u<m<m|m<m<m|m|m|u<u<u<u<m<m<u|u<m<m|m<u<u|m<m<m<m¼}>׿÷ÿÿÿÿÿÿ¿ï=¦|u<m<u<m|m|m<m<m<u|m<m<m<u<u<u|m|u<m<m|u<m<m<m<m<u<m<u<u|m<u|m<u<u|m<m<u<m<m<u<u<m<m<u<m<u|m<m|m|m<m<m<m<u<u<m<u<m|m<m<u<u|m<m|m<m<u<m<m<u<m<u|u<u<m<m<u<m<m<m<m<m<m<m|u|m<m<m<u<u<m<m|m<u|u<m<m<m<m<m<m<m<m|m<m<m<u<u<m|m<u<m<u<m<m<m<m|u<u|m<m<u<u<u<u<u<m<m<u<m<m|m|m<m<m<m<m<m<u<m<m<m<m|m<m<u<m<m<m<m<m<m<m<m<u|m<m<m<m|u|m<m<m|u<u<m<m|m<u|m<m<m<m<m|m<u|m<u|u<u<m<m<m|m|u<u<u|u<u<m<m<m|u|m|u|u<m<m<u<u|u<m<u<m<m<m<m|m|m|u<m<u<u<m<u<m<m<u<u<u<m<u<u<m<u|m<m<m<m<u<m<m<u|m=¦¿ïÿÿÿÿÿÿ>ß½
<u<m<m<m<m<m<u<m<m<u<m<m<m<u|m<m<m<u<m<m<m<u|u<m<m<m<m<m<u<u<u<u<u<m|u<u<m<u<m<m|m<u<m<m<m<u<m<u<m|m<m<u<u<u<m<u<u<u<m<m<u<m<u<m<m|m<m<u<m<m<u<m<m<u<u<m<u<m|m|m<m|u<m<u<u<m<m<m<u<u<m|u<m<u<u<m|m<m<m<u<u<m|m<u<m<m<m<m<m<m<m<u<m<u<m<u<m|m<m<u<u<m<m<m|u<m<u|m<m<u<m<m<u<m|m<m<u|m<u<u<u<m<m<m<m|u<m<u<m<u|u<m<m<u<m<m|m<u<m<m<m<m<m<u<u<m<u<u<m<u<m<u<u<m|u<u<m<m<u<m<m|m|m<u<m<m<m<m<m<m<u<m<u<m<m<u<u<u<u<m<m<m<m<u<m<u<m<m<m<m<m<m<m<u<m<m<m<m<m<m<u<m<m<u<m<u<m<m<u<m<m<m<m|}þÆÿÿÿÿ¿÷¾¾|}<m<m<m<u<m<m<m<m<m<m<m<u<u<m<m<m<u<m<u<m<u<u<m<m<m<m<m<m<m<m<u<u<m<m<u<u<m<u<m<m<m<m<u<m<m<u<u<m<u<m<m<m<m<m<u<u<u<m<m<m<m<u<u<m<u<m<m<m<m<u<u<m<u<u<m<m<u<u<u<u<m<m<u<m<m<m<m<u<u<m<u<u<u<m<m<m<m<m<m<m<m<m<m<m<u<u<m<m<m<m<u<m<m<u<m<m<m<m<m<m<m<u<m<u<u<u<m<u<u<m<m<m<m<m<m<m<m<m<m<m<u<m<m<m<m<m<u<m<m<m<m<m<u<m<u<u<m<m<m<m<u<u<m<m<u<u<m<m<m<u<u<u<m<m<m<m<m<m<u<u<m<m<u<u<m<m<u<m<m<m<m<m<m<u<m<m<m<m<u<u<m<m<m<u<m<m<u<u<m<u<m<m<m<m<m<u<u<m<u<u<m<m<m<u<m<m<m<m<u<m<m<u<m|u=¦¿ïÿÿ~ß½<u<m<u<m<m<m<m<u<m<u<m<m<u<u<m<m<u<m<m<u<u<m<u<m<m<m<m<u<m<m<u<m<u<u<m<u<m<u<u<u<m<u<m<m<u<u<u<m<m<u<m<u<u<u<u<m<m<m<m<m<m<m<m<u<m<m<u<m<m<m<m<u<m<m<u<m<m<m<u<m<m<m<m<m<m<m<m<m<u<u<m<m<m<m<m<m<m<u<m<m<u<u<m<m<u<m<u<m<m<m<u<u<m<m<u<u<m<m<m<u<u<m<m<m<m<m<m<u<u<m<u<m<m<m<m<m<u<m<u<m<u<m<m<m<m<u<m<m<m<m<u<m<u<m<m<u<m<m<m<u<m<m<m<m<m<m<m<m<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<u<m<u<u<u<m<u<m<u<m<u<m<u<u<m<u<u<m<m<u<u<u<m<m<m<u<m<m<m<m<u<m<m<u<m<m<m<m<m<m<u<m<u<u<m<m<u<m<m<m<m<uýþÎ>ß}®<u<u<m<u<u<u<u<m<u<u<u<m<m<m<m<u<m<u<m<m<u<u<m<u<m<m<m<u<m<m<m<m<m<m<u<m<m<u<m<m<u<m<m<u<m<u<m<u<m<u<m<m<u<m<m<m<m<m<u<u<u<m<m<m<u<u<u<m<u<m<u<m<m<m<m<u<m<u<m<m<m<m<u<m<m<m<m<u<m<m<u<u<m<m<m<u<m<m<m<m<u<m<m<m<m<m<m<u<u<m<m<u<u<u<m<m<m<m<u<u<u<m<m<u<m<u<u<m<m<m<u<m<u<m<m<u<m<u<m<m<m<u<u<m<m<m<m<u<m<m<m<m<m<u<m<m<u<m<m<m<m<m<m<m<u<m<m<u<m<m<m<m<m<u<m<m<u<m<m<u<m<m<u<m<u<m<u<m<m<u<m<m<u<u<u<m<m<m<u<m<m<u<m<m<m<m<m<m<m<m<m<u<m<m<u<m<m<u<u<u<m<u<m<u<u<m<m<m<u<u<m<u<u<m<u<u<m¼ý<m<m<m<m<u<m<m<m<u<m<u<m<m<m<u<u<u<u<u<u<u<u<u<u<m<u<m<u<m<m<u<u<m<u<m<m<m<m<m<u<u<m<u<u<u<u<m<m<m<u<u<m<m<m<u<m<m<m<m<m<u<u<m<m<m<m<u<u<u<m<m<m<u<m<u<m<m<m<m<m<u<m<m<u<u<u<m<m<m<m<m<u<m<u<m<u<m<m<m<m<m<m<u<m<m<m<m<m<m<u<u<m<u<m<m<m<m<m<m<u<m<u<m<m<m<m<u<m<m<m<u<u<m<m<u<m<m<m<u<u<m<u<m<u<m<m<m<m<m<u<u<u<u<m<u<m<u<m<u<u<m<m<u<m<u<m<m<m<m<u<u<m<u<u<m<u<m<m<m<m<u<m<u<m<m<m<m<m<m<u<u<m<u<u<m<u<m<m<u<u<u<m<m<m<u<u<u<u<m<m<u<u<m<u<u<m<u<u<u<m<u<m<m<m<m<m<m<m<m<u<u<m<m<u<m<u<m<m<m<u<u<u<u<u<m<m<u<m<m<u<m<u<u<m<u<m<u<m<m<m<m<u<m<u<m<m<u<u<m<m<m<m<m<u<u<m<m<u<m<m<m<u<m<m<u<u<u<u<u<m<m<m<m<m<m<m<m<m<u<m<u<m<m<m<u<m<m<m<m<m<u<m<m<m<m<m<m<u<m<m<m<u<m<m<u<m<m<u<m<m<m<u<m<m<m<m<u<u<m<m<m<m<m<m<u<u<m<m<m<m<m<m<m<u<m<u<u<u<m<m<u<u<m<u<m<m<u<m<m<u<m<u<u<u<m<u<u<m<m<u<m<u<u<u<m<m<m<m<u<m<m<m<u<m<u<u<m<m<m<u<m<u<m<m<u<m<u<u<u<u<m<u<u<m<u<m<m<m<u<u<m<m<u<u<u<m<m<u<m<u<m<m<m<u<m<u<m<u<u<m<u<m<u<m<u<m<m<m<m<u<m<m<m<m<m<u<m<m<m<m<u<u<m<m<u<m<u<m<u<m<u<m<m<m<m<m<u<m<u<m<u<m<m<m<m<u<u<m<u<u<u<u<m<m<m<m<u<m<u<u<m<m<m<m<m<u<u<u<m<m<m<m<u<m<m<m<m<u<m<u<u<u<m<m<m<m<m<u<m<u<m<m<m<m<m<u<u<m<m<u<u<m<m<u<m<m<u<u<m<u<u<u<m<m<m<u<m<u<m<m<u<m<m<u<u<m<m<u<m<m<u<u<m<m<m<m<u<u<u<m<u<u<m<m<u<u<m<m<m<m<m<m<m<m<m<u<m<u<u<m<m<u<u<m<u<m<u<m<m<u<u<m<m<u<m<m<m<u<m<u<m<m<m<u<m<m<m<m<u<m<m<u<m<u<m<m<m<m<u<u<m<u<m<m<u<m<u<m<u<u<u<m<u<m<u<m<m<m<u<m<u<u<u<m<m<u<u<m<m<u<u<m<m<m<m<m<u<u<m<u<u<u<m<m<m<u<u<m<u<m<u<m<m<u<m<m<u<u<m<u<m<u<m<m<u<m<m<u<m<u<u<m<m<m<m<m<m<m<m<m<u<m<u<m<m<u<m<u<u<m<u<m<u<m<m<m<u<u<u<m<m<m<m<m<u<m<m<m<u<m<m<m<m<u<u<m<m<m<m<m<u<u<m<m<u<m<m<u<m<u<m<u<u<m<m<m<m<u<u<m<m<u<u<u<m<m<m<m<m<m<m<u<m<m<m<m<m<u<m<u<m<m<u<m<m<u<u<m<m<u<u<m<u<u<u<u<u<m<u<m<m<m<m<m<m<m<m<m<m<m<m<u<m<m<m<u<m<u<m<m<m<m<u<u<u<u<u<m<m<u<u<u<m<m<m<m<m<u<m<u<u<m<m<u<u<m<m<m<m<m<u<u<u<m<m<u<m<m<u<m<m<u<m<m<m<m<m<m<m<m<u<m<m<m<m<u<u<m<m<u<u<m<m<u<m<m<u<u<m<m<u<m<m<u<m<m<u<u<u<u<u<m<u<u<m<m<m<u<m<m<m<m<u<m<m<u<m<u<m<m<m<m<m<m<m<u<u<u<u<m<m<m<u<m<m<u<m<m<u<m<m<m<u<m<m<u<m<m<m<u<m<m<u<m<u<m<u<m<m<u<m<m<u<m<m<m<m<m<u<u<m<u<m<u<u<m<u<m<m<m<u<m<m<m<u<u<m<m<m<m<u<u<m<m<m<m<m<m<m<m<m<u<m<m<m<u<m<u<m<m<u<m<m<m<u<m<u<u<u<m<u<u<m<m<m<m<m<u<m<m<u<u<u<m<m<u<m<u<m<m<m<m<u<u<m<u<m<m<u<u<u<m<m<m<m<u<m<m<m<m<m<m<m<u<u<m<m<m<m<m<u<m<u<u<m<u<m<m<m<u<m<m<m<m<m<u<m<u<u<m<m<m<m<m<u<u<m<m<m<m<u<m<m<u<u<u<u<u<m<u<u<u<u<u<m<u<m<u<u<m<m<u<m<m<m<m<u<m<m<m<m<u<m<m<u<m<u<m<m;m;u<m;m;u<m;m;m;m;m;m;u<m;m<u<u<m;u;m<m;u<u;m<u<m<m;u<m<m;u<u<m;m<u<m<u;m<u;u<u<u;m;m;m;u;m;m<m;m;m;m<u;u;u<m;m;m<m;u<u;u;m;u<m<m<u<m<u;m<u;m<m<m<u<m;u;m<m;m;u<m<u<m<m<m;u<m<m;m;u<u;m<u;m;u;u<u<m<m;u;m;m<u<m<u;u<u<m<u<m;m<m<u;m<m;m;m;u;m<m<m;u;u<m;m;u<m<m<u<m;m<m<u;m<m;m;m<m<m<m<m<m;u<m;u<m<m<u;m;u<m;m<m;u<u;m<m;m;m;m;m<m;u;m<u;u;u<m<m;u<u<m<m;m;m<m;m;m;m<m<m<m<m<m<m<u<m<u<m;m<u;u;u<u;m<u<m;u<u;m<u<u;m<m;m<m;m;m;m;m;u;m<u;u;m;m;u;m;u;m;u;m;m;u<m<m<u<u;u<m<m<u<m<m;m<m<u<m<m;u;m;m;u<u;m<u;u;m;m;u;u;m;u;u;u;u<m;m;m;m;u<m;u;m;u;u;u;u;m;u;u;u;u;m;m;u;m;u;m;m;u;m;m;m;u;u;m<m<m;m;m;u;m;u<u;m;u;m;m;u;u;m;u;m;u;u;m;m;u;m<m;m;m;u;m;u;m;m;u;m;m;u;u;m;u;u;m;m;m;m;m;m;u;m;m;m;m;m;m;u<u;m;u;m;u;m<m;m;m;m;u;m;u;u;m;m;m;m;m;u;m;u;m;m;m<m<m;m;u;u;m;m;u;m;m;m;u;u;m;m;m;m;m;m<u;m;m;u;u<u;m;u<u;m;u;m;u;u;m<u;m;m;u;u;m;m;u;u;m;m;m;u;u;u;m;u;m;u;u;m<m;m;m;m;m;m<m;m;m;u;m;m;m;u;m;m;u<m;m;m;m;u;m<u;m;m;m;m;u;u;m<m;m;u;m;u;m;m;u;m;m;m;u;m;u;u;u;m;m;m;m;u;m;u;u;u;m;m;m;m;m;m;u;m;m;u;m;m;m;m;m;u;m;u;m;u;u;m;m;m;u;m;m;m;m;m;u;m;u;m;m;m;m;m;m;m;m;m;m;u;u;u;m;m;u;u;m;m;m;m;m;m;m;m;m;m;u;m;m;u;u;m;m;m;m;m;m;m;u;u;u;m;u;m;u;m;u;m;m;m;u;u;m;u;m;u;u;m;u;m;m;m;m;u;m;u;u;m;m;m;u;m;u;u;m;u;m;m;m;u;m;u;m;m;m;m;u;m;u;u;m;u;m;m;u;u;u;m;m;u;u;m;m;m;u;m;m;m;u;m;m;u;u;m;m;m;u;u;u;u;m;u;u;m;m;m;m;m;m;m;u;u;u;u;m;m;m;u;m;m;u;m;m;m;u;u;m;m;m;m;u;m;u;m;u;m;u;m;m;m;m;m;m;m;m;m;m;m;u;m;u;u;m;m;m;m;u;m;u;u;u;u;m;m;u;u;m;m;m;u;m;m;m;u;m;m;m;u;m;m;m;m;m;u;u;m;u;m;m;u;m;u;u;m;m;m;u;m;u;u;m;m;u;m;m;m;m;u;m;m;m;m;u;u;u;m;m;u;u;u;m;m;u;m;m;u;m;m;m;u;u;u;m;m;u;u;m;m;m;m;m;m;u;u;u;m;m;u;u;m;u;u;u;m;m;m;m;m;u;m;m;m;m;m;m;m;u;m;u;m;u;m;u;m;u;m;u;u;u;u;m;u;m;u;m;m;u;m;m;u;u;m;m;m;m;m;m;u;m;m;u;m;m;m;u;u;u;u;u;m;u;m;m;m;m;m;m;u;m;m;u;u;m;m;u;u;u;u;m;u;m;u;u;m;m;u;m;m;u;m;u;m;m;u;u;u;u;m;m;u;m;u;u;u;m;m;m;u;m;u;u;m;u;m;u;m;u;u;u;u;m;m;m;m;m;m;u;u;u;u;m;u;m;m;m;m;m;m;m;m;u;m;u;m;u;m;m;m;m;m;u;u;m;u;m;u;m;u;m;u;m;m;m;u;u;m;m;u;u;u;m;u;m;m;m;m;u;m;u;u;m;m;u;m;m;u;u;u;u;u;m;u;u;m;m;u;u;u;u;u;u;m;u;m;u;u;u;m;u;u;u;u;m;u;m;m;m;u;u;u;m;m;m;u;u;m;u;m;m;u;m;u;u;m;m;m;m;m;u;m;m;m;m;m;m;m;m;m;u;u;m;m;m;m;m;m;m;m;m;u;u;u;m;m;m;u;u;m;m;m;m;m;u;m;m;m;m;m;m;m;m;m;m;m;m;m;u;u;m;m;m;m;u;m;u;m;m;u;u;m;m;u;m;m;m;m;u;u;m;m;m;m;u;m;m;u;m;u;m;m;m;u;m;m;u;m;m;u;u;m;m;m;m;m;u;m;u;m;m;m;m;m;m;u;u;u;m;u;m;m;m;m;u;m;u;u;m;m;u;m;m;u;u;m;u;m;m;m;u;u;u;m;u;u;m;m;m;m;m;m;m;m;m;u;m;m;m;m;m;u;u;m;m;u;m;m;u;m;u;u;m;u;m;u;m;m;u;u;u;u;m;u;m;u;u;m;m;m;m;u;m;m;m;m;m;u;u;m;u;m;m;m;u;m;m;m;m;m;m;u;u;u;u;m;u;m;m;u;u;u;m;m;u;m;m;u;m;m;m;m;m;u;u;m;u;m;u;m;m;u;m;u;u;m;u;m;m;u;u;m;u;m;u;m;m;m;m;u;u;m;u;u;m;u;m;u;u;m;m;m;m;u;m;m;u;m;m;m;u;m;u;u;m;u;m;m;m;m;u;u;m;m;m;m;m;u;u;m;m;m;m;m;u;u;m;m;u;m;m;m;m;m;u;m;m;m;m;m;u;m;u;u;u;m;u;m;m;m;m;u;u;u;m;m;m;m;u;u;m;u;m;m;m;u;u;u;u;u;m;m;m;u;u;m;m;m;m;u;m;u;u;m;m;u;u;m;m;u;m;u;m;m;m;u;m;m;m;m;m;u;m;u;m;u;m;m;m;m;m;m;m;u;m;u;m;u;u;m;u;u;u;u;m;m;u;m;m;m;u;u;m;u;m;m;u;m;m;m;m;m;m;u;m;m;u;m;m;u;m;m;m;u;m;m;m;u;u;u;m;u;u;m;u;m;u;u;u;m;m;u;m;m;u;m;m;m;m;u;u;u;m;m;u;m;u;m;u;u;m;m;m;u;u;u;m;m;m;m;m;m;u;m;u;u;m;u;m;u;m;u;u;m;u;m;m;u;m;m;u;m;m;m;m;u;m;m;u;m;m;m;m;u;m;u;m;u;u;m;m;m;m;u;m;m;u;u;u;m;m;u;m;m;u;m;m;u;m;m;m;m;m;u;m;u;m;m;u;u;u;m;m;u;m;u;m;u;m;m;m;u;u;m;u;u;m;u;m;m;u;u;u;u;m;u;u;u;m;m;m;u;m;m;m;u;u;m;u;u;u;m;m;u;m;m;u;u;m;m;u;u;u;u;m;m;u;m;m;m;u;m;m;m;u;u;u;m;u;m;u;m;m;m;m;u;u;u;u;m;m;u;m;m;u;u;m;m;u;m;m;m;m;m;m;m;m;u;m;m;u;m;m;u;u;m;m;m;m;m;m;u;m;m;m;m;m;u;m;m;m;m;m;u;u;u;u;u;m;u;u;u;u;m;m;m;u;m;u;u;m;m;m;m;u;m;u;u;m;m;u;u;u;m;u;u;m;m;u;m;m;m;u;m;u;m;m;u;m;m;u;m;m;u;m;u;u;m;u;u;u;m;u;m;m;u;m;m;u;m;u;u;u;u;m;u;m;u;u;m;u;m;u;m;m;m;m;m;u;u;m;u;u;m;m;u;m;u;m;u;m;m;m;u;m;u;u;u;m;m;m;u;m;u;m;u;u;u;u;u;u;m;m;u;u;m;m;u;u;m;m;m;m;m;m;m;m;m;u;m;m;u;m;u;m;m;m;u;m;u;m;u;m;u;u;m;m;u;m;u;m;u;m;u;u;u;m;m;m;u;m;m;m;u;u;m;m;u;m;m;m;u;u;u;m;m;m;m;m;u;m;u;m;m;u;u;u;u;u;m;m;m;u;u;m;m;m;m;u;m;m;m;u;m;m;m;u;u;m;u;m;m;m;m;m;u;m;m;m;m;m;m;m;u;m;u;m;u;m;m;u;m;u;u;m;u;u;u;m;m;u;m;u;u;u;u;u;m;m;m;u;u;m;m;m;m;m;u;m;m;m;u;m;u;m;u;u;u;u;m;u;u;m;u;m;m;m;m;u;u;m;u;u;u;m;u;u;m;m;u;u;m;m;u;m;m;u;u;m;m;m;m;m;m;m;u;m;u;m;u;m;m;m;m;m;u;m;u;m;m;u;m;m;u;u;m;m;m;u;u;m;u;m;u;m;m;m;m;u;u;u;u;m;u;m;u;m;u;u;m;u;m;m;m;u;u;u;u;m;m;m;u;u;m;m;u;m;u;u;u;u;m;u;u;m;m;u;u;m;m;m;u;u;m;m;u;u;m;m;u;m;m;u;m;m;m;u;m;m;m;m;m;m;m;m;u;m;m;m;m;u;u;m;m;u;u;u;m;u;u;u;u;m;m;u;m;u;m;m;m;u;m;m;u;u;u;u;m;u;m;u;m;m;m;m;m;u;m;u;m;m;u;u;u;m;m;u;u;m;u;m;u;u;u;m;m;m;u;m;m;u;m;m;m;m;u;u;m;m;u;u;u;m;u;m;u;u;u;m;m;m;m;m;m;m;u;u;m;u;m;m;u;m;m;m;m;u;m;m;m;u;m;u;u;u;m;u;u;m;u;m;m;m;u;m;u;m;m;u;u;u;u;m;m;m;u;m;m;m;u;u;u;u;u;u;m;u;m;u;u;m;u;u;u;u;u;m;u;u;m;m;u;u;m;u;m;u;m;m;u;m;m;m;u;m;m;m;m;m;u;u;m;m;m;u;m;m;m;m;u;m;u;u;m;u;m;u;u;u;m;u;u;m;u;m;m;u;m;u;m;m;u;m;m;m;u;m;u;m;m;m;u;u;m;u;m;m;u;u;u;m;m;u;m;m;m;u;m;u;m;m;u;u;u;m;m;m;u;u;u;m;u;u;m;u;m;m;m;u;u;u;m;u;m;m;u;u;u;m;u;m;m;u;m;u;u;m;m;u;m;m;m;u;u;u;u;m;u;u;m;u;m;u;m;u;m;m;m;u;u;m;m;m;u;m;u;u;m;u;u;m;u;u;m;m;u;m;m;u;m;m;u;m;u;m;u;u;u;u;m;u;m;m;u;u;m;u;u;m;m;u;m;u;u;m;u;u;m;m;u;m;m;m;m;m;u;m;u;u;m;u;u;m;m;m;m;m;m;m;m;m;u;u;m;m;u;u;u;u;u;u;m;m;m;u;m;u;u;m;m;u;m;m;m;m;m;m;u;m;u;u;u;m;m;m;m;m;m;m;m;m;u;m;m;u;m;u;m;u;u;m;m;m;m;u;u;m;m;m;m;m;m;u;u;m;u;u;m;m;u;m;m;u;m;m;u;u;m;u;m;m;m;u;u;m;u;u;u;m;m;u;m;m;m;u;m;u;m;u;u;m;u;u;m;u;m;m;u;m;u;m;u;m;m;u;m;u;u;m;u;m;m;u;u;u;m;m;m;u;u;u;u;m;m;m;m;m;u;m;m;u;m;m;u;m;m;m;u;u;m;m;m;u;m;u;u;u;m;u;m;m;m;m;u;m;m;m;m;m;u;u;u;m;u;m;m;m;m;u;m;m;u;u;m;u;u;u;m;m;m;m;u;m;m;m;u;m;m;u;m;m;u;m;m;u;m;m;m;m;u;u;u;m;m;m;m;u;m;m;m;u;u;u;u;u;m;u;m;u;m;m;u;m;u;m;m;m;m;u;m;m;u;m;u;m;m;u;u;m;u;m;u;m;u;m;u;u;u;m;m;m;m;m;m;u;u;u;m;u;m;u;u;u;m;m;m;m;u;m;m;u;m;m;m;m;m;m;u;m;u;u;u;u;m;u;u;m;u;m;u;u;u;m;m;m;m;u;u;u;u;u;m;u;m;u;m;u;m;m;m;m;u;u;m;m;u;u;m;m;u;u;m;m;m;m;m;u;m;u;m;m;m;u;u;m;u;u;u;u;m;m;u;m;m;u;m;m;m;m;m;u;m;u;u;m;m;u;u;m;m;m;m;m;u;u;u;u;u;m;u;u;m;m;u;u;u;m;m;m;u;u;u;u;u;m;m;u;m;u;u;u;m;m;u;m;m;u;u;u;m;m;m;u;m;u;u;m;u;u;m;u;u;m;u;m;u;u;m;m;u;m;u;u;u;u;u;u;u;m;u;u;m;u;u;m;m;m;m;u;u;m;u;m;u;u;m;m;u;u;m;u;u;m;u;m;m;m;u;m;m;m;m;m;m;u;m;u;m;m;u;m;m;u;m;u;m;m;u;m;u;m;u;u;u;m;u;m;m;m;u;m;m;u;u;u;u;u;m;u;u;u;u;m;u;u;u;m;u;u;m;u;m;u;m;u;m;m;u;u;u;m;u;u;u;u;m;u;u;u;m;m;m;m;m;u;u;u;u;u;u;u;u;m;u;m;m;u;m;u;m;m;m;u;u;m;u;u;u;m;u;m;u;u;m;u;m;u;m;m;m;u;m;u;u;m;m;m;u;u;m;u;m;u;m;m;m;u;u;u;m;m;u;m;u;m;m;m;u;m;u;u;m;u;m;u;u;u;u;m;m;m;m;u;u;m;u;u;u;u;u;u;m;m;m;m;u;m;u;m;m;m;u;m;m;u;u;u;m;m;u;m;m;u;u;m;m;u;m;m;u;m;u;m;m;m;u;u;u;m;u;u;m;m;m;u;u;m;m;m;m;m;m;u;u;u;m;u;u;u;u;u;u;m;m;m;m;u;u;m;u;m;m;m;m;u;m;m;m;u;m;u;m;m;m;m;u;m;u;m;u;m;u;u;u;u;m;m;m;m;u;m;m;m;m;u;m;m;u;u;u;m;m;m;u;m;m;m;u;u;u;m;m;u;u;u;m;m;u;m;u;u;m;u;u;u;u;m;m;m;m;m;m;m;u;m;m;m;m;u;u;m;m;u;m;u;m;m;u;u;m;m;u;m;m;u;m;m;m;m;m;u;u;m;u;m;u;u;m;u;u;u;u;m;m;m;m;u;m;u;m;u;u;u;m;m;m;m;u;u;u;u;u;m;u;u;m;m;m;m;m;m;m;u;u;m;m;u;m;u;m;m;m;m;u;m;m;m;u;u;u;m;u;m;u;m;m;m;u;u;u;u;m;m;m;m;u;m;m;u;u;u;u;u;m;u;m;m;m;u;u;u;u;m;m;u;m;u;u;u;m;m;m;m;m;m;u;m;u;u;u;m;m;u;m;m;u;m;u;m;u;u;m;u;u;u;m;m;m;u;u;u;u;u;u;u;u;m;m;u;u;u;m;u;u;u;m;m;u;u;m;m;u;m;m;u;m;m;m;m;u;u;u;u;m;u;m;m;u;m;m;m;u;u;u;u;m;u;u;u;m;u;u;u;m;m;u;m;u;m;u;u;m;m;m;m;m;m;m;u;m;m;u;u;u;u;u;m;m;u;u;u;u;u;u;u;u;u;u;u;u;u;u;m;u;m;m;u;u;u;u;u;u;m;m;m;m;u;m;m;m;u;m;m;u;m;m;m;u;u;u;u;u;m;u;m;u;u;u;m;m;u;u;m;u;u;u;u;u;m;m;m;m;m;m;u;u;m;u;u;m;m;m;m;u;m;u;m;m;m;u;u;m;m;u;m;u;u;u;u;m;u;m;m;m;u;u;m;m;u;u;u;m;u;m;m;m;u;m;m;m;m;u;u;m;m;u;u;m;u;m;m;m;u;m;m;u;u;u;m;m;m;u;u;u;m;u;m;m;u;u;m;u;u;u;m;u;m;m;u;m;m;u;u;u;u;u;u;m;m;u;m;m;m;u;m;u;u;u;m;m;m;u;u;m;u;u;u;m;u;m;u;u;u;u;u;m;u;u;u;m;u;u;m;u;m;m;m;u;u;u;u;u;u;m;u;m;m;u;u;u;u;u;m;m;u;u;m;u;u;u;u;m;m;u;u;u;m;m;u;m;u;u;u;u;u;m;u;m;m;u;u;u;u;m;u;m;m;u;u;u;m;m;m;u;m;m;u;m;m;m;u;m;m;m;m;u;u;m;u;m;u;m;m;m;u;m;m;m;m;u;u;u;m;m;u;u;u;m;u;m;m;m;u;u;u;m;m;m;m;m;u;m;u;u;u;m;m;m;u;u;m;m;m;m;u;u;m;u;u;u;m;m;m;m;m;u;m;m;u;u;m;u;m;u;m;m;m;m;u;m;m;u;u;m;u;m;u;m;m;u;u;m;u;m;u;m;m;m;u;u;u;u;m;m;m;u;u;u;m;m;u;u;m;u;u;m;m;m;m;m;u;m;u;m;u;u;m;m;u;m;m;u;u;u;m;m;u;m;u;u;u;m;m;m;u;u;u;u;u;u;u;u;m;u;m;u;m;u;m;m;u;m;m;m;m;u;u;m;u;m;u;m;u;u;m;u;m;u;m;m;m;m;u;u;u;m;m;m;m;m;m;m;m;u;u;m;u;u;u;m;m;u;u;m;u;m;u;m;m;u;m;m;m;u;u;u;m;u;m;m;u;m;u;u;m;u;u;m;m;m;u;u;m;m;u;u;u;u;u;m;u;m;u;u;m;u;u;m;m;u;m;u;m;u;m;m;m;m;m;u;m;m;m;m;u;m;m;m;u;u;u;u;m;m;u;u;m;m;m;u;m;m;u;m;u;u;u;m;u;m;u;u;u;m;m;m;u;m;u;m;m;m;u;u;u;u;m;m;u;u;u;m;m;u;u;u;m;u;m;u;m;m;m;m;m;m;m;u;m;u;m;m;m;u;m;u;u;u;m;u;u;m;u;m;u;u;u;m;u;u;m;u;m;m;u;m;u;m;u;u;u;u;m;m;m;u;m;u;u;u;u;m;u;m;u;u;m;m;m;u;m;u;m;u;m;m;m;m;u;u;m;m;u;m;m;u;u;m;m;u;u;m;u;m;m;m;m;u;u;u;m;m;u;m;u;m;m;u;m;m;u;u;u;m;u;m;m;m;m;m;m;m;m;m;m;u;u;u;m;u;u;u;m;m;u;u;u;m;u;u;u;u;m;u;m;m;m;m;u;m;u;m;m;m;m;m;u;u;m;u;u;m;u;u;u;m;m;u;u;m;m;m;m;u;u;u;u;u;m;m;m;u;m;m;m;u;u;m;m;m;m;m;u;u;m;m;m;u;u;u;u;u;m;u;u;u;m;u;m;m;m;u;u;u;m;u;u;m;u;u;u;m;m;m;m;u;u;u;m;m;m;u;m;u;m;m;u;m;u;m;u;u;m;u;u;u;m;u;u;u;m;m;u;m;u;m;u;u;u;u;m;m;m;m;u;m;m;m;u;u;m;u;u;u;u;u;u;u;u;m;u;u;u;m;u;u;m;u;m;u;m;m;m;u;u;m;u;m;u;m;m;m;m;u;m;u;m;u;u;m;u;u;m;u;m;u;u;m;m;u;u;u;m;u;m;m;m;u;u;u;u;m;u;u;m;m;m;m;u;m;u;m;u;u;u;m;u;m;m;u;u;m;m;u;m;m;m;u;m;u;m;m;u;m;u;m;m;u;m;m;u;m;m;u;m;m;m;m;u;u;u;u;u;m;u;m;m;m;u;m;u;u;u;m;m;u;m;u;m;u;u;m;m;u;m;m;u;u;u;u;u;m;m;u;m;m;u;u;m;u;m;u;m;m;u;m;u;m;m;u;m;u;m;m;u;m;m;u;u;u;m;m;m;m;m;m;u;u;m;u;u;m;u;m;u;u;m;u;u;m;m;u;m;m;u;m;u;u;u;m;m;u;u;u;m;m;u;m;u;m;m;m;u;m;m;u;m;u;u;m;m;m;m;u;u;m;u;m;m;u;u;m;m;m;u;m;u;u;u;m;u;u;u;m;u;m;u;u;m;m;u;u;m:u;m;m;m:m;m;u;u:u;u;u:u;m;m;u;m;m;m;m:u:m;u;m;u;m;u;m;u:u;m;u;u;m;u;m;u;m;m;m;u:u;m;u;u:u;u;m:u;m;m;u;m;u;u:u;m;u:u:u;m;u;u:u;u:m:u;u;u;u:u;m;m;m;u;u;m;u:u;u:u:m;m;u:u;m;u;u;m:m;m:u;u;u;m:u;u;u:u;u;u;u;m;u;u;m;u;u;u;u;m:m;u;u;u;u:u;u;m;m;u;m;m:u:u;u;u;u;u;u:u:m:m;u:u;m;m:u;m:m:m:u;u;m;u;u;u;m;u;m:u:m;m;m;u;m;m:m;m;m;u;u:m;m;u;m;u:m:m;m;u;m;u:u;u;m;u;u:m;m;m;m;m;m;u;m;u:m;u;u;u;m:u;m;m;u;m;m;m;m;m:u:m;u;m;m;m;u:u;m;u:u;m:m;m:m;m:u;u;m;m:m;m;m;m:m;u;u:u:m;u;m;u;m;m;m;u;u;u;u:m:u:u;u:u;m;m:u:m:u:u;u:m;u;u:u:m;u;m;m:m:u:u;u:m:u:u:u;u:u:u;m:m:u:u:u:m:m;u:u;u;u:u:u;m:u:u:m:u;u;u:u;m:u:m;u:u;m;u;m:u:u;u;m;u:u:m:u:m;u:u;u:u:u;m;u:m;m:u:m:m;m:m:u:u:u:u:u:m:m:u;m:u:u:m:u:m;u:u;m:m;u:m;u:u:u;u:m:u:u:u:u:u:m;m:m:u:m;u;u:m:m;m:m:u:m:m:m:u;u:u;m:m:u:m:u;u:u:m:u:u;u:u:u;m;u:u:u:u:m:u:u:u:u:u:u:m:u:m:m:u:u;u:m:m;m;u;m:u:u:m:u:m;u;u{
{
{
;u:u;u:m:u:m:m:m:u:u:u;u:u;u:m:m:u;u;u:m:u:u:m:u:m:u:u:m:u;m:u:u;u:u:m:u:u:u:u:m;u:m:u;m:u:u:m:u:m;m:u:u;u:u:u;u:m:m;m:m;m:u:m:m:m:u:m:u:m:m:m:u:u:m:m:m:m:u:m:m:u:u:u:m:u:u:m:m:u:u:m:u:m:u:m:m:m:m:m:m:m:m:u:m:u:m:u:u:m:m:m:m:u:m:m:m:u:m:m:m:m:m:u:u:u:m:u:m:u:m:u:m:m:u:m:u:m:m:u:u:m:u:m:m:m:u:u:u:m:m:m:m:u:m:m:m:u:m:u:u:u:u:u:m:u:m:m:m:u:u:m:m:m:m:u:m:m:u:u:m:u:m:u:m:m:m:m:m:m:u:m:m:m:m:u:u:m:u:u:u:m:m:m:u:u:u:u:u:m:m:m:u:m:m:m:m:m:u:m:m:m:m:m:u:u:u:m:u:u:m:m:u:u:u:m;u{
½¾>ßýÆü{}:u:u:u:m:u:u:m:u:u:u:u:m:u:m:m:m:m:m:u:m:u:u:u:u:u:m:m:m:u:m:m:m:u:m:u:u:m:u:u:u:m:m:u:u:u:u:u:m:u:m:m:m:m:m:m:m:u:m:u:u:u:m:u:m:m:u:m:u:m:u:u:m:m:u:u:m:u:u:m:u:u:m:u:u:m:m:m:u:u:u:m:u:u:m:u:m:m:u:m:m:m:m:m:m:m:m:u:m:m:u:u:m:u:m:m:u:m:u:u:u:u:u:m:m:u:m:u:m:u:m:m:u:m:m:m:m:u:u:u:u:u:m:u:m:u:u:u:m:m:m:u:m:u:m:u:m:m:u:u:m:u:u:u:u:u:u:u:u:u:u:u:u:m:m:m:u:m:u:u:u:m:m:u:m:m:u:m:m:m:u:m:m:m:m:u:u:m:u:u:m:m:m:u:u:u:u:m:u:m:m:m:u:u:u:u:u:m:m:u:m:m:u:m:m:m:u:u:u:m:u:m:u:m;u<¦¾ïÿÿ¿÷¿ï½¾{
;}:u:u:m:m:u:m:u:m:u:m:u:u:m:m:u:u:m:u:u:m:m:u:u:u:m:m:u:u:u:m:u:u:u:m:u:u:u:m:m:u:m:m:u:u:m:m:m:m:u:u:u:m:u:m:m:u:m:u:m:m:u:u:m:m:m:u:u:u:u:u:m:m:u:m:m:u:u:u:u:u:u:m:m:u:m:m:m:m:u:u:m:u:u:u:u:u:u:u:m:u:m:m:u:u:u:u:u:m:m:u:u:m:m:u:u:u:m:m:m:m:m:u:u:u:u:u:m:m:m:m:m:m:u:m:m:m:m:m:m:u:m:u:u:m:m:u:u:u:m:u:u:m:m:u:u:m:u:u:m:u:m:m:m:m:m:u:m:u:u:m:m:u:m:m:u:u:u:m:u:u:m:m:m:u:u:u:m:u:m:u:u:u:m:m:m:u:u:m:m:u:u:m:m:u:u:u:u:u:m:u:u:m:u:m:u:u:m:u:u:m:m:m:m:u:m:m:u:u:u:u:u;u}¶ÿ÷ÿÿÿÿÿÿ¿÷>×û;}:m:m:u:u:m:u:u:m:m:m:u:m:u:u:m:m:m:u:m:u:u:u:u:u:m:m:m:u:u:m:u:m:u:u:u:m:u:u:u:u:u:u:m:u:m:m:u:u:u:u:m:m:u:u:u:m:u:m:m:m:u:u:m:u:u:u:m:m:u:u:u:u:u:m:u:u:u:u:m:m:u:m:m:u:u:u:m:m:m:m:m:u:u:m:m:m:u:u:m:m:u:u:u:m:u:u:u:m:u:u:m:u:u:m:m:m:m:u:m:u:m:m:u:u:m:u:u:u:u:m:u:u:u:m:u:u:u:u:u:m:u:u:u:u:u:u:m:u:u:m:u:u:u:m:u:m:u:u:m:m:m:u:m:m:m:u:m:u:u:m:u:u:m:m:u:m:u:m:u:m:u:u:u:m:m:m:u:m:u:m:u:u:u:u:u:u:m:u:m:m:u:u:u:m:u:m:u:m:u:m:u:u:u:u:m:m:m:u:u:m:u:m:u:m:m:u:u:u:u:u:u}¶¿÷ÿÿÿÿÿÿÿÿ¿÷>×<®;}:u:u:u:m:m:m:m:m:m:u:m:u:m:u:m:m:m:u:u:m:m:m:u:u:u:m:u:u:u:u:u:m:m:u:m:u:m:m:u:u:m:u:m:m:u:m:u:m:u:u:u:u:m:u:u:u:m:u:múl:u:mút:m:m:m:u:uút:u:u:m:u:m:u:u:u:u:m:m:uúl:m:u:u:uútút:m:u:u:m:m:u:m:u:m:m:m:u:u:uúl:m:m:uút:u:m:uút:u:uúl:uút:m:u:m:múl:m:u:u:m:mút:múl:uút:u:u:m:u:uúl:u:m:m:uút:u:u:u:m:uúl:u:u:u:m:m:u:m:u:m:u:m:u:m:m:múl:uúl:m:u:m:m:u:u:m:u:u:u:m:m:u:múlúl:u:u:u:u:u:u:u:u:u:uúl:u:m:m:u:m:uút:m:u:m:uút:m:u:m:u:múl:m:m:m:m:u:m:m:múl:m:m:m:m:m:múl:u:u:u<®¿ïÿÿÿÿÿÿÿÿÿÿ¿÷~ß<®:u:u:m:u:uútúl:uúl:u:u:u:uút:m:u:m:u:m:u:u:u:u:u:u:u:u:u:u:m:mútútút:u:múl:m:m:u:u:m:uút:u:m:múl:m:múl:u:m:u:mút:u:uúl:múl:uút:uút:u:m:mút:u:uútúlút:m:uúlúl:múlúlút:m:m:u:m:u:m:u:u:m:uúlúlúlúl:m:múl:uútútúlút:uúlút:m:mút:uútúl:uúl:uút:uút:uúl:u:u:u:m:mútútút:uúl:u:uút:mútúl:m:u:uúlúlút:uúl:uúl:u:m:m:múl:u:m:uútúl:múl:m:uút:u:u:u:uúl:uúlútúlúlúl:mútútútúl:u:múlúl:uút:uútút:m:uútút:uúlút:uútúlútúlúl:u:u:u:uúl:u:uúl:m:m:u:uúlúlútúl:múl:múl:m:u:u:uút:uúl:m:u:uû¿ïÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ýÎ{
:u:m:múlút:múl:uúl:múl:m:múlútúl:u:u:uúl:m:u:mútúl:u:u:u:m:uút:m:uút:mútút:u:m:u:m:u:u:múl:m:m:m:m:u:múlúl:uúl:u:uútúlút:uúlúlúl:uút:u:u:mútút:múlútúlút:uútútútútút:uúlútúlútúl:m:u:u:u:u:m:uúlút:m:uútút:u:u:uútút:mútútúl:uútút:uútútútút:m:u:uúlúlúlútút:uútútúl:m:u:m:uút:uúl:mút:u:u:uúlúl:múl:uútúl:mútútútúlútúlúl:uútút:m:m:uút:múlút:uúlúl:m:m:múl:uúl:u:u:uút:mút:uútútút:u:m:m:u:uúlútútút:uútútúlútútúlúlútúlút:mút:u:u:mút:uút:u:u:uútútúl:uút:m:u:u:u:uúl:u{>×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÖ:}úl:u:uútúlútúlút:múlútúlúlúlúl:u:u:uút:mútúlúl:u:múlúl:u:u:uúl:múlúlút:múlútúlút:uútútúlúl:mútúlútútút:uúlúlúlúlútútútúlúl:uútúlúlútút:uútútútút:uútúlúlútúlúlúlútút:uúlútútúlúlúlúlútúl:múlúlúl:uútútútútúlúlúlúl:múlúlútútútúlútútútútúlúlúl:múlúlúlútúlútútúlúl:mútúlútútúlút:uúlúlúl:uúlút:uúlútútútúlúlútútútútútútút:múlútút:uúl:uútúlúlúlútúl:u:múlúlútúl:m:m:uúlúlúl:uútúlúlútútútúlúlúlútúl:u:uúlútúl:mútútúl:mútúlútútútútútútúlúlútúlúlútútút:}:u:}:u:uútútút:u:}}¶¿÷ÿÿÿÿÿÿÿÿÿÿ¿÷½¾:}:}»:}:}:uútútúl:uútúlúlúlút:uúlútútútútútút:mútútútútútútútútúlúlútúlútútútúlúlúlútútútúlútútúlúlútútútútúl:múlútútúlútútútúlúlútútútútútútútúlútútútúlútútútútúlútúlúlúlúlútútúlútútútútúlúlútútútúlútútútútúlúlútútúlútúlútútúlúlúlútútútútútúlútúlúlútútútúlútútútútútútútúlúlútútúlúlútútútúlúlútúlútútúlútúlútútúlúlútútútúlútúlúlútútúlútúlútútúlúlúlútúlútúlútútúlútúlútúlútútútútútútútútútúlútúlútúlútútútútútúlúlútúlútúlúlúlútútútútúlúl:u{|®ýÆýÆ<®{
:}útúlút:uû~çÿÿÿÿÿÿÿÿÿÿ¾ï|®ûýÆ>×ýÎ<¦:}úlútútúlútútútútúlútúlúlútútúlúlútútútúlútútútútútútútútúlútútúlútútúlútúlúlúlútútúlútútútútútútútútútúlúlútúlúlútúlútúlútúlútútútútútútútúlúlúlútútútúlúlútútútúlúlúlúlútútútútútúlútúlúlútútúlútútúlútútútútútútúlúlútúlútútúlúlútútúlúlútútúlútúlúlúlútúlútútútúlúlúlútúlúlútútútútútúlútútúlúlúlúlúlúlútúlútúlútútúlútúlúlútúlúlúlúlútútúlútútúlútúlútútútútúlútútútúlúlútúlúlútúlútúlúlútúlútútútútúlúlútúlútúlúlútútútútúlútúlútúlút:u<®¾ïÿÿ¿÷¿ï>×}¾»:u:u{
{
>׿÷ÿÿÿÿÿÿÿÿ¾ïýƾï¿ïÿ÷ÿ÷~ß}¶{
:uútútútútútúlúlútúlúlúlútútútúlúlútúlútúlútúlútúlútúlúlútúlútútúlúlútúlútúlútúlúlútútúlútútútúlútútútúlúlútúlúlútúlútúlútútúlúlúlúlútútútúlútútútúlútútútúlúlútúlútútúlúlútúlútútúlúlútútútútútúlútútúlútútútútútútúlútúlúlúlútúlútútúlúlútútúlúlútútútútúlúlúlútúlúlúlúlútútútútútútúlútútútúlútúlúlúlútútúlútútútútútútútúlúlúlútútútútútúlúlútúlútútútútúlútútútúlútúlútútúlúlútútútúlútútúlútútúlútútútútútútútúlútútúlútútútúlútút:}½¾¿÷ÿÿÿÿÿÿÿ÷¿÷>×<¦{
<¦ýÆ|¶¿÷ÿÿÿÿÿÿÿÿÿÿÿ÷ÿ÷ÿÿÿÿÿÿÿ÷¾ï½¾»:uútúlútúlúlúlútúlúlúlútútúlúlútúlútúlúlútútútútútútútúlúlúlúlúlútútúlúlútútúlútúlútútúlúlútúlúlútútútútútútúlútútútúlúlútúlúlúlúlútútúlútútútúlúlúlútúlúlútútútúlúlúlúlútútútúlúlútúlúlútúlúlútútútúlútúlúlútúlúlútúlúlútútútútútúlúlútúlútúlútúlúlúlútútútútúlútúlúlúlútúlúlútúlútútútútútúlúlúlútúlúlúlútútútútúlútúlútútúlútúlútúlúlútútútútútúlúlútúlúlútútútútúlútútútútútútútútútúlútúlútútútúlútúlútúlúlúlútúlútúlútútúlútútút:u<®¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ~ç½¾|¶ýÎ>ß¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¿÷>×û:uútútútútútúlútútútútúlútúlútútúlútúlútúlútútúlúlúlútúlútútúlúlútútútútútútúlútútúlúlúlútúlútúlútúlúlútútútúlútútútútútútútútúlúlúlútúlútútúlútútúlúlútútúlútútútútúlútúlúlútútúlúlútútúlúlútútútútútútútútútúlúlútúlútúlúlútúlúlútúlúlútúlúlútútútútútúlútúlútúlútútútútútútútútútúlútúlútúlútúlútúlútútúlútúlúlúlútútútútúlútúlúlútúlúlúlútútúlútútútúlútútútúlúlúlúlútútúlútúlúlútútútútútútúlútútútútútútútúlútútúlútútútútútúl:u»~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷>ß>ß¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ï»:uútúlúlúlútúlúlúlúlútútútútútútútútútútúlúlúlútúlútúlúlútútútútúlúlúlútútútútúlútúlúlúlúlútútúlúlútúlútúlúlúlútútútútúlúlútútútútútúlútútúlútúlúlúlútútútútútútútútútúlútútútútúlútútúlútútútútúlútútúlútútútútúlúlúlútútútútútútútúlútútútútútúlúlúlúlútútútútúlútúlútúlútútútútútútútúlútútútúlútútútúlútútútútútútúlúlúlúlútútúlútúlútútúlútúlúlúlútútútútútútúlúlútútútútúlútútútútúlúlútútúlútútútútútútútútúlútútúlútúlúlút:uz
½¾¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=×:uúlúlútúlúlútútútútúlútútútúlútútúlútútútútútúlúlúlútúlúlúlúlúlúlúlúlútúlúlúlútútútúlútútútútútútúlútútúlútútúlútúlútútúlúlúlútúlútútútúlútútútútútútútúlútútútútútúlútútútútútútútútútútútútútúlútúlúlútúlúlútúlútútúlútúlútútúlútútútútútúlútútútúlútútútútúlútútútútútútúlútútútúlútútúlúlúlúlútútútútútútútútútúlútútútútúlútúlúlúlúlúlútútútútútútútúlútútútútútútútúlútúlútúlútútútúlútútútútútútútúlúlútútútúlúlútútúlúlúlút:u<¦~çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷¿÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿÷ýÎz
útútútúlúlúlútútútútúlútútútúlútútútúlúlútútútútútúlúlútúlútútútútútútútútútútúlútútútútútútútútútúlúlútútútúlúlútúlúlùlútútútútùtútútùlúlútútúlútúlútúlútútútútútútúlútútúlútútúlúlúlútútùtúlútútútútútúlùtúlútútúlútùtúlúlúlútútúlúlùtúlúlútútútútútútúlúlúlútùtútúlútútútútúlútúlútúlúlùlúlútúlútúlútùlútútúlùlútútútúlútùlútúlútúlúlútúlútútúlútútútútútùtúlútútúlútúlúlùtúlúlútúlútúlùtúlútútútútúlútúlútútúlútútútùtúlútùtútúl:}ýο÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~çýÎ|¾>ß¾ïÿ÷ÿ÷ÿÿÿÿÿÿ¿÷¿÷¾ï~ç½Æûútúlúlúlútútúlútúlútùlúlútúlútúlúlútúlútútútútúlútútútútúlùlúlúlúlútútútútùtúlútútútútúlútútùtùlútútùtùtútùtùlútùtútùlùlútúlúlùlùtùtùlútùlùlùlúlùlùtútùlùtútùtùtúlùlùtùtùlúlúlútùtùlùtùlútùtùtùtútútútúlútùtútùtùlùlùtùlùtútùlùtùlùlútùtùtútùtútùtùlútúlùtútùlútùtúlùtútútùtùlùtùlùtùlùtúlúlúlùtútùtútútùtùlùtùtùlùtùtùtúlùlùtùtùtùtùlútùtútúlúlútùlùtútùlúlùtútúlútùtùlùtùtútúlúlùtútùlúlùlútùtùtùtùlùlùlútúlùtùtútútùlùlúlúlùtùtùlùtút»¿ï¿÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>×ûz
»û|¾ýÖ>ß~ç~çýμ¾<¦zútútùlùtútútùlùtùlùtùtúlútútùtútùtútùlùtùlútùtúlùtùlùtútùlútútútùtùlúlùtúlútùlùtùtútùtùtútùtútùlùtùtùtùlùtùlùlùtùtùlùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùtùlùtùtùlùlùlùtùlùtùtùlùlùtùlùlùlùtùlùtùlùtùtùlùtùtùtùtùtùtùtùtùtùtùlùlùlùtùtùlùlùlùlùtùlùlùlùtùlùtùtùlùlùlùtùtùtùtùtùlùlùtùtùtùtùlùtùtùtùtùlùtùtùtùlùlùlùtùtùlùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùlùtùtùtùlùlùtùtùtùtùtùlùtùlùlùtùlùtùtùtùtùlùlùtùtùtùlùlùlùlùtùtùtùtùtùtùlùtùt:}|¶~ç¿÷¿÷¾ï¿÷ÿÿÿÿÿÿÿÿÿ÷ýÖ»:u:u:}z
z
z{z
z
:}útùlùtùlùtùlùtùtùtùtùtùlùlùlùlùtùtùlùtùlùlùtùtùlùlùlùlùtùtùlùtùtùtùtùlùlùlùtùtùtùtùlùtùlùtùlùlùtùtùtùtùtùtùlùtùtùtùtùtùlùlùtùlùlùtùtùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùtùtùlùlùlùtùtùlùtùlùlùlùtùtùtùtùtùtùlùlùlùtùtùtùtùlùtùtùtùlùtùtùtùtùlùtùlùtùtùtùtùtùtùtùlùlùlùtùtùtùtùtùtùtùlùtùlùlùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùlùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùtùlùtùtùtùlùtùlùlùtùlùtùtùtùlùtùtùtùlùtùtùtùtz
ûû¥û|¶ýÖÿÿÿÿÿÿÿÿÿÿ~ç»:uùlùtútútùtùtùtùtùtùtùtùtùlùtùlùtùtùtùtùtùtùlùtùlùtùlùlùtùlùlùtùtùlùlùtùlùlùlùtùtùtùlùlùlùtùtùtùtùlùtùtùlùtùlùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùlùtùtùtùtùtùlùlùlùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùlùtùlùtùlùlùtùlùlùlùtùlùtùlùtùtùtùtùtùtùtùlùtùlùlùlùlùlùtùtùtùlùlùtùtùlùlùtùtùlùlùlùlùtùtùlùtùlùtùtùtùtùlùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùlùlùlùtùtùlùlùtùtùtùlùlùlùtùlùlùtùtùlùtùtùlùtùtùlùlùlùtùtùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùtùlùtùlùlùtùtùtùtùlùtùlùlùtùlùtùtùl9uùtz
¼¾¿ïÿÿÿÿÿÿÿÿÿÿ~ç»:}ùtùtùlùlùtùtùtùtùtùlùlùlùlùtùtùlùtùtùtùlùlùtùtùlùlùlùlùlùtùlùtùlùtùlùtùlùlùtùtùlùtùlùlùtùlùtùlùtùtùlùtùtùlùlùlùtùtùtùtùtùlùtùtùlùtùlùlùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùlùtùtùtùtùtùtùlùtùtùlùlùtùtùtùtùtùlùlùtùlùtùtùtùtùtùlùtùlùtùtùlùlùlùlùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùlùlùlùtùlùlùlùtùtùlùlùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùlùtùtùtùlùtùlùtùtùtùtùlùtùtùtùtùtùlùlùtùtùtùlùlùlùtùtùlùlùtùlùlùlùlùlùtùtùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùlùtùtùtùtùt:}|¶~çÿ÷ÿÿÿÿÿÿÿÿÿÿ~çû:}ùtùlùlùlùtùtùtùtùtùtùlùlùlùtùtùtùtùtùlùlùlùlùtùtùtùtùtùtùtùlùlùlùtùtùtùlùtùtùtùlùtùlùtùtùlùtùtùtùlùtùlùtùtùlùlùtùtùlùtùlùlùtùtùlùtùlùtùtùtùlùtùtùlùlùtùtùlùlùlùtùtùtùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùlùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùlùlùtùtùlùtùtùlùtùtùtùlùtùlùtùlùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùlùtùlùlùtùlùlùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùtùlùtùlùtùtùtùtùtùlùtùtùlùtùtùtùlùtùtùtùtùtùlùlùlùtùlùlùtùtùlùtùtùt:}ýÖ¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ~ç»ùtùtùlùlùlùtùtùtùlùlùtùlùtùtùtùtùtùlùtùtùtùtùlùtùtùtùlùtùtùtùtùlùtùtùtùlùlùlùtùtùtùtùlùlùtùtùlùlùtùtùtùlùlùlùtùtùtùtùtùtùtùtùlùtùlùtùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùtùtùtùtùlùlùlùtùlùtùtùtùtùlùtùlùtùtùlùtùtùlùlùlùtùtùlùtùtùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùlùlùtùlùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùlùtùtùlùtùlùlùtùlùlùlùtùtùtùtùlùlùtùlùtùlùlùlùtùtùtùtùtùlùtùlùtùtùlùlùtùtz
ýÖ¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ~ç»ùtùtùtùlùtùtùtùtùtùtùtùlùlùlùtùlùtùlùtùlùtùtùtùlùtùtùlùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùtùlùtùtùlùtùlùlùtùtùtùlùtùtùlùlùtùtùtùlùtùlùlùtùtùtùlùtùtùtùtùtùtùtùlùlùlùlùtùtùlùtùtùtùtùlùtùlùtùtùtùlùtùtùlùtùtùtùtùtùtùtùtùtùtùtùlùlùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùtùtùtùlùlùlùtùlùlùlùlùtùlùlùlùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùlùlùtùtùtùlùlùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùlùtùtùlùlùtùtùtùtùtùlùtùtùlùtùlùtùlùtùlùtùtùtùl9}|¶¿÷ÿÿÿÿÿÿÿÿÿÿÿÿ=×z
ùtùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùlùlùtùtùtùlùtùtùlùtùlùlùlùtùtùtùtùlùlùtùlùtùtùtùtùlùtùlùlùtùtùlùlùtùtùlùtùtùlùtùtùlùtùtùtùtùlùtùtùtùlùtùlùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùlùlùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùlùlùlùtùtùtùtùlùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùlùlùlùtùtùlùlùtùlùtùtùlùtùtùlùlùtùtùlùlùtùtùtùlùtùtùtùtùlùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùlùtùtùtùtùlùlùlùtùtùtùlùlùtùlùtùlùlùtùtùtùtùlùtùlùtùtùtùlùlùtùtùlùlùtùlùlùtùtùtùlùtùtùlùlùtùtº>ßÿ÷ÿÿÿÿÿÿÿÿ¿÷|¶9uùtùtùlùtùlùtùlùtùlùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùlùtùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùlùtùlùtùtùtùtùlùtùtùlùtùtùtùlùtùtùtùtùlùtùtùtùtùlùtùlùlùtùlùtùtùtùtùtùtùlùtùlùtùtùtùlùtùlùtùtùtùlùtùtùlùtùlùtùtùtùlùtùtùlùlùlùtùlùlùlùtùtùlùtùtùlùlùtùtùtùtùtùtùtùlùtùlùlùtùtùtùtùtùlùtùlùtùtùtùtùtùlùtùtùtùlùtùlùtùtùt|¶¿÷ÿÿÿÿÿÿÿÿ~ç»ùtùtùlùtùtùtùtùtùtùlùtùtùlùtùtùlùtùlùtùtùlùtùtùlùlùtùtùtùlùtùlùtùtùlùlùlùtùtùlùtùlùlùtùlùlùlùtùtùtùtùlùlùtùtùlùtùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùlùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùlùlùlùlùtùlùtùtùlùtùtùtùlùtùtùtùlùlùtùtùtùtùtùlùlùtùtùlùlùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùlùlùlùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtz
~çÿÿÿÿÿÿÿÿ¼Æ:}ùtùtùtùtùtùtùlùlùtùlùtùtùlùtùtùtùtùtùtùtùtùlùtùtùlùtùtùtùlùlùtùtùtùtùtùtùtùlùtùtùtùtùlùtùlùtùtùlùlùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùlùtùtùlùtùtùtùtùlùtùlùtùtùtùtùtùtùtùlùlùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùtùlùtùlùtùtùtùlùtùtùlùlùtùlùtùtùtùlùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùtùtùlùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùlùlùlùtùtùtùtùtùtùtùlùtùtùtùtùt:
¼Æ¿÷ÿÿÿÿ~ï»ùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùlùlùtùtùtùtùtùtùlùtùtùtùtùtùtùlùtùlùtùtùtùtùlùtùtùlùtùlùtùtùtùlùtùlùlùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùlùtùlùlùtùtùtùlùtùtùtùlùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùtùlùlùtùtùlùtùtùtùlùlùtùtùtùtùlùtùtùtùtùtùlùlùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùlùtùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùlùtùlû¥>ß¿÷~ï|¶:
ùlùtùtùtùlùtùlùlùtùtùlùtùtùlùlùtùtùlùtùtùtùlùtùlùtùtùtùlùlùlùtùtùlùtùlùtùlùtùlùtùtùlùtùtùlùlùtùlùtùtùtùtùtùlùlùtùtùlùtùtùtùlùtùlùtùtùtùtùlùlùlùtùtùtùtùlùtùlùtùlùtùtùtùtùtùlùlùtùlùtùtùtùtùtùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùlùlùlùtùtùlùlùtùtùlùtùlùtùlùtùlùtùlùtùlùtùlùtùtùlùtùtùtùlùtùtùtùlùtùtùtùlùlùlùtùtùtùlùtùtùtùlùtùtùtùtùlùlùlùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùtùtùtùtùlùtùlùtùtùlùlùlùlùlùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùlùtùtùtùlùlùlùtùtùtùtùtùtùtùtùlùtùtùtùt;¦¼Æ¼¾ùtùtùtùtùlùtùlùtùtùlùtùtùlùlùlùtùlùlùtùlùtùtùtùtùtùtùtùlùtùtùtùlùtùlùtùlùlùtùlùlùtùtùtùtùtùtùlùlùtùlùlùtùlùtùtùlùtùtùtùlùtùtùtùlùtùtùtùtùtùlùtùtùlùlùtùtùtùtùlùtùlùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùtùtùtùtùlùtùtùlùlùtùlùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùtùlùtùlùlùtùlùtùlùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùlùlùtùtùlùtùtùlùtùlùlùlùtùlùtùtùlùtùtùlùtùtùlùtùtùtùtùlùtùtùtùtùlùtùtùlùlùlùtùlùtùtùlùtùlùtùtùt9}9}ùlùtùlùtùlùlùtùlùtùtùtùtùlùtùtùlùlùtùlùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùlùtùlùtùlùtùlùtùlùtùtùtùtùlùlùlùtùtùtùtùlùlùtùtùlùlùtùtùtùlùlùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùtùtùlùtùlùlùtùlùtùtùlùtùlùtùtùtùlùtùtùtùtùtùlùlùlùtùlùlùtùtùlùtùtùtùlùtùlùtùtùtùtùtùtùtùlùtùtùtùtùlùtùtùtùtùtùtùlùtùlùtùlùtùtùtùtùtùlùtùtùtùtùlùlùtùlùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùlùlùlùtùtùtùlùlùtùtùtùtùlùtùlùtùtùlùtùlùtùtùlùtùtùlùlùtùtùtùtùtùlùtùlùtùtùtùtùtùtùlùtùtùtùtùtùtùtùlùlùtùtùtùtùtùtùlùlùtùlùtùlùtùtùtùlùtùtùtùlùtùtùlùtùtùtùtùlùlùtùtùtùtùlùlùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùtùtùtùtùlùlùlùlùtùtùlùtùlùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùtùlùtùlùtùtùtùtùlùlùtùtùlùtùlùtùtùtùtùtùtùlùlùtùtùtùtùtùlùtùtùtùtùtùtùtùtùlùlùtùtùtùlùlùtùlùtùtùtùtùlùtùtùtùtùtùtùlùtùtùtùtùlùlùtùtùtùtùtùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùlùlùlùlùlùtùtùtùtùtùtùlùlùtùtùtùtùtùtùtùtùtùlùlùlùlùtùtùtùlùtùtùtùtùtùlùtùtùtùtùlùtùtùlùtùtùtùtùlùtùtùlùtùlùtùtùtùtùlùlùtùtùtùtùlùtùtùlùtùtùtùtùtùtùtùlùtùlùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtùtùtùtùtùtùtùtùtùlùtùlùlùtùtùtùlùtùtùlùtùlùlùlùtùtùtùtùtùtùtøtùlùtùtùtùlùtùtùtùtùtùlùtùtùlùtùlùtùtùtùtùtùtøtùtùtøtøtùtùtùtùtùtùtùløtùlùlùtùtùtøtøtøtùtùtùtùlùlùtùtùtùtùtùlùtøtùtùtùtùtùtùtùtùtùlùtølùtùtùtùlùtùtùtùtùtøtøtùtùtùtùtùtùtùtùtùtùtølùtùtùtùtùtùtùtùtùtùtùlùtùtùtùtøtøtøtùtùtùlùtøtùtùtùtùtùtùtùtùtùtùtùtùlùtùtùlùtøtùtøtùlùtùtùløtùtùtùlùtùlùtølùtùtùtùtùlùtùtùtøtùtùtùtùtùtùlùtùtùtùlùtøtùtùtùtùtùtùtùtùtùtùtùtùtùtùtùløtùtùlùlùtùlùløtùlùlùtùtøtùtùtùtùlùtùtùtùlùtøtùlùtùtùtùlùtùlùtøtùlùløtùtùlùløtùtùlùtùtølùtøtøtùtùtølùlùtøløtùtøtøtøløtùtùtùtøløtøtøtùtùtùtùlùtøtùtùtùtøtøtøtùtùtøtøtøtøtøtølùtùtøtùtùlùtùtøtøtøløtùtøtøtùtùlùtøtøtùtøtøtùtøtøtùløløtøtùlùtùlùtøtøtøtøtøtùtùtøtølùtùtùlùtùtùlùtølølùtùløtøtøtùtùtøtølùtøtùtùtøtøløløtùtøtøtøtùtùløtùløtøtùtùtøtùtølùtùløløtølùtølùtøtùtùtøtùlølùtøtùtùtùtùlùtùtùtùtùløtùtølùtøtølùlùtùløløløtùløtùtøløtøtùtùtùtøtøløtùtøtøtøtølùtøløtùtøløtøtùtøtølùtùtøtùtøtøløtølùtùløtùtøtùløtøtùtùtùtùtølùtøtøtølùtøtøtølùlùløtùtùtùløløtøtøtùlølùtùtøtùtùtølùløtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtùtøløtøtøtøtøtøtøtøløtøløtøtøtøtøtøløløtøtøløtøtøløtøtøløløtøtøtøtøtøtøtøløtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøløløløløtøtøtøtøtøtøtøtøtøløtøtøtøløtøtøtøtøtøløløtøtøtøløløløtøtøløtøtøtøløtøtøtøløtùtøtøløløløtøtøtøløløtøtøtøtøløtølùtøløtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøløtùtøtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøløløtøtølùløtøtøløtøtøtøtøtøtøtøtøtøløløtùtùtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtùløtøtøtøtøtøtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøløløtøtøtøtøtøtøtøtøtøtøløtøløløløtøtøløtøløtøtøløtøløløtøtøtøtøtøtøløløtøtøtøtøtøløtøløløtøtøtøtøløtøtøtøtøtøtøløtøtøtøtøtøtøtøløløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøløløløtøtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøløløtøtøtøtøtøtøløtøløløtøtøløtøtøtøløtøløtøløløtøtøtøløtøløtøtøtøløtøløløtøløtøtøløtøløtøtøtøløløløløløløløtøtøtøtøtøtøtøtøtøløløtøløløløtøtøtøtøtøtøtøløtøtøtøtøløtøtøløtøtøtøtøløtøløtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøløtøløløtøtøtøtøtøtøløtøtøtøtøtøtøtøtøløtøløtøtøtøtøløtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøløtøtøløtøløløtøtøtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløløtøtøløtøtøtøtøtøløtøtøtøløtøtøtøløløtøtøløtøtøtøtøtøtøtøtøtøtøtøløløtøtøløtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøløtøtøtøtøløløløløtøløløtøløtøløtøløløtøløtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøløløløtøtøtøløtøtøtøtøtøløløtøtøtøtøtøløløløtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøløtøtøtøløtøtøtøtøløtøtøtøtøtøtøløløtøløløtøløtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøløløtøtøtøtøtøløtøtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøtøløtøløløtøløtøløtøtøtøtøløtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøløtøtøtøløtøtøtøtøtøtøtøtøtøløtøløløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøløløtøtøtøtøtøtøløtøtøtøløløtøtøtøtøtøtøtøtøtøløløtøtøtøløtøtøtøtøtøløtøløtøløløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøløtøtøtøtøtøløtøtøløtøtøtøløtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøløtøløtøtøtøtøtøtøløløtøtøtøtøløtøtøløløtøtøtøløløtøtøtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøløtøtøtøtøløtøtøtøtøløtøtøtøtøløtøløtøtøtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøløtøtøtøløløtøtøtøtøtøløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøløløtøtøtøtøløtøtøtøtøtøtøtøløtøløtøtøtøtøløtøtøløløløtøtøtøtøløtøtøtøtøtøtøløløtøtøtøtøtøtøtøløtøtøtøtøløtøtøløløtøløtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøløtøtøløtøtøtøtøløtøtøtøtøløtøtøtøtøløtøløtøtøløtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøtøløløtøtøtøtøtøløløtøtøtøløtøløtøløtøtøtøtøtøløløtøtøtøløtøtøtøtøløtøtøtøtøtøløtøtøløtøtøtøtøtøløtøtøtøtøtøtøløløtøtøløtøtøtøtøtøtøløtøløtøløtøtøløtøløløløløtøtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøtøtøløtøløtøtøtøtøtøtøtøtøløløtøtøløtøtøtøtøtøtøtøløtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøløløtøtøtøtøtøtøtøløløtøtøtøtøtøløløtøtøtøløtøtøtøtøløtøtøtøtøtøløtøtøløtøtøløtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøløtøtøtøtøløtøtøløtøtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøløløtøtøt¸tøløtøtøtøløtøtøløtøl¸tøtøtøtøløt¸tøtøtøtøløtøløtøløt¸tøtøt¸tøløtøtøtøt¸løtøtøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøtøt¸tøtøtøløløtøtøtøtøtøtøtøtøtøtøløtøtøtøtøt¸tøløtøtøtøtøløtøt¸tøtøtøløtøtøtøtøtøtøtøtøløtøtøtøtøtøtøløtøtøløtøtøtøtøtøtøtøtøtøløløtøtøtøtøløløtøl¸tøtøtøtøløtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøtøløløtøtøtøløtøtøtøtøtøtøløtøtøtøløtøtøløtøtøtøtøløtøløtøtøtøtøtøtøtøtøtøløtøtøløtøtøløløt¸løt¸tøl¸tøtøtøløtøtøtøtøløtøtøtøtøtøløtøtøtøtøt¸tøtøtøtøtøtøtøtøtøtøtøtøløt¸løtøt¸t¸tøtøtøtøt¸tøt¸tøtøløtøtøløt¸tøløtøl¸løtøtøtøløtøløtøløtøtøt¸tøtøt¸t¸tøt¸tøt¸løtøtøtøtøtøtøtøt¸t¸tøtøløtøløløløtøt¸tøløtøt¸tøløt¸tøløtøtøtøt¸tøløløtøløløtøløl¸tøl¸løt¸t¸tøt¸tøt¸t¸tøtøtøtøtøløtøtøtøtøløtøtøtøtøt¸tøløtøtøt¸tøtøtøtøtøtøt¸t¸tøtøl¸tøløt¸tøt¸t¸t¸tøt¸tøtøt¸løtøt¸tøtøl¸tøtøtøløt¸tøtøtøtøt¸tøtøt¸t¸t¸tøt¸tøtøt¸løt¸tøtøtøtøtøtøløt¸tøt¸t¸tøt¸tøløtøtøt¸tøtøl¸t¸tøl¸tøtøtøtøtøløtøtøtøtøtøt¸tøtøtøtøtøtøløtøtøt¸tøl¸løt¸tøt¸tøt¸tøtøtøtøt¸tøtøtøtøløt¸tøl¸l¸tøt¸t¸løtøtøl¸t¸tøløt¸tøt¸tøtøt¸løt¸l¸tøtøl¸tøt¸tøtøt¸tøløt¸t¸t¸t¸tøt¸tøt¸l¸tøl¸tøtøtøt¸løløt¸l¸t¸t¸l¸t¸løl¸t¸t¸t¸t¸t¸tøløt¸tøt¸tøt¸tøtøtøt¸tøt¸tøtøt¸løt¸l¸t¸tøt¸tøtøt¸t¸t¸tøt¸tøtøtøtøløt¸l¸t¸tøløl¸l¸tøt¸t¸t¸tøt¸tøtøtøtøtøtøtøt¸tøtøtøtøt¸tøt¸l¸løløl¸tøløtøt¸t¸t¸tøtøtøt¸tøt¸tøtøt¸t¸l¸t¸t¸t¸l¸t¸t¸t¸tøt¸t¸l¸tøl¸t¸løt¸tøt¸t¸tøt¸tøtøt¸t¸t¸løtøt¸tøt¸tøt¸tøt¸l¸tøt¸l¸t¸tøt¸løtøtøtøtøt¸t¸tøtøtøtøløt¸l¸t¸t¸t¸tøt¸t¸tøt¸l¸t¸tøtøt¸tøl¸l¸løtøt¸tøt¸t¸tøtøt¸tøt¸t¸tøtøt¸tøtøt¸t¸løtøt¸l¸t¸t¸tøt¸tøt¸t¸tøtøt¸t¸t¸t¸t¸t¸t¸t¸t¸t¸tøt¸t¸tøtøt¸t¸t¸t¸t¸t¸t¸tøt¸tøt¸t¸t¸tøl¸tøt¸t¸l¸tøt¸t¸tøt¸tøtøt¸tøl¸t¸t¸l¸tøt¸tøtøt¸t¸t¸tøt¸tøtøt¸tøt¸t¸t¸løt¸tøt¸t¸l¸t¸tøl¸t¸t¸t¸tøl¸t¸tøløtøl¸t¸tøløt¸l¸t¸t¸t¸t¸t¸løt¸t¸tøtøt¸t¸t¸tøtøtøt¸t¸tøtøt¸l¸t¸t¸t¸l¸l¸tøløløtøl¸t¸t¸tøt¸t¸løt¸t¸t¸tøløt¸t¸t¸t¸tøt¸tøt¸l¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸tøtøl¸l¸t¸t¸løt¸tøtøtøtøt¸t¸tøtøt¸t¸t¸tøl¸t¸t¸tøt¸t¸t¸tøt¸t¸t¸t¸l¸tøtøt¸tøt¸t¸tøt¸t¸tøtøt¸tøtøl¸t¸tøtøl¸tøt¸tøtøt¸t¸t¸l¸løt¸t¸t¸tøtøtøtøt¸tøtøtøtøt¸t¸t¸t¸l¸t¸tøt¸t¸t¸t¸tøtøl¸t¸t¸t¸t¸t¸tøt¸tøt¸t¸løtøt¸tøtøtøt¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸tøt¸tøt¸t¸t¸t¸l¸tøt¸t¸t¸l¸t¸t¸tøt¸løt¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸tøt¸t¸tøt¸t¸t¸tøl¸løt¸t¸t¸t¸t¸t¸t¸t¸t¸t¸tøt¸t¸t¸tøt¸t¸t¸t¸tøtøl¸l¸l¸tøt¸t¸t¸tøt¸t¸tøt¸t¸t¸t¸tøtøt¸l¸t¸t¸tøl¸l¸t¸l¸t¸t¸l¸tøt¸tøl¸t¸l¸t¸t¸t¸t¸tøt¸tøt¸t¸t¸l¸t¸t¸t¸tøtøtøl¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸tøt¸tøl¸l¸t¸l¸t¸t¸t¸t¸løt¸l¸t¸l¸t¸tøt¸l¸t¸t¸l¸t¸t¸t¸tøtøt¸tøt¸l¸t¸t¸t¸t¸t¸tøl¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸tøt¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸tøt¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸l¸t¸l¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸l¸tøt¸t¸t¸l¸l¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸l¸t¸t¸t¸tøt¸t¸t¸t¸t¸t¸tøt¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸t¸l¸t¸l¸t¸l¸t¸l¸t¸t¸l¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸l¸l¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸l¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸l¸l¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸l¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸l¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸l¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸l¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸l¸t¸t¸t¸t¸l¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸l¸l¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸t¸t¸t¸t¸l¸t¸t¸l¸t¸l¸t¸t¸t¸l¸t¸l¸l¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸l¸t¸t¸t¸t¸l¸t¸t¸t¸t¸t¸l¸t¸t¸t¸t\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/econbutterfly.bmp u-boot-2008.10/tools/logos/econbutterfly.bmp
+--- u-boot-2008.10_original/tools/logos/econbutterfly.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/econbutterfly.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1 @@
++BM8X\x02\0\0\0\0\06\0\0\0(\0\0\0ð\0\0\0@\x01\0\0\x01\0\x10\0\0\0\0\0\x02X\x02\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W6W:W6W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W6W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W6W:W:W6W:W:W6W:W6W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W6W:W6W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W6W6W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W6W:W6W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W6W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W6W6W:W:W6W:W:W:W:W:W:W6W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W6W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W6W:W:W:W:¹F\c}k|gúRW:W:W6W:W:W:W:W6W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6W:W:W:W:W6W6W:W:W:W:W6W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W6W:W:W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W6W6W:W:W:W6W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W6W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W6W:W:W:W:W6W:W:W:W:W:W:W:W:W6W6W:W:W:W:W:^[W¾wÿ{ß{oúRx:W6W:W:W:W:W:W6W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W6X:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:X:W:W:W:W:W:X:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:W:X:W:W:X:W:W:W:W:X:W:W:X:W6W:W:W:X:W:W:W:W:W:W6W:W6W:x>^[WÞ{ÿ\x7fÿ\x7fÿ\x7f¾s<_ÙJx>X:W:W6W:W:X:W:W:X:W:W:W:W:X:W:X:W6W:X6W:W:X:W6W:W:W:W:W6W:W:W:W:W6W:W6W:W6W6W:W:W:W:W:W:W:W:W:W:W:X:W:W:W:W:W:W:W:W:W:W:W:W:W:X:W6W:X:W:W:W:W6W:W:W:W:X:W:W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W:W:W6W:W:W:W:W:W:W6X:X:W:W:W6W:W:W:W:W:W:W:W:W:W:W:W:X:W:X:W:X:W:X:W:W:W:W:W:W:X:W:W:W:W:W:W:W6W:W:W:W:X:W:W:W:X:X:X:X:W:W:W:X:X:W6X:W:W:X:W:W:W:X:W:W6X:W:W6W:X:W:X:X:W:X:W:X:W:W:X:X:W:X:W:W:X:W:W:X:X6W:X:W:X:X:W:X:W:W:X:X:W:W:X6X:X:W:W6W:W:X:X6W:W6W6W:W:W6W:W6W:X:W:W:W:X:W:x:^[WÞ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾s^[Wx>x:W:X:X:W:W:W:W:W:X:W:W:X:X6X:W:W:X:W:X:W6W:W6W:X:X6W:X:W:W:X6X6X:W:W6W:W:X6W:W:W:W:W:W:W:X:X:W:W:W:W6W:X:W:X:X:W:X:W:W:W:X:W:W:W:W:W:X6W:X:X:W6W:W:W:W:X:X:W:W:W:W:X:W:W:X:X:X:X:X:W:X6X:X:X6X:W:X:W6X:X:X:W:X:W:W:W:W6X:W:W:W6W:X:W:W:X:W:X:X:W:X:X:X:W:W:X:X:X:W:X:W:X:W6W:X:W:W:X6X:W:X6X:X:X:W:X:X:X:X6X:X6W:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:W:X:X:X6X:X:X:X6W:X:X:X:X:X:X:W:X:X6X:X6X:X:X:X:X:X:X:X:X:X6X:X:X6X:X:W:X:W:X:W:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X6X:X6X:W:x:ûRÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{¾s^[Wx:X:X:X:X:X:X:X:X:X:X:X6W6X:W:X:X:W:X:W:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:W:X:X:X:X:W:X:X:X:X:X:X:W:W:X:X:W:X:X:W6X6W:W:X:X6W:X:X:W6X:X:W:X:X:W:X:X:X:X:W:X:X:X:X:X:X:X:W:W:W:X:W:X:X:W:X:W:X:X:X:X:X:X6X:X:X:W:W:X6W:X6X:X:X:W:X:X6W:W:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:W:X:X:X:W:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X6X:X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X6X6X:x:ÚN¾wÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{|gBX6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X6X:X:X:X:X6X6X:X6X6X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X6X6X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X6X6X6X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X6X6X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X6X:X:X:X:X6X:X:x:ÚJ¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{o>x:B¹F>X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X6X:X:X:X6X:X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X6X6X:X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X6X:X:X:X:X:X6X:X:X:X6X6X:x:Boÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{\c¹FûV}k¾s\cÚJ>x:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X6X6X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:>\cß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{<_\cÞwÿ{ÿ{ß{¾s\cÚJx>x:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X6X:X:X:X:X:X6X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X6X:X6X:X6X:X:X:X6X:X:X6X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:x:ÚJ¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{Þwß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{Þw}gÚJx:x:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X6X:X6X:X:X6X:X:X6X6X:X:X:X6X6X:X6X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X6X6X:X:X:X6X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X6X:X:X:X6X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X6X6X:X6X:X6X:X:X:X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:x:><_Þ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾s^[W>X6X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X6X:X6X:X:X6X:X:X6X:X:X:x6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:x:X:x:X:X:X:x:x6X:X:x:X:X:x:X:X:X:X6X:X:X:X:X6X6X:X:X:X:X6X6X:x6x:X:x:X:X:X:X:X:x6X:X:X:X:X:X:X:X:X:X:x:x:X:x:X:X:x:X6X:X:X:x:X6X:x:X:X6X:X:X:X:X:X:X:X6X:X:X6X:X:X:X:>¹F}kÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞwûRx:x:X:x:X:x:x:X:X:X:X:X:X:X:X:X:x:X:X:x:X6x:X:X:x:X:X:X:X:X:X:X6X:X:X6x:X:x:x:X:X:X6X:x:X:X:X:X6X:X:X:x:X:X:x:X:X:X:x:X6x6X:X:X:X:X:X:X:X:X:x:X:x6x6X6x:X6X:X:x6x:X:X:X:X:X6X:X:X:x:X:X:x:X:X6X6x6x:X:X:X:X:X:X:X:x:X:X:X:X:X:X6x:X:x:X:X:X:X:x:X:X:X:X:x:X:X6X:x:X:x:X:X6x:X:x:X:X:X:X:X6X:X:X:x:X:x:X:x:x:X:X6X:X:x:X:X6X:X:X:X:X:X:X:x:x:X6X:X:X:X:X:x6X:X6x:X:x:X:X:x:x:X6x:X:X:X:X:x:x:X:X:X:X:x:X:X:X:x:X:X6X:x:x:x:X:x:X:X6X:X6x:X:X6X:X:x:X:X:x:x:>ÚNoÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{\g>x:X:X:X6x:x:x:X:x:X:X:X:X:X:X:X6X:X6x:X:X:X:X:X:x:X:x:X:x:x:X:X:X:X:x:X:X:x:X:X:X:x6X:x6X:X:X:x:x:X:X:x6x:x6X:x:X6X:X:X:X:x6X:x:x:x:x:x:X6X:X:X:X:X:X:x:X:x:x:X:x6x6x:X:X6X6x:x:x:x:X:x:X:X6X:X:X:X:X:x6X6x:x:X:x:X:X:x:X:X:x:X:X:x6X6X:x:x6x:X:x6X:X:X6x6x:X:X6x:x:x:X:x:X6x:x:X:x:X:X:x:X:X:x:X:X:X:X:X:x6X6X:x6x6X:x:X:X:x:x:x6x:x:x:x:X:X:x:X:x:X:x:X:X6x:X:X:X:X6x:x:x:x:x:X:x6X:x:x:x:X:X:X:x:X6x6X:x:X:X:x:x:X:x:x:x:x:x:x:x:x:x:x6x6x:X:X:X:x:X:x:B;[Þwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{Þw<_>x:x:X:X:x:x:x:x:x:X6x:X:X:X6x:x:x:x:x6X:X:x:X:X:x:X:X:X:x:x:x:X:x:X:x:X:x:x:x:X6x:x:x:X:x:X:x:X:X:x:X6x:X:x:X:x6x6X6X:x:x:x:x:x:X:X:x:x:x:X:X:x:x:x:X:x:x:x:X6x:x:x:X:X:x:X:X:x:x:X:X:X6X:x:x:x:X:x:X6X6x:X6x:X:X6X:x:X:x:X:X:X6x:x:X:X:X:X6x:X:X6x:x:x6X:x:x:X:X:x:x:X:X:x:x6x:x:x6x:x:x6x:x:X:x:x:X:x:x:x:x:x:X6X:x6x:x:x6x:x:x:x:x6x:X:X6x6x:x6x:x:X:x:x:x:x:X6x6x6X:X:X:x:X:x:x:x:x:x:x6x:x6x6X:x:x:x6x:x6x:x6x:x:X:x6x:X:x:X:x:x:x:x6x:X:X6x:X:x:y>>B^[[oÿ\x7fÿ\x7fÿ\x7fÿ{ß{ß{ß{ÿ\x7fß{ß{ß{Þw¾s<_>x:x6x:x6x:x:x:X:X:x:x6x:x:x6x:x:x:x:x6x:x:x:X6x:x:x6x:X6x6x:X:x:x:x:x:x:x6X6x6x:x:x:X6X:x:x:x6x:X:x:x6x:x:x6X:X:X:x:X:x:x:x:x6X6x:X:x:x:x:x:x:X:x:X:x:x6X:x:X:x:x:x:x:x:x:x:x:x:x:x:x6X:X:x:x:x6x:X:X:x:x:x6x:x:x:x:x:x6X:x6X:x:x:x6x:X:X6x:x:X:x:x:X:x:x:X:x:x:X:x:X:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:X:x:x:x:x:x6x:x:x:x:x6x:x:x6x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x:x6x6x6x:x:x:x:x:x:x6x:x:x:x:x:x:x6x6X:x:x:x:x:x:x:x:x:¹FºFûR^[W}gÞwÿ\x7fÿ\x7fÿ\x7f¾s|g^[W;[<_<_\_^[WûR¹F>x:x:x:x:x:x:x:x6x6x6x:x:x:X:x:x:x6X6x:x:x:x:X6x:x:x:x:X:x:x:x:x:X:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x6x6x:x:x:X6x:x:x:x:x:x:X:x:x6x:x:X:x:x6x:x:x:x:x:x6x:x6x6x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x6x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x6x:x:x6x6x6x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:y>ºF^[W}k¾s¾wÞ{ÿ{ÿ\x7fÿ\x7fÿ\x7fß{¾s\cûRBx:y>y>y>x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x6x6x:x:x:x6x:x:x6x:x:x:x6x6x6x6x:x:x:x:x:x:x6x:x6x:x6x:x:x:x:x:x6x6x6x:x:x:x6x:x6x:x:x:x6x:x6x6x:x:x6x:x:x:x:x6x6x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x6x6x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:>^[WoÞ{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞ{\c;[^[Wx:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x6x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x6x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x6x6x:x:x:x:x6x:x:x:x:x:x:x6x6x6x:x:x:x6x:x6x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:><[¾wÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞ{\cÚJy>x:x:x:x:x6x:x:x:x:x:x6x6x:x:x:x:x:x:x:x6x6x:x:x:x:x6x:x6x6x:x6x:x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x6x6x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x6x:x6x:x6x:x6x6x:x:x6x:x:x6x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x6x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:¹B<_¾wÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞw\cºFx:x:x:x:x6x6x:x:x:x6x6x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x6x6x6x:x:x:x:x:x:x:x6x6x:x:x:x:x:x6x6x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x6x:x6x:x:x:x6x:x6x:x:x:x6x:x:x:x:x:x:x:x:x6x6x6x:x:x:x:x:x6x:x:x:x6x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x6x6x6x6¹B\_ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{oûR>x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x6x:x:x:x:x:x6x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x:x6x6x:x:x:x6x:x:x6x:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x:x:x6x6x6x:x:x:x:x:x6x:x:x6x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x6x:x6x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x6x6x6x:x6x:x:x:x:x6x:x6x:x:x:x:x:x6x6x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x6x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:;[Þwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾wß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾wûR>x:x6x:x6x:x:x:x:x:x:x6x:x:x6x:x6x6x6x:x:x:x:x:x6x:x6x:x:x6x:x:x:x6x:x6x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x6x6x6x:x6x:x6x:x:x:x:x:x:x:x:x6x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x6x:x:x:x:x:x:x6x6x:x:x6x6x6x:x:x:x6x:x:x6x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x6x:x:x6x:x:x:y:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x:x:x6x6x:x:x:x:x:x6x6x6x:x6x:x:x6x:x6x6x6x:x:x:y:x:x:x:x:y6x:x:x:x:x:x:x6x:x:x:y:x:x:x:x:ÚJkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{Þw^[W¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{oÚJy:x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x:x6x:x6x:x6x:x6x:x:x:x6x:x:x:x6x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6y:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x:x6x:x:x6x6x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x6y6x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:y:x6y:x6y:y:x6y:x:x:y:x:y:x6x:x:y:y:x:y:y6y:y:x:y:x:x:x6x:x:x:y:x6y:y:y:x:y:y:y:y:x:y:x6y6y6x:x:x:x6y:y6x:y:y6y:y:x6x6y:y:x6y6x:x:x:x6y:y:y:x:x6x:y:y:y:y:ºFkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}gÚJ}gÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}g>y:y6y6y:y:x:x:x6y:x6x:x:x:x:x6y:y:x:y6y:y6x6y:x:y:x6x:x:x6x6x:x6x6x6y6y:x:x6y:x:x6x6x:x:y:x:y6y:y6x:x:y:x:x:x6x:x:x:x6x:y:x6y:y:y:x:y:x:x:y6x6x:x:x:x:y:x:y:x6x:x:y:y:x:x:y:x:x:x:x:x6y:y:x:x6x:x:x6x:x:y:y:y:x:y6x:y:x6x6x:y:x:x6y:y6x6y:y:x:y6x:y:x:x:x:y:y:x6y:x6x6x:x:x6x:y:x:y:x:y:y:y:y:y6y:y:y:y:y:y6x:y:y:y6y:y:y:y:y:y:y:x:y:y:y6y6x:y6y:y:y:y:y6x:y:y6y:x:y:y6y:y:y:y:y6y:y:y:y:y6y:y6y6y:x:y:y:y:y:y:y:y6y:y6y:y:y:y6y:y6x:y:y:x6y:y:ÚJ\c¾s¾sÞwÞwÞwß{ÞwoûN><[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÚJy:x:y:y:y:y:y6y:x6y6y:y:y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y6y:y6x:y:y:y6y:y:y6y:y:x:y6y:y:y:y:y:y:y:y:y:x6y:y:y6y:y:y6x:y6x:y:y6y:y:y6y6y:y:y:y6y:y6y:y:y6y6y6y:y:y6y:y6y6y:y:y:y6y:y:y:y:y:y6y:y:y6y:y6y:y:x6y:y6y:y:y:y:y:y:y:y6y:x:y:y6y:y6x:y:x6y:y:y:y:y:y6y:x:y:y:y:x:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y6y6y6y:y6y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y6y6y6y:y:y:y:y6y:y6y:y:y:y:y6y:>ÚFºFÛN^[W<[\x1c[ÚJ>y:ÚJkß{ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾wºFy:y:y:y:y:y:y:y6y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y:y:y:y:y:y6y6y:y6y:y:y6y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y6y6y:y:y:y:y:y:y:y6y:y:y:y:y6y:y6y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y6y:y:y:y:y:y6y:y:y6y:y:y:y:y6y:y6y:y:y:y:y:y:y:y6y6y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y:y6y:y6y:y:y:y6y:y:y6y:y:y6y:y:y:y6y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:>>y:y:y:>ûN\c}g}k¾s¾sÞwÞwo\_ºBy:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y6y6y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y6y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y6y6y:y:y6y:y:y:y6y6y:y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y:y:>BºFºFÚJÛNÚJÚJ>y:y6y:y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y6y:y:y:y:y6y:y:y:y6y:y:y:y6y:y6y6y:y:y6y:y:y6y6y:y:y6y:y:y:y6y:y6y:y:y:y6y6y6y:y:y6y:y6y:y6y:y6y:y:y6y:y:y6y6y:y6y:y:y:y:y:y6y6y:y:y6y:y:y:y6y:y:y:y6y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y:y6y6y6y:y:y6y6y:y:y6y:y6y:y6y:y6y:y6y:y6y:y6y:y:y6y:y:y:y6y:y:y:y6y:y:y:y6y6y6y:y:y:y6y:y:y:y6y:y:y:y:y6y6y6y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y:y:y:y:y6y:y6y:y:y6y6y6y6y6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y6y6y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y6y:y:y6y6y6y:y6y6y:y6y:y:y:y:y:y:y:y6y:y:y:y6y:y6y:y6y6y:y6y6y:y:y:y:y:y:y6y6y:y6y6y:y6y:y:y6y:y:y:y6y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y6y:y:y6y:y6y:y:y:y6y:y6y6y:y:y:y:y:y:y6y:y:y6y6y:y6y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y:y6y:y6y6y:y6y:y6y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y:y6y:y6y6y6y:y6y:y:y6y:y:y6y:y:y6y:y:y:y:y6y:y:y:y:y6y:y:y6y6y6y:y6y:y:y6y:y6y:y:y:y:y:y6y:y6y:y6y6y:y6y:y:y:y:y6y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y6y:y6y:y6y:y6y:y:y:y:y6y6y6y:y:y:y:y6y6y:y:y:y6y:y:y:y:y6y6y6y:y:y:y:y6y:y6y:y6y:y:y:y:y:y6y6y:y6y:y:y:y:y:y6y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y6y6y6y:y6y6y:y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y6y:y:y:y:y6y:y6y:y:y:y:y6y6y6y:y6y:y:y:y:y:y6y:y:y:y:y6y6y:y6y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y:y:y6y6y6y6y6y:y:y6y6y:y:y:y:y6y:y6y:y:y6y:y6y:y:y6y:y:y6y6y:y:y:y6y:y6y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y6y6y:y6y:y6y:y:y:y6y:y:y:y6y:y6y6y:y:y:y:y6y6y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y6y:y:y:y:y6y:y6y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y6y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y6y6y:y6y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y6y6y6y6y6y6y:y:y:y:y6y6y6y:y:y:y:y:y6y:y:y:y6y6y6y6y:y:y:y6y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y:y:y:y6y:y:y6y:y6y:y:y:y:y6y6y:y:y:y:y6y:y:y6y:y:y:y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y6y6y:y6y6y:y:y:y6y6y:y:y6y:y:y:y:y6y:y6y:y:y:y:y:y6y:y:y6y:y:y6y:y6y6y:y6y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y:y:y:y:y:y:y:y6y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y6y6y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y:y6y:y:y6y:y:y:y6y:y6y:y6y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y6y:y6y6y:y6y6y:y6y:y:y:y:y6y:y:y:y6y6y:y6y:y6y:y6y:y6y:y:y6y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y6y6y6y6y:y:y6y:y6y:y:y6y6y:y:y:y6y6y:y:y:y:y:y:y:y6y:y6y:y6y6y:y:y:y:y:y:y6y:y:y:y:y6y:y6y:y:y6y:y6y:y:y:y6y:y6y:y:y6y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y6y:y6y6y:y6y:y6y6y:y:y:y6y:y:y:y:y:y6y6y:y6y:y:y:y:y6y:y6y:y:y:y:y:y:y6y:y6y6y:y6y:y6y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y:y6y6y:y6y6y6y:y6y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y6y:y6y:y:y6y:y:y:y:y6y:y:y:y:y6y6y:y6y:y6y:y:y:y6y:y:y:y:y:y:y6y:y:y:y6y:y:y:y6y6y6y:y:y:y6y6y:y:y:y6y6y:y:y:y:y:y6y6y:y:y:y6y6y:y:y6y:y6y6y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y6y:y:y6y:y6y:y:y6y:y6y:y:y:y:y:y6y6y6y:y6y:y:y6y:y6y6y6y6y:y:y6y:y:y:y6y:y:y6y:y6y:y6y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y6y:y:y:y:y:y6y6y6y6y:y:y:y6y6y:y:y:y:y6y:y:y:y6y:y:y:y:y:y6y6y:y:y:y6y6y6y:y:y6y:y:y:y6y:y:y:y6y:y6y:y6y6y6y:y6y:y6y6y:y:y:y:y6y:y6y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y:y6y6y:y:y:y:y:y6y6y:y6y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y6y6y:y6y:y:y:y6y6y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y6y:y:y6y:y6y:y:y6y:y6y6y:y:y:y:y:y:y6y6y:y:y:y:y:y6y:y6y6y6y:y6y:y6y:y6y6y:y:y:y6y6y:y:y:y:y:y6y6y6y:y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y:y6y:y:y:y6y6y6y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y6y6y:y6y6y6y:y:y:y:y:y:y:y6y:y6y:y6y6y6y6y:y:y:y:y:y6y:y6y6y:y:y6y:y:y:y6y:y6y6y6y6y:y:y:y6y:y6y:y:y:y6y:y6y6y:y6y:y:y6y6y6y:y:y:y6y6y6y6y6y6y6y6y:y:y6y:y:y:y:y:ÚF<_<_ûNy6y6y:y:y:y:y:y:y:y6y:y:y:y:y6y:y6y6y:y:y6y:y6y6y:y:y6y:y6y:y6y:y:y6y:y:y:y:y:y6y:y:y6y:y6y:y:y:y:y6y:y:y6y:y:y6y:y:y:y:y:y:y6y:y6y6y6y6y:y:y:y:y:y:y6y:y:y6y:y:y:y:y:y6>ÚFºF>:y6y6y6y:y:y:y6y:y:y:y:y:y:y:y6y:y:y6y:y:y:y6y:y6y:y6y6y:y6y6y:y:y6y:y6y:y6y:y6y:y6y:y:y:y:y:y:y6y6y:y:y:y6y:y6y:y:y:y6y6y6y:y6y:y:y:y:y:y6y:y:y6y6y:y:y:y6y6y:y:y6y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y6y:y6y6y:y:y:y6y:y:y:y6y:y:y6y:y:y6y:y:y:y:y6y6y6y6y6y6y6y:y6y:y6y:y6y6y:y6y:y6y6y:y:y:y:y:y:y:y:y:y:\_Þwß{kûNy:y6y6y:y:y6y6y6y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y6y6y6y:y6y:y:y:y6y:y:y6y:y:y6y6y:y:y:y:y6y6y:y6y6y:y6y6y:y6y:y:y:y:y:y:y:y:y6y6y6y:y:y6y:><[¾o¾s]cûNºFy:y:y:y6y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y6y:y:y:y6y:y:y6y6y:y:y6y:y6y:y6y:y6y6y6y6y:y6y6y:y:y6y6y6y6y:y:y6y6y:y:y:y:y:y:y:y:y6y:y:y6y:y6y6y:y:y6y6y:y:y:y:y6y:y:y:y6y6y6y6y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y:y:y6y6y:y6y6y:y:y:y:y:y:y:y:y:y:y:ºFoÿ\x7fÿ\x7fß{]cBy6y:y:y:y:y:y:y6y6y:y:y:y:y:y:y6y6y:y6y6y6y:y6y:y6y:y:y:y6y:y:y6y:y6y:y:y:y:y:y:y6y:y6y:y:y6y:y:y:y:y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y6y:y6y:y:y:y:y:y6>}kÿ\x7fÿ\x7fÿ\x7f¾w}g^[S>y:y:y:y:y6y6y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y6y:y6y:y6y:y:y:y6y:y:y6y:y6y:y6y:y:y6y:y6y6y:y:y:y:y6y:y6y6y6y:y6y:y6y6y:y:y:y6y6y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y6y:y6y:y:y:y:y6y:y:y6y:y:y:y:y6y:y:y:y:y6y:y:y:y:y6y:y:y6y:y6y:y6y:y:y6y:y:y:y6y6y6y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:\x1cWÞwÿ\x7fÿ\x7fÿ\x7f¾s^[S:y6y6y6y:y6y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y6y:y6y6y6y:y:y:y6y:y:y:y6y:y:y6y6y:y:y:y:y:y6y:y:y:y6y:y6y:y:y6y:y:y6y:y6y6y:y6y:y6y:y:y6y:y6y:y:y:y:y6y6y6y6y6y6y:y6y::<_ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fkºB:>>y:y:y:y:y:y6y6y:y:y:y6y:y:y6y6y:y6y6y:y6y6y:y:y6y:y6y:y:y:y:y6y:y:y:y6y6y:y6y6y:y:y6y:y6y:y:y6y:y:y6y:y6y6y:y6y:y6y:y6y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y6y6y6y6y:y:y:y6y:y:y6y:y:y6y6y:y:y:y:y:y:y6y:y:y:y6y:y6y6y6y:y:y:y:y:y6y6y:y:y:y6y:y6y:y6y:y:y6y6y:y6y6y:y:y:y6y6y:y:y:y6>]cÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fkÛJy:y6y:y:y:y6y:y:y:y:y6y6y6y6y:y6y6y:y:y6y:y:y:y6y:y:y:y:y:y6y6y:y:y:y6y:y:y:y:y:y6y:y6y:y6y6y6y:y:y:y:y:y:y6y:y:y:y6y6y:y6y6y:y:y:y:y:y6y:y:y:y6y6y6y6y:y6y6y:y:z:ûN¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛF\x1cW]c<_ûR>:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y6y6y:y:y6y6y:y:y6y6y:y:y6y6y6y:y:y:y:y:y6y6y:y:y:y6y:y:y:y:y6y6y:y:y:y:y6y:y6y6y:y:y6y:y:y:y:y:y:y:y6y:y6y6y:y:y:y:y:y:y:y:y:y6y:y:y:y6y6y6y:y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y6y:y:y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y6y6y:z:ºFkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}gºBy:y:y6y:y:y6y6y:y:y:y:y:y:y:y:y6y:y6y6y:y:y6y:y6y:y:y6y:y:y6y:y:y:y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y6z:z:y:z:z:y6z:y:y:z:z:y:y:y:y:y:y:y:y:z:y::<_ÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾w}c¾oÿ\x7fß{¾s}k\x1cWºBy:y:z6y6y:z6z:z:y:y:y:z:y:y:y6z:z:y6z:z6y:z6y:z:z:y:y6y:z:y:y6y:y6y:y:z6z:z6y:z6y6z6y:y6y:y:z6y:y6z:z:z6y:y:z:z6z6y6y:z:y:z6z6y:y:z:z:y6z6z:y6y:y:z:y:y6y:y:y:y:y6z6z6y:z:y:y6y:z:y:z:z:z:z6y6y6y6y:z6z:y6z6z6y:z:z6y:z:z:z6y6z:y6z:y:y:z6z6y:y6z6z:y6y:y:z6y:y:y:y6z:y:z6z:z:ºF¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞw<[:z:y6y6y6z6z:y:z:y:z:z6y:y:z:z:y6y:y:y:y:y:y6z:y6z:y6z6y:z6z:y6y6y6y6z:y6y6z:z:z:y6y6y:y:y6y:z6z:z:y:z:z:y:y:z:z:z6z6z6z:z6z:z6z:z:z:z:z:z:z:z:z6z6z:y:z:z:y6y::ÛF}gß{ÿ\x7fÿ\x7fÿ{ß{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7f]c>z:z6y:y:y6z:z6y6y:y:z6z6z:z6y6z:z6z6z6z6z6z:z:z:z:z6z:z:z6z:z:z:z:y6z6z:z6z:z6z:z6z:y:z:z:z6z:z6z:z:z:z:y:y6z:z:y:z:y:z6z:z6z6z:z:z6z6y:z6z:z6z:z6z:z:z6y6z6z:z:z:z6z:z:z:y6z6z:z:y:z:z:z6z:z:z6z:z6z6y:z:z:z:y:z:z:y6z:z:z:y:z:z:y6z6z:z6y:y:y:y6z:z:z6z:z:z:y:z6y6z:y6z:z:ÛJÞwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{]c>z:z6z6z6z:z:y:z:z6z:z:z6z:z:z:z:z:z:z6z:z6z:y6z:y:z:z6z6z6z6z:z6z:z6z6z:z6z6z:z6z:z:z6y:y6z:z6y:z:z:z:z:z6z:z:z:z:z:z:z6z6z:z6z:z6z:z:z6z6z6z6z6z6z6:»Bº>»B::ºB<[¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f}gÛFz:z:z:z6z:z6z6z:z:z:z:z:z:z:z:z:z6z:z6z:z6z:z6z:z:z6z6z6z:z:z:z:z:z:z:z6z:z:z:z:z6z:z:z6z:z:z:z:z:z6z6z6z6z6z6z:z:z:z:z:z6z:z6z:z:z6z:z6z:z6z:z:z6z6z:z:z:z:z:z:z6z:z6z6z6z:z:z:z6z:z:z:z6z:z:z6z6z:z:z6z:z6z:z:z6z6z:z:z6z:z:z6z6z:z6z:z:z:z:z6z:z6z:z6z:z6z:z:z:z6z:z:z6:ÛJÞwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw]_>z:z:z:z:z:z:z:z:z:z6z:z6z:z:z6z:z6z6z:z6z:z6z6z:z:z6z:z6z6z:z6z:z:z:z6z:z6z:z:z:z:z:z6z6z6z:z6z:z:z6z:z6z6z:z:z:z:z:z6z:z:z:z6z:z:z:z:z:z6z:z:z:z6>\x1cWko}g}c\x1cS\x1cS}c¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}gûNz:z:z6z6z6z:z6z:z:z6z:z6z:z:z6z6z6z:z:z6z:z6z:z:z6z:z:z6z6z:z:z:z:z:z6z6z:z:z:z6z:z:z:z6z:z:z:z6z6z6z6z6z:z6z:z:z:z6z6z6z:z:z6z6z6z6z:z:z6z:z:z:z6z6z6z6z:z:z6z:z:z:z6z:z:z:z6z6z:z:z:z6z6z:z:z6z:z6z:z6z:z:z:z:z:z6z:z6z:z6z:z:z:z:z6z6z6z:z:z:z6z6z:z:z:z:z6z:z:z:z:z:z6z6z:ÛF¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{¾sÛJ:::z:z6z:z:z:z:z:z:z:z:z6z:z:z:z:z:z:z:z:z6z6z:z:z6z6z:z6z6z:z6z6z6z6z:z:z:z:z6z:z6z6z:z6z:z6z:z:z:z:z6z:z:z:z6z6z6z6z:z:z:z:z:z:z:z6z:z:z:z:z6z:>}gÿ\x7fÿ\x7fÿ\x7fß{ÿ\x7f¾s¾sß{ÿ\x7fÿ\x7fß{ßwß{ß{ßw}k<W>z6z6z6z:z:z6z6z:z:z:z:z:z6z:z:z:z:z:z:z:z6z6z:z6z:z6z:z6z6z6z6z:z:z6z6z6z6z:z6z6z6z:z:z:z:z:z6z:z:z:z6z6z:z6z:z:z6z:z:z:z6z:z6z:z:z:z6z6z6z:z:z:z6z6z6z:z:z:z:z6z6z:z:z:z:z6z:z:z:z6z:z:z:z:z:z6z6z:z6z:z:z6z:z6z6z6z:z6z:z:z:z6z:z:z6z:z6z:z:z:z6z:z:z6z:z:z:z6z:z6z6z:z:z6z::ÛFoÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{<[ÛJüN\x1cWûJ>z:z:z:z:z6z6z:z6z:z:z:z:z:z6z:z:z6z:z:z:z:z:z:z:z:z:z:z:z6z:z:z:z:z:z:z6z:z:z6z:z:z:z:z:z:z:z6z:z:z:z:z6z:z6z:z:z6z6z:z:z:z6z:z:z:z:z6z:z:z::]_ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fo<[\x1cW<W\x1cWûN>:z:z:z:z:z:z6z:z:z:z6z6z:z:z6z6z:z6z:z:z:z:z:z6z6z6z:z6z6z6z:z:z:z6z6z6z6z:z:z:z6z:z:z:z:z:z:z6z:z:z:z6z:z6z6z6z:z:z:z6z:z:z6z:z:z:z6z6z:z6z:z:z:z6z6z:z:z6z:z6z6z:z6z:z6z:z:z:z:z:z:z6z:z:z:z:z6z:z:z:z6z:z:z:z:z6z:z6z:z:z:z:z6z:z:z6z:z:z:z:z:z:z:z:z6z:z:z:z:z:z6z6z6z6z:z:z::»B]_ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{ooÞwßwßw\x1cW>z:z:z:z6z6z6z:z:z:z:z:z:z:z:z6z:z6z:z6z:z:z:z:z6z6z6z6z:z:z:z:z6z:z6z:z:z6z:z6z:z:z6z:z6z:z:z:z6z6z6z6z:z6z:z:z6z:z6z6z:z6z6z:z:z6z:z6z6z6z:»B}gÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{k»F:>::z:z:z:z:z6z:z:z6z6z:z6z:z:z:z:z:z:z6z6z:z6z:z:z:z:z:z6z:z6z6z:z6z:z6z6z:z6z:z:z6z:z6z:z:z:z:z6z6z6z6z6z6z:z:z:z:z:z6z:z6z:z:z:z:z:z6z6z:z6z6z:z6z:z:z:z6z6z:z:z:z:z:z:z6z:z:z6z6z:z6z6z:z6z:z:z6z6z6z6z:z:z6z:z6z6z:z:z6z6z6z:z6z:z:z:z6z:z:z:z6z:z6z:z:z:z:z:z:z6z6z:z6z:z:z:z:z:z:z:>\x1cSßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{Þw\x1cS:z:z6z:z6z:z6z6z6z6z:z:z:z:z:z:z6z:z:z6z:z:z:z6z:z6z6z:z:z:z:z:z6z6z:z6z:z6z6z:z6z6z:z:z:z6z:z6z6z:z6z:z:z:z:z6z6z:z:z6z:z:z6z6z6z:z:z:z6z::üNkß{ÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ\x7f¾sûJ:z:z6z6z:z:z:z:z:z:z6z:z:z6z6z:z:z:z:z:z:z:z:z6z6z:z:z6z6z:z6z6z6z:z:z6z:z:z:z:z:z6z:z6z6z6z:z6z:z6z:z6z:z:z6z6z:z:z:z6z6z6z:z6z:z:z:z6z6z:z6z6z6z6z6z6z:z6z:z6z:z:z:z6z:z:z6z:z6z6z6z6z6z:z6z:z:z:z6z:z:z6z:z:z6z:z6z6z6z:z:z6z6z6z:z6z:z6z:z:z:z6z:z6z:z6z:z6z:z:z:z:z:z6z:z:z:z:::»>::>ûN¾oÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{oûN:z:z:z:z:z6z:z:z6z6z:z:z:z6z:z6z6z6z:z:z:z:z6z:z:z6z6z:z6z:z:z:z6z:z:z:z6z:z6z6z:z:z6z6z:z6z:z6z:z6z6z:z:z6z6z6z:z:z:z:z:z6z6z:z6z:z:z6z:z6z:üN¾s¾sooß{ÿ\x7fÿ\x7fß{]_>z:z:z:z:z6z6z:z:z6z:z:z6z6z6z6z:z6z6z6z:z:z:z6z6z:z6z:z:z:z6z:z:z:z:z:z6z:z:z:z:z6z:z:z:z:z:z:z6z:z:z6z:z:z:z6z6z6z:z6z:z:z6z:z6z:z:z:z6z:z:z:z:z:z:z6z6z6z:z:z:z:z:z:z6z6z:z:z:z6z:z:z6z:z6z:z:z6z:z6z:z:z:z:z:z:z:z:z:z6z:z6z:z6z:z:z:z:z6z6z:z:z:z:z:z:z:z6z6z6z6z:z:z::>>ÛFÛJûNÛJÛFÛFÛF\x1cWkÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{]c»B:z:z6z:z:z6z:z6z:z6z6z6z:z:z:z:z:z:z:z6z:z:z6z:z6z:z:z:z:z:z:z:z6z:z:z:z:z6z:z:z:z:z:z6z6z6z:z:z:z:z6:z6z6z6z:z:z:z6z:z6z:z:z6z6z6z:z6z:z::ÛFüN»B}gßwÿ\x7fÿ\x7fÿ\x7f}g>z6z6z6z:6z6:z:z:z:z6z:z6z6z:z6z6z6z:666z6z:z:z6:z:z:z6z6z6z:z:z::z:6z6z6z:6z6z6z:z6:z6z6z6z6z6z:z:z:z6z:z:z6z6z:z:z:z6z6z:z:z6z6z::z:z:z:z6z:z:z6z:z::z:z6z:z6z6z6z:z6z:z6z:z:z:z:z:z6z6z6z:z:6z6z:z6z:z:z6z:z:z:z6z6:z:z:z:z:6z:z6:z6z6z6z6z6:z6z:z::>ÛF<[k¾s¾s¾w¾w¾sk}ckÞwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞw\x1cW:z::6z6z:z:z:z6z6z::z:z:z:z:z6z::z6z:z:z::z6z:z6z:z:6z:z6z:z:z:6:z:z:z:z6z:z:z::z:6::::z::z6:6z:z::666z:6:z6z:66z:z:z6:ÛFoÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾s»Fz:z:z:z666z:z6z::z:z6z6z:6z6::z66z:z66:z6::z6:z:z6z6z::z:z::z6z:z6z6z6:z:z:z::6z6:z6z6:66z:z::z:z6z:6z:6z:z:z:6:z:z:z6:6:z66:z6:z6z:z6::6z6:z:z:::6z6:z:z:6z6:z:z:z6:z:z:z6:::6z6:6z6:z:6z66z6z:z::6z:z6z6:z6:ÛF]_¾sßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fk»Bz:z6:z6z6z66z6z6z66z:6z:z:z::z6z6z:z6z:z666z::66z66:z:z:6:z6z:6z:z66:z6z:z6z6z6z6666:z6z::z6z:z:::z6:z:66:z:z6z:z::»B~kÿ{ÿ\x7fÿ\x7fÿ\x7foÛFz::z66:z6z6z:z:::z::6z6z6:::z6:6z:z::z6z66z:z:66z::z6z6:::z::6:z:z6:z6z:z:6z::z666z6:6z6:z:z::z:6z:6z:z66z6:::6z6z::6:z:6z66:6:z:z6z6z6:6:z:::z:66z6z::6z:z6z::z:6::z::z:z:z6:6z6z::z:z:66:z::z6=[oß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾skkßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1cS:6z::z6:6z6z:z6z6:z6z666z6:66z::6:66z:z::z::z::66:6z:6z:6z6z:z66666:::::6z:::z:::6::6z:::6z:6z:::\x1cWÞwÿ\x7fÿ\x7fÿ{o»Bz6::z6::66:6:z6:6:::z666:6:6::::::6:66z:::6z:z6:6z:6:::z:z666::6z:z6:66z:::::z666:6:z::6z:::z::666666:6z:z6:666::666:::6z:z::::66:6:66::6z:66:6:6::z::6:üN¾sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾so]c\x1cSüN}g¾wß{ÿ{ÿ\x7fÿ\x7fÿ\x7fÞwüN:::6:::::::6:z66z:z::::6z6::66:z::66:66:z:::z:666666:6:6::6:66:::::6:6:::66:6:6::\x1cWßwÿ\x7fÿ\x7f]c>66:66::6:::66:666::::::::::6:66:6::6:6::6:6:666666:66666666666::::6:::::6::::6:::6:6:::::6:6:6::::::::::66:::66666::6:::666666:6:ÛJ¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{<[]cüN>»>ÛJ]_}go¾so]_ÛF:6666::666::66:::6:::6::6::6666:6:66::6::::6:::::6:66::66::6:6:6666:6::666»>]_¾wÞw\x1cW::6:6:6666:::6:666:::::6::::6:::6:66::6:6::666::66:666666:::::66:::::::6:666::666:66:666666:6:::66:6:6:::6::6::6:::6:6::666666:666:üN¾wÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{oÛJ»>:::>»BÛFÛFÛB>::::6::66:6:666:::666:::6::::6::6:6666::66:66::::6:::66::::6666::66:::6:66:::=[<[ÛF:66::666666:6::::66:::::66::6::::::6::66:6:6:::6::::::::6:666:::66::66::66:::66:66:6:66:6666::::6:66:666:::6666666:6::::666:6::::66:ÛJ]c¾sß{ÿ{ÿ\x7fÿ\x7fÿ\x7fß{¾o¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw<W»>:666::::::6:6::666666666:::6::6:66:::6:66::::6:::66::::6:6:66::66666::6:::66:::::::666>»>6::666:6:666:666:666::66:::66666::6:666:66:6:66:::66:66::6:6:66:::::6666::66::666::::6::666::66:::::6::::::::66:6::6666:::66:66::::66::ÛF]c¾oß{ÿ{Þwk\x1cSoÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛJ:::::::::6:6:66::::6:6:6::::66::6::6::::::::6::666:::::66::::66::66:::66:6::6:6::66:::6:66::6:6::666:6:6::6:6:6:::::::::6:6:66::::66:6:666::::66::66::66:666::6::::6666::::6:66::::6:66::66:::6::::66::6::6::6:666::6::::::::6::»>üN]_k]_ÛFÛB¾oÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f]_»>66666:6:6::6666:66666:::::6666666:::6::::6666666:6:6666:6::666666:::::66:666666:6:6:66:66:6666::6:66:6::::6:::66:66:6666:6::::66:6:66::::6:6:66:::::666:6:::::6:66:66::::666:::::66:666:::66:6:6:6:6:66:6::66:6:6:66::6::66:6::6:»>»>»>:ÛF¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞwüJ:66::6:6666::6::::66:6:66:::66:66:6::666:::::6666:::6:::666:6666::::6:6:66666666:66:66:::666:::::66:6::::6:::6:6::66:::66:6::6:::::::6::6:::6::66:6:::6:6666::66:6:::66::66:666:666:6666:66:6:66:6:::::66666::66::6:6::66:66:66:6::::ÛFkß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{=W:::::66:::66666::::6666::6::6::::::66:6::66::66:66:666:6:::6:666666:6:6::66666666:::66:6::6:6:666::::66:66::::6:::::66::6:66:66:6:666:6:6::6::::::::66::6:6::::::666666::::6666::6:666::6:6::6:6:6:6666:6::66::6::66:6666:66::66666:6><Woß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f}g»>::66:::66:6::66:6::66:::::6::6::::::6:666:6::66::66::6:66:666:::::::::66666:6:6::6:666::::6:66:6666:6:::6::66666::6:66:6::::6::6::::6:66:::::6::666:6:666::6:::66:6:6:66666:6::666:6666::::::6:::666:6:66::::666::::6:6666::::6:66:6:»>üN]cßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fk»B::666:66:::6666:::66:66:666::6:66:66:66:::::66:6:6:666:66::::6:6:6::::6::6:::66::6::::6:6666::6:66:6:666:::6::666:::6:6::66::6::66::::6::6666:66::6666:::6:66::::::6:6::::6::666:66:6:66:::6::66:6::666:66666666:666:6666::6:66:::66:::ÛBüN~g¾sß{ÿ{ß{}g»>::66:66::6:66:6666::66::66:::::::6:6666:66:66:66:66:6::6::6:6::::66666:6::6666:::::66::6:6::6666666:6::::66:::::::6:666:::6::6::::66::66666666::::6::::6:6:6:66::6::6:6::6::6::::666:6::6::66:6666:66:666:6::::6:6:::666:::666:6:666::::::üN]_}g~güN:::6:666:::::::::6:6:666:6::::6::6:::6666:::::::6::6::66:::666:::66::6666:6666:6:6666:66:::666:6:6666::6:::::666:6:66:66:666:6::6:6:66:66:::6:::6:66:66:66:6::666:::666666::6::666::6:6:66:6666:66:6:6::::666666::6666::66:::::66:6::6:6::::»>»>»>»:::6:::::6:6:::::6:::6::::::66:6:66:66:6::666::6:::::6:::66::6::6:6::6:6:666666:::6:6:66:::66:::66:::66:6::66::6::66::6666666::6:666:6::::6666::6::6::6:::6:6:66::66::666:6666:6:::666::66:::6:666::6:6::66::666:666:::6:6::66:6:66:::666666::::::6666:6:6:6:::::666:6::666:::6:66::6:6::6:6666::66:66:::666:6::6666:6::66::::6::6:6::6666::6::6:666:6:66:6:6:::66:6:6:6666:6::6:666:66666:::6::6::66666::66::6:666666::66::6:6:6:::::66666:6:666:6666::6::::666::6:666:66:::66::::::6::666:666:66:66666::6::6:66::666666:6:6:::6:6::::6666:66:66:::666:6::6:::6:6::6:6:::::::666:::::666:66::6666::66::6:666666:6666:6::::::66:666666:66:66:6:6::66666::66:66:66:6666::6::::66:6:66:::6:6:66:666:6666666::6666::66::666::::6::66:66:66:6::6666::6::::::::666:6:6666:6::666666:6:6::66::6:6::::666::6666::6666666:6:66:6:666::666:66:::666::66:6:666:666:6:6666666:6::66::6::666::::6666::6:6:6666::666::6::66666:::66:6:::6666::6:::66::666666666:6666::6:66:666::6::666:6:::::6::6::6666666:6::6:::6:666:66:66666:::66::::66:6:::6666::66666::6:::666::66:6:66666:666::66:::::66:666666::66:6:6:6:::66:::::66:66666:666:666666::6666666:6666:666::666:666666:::::6666:::::666:6::66666::66::666666:6:::6666:66:66:6:666::66:6:::66::6:6:6:66666::::6::66:6::6::::6:6:666666:6:6::6:::66:66666:::66::66:::6:6666:6::6:6::6:6::6666::66:66:6666:::::::6::666:6::6:66:666:6:::6666:::6::66:666:666:6::6::6::::6::66:666::666666:6:66::666:::666::6666666::::66::666::666::::6666::6:66666:666:::6::6:666::6::6:6:::6:66::66:::666666:::6:666::6666:66:6::::66::::66:6666::6:::66666666666::6666:66:::::666:6:::6::6::66666666:66:66:66666:6::66:6::66::666:::6:6666::6:::6::6666:6:6:6:::6::6:666:6::6:6::::6::6:6666:66:6:666666:66666:66:66::666:666::66666:::::6::::6:6:666:6:6:6:::6:::6::6:6666:66:6::666:666666666::6666666:66::6::6:666::66::6:6::6:66::::6:666:6:6:::6666:6666:6:66:6:6:66666:66:666666:6:6::6::6:::6:6:6:::::::66:::6:6666666::66666:66:6:66:666::666::666::666:666::6:6:6:6::66:66:66::66::6:6666:66::6:666:6:::6666::6:6666::6::6:666::6666:66::666:6666:666:66:::6:::6666:::66::::666:6:66:6:666::6666:66666:66:6666:66:66:66666:66:66:66:6:6:66::6:::66:66::666:66::6:66666::6::666:6666:6::66:::::6::6666:6:66::66::6::6:6666:66:6::6:6:::6:66:::66::::::66666666:66:6666:666666::6:::66666:6:::666666:66666:::6:66:666:6:6666:666::6::666::6:6:6:666::::6:6:6::66:6:666:::6::6:6666:6:666:66::6::6:66:6::66:::666:6666:66:66:666:6::66:6666::6:6::6::::6:::6666:6:6:::6:666::66666::6:66:6::6:6:6::6:6:666:::66::::6:6:6:66::666:66:66:666:66::::666666::6666666:6:::66::6:66:66:6:::6::66:6:::6666:66::6::666:6:66:6::::6::6:666::66:::66:6:66::::6:::66:666666:66::6:66:::6:6::666::6::6:::6666:6::66:6:666::::::::::6:6:66::6:66666::6::::666::666:66666::6666:::666:6:66:66:66::66:66::6666:::6::66::666666:66:6::66::6:6:66::66:666:6:666:6666:66:6:6666::6:66:6:6:::6:6:666:6:::66::66::66666::6::666::::66::6::6:::6:66666666::6::6:6666::::66:66:6::6:6:6666:6:66::66666::66:666:66:::::666666666:6:666::6666:666666:6:66:6:::66::6:::::6:666666666666:6:6:::6666::::::6:::66666:6::66::6:666:::66:66:66:66666666:6666::66::66:66::66:66:66:::6:6:6:666::66666:6666::66:6:6:6:66666:6:6:6666::6::::6666:6::666:6:::6666:6666:6:::66666:6:66666::66::66:66::6:::666::::6::66666:66:::66:6:6666::6:66:::6666:6666666::66666:6::6:666:66666:6::66666::6666:66:::::6:::::6:6::66:6666:6666:66:6:66:::666::6:6:66:66::6:6:66:66:6::666666666:6:66:6::6:6:666:::66666:666:6666::66666::66:66:6:6::6666::66:::6666666:6666:666::66:66:666:666666666:6:66:6:666::6666666:6:::66::66666666666666:6:66::::6:6¼:¼>ÜB::66666666:6::66:6:6:66:66:::6666666:66:::6::666:6666:66:6:6666666::::666:66:66:666:66:666:66:6:6:66:66:66666::6:6::6:666:666::6666::666666666:666:6:66:666:66666:666666::66:666::666666:66::66::6:6::6:66::66::666:::6:66:6666666666:666:6¼:ÜB^_¿s~cýJ66:6666::666:6:66:666:6::66666:66:666666:66:666666666::6:66:66:66:66::66:6:6::::666:666666:::6666:::6666:6:6:666:6:666:6:666:666::6:6:::66:66:6:::6:666:66666666:66:::66::6666666:66::666:::66::6666666::::666:66:666::6666:6:6666666666:¼:\x1dSßwÿ{ÿ\x7fßw]_:6666:6::::66::666:666:666:66666::6:66:66::6::66::6:6::6666:666::::6::::66:6666:666::66666:6::6:66:66:66:66:666666:66:66::6::666666:666666::6:6:66666:6::666::6:666666:666:666:::6:6::66:66:6:66::6:66:6:6:666:6::6:6:6::::666666::::66:¼>\x1dS¾oÿ\x7fÿ\x7fÿ\x7fÿ{^_Ü>:6:66666::6:6:666:666::66:::6:6666:6::66:66:66666:666::666:6666666:6666666666:6:66::6666666666:66::6666666:6:66666:666:66:6::6:666666::666:6::6:666:6:6666:::66:6666::6666:66:6:666:66666::66666:6:666666:::6:6666:6::66666::6:666::¼:¼:ÜF~cßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ{g¼>66666666:66:66:6::6:6:66::::6:6:66666:6::666:66:66:6666:66666::66::6666666666::666::666666:6:66::6:::6666666666666:6:6:6:6:6::6:6:6:66:666:666666:66:666:6:66666:66666:6:::6:6666:::6666::6:666:::::666::6666:66:66::66:66666:66666:¼:ýJ~gßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f~g¼>¼::6::6::::66:6666:6:66:666666:66:66:6666666:::::6::666:::::666:::6::::6:666:::666:66:66:6::66666:666666666::666666666::6666::66666:66666666666666:6666:6:66:66666:66666::66:6:66::::6:::6666666:66:6:66:66::66::::66:666:6666::6:6:¼:ÜBkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{g¼>::66666666666:66:66:6666666:66666:666666666:66:666:666666::6:6:66:::66:666666666:6:6666666:6:66::666:6666::6::6:6::6666:666666:6::6:6666:6666666:66666::66::666::66:666:66:66:6666:::6::66666666666:6:¼6¼::66666¼666:6::6:6666:::6¼:666¼:ýJ¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{~cÜ>:6:6::66:6¼66:6:6:666:6¼6:6¼666666:¼66:66:6:666::66:66:66:6¼66:66:66¼66:¼:¼:66:¼6:6::666:::¼666¼6¼666¼66:6:¼666::6666¼666:¼6666:66:6666:666::6666:666::6¼6:66:66:66666:6:6¼6:6:¼66¼6:::66¼66:¼6¼66:66:6¼:6¼:6¼66:6666:666::6¼6¼66¼6:666:666¼66666:666¼6¼::6¼66::¼6¼:¼:¼:¼:ýF¿sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{~c¼>:¼6:¼6¼:6666666:6¼:¼66¼:¼6:¼66:66¼66¼6::666:6¼6:¼6¼66:6:¼66¼:¼:6:¼6¼6¼6:6:¼:6666¼:6:¼:66::66¼::¼6¼6:6¼66:6:¼6¼6:¼666¼66¼:¼6¼::6¼6¼:¼:6:66¼66¼6:6¼:¼:6¼:6:6¼:66:666666¼6:66::¼66¼:6¼:6¼666¼666::666¼6:66¼6¼6¼:6¼:¼:¼6:¼66:¼6¼6::¼6¼:66¼:66¼66¼66¼6:6¼6¼6¼6¼6:666::¼6¼:66:::6¼6¼:6¼6¼6¼66:¼6¼66¼::6¼66:¼:¼6¼6¼6¼:6¼:¼6¼:¼>=S>[\x1dOÝBÝBkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{>[¼:¼:66¼6¼:¼6¼66:¼::¼:¼6¼6¼:6¼:¼6:¼6:6¼6¼6¼:¼:6¼6¼6¼:6:¼:6¼:66¼:¼:¼:¼6:¼:¼:¼66:¼6:6:¼:66¼66:¼6¼6¼6¼666¼:¼6¼66¼:6¼6¼6:6:¼6¼66¼:¼6¼6¼6¼6¼66¼::6¼::¼:¼6::¼66¼::66¼:¼6¼6¼6¼:¼6¼6¼6¼6¼66¼6:¼6¼:6¼6¼66¼666¼66:¼6¼66¼6¼6¼6¼:666¼:¼:6:6¼:6666:¼:¼6:6:6¼:¼6¼6:¼6¼66¼:6¼6:¼:6¼6¼:66¼:¼66:¼:6¼:¼6¼666:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼6¼66¼6:6¼:¼:¼6¼66¼6¼:¼6¼:¼6¼6¼6¼66¼6¼:¼:¼6¼:6¼6¼:¼6¼:¼>\x1dO~c¿sß{ßwk\x1dS>[ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s\x1dO¼:666¼:¼6¼6¼6¼6¼:¼6:¼:¼:¼6¼6¼6¼6¼6¼6¼:66¼6¼66¼:¼6¼:¼6¼:¼6¼6¼6¼6¼:¼6¼6:6¼66¼:¼:¼6¼6¼::6¼6¼:¼6¼:¼::¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6:¼666¼6¼6¼66¼:6¼6¼6¼:¼6¼:¼:¼:66:6¼:¼6¼6¼66¼6¼:¼6¼6¼::¼:¼:6¼6¼6¼:¼6¼6¼6:¼::¼:¼:¼6¼6¼:¼6¼:¼:6¼6¼:¼:¼:¼:¼6¼:¼66¼6¼:¼6¼6¼6¼6¼:¼6¼6¼:666:¼66¼6¼66¼:¼:¼66¼6¼:¼666¼6:¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6:¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼::¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼66¼6¼6¼6¼:¼:¼6¼:¼:¼:¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼:¼>\x1dOkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ{¿skß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{~g¼>¼:¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6:¼:¼6¼6¼6:¼6¼6¼:¼6¼6¼6¼6¼6¼:¼6¼:¼6¼66¼6¼6¼:¼:¼:¼66¼6¼6¼6¼:¼66¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼6¼6¼66¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼66¼6¼6¼6¼6¼6¼6¼6¼::¼6¼6¼:¼:¼6¼:¼:¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼:¼6¼66¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼666¼6¼6¼:¼6¼:¼:¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼:¼6¼:¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼:¼6¼:¼:¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼:¼:¼6¼:¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼:¼:Ý>^[ßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw=S¼:¼:¼6¼6¼:¼6¼:¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼:¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼:¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼:¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼:¼:¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼:¼:¼6¼:¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:Ý>^[ßsÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{~gÝBÝ>¼:¼6¼6¼6¼:¼:¼:¼:¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼:¼:¼6¼6¼6¼6¼6¼:¼:¼6¼:¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼:¼:¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼:¼6¼:¼:¼6¼6¼:¼6¼6¼:¼:¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼:¼6¼6¼6¼:¼6¼6¼:¼:¼:¼:¼:¼6¼:¼:¼6¼:¼6¼:¼:¼:¼6¼6¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼:¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼:¼6¼6¼:¼:¼6¼6¼6¼:¼6¼:¼:¼:¼:¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼:¼:¼6¼:Ý>^[ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾o\x1dOÝ>¼:¼6¼6¼:¼6¼6¼:¼6¼:¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼:¼:¼:¼6¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼:¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼:¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼:¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼:¼6¼6¼6¼:¼6¼6¼6½6¼6¼6¼6½6¼6¼6¼6¼:¼:¼6¼:¼6¼:½6¼6¼6¼:¼6½6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6½:¼6¼6¼6¼:¼6½:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼:¼6¼6¼6¼6¼:¼:ýJ¾oÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw>WÝ>½:¼6½:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼6¼6½6¼6¼6¼6½6¼6¼6¼6½:¼6¼:¼6¼6¼6½:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼:¼:¼:¼6¼6¼:¼6¼6¼6¼6¼:½6¼6¼6¼6¼6¼:¼6¼6¼6¼6½6¼:¼:¼6¼:¼:¼:¼:¼6¼6¼:¼:¼6¼6¼6½:¼:¼6¼6¼:¼6¼6¼6½6¼6½6¼:¼6¼6½6¼6¼:½:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼:¼6½:¼6¼:¼6½:¼:¼:¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6½6½6½6¼6¼6¼:½6¼6½6¼:¼:¼6¼:¼6¼6¼:¼6¼6¼:¼:¼:¼6¼6¼6¼:¼:¼6¼:¼:¼6½6½:¼6½:¼6½6½6½:¼6¼:½:¼6½:¼:¼6¼6¼:¼6½6¼6¼6¼6½6½6¼6¼6½6½6½6½6½6¼6¼6½6½6¼:¼:½:¼:¼6½6½6¼:¼6½6¼6½:¼6½6¼:½6½:½:½:¼6½6½6½:\x1dOßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¾o>WÝB½>½:½>½:¼6¼6½:½6½:½6½6¼6¼6¼6½6½6½6¼6½:½6½6½6¼6¼6½:¼:¼6¼6½:½6¼6½6½6½6½:½:¼6¼6¼6¼6½:½:½:½6½:¼6¼6¼:½6¼6½6½:¼:¼6¼:¼6¼6½:½6½6½:½6½:¼:¼:¼:¼6¼6¼:½6¼6½6½:½6¼6¼:¼:¼6½6¼6½6½:½6¼:½6¼:½6¼:¼6¼6½6½6¼:½:½6¼6½6½:½6¼:¼6½6½6¼6½6¼6½:½6½:½:¼6¼:¼6¼:½6½6½:½6¼6½:½:½6¼6½:¼6½6½:¼6½6½:½6½6¼6½6¼:½6¼6¼:¼6¼6¼6¼:½6¼:½6¼6½6½6½6½6½:½:¼6¼6½6¼6¼:¼:½6½6¼6½:½6½:½6½6½:½:¼6½6½6½6½:½:¼6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6¼:½:½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½:ýFkß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s^_\x1dOýFÝFÝ>Ý>½:½:½:½:½:½6½6½6½6½:½6½6½:½:½6½6½6½6½6½:½6½6½6½:½:½6¼:½:½6½:¼:½:½:¼6¼6½:½:½6½6½:½6½6½6½6½6½:½6½6½6½:½:½6½6½:½6½6½:½:½:½6½6½:½6½:½6½6½6½6½6½:½:½:½6½6½:½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½:½6½:½6½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½:½6½:½6¼6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½:½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½:½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½:½:½6½6½:ýF^[g¿o¿s¿s¿o¿o~c~g~_^_ßwÿ\x7fÿ\x7fÿ\x7fß{ßw¿s¿ok~g^[\x1dOÝB½:½:½:½6½6½6½:½6½6½:½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½6½6½6½:½:½6½6½:½6½6½6½6½6½:½6½:½:½6½:½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½:½:½6½6½:½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½:½6½:½6½6½:½6½6½6½:½:½:½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½:½:½:Ý>ÝBýJýFýFÝ>ÝBÝB^_¿o¿oÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ß{ßwo>WÝ>½:½:½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½:½6½6½6½:½6½6½6½:½6½6½:½6½6½6½:½6½:½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½:½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½:½:½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½:½6½:½6½:½:½6½6½6½:½6½6½6½6½6½:½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½:½6½6½:½:½:½:½:½:½:ýJ^[^[kß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw~_ýF½:½:½6½:½6½6½:½:½:½6½6½6½6½6½6½6½6½:½6½6½:½:½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½:½6½:½6½6½:½6½6½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½:½:½6½:½6½:½:½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½:½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½:½6½:½6½6½6½:½6½:½6½6½6½6½:½:½6½6½6½6½6½:½6½:½6½6½:½6½6½:½:½:½6½6½6½:½:½6½:½:½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½:½6½6½6½6½:½6½6½:½:ýF>W¿sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{k\x1dO½:½6½6½:½6½:½:½6½:½6½:½6½6½6½6½:½:½:½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½:½6½6½:½6½6½:½:½:½6½:½6½6½6½6½:½6½6½:½:½:½6½:½6½6½6½:½:½:½6½6½:½:½:½6½:½:½6½6½:½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½:½6½:½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½:½:½6½:½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½6½6½:½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½:½6½6½:½:½6½:½:½6½6½:½6½6½6½6½6½6½:Ý>^_ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿o\x1dOÝ>½6½6½:½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½6½:½6½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½:½6½6½:½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:ÝB^_ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fo\x1eS½6½6½:½6½:½:½:½6½6½6½:½6½6½:½6½:½6½6½:½:½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½:½6½:½:½6½:½:½6½6½6½:½6½6½6½:½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½:½6½:½:½:½6½:½6½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½:½6½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½:½6½:½6½6½6½:½6½:½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½:½6½:½6½:½6½6½:½6½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½:ÝB~cß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{ßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{kÝ>½:½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½6½:½6½6½6½6½6½6½6½:½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½:½6½6½6½6½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½:½:½:½:½6½6½6½6½6½6½:½6½6½6½6½6½:½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½:½6½:½:½:½:½6½6½:½6½:½6½:>Wßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿o^_ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{kÝB½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½:½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½:½:½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½6½:½6½6½:½:½:½6½:½6½6½6½6½:\x1eO¿sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{~_ýJkß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ßwo>W½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½:½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½:½:½:½6½:½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½6½:½6½:½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½:½6½6½:½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½:½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½6½:Ý>gÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{^[Ý>\x1eOoß{ß{ß{¿sg~c^[^[½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½:½:½:½6½6½6½:½:½6½6½6½6½:½6½:½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½:½:½:½6½6½:½6½6½:½6½6½:½6½6½6½:½6½6½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½6½:½:½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½:½6½:½6½6½6½6½6½:½6½6½6½:þJ¿sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿sþJ½:½:\x1eK^[^[\x1eOþJÝB½:½6½6½6½6½:½:½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½:½:½6½6½6½6½:½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½:½6½6½6½:½:½:½6½6½:½6½:½6½6½:½6½6½6½6½:½6½6½6½:½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½6½:½6½6½:½6½6½:½:½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½:½6½:½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½:½6½6½6½6½:þJßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ß{ßw^_Ý>½:½:½:½:½:½:½:½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½:½6½:½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½:½6½:½6½6½6½:½6½6½6½6½:½:½6½:½6½6½6½6½:þFkßwÿ{ß{ß{¿s¿ok^[\x1eKÞB½6½6½6½:½6½6½:½:½:½6½6½6½6½:½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½:½:½:½6½6½6½6½:½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½:½:½6½6½:½:½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6Ý:þB>W>W^[\x1eO\x1eOþFÝ>Ý:½:½:½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½:½:½:½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½:½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½:½6½6½:½:½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½:½6½6½:½:½6½6½6½:½6½:½:½:½6½6½6½6½6½:½:½:½:½:½:½:½:½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½:½:½6½6½6½6½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½:½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½:½6½:½6½6½6½6½6½:½:½:½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½:½6½:½6½6½6½:½6½6½6½6½:½6½6½:½6½:½6½6½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½:½6½6½:½6½:½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½6½:½6½:½6½6½:½6½6½6½6½:½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½:½6½6½6½6½:½6½6½6½6½:½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½:½6½6½:½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6¾6¾6½6½:½:½6½6½6½6½:¾6½6¾:½6½6¾6½6½:¾6½6½6¾:½6½:¾6½6½6½6½6½6½:½6¾6½6½:½:½6½6¾6½6½6½6¾6½6½6¾6½6½:¾6¾:½6½6½6½6½6½6½:½6½:½6½6½6½:¾6½:½6½6½6½6¾:½:½6½:¾:½6¾6½6½6½6½6½6½6½6¾6½6½6½6½:½6½6½6½:½6½6½6¾6½6½6½6¾6½6½6½6½6½6¾:¾6½6½6¾6½6¾6½:½6½6¾6½6½6½6½6¾6½6½6½6¾6½6½6¾6½6¾6½6½6½:¾:½6½6½:¾:¾6½6½6¾6½6¾6½6¾:½6½6½6½:½6¾6½6½6½:½6½6½6¾6½6½6½6¾6½6½6½6¾6½6¾6½:½6½6½6½6½6½:½6½:½6½6¾6½6¾6½6¾:½6¾:¾:½6½6½6¾6½6½6½6½6½6½6½6½6½6½6½:½6½:½6¾:½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6¾6½6½:½6½6½6½6¾6½6¾6½6½6½:½6¾6¾6½6½6½:½6¾:¾:½6¾6½6½6½6¾6¾6¾6½:¾6¾6½6½6¾6½6½6¾6½6½6¾6¾6½6¾6½6½6½6¾6¾6½6¾6¾6¾:½6½6¾6½6½6½:¾6½6¾6½6¾6¾6½6¾:¾6½6¾:½6½6¾6½6¾6½6¾6½6½6¾6½6¾6¾6½6¾6½6½6¾6¾6¾:½6½6½6¾:¾6¾6¾:½6½6½6½6¾:¾6½6½6¾6¾6½6¾6½6½6½6¾6¾6½6½6½:¾6½6¾6¾6¾6½6¾6½:½6½6¾6¾6½:½6¾6½6½:¾6¾6¾:½6¾6½6½:½6½:¾6½6½:¾6½6½:½6¾6¾6½6½6¾6¾:¾6½6¾6¾6¾6¾:¾6½6½6¾6½6½6½6½:¾6¾6½6¾6½6½6¾6½:½:½6½6¾6½6½6¾6¾6½6¾6¾6¾6½6¾6¾:½6¾6¾6½6½6¾6½:¾6½6¾:¾6¾6¾:¾6½6½6½6¾6½6½:½6¾6¾6¾6¾6¾:¾6½6¾6½6¾6¾6½6¾:¾6¾:¾6¾6½6¾6¾6½6½6¾:¾6½6¾6½6¾6¾6½6¾6½6½6¾6¾6½6½6½6¾:¾6¾6¾6¾6¾:¾6¾:¾6½6¾6¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6½:¾:¾:¾:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6½6¾6¾6¾6¾6¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6½6½6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6½:¾6¾6¾6¾:¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6½6¾6¾:¾:¾6½:¾:¾6½6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6½6¾6¾6¾6¾6¾:¾:¾6½6¾6¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6¾6½6¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾6½6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6½6¾6¾:¾6½6¾6¾6¾:¾6¾6½6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾:¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾:¾6¾:¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾:¾6¾6¾:¾6¾:¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾:¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6`\0¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6\x1f\0¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾:¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6ã\x04á\x04¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾:¾6¾:¾6¾6¾6¾6¾:¾:¾6¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6²Fá\x04À\0³J¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6\x1e\0\x1f\0¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾:¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:±B#\rª%¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6\x1f\0\x1d\0¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6$\rá\x04¦\x19¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6\J¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾6¾6¾6¾6¾6rFá\0 \x01" ¾6Þ6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6Þ6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6Þ6¾6¾6Þ6¾6¾:¾6¾6¾6¾6Þ6¾6¾6¾6¾6<\x04\x1e\0[\x04¾6¾6¾6Þ:¾6¾6¾6¾6¾6¾6¾:\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6À\0à\0D\x11¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6Þ6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6Þ:¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6Þ:Þ6¾6Þ6¾6Þ6¾6¾6Þ6¾6Þ:¾6¾6¾6Þ:¾6Þ6¾6¾6¾6¾6Þ6¾6Þ6Þ6¾:¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:Þ6¾6Þ6¾6¾6¾6¾6¾6¾6Þ6Þ6¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6Þ6¾6Þ:¾6¾6Þ6Þ6¾6Þ6¾:Þ6¾6¾6¾:¾6¾6¾6Þ6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾:¾6¾6¾:¾6Þ6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6\x1f\0\x1f\0\x1f\0¾6Þ6¾6¾6Þ6¾6¾6¾6Þ6Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6¾6!\x01!\x01!\x01!\x01!\x01¾6¾6¾:Þ6Þ6¾6¾:¾6Þ6Þ6²J\f.Þ6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾:¾6Þ6Þ6¾6¾6¾:!\x01Þ6¾6!\x01!\x01¾6Þ:!\x01!\x01Þ6Þ6!\x01¾6¾6!\x01¾6¾6¾6¾6¾6!\x01!\x01¾6¾6!\x01¾6Þ6¾:¾6!\x01¾:!\x01¾:¾6!\x01Þ6Þ6!\x01!\x01!\x01¾6¾6¾6Þ6¾6!\x01!\x01!\x01Þ6!\x01¾6¾:!\x01¾6!\x01Þ6!\x01!\x01!\x01¾6¾6¾6!\x01!\x01!\x01Þ:Þ6!\x01!\x01!\x01Þ6¾6!\x01!\x01!\x01¾6Þ6!\x01!\x01!\x01¾6¾6!\x01!\x01!\x01Þ6Þ6Þ6¾6¾6!\x01Þ6!\x01Þ6¾6¾6!\x01!\x01Þ6Þ6!\x01¾6¾6!\x01¾6Þ6!\x01!\x01!\x01¾6¾6¾6¾:Þ6¾6Þ6Þ6Þ6¾6¾6¾6¾6Þ6Þ6Þ6¾6¾6Þ6Þ6¾6Þ6¾6Þ6Þ6¾6Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6¾6¾6¾6¾6Þ6¾6Þ6Þ6¾6¾6¾6¾6Þ6¾:¾6¾6Þ:¾6Þ6¾6Þ6¾6Þ6Þ6Þ6¾6¾:Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6Þ6¾6¾6¾6¾6X%\x1f\0\\x04¾6Þ6¾6¾:¾6¾6¾6¾6Þ6Þ6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6Þ6!\x01!\x01!\x01!\x01!\x01¾6¾6¾6Þ6Þ6¾6¾6\0\x05\0\x05¾6¾6¾6Þ6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6¾6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6¾:!\x01Þ6!\x01Þ6Þ6.*!\x01¾6¾6!\x01Þ6!\x01¾6Þ6!\x01Þ6¾6¾6¾6!\x01¾6¾6!\x01¾6!\x01Þ6Þ6¾6¾:!\x01¾6!\x01¾6¾6!\x01¾6!\x01Þ6¾6Þ6¾6¾6¾6Þ6!\x01¾:¾6Þ6¾6!\x01Þ6Þ6!\x01¾6!\x01Þ6!\x01Þ6¾6!\x01¾:!\x01¾6¾6¾6¾6!\x01Þ6Þ6!\x01Þ6!\x01Þ6Þ6!\x01¾6!\x01¾6Þ6Þ6¾6!\x01Þ6Þ6!\x01¾6Þ6¾6Þ6!\x01!\x01¾6!\x01!\x01¾6!\x01¾6Þ6!\x01Þ6!\x01¾6Þ6!\x01Þ6!\x01¾6Þ6!\x01¾6¾6¾6¾6Þ6Þ6Þ6¾6¾6Þ6Þ6¾6¾6Þ6Þ6¾6¾6¾6¾6¾6¾6¾6Þ6¾6Þ6¾6¾6Þ6¾6Þ6¾6Þ6¾6Þ6Þ6¾6¾6¾6Þ:¾6¾6Þ6Þ6Þ6¾6¾6¾6Þ6Þ6¾6¾6¾6Þ6Þ6Þ6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6Þ6¾6Þ6¾6Þ6Ù\x10\x1e\0-Þ6¾6Þ6Þ:¾6Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6!\x01!\x01!\x01!\x01!\x01¾6Þ6Þ6¾6Þ6Þ6\0\x05\0\x05\0\x05\0\x05Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6¾6¾6¾6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6!\x01Þ6!\x01¾6¾6Þ6!\x01Þ6Þ6!\x01Þ6!\x01Þ6¾6!\x01Þ6Þ6Þ6¾6!\x01Þ6Þ6!\x01¾6!\x01Þ6Þ6Þ:Þ:!\x01¾6!\x01Þ6¾6!\x01Þ6!\x01!\x01!\x01!\x01¾6Þ6Þ6Þ6!\x01!\x01!\x01!\x01¾6!\x01Þ6¾6!\x01¾6!\x01Þ6!\x01¾:Þ:!\x01Þ6!\x01!\x01!\x01!\x01Þ6!\x01Þ6Þ6!\x01¾6!\x01Þ6Þ6!\x01¾6!\x01!\x01!\x01!\x01¾6!\x01Þ6Þ6!\x01Þ6Þ6¾6Þ6!\x01¾6!\x01Þ6!\x01Þ6!\x01Þ6¾6!\x01Þ6!\x01Þ6Þ6!\x01¾6!\x01¾6Þ:!\x01Þ6Þ:¾6¾6¾6¾:Þ6Þ:¾6Þ6¾6Þ6Þ6Þ6¾6Þ6Þ6¾6Þ6¾6¾6¾6¾:¾6Þ6¾6¾6Þ:Þ>\x1fOþF¾6Þ:Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6Þ:¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ:Þ6¾6Þ6Þ6¾6Þ6¾6¾6:B\x1f\0\x1f\0\x1f\0ú9Þ6Þ6Þ6¾6Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6!\x01!\x01!\x01!\x01!\x01¾6Þ6Þ6¾6Þ6Þ6\0\x05\0\x05\0\x05\0\x05Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6¾6!\x01Þ6!\x01Þ6¾6\f&!\x01Þ:Þ6!\x01¾6!\x01Þ6¾6!\x01Þ6¾6Þ6Þ6!\x01Þ6Þ6!\x01Þ6!\x01Þ:Þ:Þ6Þ6!\x01Þ6!\x01Þ6Þ6!\x01¾6!\x01Þ6Þ6!\x01Þ6Þ6Þ6Þ:!\x01ûJÞ6!\x01¾6!\x01Þ6¾6!\x01¾6!\x01Þ6!\x01Þ6Þ:!\x01¾6!\x01Þ6Þ6!\x01¾6!\x01Þ6Þ6!\x01¾6!\x01Þ6¾6!\x01Þ6!\x01Þ6Þ6!\x01Þ:!\x01Þ6Þ6!\x01Þ6Þ6Þ6!\x01!\x01¾6!\x01¾6!\x01¾6!\x01Þ6Þ6!\x01Þ6!\x01Þ6Þ6!\x01¾6!\x01Þ6Þ6!\x01Þ6Þ6Þ6Þ6¾6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6¾:Þ6¾6Þ6Þ6Þ:Þ6Þ:þF\x7fcßwßwgÞ>Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6¾6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6:>\x1f\0\x1f\0\x1f\0Y%Þ6Þ6Þ6Þ6Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6Þ6!\x01!\x01!\x01!\x01!\x01¾6Þ6¾6Þ6Þ6Þ6\x19\0\x05\0\x05Þ6¾6Þ6Þ:¾6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6!\x01Þ6Þ6!\x01!\x01Þ6Þ6!\x01!\x01Þ6Þ6!\x01!\x01!\x01Þ6Þ6Þ6¾6Þ6Þ6!\x01!\x01Þ:!\x01!\x01!\x01Þ6Þ6!\x01!\x01!\x01!\x01!\x01!\x01Þ6Þ6Þ6!\x01!\x01Þ6Þ6¾6Þ6Þ6Þ6!\x01!\x01Þ6Þ6!\x01!\x01!\x01Þ6!\x01!\x01¾6!\x01!\x01!\x01Þ6Þ6Þ6!\x01!\x01Þ6Þ6Þ6!\x01!\x01!\x01Þ6Þ6!\x01!\x01!\x01¾6¾6!\x01!\x01Þ6Þ6Þ6!\x01!\x01!\x01Þ6Þ6Þ6!\x01¾6¾6³BÞ6¾6!\x01Þ6!\x01!\x01Þ6Þ6³B!\x01Þ6!\x01Þ6Þ6!\x01!\x01!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ>\x1fKkÿ{ÿ\x7fÿ\x7f¿o\x1fOÞ6Þ6Þ6¾6Þ6Þ:¾6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6\f\x1f\0=\x04Þ6Þ6Þ6Þ6Þ6Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6!\x01!\x01!\x01!\x01!\x01Þ6Þ6!\x01!\x01!\x01ñBÞ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ:!\x01Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:!\x01Þ6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ:Þ6Þ6!\x01Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ:ÿB_[ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1fKÞ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6\x1f\0\x1f\0\x1f\0JÞ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6!\x01!\x01!\x01!\x01!\x01Þ6!\x01!\x01!\x01!\x01!\x01Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6ß6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01!\x01ß6Þ6Þ6!\x01ß6!\x01Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6!\x01Þ:Þ:Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ:Þ6Þ6!\x01Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01ß6Þ6Þ6Þ6!\x01Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ:\x1fKgßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1fOÞ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ:Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6ß:Þ6Þ6Þ6Þ6Þ6Þ6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6!\x01!\x01!\x01!\x01!\x01Þ6!\x01!\x01!\x01!\x01!\x01ß6Þ:Þ6ß:Þ6Þ6Þ6Þ6Þ6Þ6ß6ß6Þ6Þ6Þ6Þ6Þ6Þ6ß6ß6ß6ß6Þ6ß6Þ6ß6Þ6Þ6Þ6Þ6ß6ß6Þ6Þ:Þ6ß6Þ6Þ6ß6Þ6ß6Þ6Þ6Þ6Þ6ß6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6ß6ß6Þ6ß6Þ6Þ6ß6ß6ß6Þ6Þ6ß6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6ß6Þ6ß6ß6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ6ß6Þ6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ:Þ6ß6Þ6ß6ß6Þ:\x1fKkÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1fKß:ß6Þ6Þ:Þ6Þ6Þ6Þ6ß:Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6ß6ß6Þ6ß6ß6ß6ß:Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6ß6ß6ß:ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6Þ6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01Þ6!\x01!\x01!\x01!\x01!\x01Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß:Þ6ß6ß6Þ6ß:ß6Þ6ß6Þ6ß6ß6Þ6ß6ß6Þ6ß6ß6ß6ß6Þ6Þ6Þ6ß6Þ6ß6ß6Þ6ß6ß6Þ6Þ6ß6ß6ß6Þ:Þ6ß6ß6ß6ß6ß6Þ6Þ6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6Þ6Þ6ß6ß6ß6ß6ß:Þ6Þ6ß:Þ6ß6Þ6Þ6Þ6ß6ß6ß6ß6Þ6Þ6ß6ß6ß6ß6ß6Þ6ß6ß6Þ6ß6Þ6Þ6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6Þ6Þ6Þ6ß6Þ6ß6ß6ß:ß6Þ6ß6ß6Þ6ß6ß6ß6ß6Þ6Þ6Þ6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6Þ6ß6ß6Þ6Þ6Þ:_[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s\x1fKß:ß6ß6ß6ß6ß6Þ6ß6ß6ß6Þ6Þ6ß6ß6Þ6ß:ß6ß6ß6Þ6ß:ß6ß6ß6ß6ß6ß6Þ6ß6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß:ß6ß6ß:ß6Þ6ß6ß6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01ß6B!\x01!\x01!\x01P:ß6ß6ß6ß6ß6Þ6ß:Þ6ß6ß6ß6ß6ß6ß6ß6ß6Þ6Þ6Þ6ß6ß6ß6Þ6ß6ß6ß:ß6ß6ß6ß6Þ6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6Þ6Þ6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6Þ6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß:ß6ß6ß6Þ6ß6ß:ß6Þ6ß6ß6Þ6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6Þ:ß:Þ6Þ6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß:ß:ß:ß>ß:Þ:\x7f[ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿oÿFÞ:ß6ß6ß6ß6ß6ß6ß6ß6Þ6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01ß6ß6ß6p>ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß>?O\x7fc_[\x1fKß>?Sßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fkß>ß:ß6ß6ß6ß6ß6ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f*\x1f*ß6ß6ß:ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:\x1fG\x7f_¿oßwß{¿s_W?Oßsÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{\x7f_ß>ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß:ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x1f\0\x1f\0\fß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:\x1fKgß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw¿oßsÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1fKß:ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f*\x1f\0ÿ%ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ÿB_[¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{\x7fcÿBß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6\fÿ\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß>_[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s\x1fKÿ>ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß:!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2?\x19¿\x10¿\x10\x7f\x1d6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!¿\x10¿\x10\x7f\x1d6ß6ß6ß6_.\x1f\x15¿\x10\x1f\x15ÿ%ß6ß6ß6¿%\x7f\x1dß6ß6ß6ß6¿%¿%ß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x7f\x1d¿\x10¿\x10¿\x10!6ß6ß6ß6ß6ß6_\x19\x1f\0\x7f2ß6ß6ß6ß6ß%ÿ\x10¿\x10\x1f\x15ÿ%ß:ß6ß6ÿ%ÿ\x10¿\x10_.ß6ß6¿%ÿ\x10¿\x10\x1f\x15ÿ%ß6ß6ß6\x7f\x1dß%ß6ß:ß6\x1f*\x7f\x1dß6ß6ß6\x7f2\x7f\x1d\x7f2ß6ß6\x7f2?\x19¿\x10¿\x10!\x7f2ß6ß6ß6ß6ß6ß6ß6ß:ß:?S¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßs?Sÿ>ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Z\bß6ß6" !\x01!\x01!\x01\0\x05!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!?\x04\x7f\b\x7f\x1d\x1f\x15\x7f\b?\x04\x7f2ß6ß6ß6ß6ß6ß6ß6\x7f2\x7f\b?\x04_\x19_\x19?\x04?\x046ß6\x7f\x1d\x1f\0¿\x10\x7f\x1d¿\x10\x1f\0?\x19ß6ß6¿\x10\x1f\0ß6ß6ß6ß6¿\x10¿\x10ß6ß6ß6ß6ß6ß6ß6\x7f\x1d\x1f\0\x7f\b?\x19\x7f\x1d_\x19\x7f\b?\x04_.ß6ß6ß6ß6?\x04\x1f\0!ß6ß6ß6ÿ\x10\x1f\0¿\x10\x7f\x1d¿\x10\x1f\0\x7f\x1dß6ß6?\x04?\x04\x7f\x1dß66\f\x1f\0\x1f\x15\x7f\x1d¿\x10\x1f\0_\x19ß6ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß6_.\x1f\0?\x04?\x19?\x19?\x04?\x046ß6ß6ß6ß6ß6ß6ß:ß>kÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{\x7f_ÿBß>ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß66\x1f\0?\x046ß6ß66\x1f\0?\x19ß6ß6ß6ß6ß6ß6ß6_\x19\x1f\0ÿ%ß6ß66\x1f\0\x7f\x1d6\x1f\0\fß6ß6ß6_\x19\x1f\06ß6¿\x10\x1f\0ß6ß6ß6ß:¿\x10¿\x10ß6ß6ß6ß6ß6ß6\x1f*\x1f\0¿\x106ß6ß6ß66?\x04ÿ\x10ß6ß6ß6\x1f*\x1f\0\x1f\0¿\x10ß6ß66\x1f\0\fß6ß6ß6\f?\x04ß6ß6\x1f\0¿\x10ß6ß6_\x19\x1f\0\x7f\x1dß6ß6ß6?\x19\x1f\06ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß6?\x19\x1f\0ÿ%ß6ß6ÿ%\x1f\0!ß6ß6ß6ß6ß6ß6ß6ÿB\x7f_ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿o?Sß>ß:ß:ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß%\x1f\0\x7f\x1dß6ß6ß6ß6_.ß6ß6ß6ß6ß:ß6ß6ß6\x7f\b?\x04ß6ß6ß6ß6\x1f\x15ß%ß%\x1f\0!ß6ß6ß6_.\x1f\0¿%ß6¿\x10\x1f\0ß6ß6ß6ß6¿\x10¿\x10ß6ß6ß6ß6ß6ß6\x1f\x15\x1f\0\x1f*ß6ß6ß6ß6ß6\x7f\x1d\x1f\0\x1f*ß6ß6\x1f\x15\x1f\0\x1f\x15\x1f\0\x7f2ß66ß%\x1f*ß6ß66\x7f\b\x1f\0ß6ß6\x1f\0¿\x10ß6ß6\x7f\b?\x046ß6ß6ß66\x7f2ß6ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß6_.\x7f\x1dß6ß6ß6!\x1f\0\x7f\x1dß6ß6ß6ß6ß:ß6ß6ß:ÿB\x7fcßwß{ß{ÿ{ÿ\x7fß{ÿ{ßwß{ÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7f¿s_[\x1fGÿBÿ>ÿ>ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f\x1d\x1f\0!\x1f*\x1f*\x1f*\x1f*\x1f*_.ß6¿\x10¿\x10¿\x10¿\x10ß%ß6\x1f\0¿\x10ß6ß6ß6ß6ß6ß6\x7f\x1d\x1f\0\x1f*ß6ß6ß6ß6\x1f\0\x7f\x1dß6¿\x10\x1f\0ß6ß6ß6ß6¿\x10¿\x10ß6ß6ß6ß6ß6ß6ß%\x7f\x1dß6ß6ß6ß6ß6ß6\x1f\x15\x1f\0\x1f*ß6_.?\x04ÿ\x10_.\x1f\0\x1f\x15ß6ß:ß66ß%ÿ\x10\x1f\0\x1f\0_\x19ß6ß6\x1f\0¿\x10ß6ß6\x1f\0\f\x1f*\x1f*\x1f*\x1f*\x1f*\x1f*6ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß6ß6ß6_.?\x19\x7f\b\x1f\0?\x04\x7f2ß6ß6ß6ß6ß6ß6ß6ß:ß:ÿ>\x1fK?S\x7f_\x7f_\x7fc\x7f__W_[_W\x7f_ßwÿ\x7fÿ\x7fÿ\x7fß{ßsk\x7fc_[?SÿBß>ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f\x1d\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¿\x10ß6\x7f\x1d\x7f\x1d\x7f\x1d\x7f\x1d\x1f*ß6\x1f\0¿\x10ß6ß6ß6ß6ß6ß6\x7f\x1d\x1f\0\x1f*ß6ß6ß6ß6\x1f\0\x7f\x1dß6¿\x10\x1f\0ß6ß6ß6ß6¿\x10¿\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2ÿ%ÿ\x10\x1f\0_\x19ß6ß6\x1f\x15\x1f\0ÿ%ß6\f?\x046ß6ß%\x1f\0\x1f\0\x7f\b_\x19_.ß6ß6ß6\x1f\0¿\x10ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f*ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß66\f\x1f\0\x1f\0ÿ\x10ß%6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ß:ß:ß:ß>ß:ß:ß>\x1fGck¿oÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ÿ{ßw¿s\x7f_\x1fOß>ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ÿ%\x1f\0\x1f*ß6ß6ß6ß6¿\x10\x1f\x15ß6ß6ß6ß6ß6ß6ß6\f?\x04ß6ß6ß6ß6ß%ß6¿%\x1f\0!ß6ß6ß6_.\x1f\0ß%ß6¿\x10\x1f\0ß6ß6ß6ß6¿\x10¿\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6_\x19\x7f\b\x1f\0\x1f\0\x1f\0ÿ\x10ß6ß6ß6?\x04\x7f\bß6ß6\x7f\x1d\x1f\0ß%ß6?\x04\x1f\0\x1f*ß6ß6ß6ß6ß6ß6\x1f\0¿\x10ß6ß:\f¿\x10ß6ß6ß6ß6\x1f*\x1f\0\x7f2ß6\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0ß6ß6ß6\x1f*\x1f\0\x1f*ß6!\x1f\0ÿ\x106ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ß:ÿB?S_[¿oÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{¿s_[ÿFß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x1f\0ÿ\x10ß6ß6ß6_.\x1f\0ß%ß6ß6ß6ß6ß6ß6ß6\x1f\x15\x1f\0\x1f*ß6ß6ÿ%\x1f\0ß%\x7f2\x1f\0¿\x10ß6ß6ß6\x7f\x1d\x1f\0\x7f2ß6¿\x10\x1f\0ß%ß6ß6ß6\x7f\bÿ\x10ß6ß6ß6ß6ß6ß6ß6\x1f*\x7f\b\x1f\0\x1f\0¿\x10_\x19ÿ%ß6ß6ß6\x1f*\x1f\0\x1f\x15ß6ß6_.\x1f\0\x1f\x15ß6\x1f\0¿\x10ß6ß6ß%?\x04ÿ%ß6ß6\x1f\0¿\x10ß6ß6\x1f\x15\x1f\0_.ß6ß6ß6ÿ\x10\x7f\bß6ß6\x1f\0\x1f\0\x7f2ß6ß6¿\x10\x1f\0ÿ%ß6ß6ß%\x1f\0\x1f*ß6\x7f\x1d\x1f\0\x1f*ß6ß6\x7f\b¿\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ÿF\x7fcßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{gÿBß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ\x18ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß%?\x04¿\x10\x7f\x1d\x1f\x15\x1f\0\fß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x7f\b?\x04_\x19_\x19\x1f\0\f6ß6\x7f\x1d\x1f\0¿\x10\x7f\x1d¿\x10\x1f\0_\x19ß6ß6¿\x10\x1f\0\f\x1f\x15\x7f\x1d\f\x1f\0ß%ß6ß6ß6ß6ß6ß66?\x04?\x04ß%ß6ß6ß6ß6ß6ß6ß6\x1f\x15?\x04\x1f*ß6ß6ß6¿\x10?\x04ß6\x1f\x15\x1f\0\x1f\x15\x7f\x1d?\x04?\x04\x7f2ß6¿\x10\x1f\0?\x04¿\x10ß66¿\x10?\x04_\x19\x7f\x1d\x7f\b\x1f\0ÿ%ß6ß6\x1f\0\x7f\b\f\x7f\x1dÿ\x10\x1f\0¿\x10\x7f\b_\x19\x7f\x1d?\x04?\x04ß6ß6\x7f2\x1f\0\x7f\b\x7f\x1dÿ\x10\x1f\0_\x19ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:?O¿oÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{gÿFß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x1f\x15¿\x10ÿ\x10!ß6ß6ß6ß6ß6ß6ß6ß6ß6ß66!¿\x10¿\x10\x7f\x1d6ß6ß6ß6_.\x1f\x15¿\x10\x1f\x15ÿ%ß6ß6ß6ß%\x7f\x1d6_\x19¿\x10ÿ\x10ÿ%ß6ß6ß6ß6ß6ß6ß6\x1f*\x1f\0\x7f\x1dß6ß6ß6ß6ß6?\x19_\x19ß6!ß%ß6ß6ß6ß6_.\x7f\x1d\x7f26ß%ÿ\x10¿\x10_\x196ß6ß6\x7f\x1d\x1f\0\x7f\b\x7f\x1dß6ß6ß6ß%¿\x10¿\x10_\x19_.ß6ß6ß6\x7f\x1dß%_.ÿ\x10¿\x10\x1f\x156\x7f2\x1f\x15¿\x10\x1f\x15_.ß6ß6ß6_._\x19¿\x10ÿ\x10ÿ%ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:?S¿oÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{g\x1fGß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x7f2\x1f\0¿\x10ß6ß6ß6ß6_.\x1f\0!ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0¿\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß>?S¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{\x7fcß>ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß:\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6_\x19\x1f\0?\x19\x1f*\x1f*ß%\f?\x04\x7f2ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0¿\x10ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:?O¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x7f_¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿o\x1fKß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ÿ%\f\x1f\0\x1f\0?\x04\x1f\x15\x7f2ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6\x7f2ÿ%ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ÿBgÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s?O_[ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ß{gÿBß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6!\x01!\x01!\x01!\x01!\x01ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:?Oßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fkÿ>ÿBkß{ÿ{ß{ÿ{¿s¿o¿ok\x7fcß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:\x7f[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ßw_[ß:ß:\x1fG_[\x7fc_[?O\x1fOÿBÿBß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6²Jß6ß6!\x01!\x01!\x01ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6J\x1f\0\x1f\0\x1f\0ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß>?Sßwÿ{ÿ\x7fÿ\x7fÿ{ÿ{ßwßw¿s\x7f_ÿBß:ß6ß:ß:ß:ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6à\0à\0f\x19ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß:ß6ß6ß6<\x04\x1f\0\fß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ÿB_[kgk\x7fc\x7f__[\x1fKÿFß>ß:ß6ß6ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6$\x11\0\x01\x01\x01\x03 ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6Y%\x1f\0\x1f\0\x1f\0:Bß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ÿ>ÿBß>ÿ>ß:ß:ß:ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6M6à\0á\0ë-ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ú9\x1f\0\x1f\0\x1f\0:Bß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß:ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß:ß:ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6¹-\x1e\0Ù\x14ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6h\x1d\0\x01\x1dß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\\x04\x1f\0X%ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6â\x04\0\x01\x02\rß6ß6ß6ß6ß6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6\x1f\0\x1f\0\x1f\0ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6e\x15 \x01²Fß6ß6Þ6ß6Þ6ß6ß6ß6ß6ß6!\x01!\x01!\x01!\x01!\x01!\x01ß6ß6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6[\x04\x1e\0<\x04ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6Þ6ß:ß6ß6ß6ß6Þ6ß6ß6Þ6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6Þ6ß:ß6ß6ß6Þ6Þ6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6Þ6ß6ß6ß6Þ:ß6ß:Þ6ß6ß6ß6ß6ß6ß:ß6ß6ß6ß6ß6ß6Þ6ß6Þ6ß6Þ6ß6ß:ß6ß6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:ß6ß:ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß:Þ6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6ß6ß6ß6ß6ß6ß6Þ6ß6ß:ß6ß6Þ6ß:ß6Þ6ß6ß:ß6ß6ß6Þ6Þ6Þ:Þ6Þ6Þ6ß6ß6ß6ß6ß6Þ6ß6Þ6ß6ß6Þ6ß6!\x01!\x01!\x01!\x01!\x01!\x01Þ6ß:\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6ß6Þ6Þ6Þ:ß6ß6ß6Þ6ß6ß6ß6Þ6ß6ß6Þ6Þ6ß6ß6Þ:ß6Þ6ß6ß6Þ6Þ6ß6ß:Þ6ß:ß6Þ6Þ6ß:Þ6Þ6ß6ß6ß6Þ6Þ6Þ6ß6Þ6ß6Þ6ß6ß6ß6Þ6ß6ß6Þ6Þ6Þ6ß6ß6Þ6Þ6ß6Þ6Þ6Þ6ß6ß6ß6ß6ß6ß6ß:ß:ß6ß6Þ6Þ6Þ:Þ6ß6ß6Þ6ß6Þ6Þ6Þ6Þ6ß6Þ6Þ6ß6ß6Þ6ß6Þ6Þ6ß6Þ6ß6Þ6ß6Þ6ß:Þ6ß6ß6ß6ß6ß6Þ6Þ6Þ6ß6Þ6ß6ß6Þ:ß6Þ6Þ6ß6ß6ß6Þ6Þ6Þ6ß6Þ6ß6Þ6ß6ß6ß6ß6Þ6ß6ß6ß6Þ6Þ6ß6Þ6ß6ß6Þ6ß6ß6ß6ß6Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6ß6ß6Þ6Þ:ß6Þ6ß6Þ6Þ6ß6ß6Þ6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6ß6ß6ß6Þ6ß6ß6Þ6Þ6ß6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6ß6Þ6ß6Þ6Þ6Þ6Þ6Þ6$\x11Á\x04ß6ß6ß6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ:ß6!\x01!\x01!\x01!\x01!\x01!\x01Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6ß6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6[B\x1f\0=\x04Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6ß6Þ6Þ:Þ:ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6ß6ß6Þ6Þ6ß:Þ6Þ6Þ6Þ:ß6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6ß6ß6Þ6ß6ß6ß6ß6Þ6Þ6ß6ß6Þ:Þ6ß6ß6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6ß6ß6ß6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6ß6ß6ß6Þ6ß6Þ6ß6Þ6ß6ß:ß6Þ6Þ6ß6Þ6ß6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6ß6ß6Þ6ß6Þ6Þ6ß6Þ6Þ6ß6ß6ß6Þ6Þ6Þ6ß6ß6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ:ß6ß6ß6ß6ß6Þ6Þ6Þ6Þ6ß6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ6\x1d%\x15Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01!\x01!\x01!\x01!\x01!\x01Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6\x1e\0\\x04Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ:ß6Þ6Þ6Þ6Þ:ß6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6ß:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6ß6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ:Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6!\x01!\x01!\x01!\x01!\x01!\x01Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ:Þ6Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6`\0Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ:Þ6Þ6!\x01!\x01!\x01!\x01!\x01!\x01Þ6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ6¾6Þ6Þ6¾6Þ6Þ:¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6\x1f\0Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6¾6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6¾:Þ6¾6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ:Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6¾6Þ6¾6Þ6Þ6¾:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6¾6¾6Þ6Þ6Þ6Þ6!\x01!\x01!\x01!\x01!\x01!\x01Þ6Þ6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:¾6¾6Þ6Þ6Þ:Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾:Þ6Þ6Þ:¾:Þ6Þ6Þ:Þ6Þ6Þ6Þ6¾:Þ6¾6¾6Þ6¾6Þ6¾6Þ6Þ6¾6¾6Þ6¾:Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ:Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6Þ6¾:Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6¾:Þ6Þ6Þ6Þ:Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6Þ6¾6Þ6Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾:¾:Þ6¾6Þ6¾6Þ6¾6Þ:Þ6¾6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6¾6Þ:Þ6¾6¾6!\x01á\0!\x01!\x01!\x01"\r¾6¾6\x1f\0\x1f\0\x1f\0\x1f\0\x1f\0¾6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6¾6¾6¾6Þ6¾6Þ6¾6¾6Þ:Þ6Þ6Þ:¾6¾6¾6Þ6Þ:Þ6Þ6¾6Þ6¾6¾6¾6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾:¾6Þ6¾6¾6¾6¾:Þ6Þ6¾6Þ6Þ6Þ6¾6¾6¾6Þ6¾6¾6Þ6Þ6Þ6¾:¾6¾6¾6Þ6Þ6Þ6¾6¾:Þ6¾:¾6Þ:¾6¾6Þ6Þ6Þ6¾6Þ6¾6¾6Þ6¾6¾6Þ6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6¾6Þ6¾6¾6¾6Þ6Þ6Þ6Þ6¾6Þ6¾6¾6¾6Þ6¾6¾6Þ6¾6Þ6Þ6Þ6Þ6Þ6¾6¾6¾6Þ6¾6¾6¾6Þ6Þ6Þ6Þ6¾6Þ6¾:Þ:Þ6¾6Þ6¾6Þ6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6¾6Þ6¾6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6Þ6¾6Þ6¾6Þ6Þ6Þ6¾6Þ6¾:Þ6¾6¾6¾6Þ6Þ6¾:Þ6Þ6¾6¾6¾:¾6Þ6¾6¾6Þ:Þ6¾6¾:¾6¾6Þ6Þ6Þ6¾6Þ6¾:¾6Þ:¾6Þ6Þ6Þ6Þ6¾6Þ6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6¾6¾6Þ6¾6¾6Þ6¾6Þ6¾6¾6Þ6Þ6Þ6¾6Þ6Þ6¾6¾6Þ6¾:Þ6Þ:¾6¾:¾6Þ6¾6¾6¾:¾6¾6¾:¾6¾6Þ6¾6¾6¾6Þ6¾6¾6¾6¾6Þ6Þ6¾6Þ6¾6¾6Þ6Þ6Þ6¾6¾6Þ:Þ6¾6Þ6Þ:Þ6¾6¾6¾6¾6¾6¾6Þ6Þ6¾6¾6Þ6¾6¾6Þ6Þ6¾6Þ6¾6¾6Þ6¾6¾6¾6¾:Þ6Þ6¾6¾6Þ6Þ:¾6¾6Þ6Þ6Þ6Þ6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6Þ6¾6¾6Þ6¾6¾6Þ6¾6¾6Þ6¾6¾6Þ6¾6Þ6Þ6¾6¾6¾:¾6¾6¾6Þ6Þ6Þ6Þ6Þ6¾6Þ6Þ:Þ6¾6¾6¾6¾6¾6Þ6¾6Þ6¾6Þ6Þ6¾6Þ6¾6¾6¾:Þ6Þ6Þ6Þ6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6Þ6¾6Þ6Þ6Þ6¾6Þ6Þ6¾6¾6¾6¾6¾6Þ6Þ6¾6Þ6¾6¾6Þ6¾6Þ6Þ6Þ6Þ6¾6Þ6Þ6¾6¾6Þ6Þ6¾:Þ6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6Þ6¾6Þ6Þ6¾6¾6¾6Þ6¾6Þ6¾6Þ6¾6¾6Þ:Þ6¾6Þ6Þ6¾6Þ6¾6Þ6Þ6¾6Þ6Þ6¾6¾:Þ6Þ6Þ6¾6¾:¾6Þ6¾6¾6¾6¾:Þ6¾:¾6¾6Þ6¾6¾6¾6¾6Þ6¾6¾6Þ6¾6¾6¾6Þ6¾6Þ6¾6¾6¾6¾6¾:¾6Þ6¾6¾6¾6¾6¾6Þ6¾6Þ6¾6¾6¾6Þ:¾6¾6¾:¾6¾6¾6Þ:Þ6Þ6¾6¾6Þ6Þ6¾6¾6Þ6¾6Þ6¾6¾6Þ6¾6¾6¾6Þ6Þ6Þ6¾6Þ6Þ6Þ6¾6Þ6¾6Þ6¾6Þ:¾:¾:¾6Þ6¾6¾6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6¾6Þ6¾6¾:¾6¾6¾6¾6Þ6¾6Þ6Þ6Þ6¾6¾6Þ6¾6Þ6Þ6¾6¾6¾6¾6Þ6Þ6Þ6Þ:¾6Þ6¾6Þ6¾6¾6Þ6Þ6¾:¾:Þ6¾6¾6Þ6¾6Þ6¾:¾6Þ6Þ6¾6¾6¾6¾6Þ6¾6¾6¾:¾:¾6¾6¾6¾6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6¾6¾6¾:Þ6¾6Þ:¾6¾6¾6Þ6Þ6¾:¾6Þ6Þ6¾6Þ6Þ6¾:¾6Þ6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾:Þ:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:Þ6Þ:¾6¾:¾6Þ6¾6¾6Þ6¾6¾:¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾:¾6Þ6¾6¾6¾6Þ6¾:¾:Þ6¾:¾6¾6Þ6¾6Þ6¾6¾6Þ6¾6¾:Þ6¾6¾6¾6¾6¾6¾6Þ:¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾:Þ6Þ6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6Þ6¾6¾6¾6¾:¾6¾6Þ:¾6¾6Þ6¾6¾6Þ6¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6¾6¾6Þ6¾:Þ6¾6¾6¾6¾6¾:Þ6¾6Þ6¾6¾6¾6¾6¾6Þ6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6Þ6Þ:¾:¾6¾6¾6Þ6¾6¾6Þ:¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6Þ6¾6¾6¾:¾6¾6¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6Þ6¾:¾6Þ6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6Þ6¾6¾6¾6Þ6¾6Þ6¾6¾6¾6¾6¾6¾6¾:¾6Þ6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6Þ6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6þBþFÞ>¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ:Þ>þB\x1eK_W¿oßs¿o_[¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:Þ>>O\x7fg¿sßwÿ\x7fÿ\x7fßw_[¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6Þ:Þ>ÞBÞ>Þ:Þ:>S¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw>SÞ>¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:Þ:ÞB\x1eK^[g\x7fc\x1eKÞB\x7fcß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßsþFÞ:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6Þ:þB>Sg¿sßwß{ß{¿o\x1eOgß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{gÞ>¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6Þ:þB\x7fcßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿o¿sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw>OÞ:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾:¾:¾6¾6¾:¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾:¾6¾:¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6Þ>^Wß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{kþB¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6Þ>>Sßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{¿oþF¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:Þ:Þ>^[¿oßwÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{k\x1eOÞ>¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾6¾:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾:¾6Þ:þJ^[g¿o¿sßwÿ{ÿ\x7fÿ\x7fÿ\x7fß{g\x1eKÞ>¾:¾:¾:¾6¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:½6¾6¾6¾:½:¾:¾6¾6¾6¾6¾6¾6¾6¾6½:¾6¾6¾6½:¾6¾6½6¾6¾6¾:½:¾6¾:½6¾6¾:¾6½6½6½6½6¾6¾6¾6¾6¾6¾6½:¾6½6¾6½6¾6¾6¾:¾6¾6½:½6½6¾:¾6¾6¾:¾:½6¾6¾6¾6¾6¾6½6¾:¾6¾:¾:¾6¾6¾:¾6¾6¾6¾:¾6¾:¾6¾6½6¾6½6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾:¾6¾6¾6¾6¾:¾6¾6½6½6¾:¾:½:Þ>þF>S~_¿oÿ{ÿ\x7fÿ\x7fo\x1eO¾:¾6¾:¾:¾6¾6¾6¾6½6¾:¾6½:¾:¾:¾6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6½:¾:¾6¾6¾:½6¾6¾6½:¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6¾6¾:¾6¾:¾6¾:¾6¾6¾6¾6½:¾6¾6¾6¾6½6¾6¾:¾6¾:¾6½6½6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾:¾6¾6¾6¾6½6¾6¾:¾:¾6¾6¾6¾6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾:¾6½6¾6¾6¾6¾:¾6¾6¾6¾6¾6¾6¾6½6¾6¾6¾6¾6¾6¾6½6¾6½6½6¾6½6½:¾6½:½6¾6¾6¾:½6¾6¾6½6½:½6½6¾6¾6¾:½6½6¾6¾6½6¾6½6½6¾6½:½6½6¾6¾6¾:½6¾6¾6¾:¾:½6½6¾6½6¾6½6½6¾:¾:¾6½6¾6½6¾6½6½6¾:½:½6½6¾:½6½:½6½:½6½6½6¾6¾6½:½6½6¾6¾6¾6¾6½:¾6¾6½6¾:½6¾6¾6¾6¾6½6¾6¾6½:½6¾6½6½:¾6½6½6¾6¾6¾6¾6½:¾6½6½:Þ:þF~ckßwÿ\x7fÿ\x7f¿o>WþBÞ>¾:½6½6¾6½:¾6¾6½6½:½6¾:½6¾6¾6½6½6¾6½6½:½6¾6½6¾6½6¾6¾6½6¾6¾6¾:¾6¾6½6¾6¾:¾6¾6½6½6½6¾6¾6½6½:½:½6¾6½6½6½6¾:½6¾6¾6½6½6½6¾:¾6½6¾6¾6½:½6¾6¾6¾:¾6½6¾6¾6½6¾:½6¾6¾6½6½6½6½6¾6¾6½6¾:¾6½6¾6½6½6½:¾6½6¾6½6¾6¾6¾6¾6½6¾:¾6¾6½:½6¾:¾6¾6½6¾6½:¾6½6½6¾6½:¾6¾6½6½6¾:½6¾6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6¾6½6½6½6¾6½6½6½6¾6½6½6½6½6½6¾:½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6¾6½6½6½6½6½6½6½6½6½6¾6½6½:½6½6½6½6½:½6½6½:¾:½6½6½6¾:½:½6½6½6½6½6½6¾6½6¾6½:½6½6¾6½6½6¾6½:½6½6½6½6½6½6½6½6½6½6½6Þ:ÞB>Wkß{ÿ\x7fÿ\x7fß{¿s~g>OþB½:½6½6½6½6½:½6½6¾6¾6¾6½6½6½:¾6½6¾6½:½6¾6½6½6½6¾:½6½6½:½6¾:¾6½6½6½6½:½:½6¾6½6¾6¾6½6½6½6½6½6½:¾6¾6½6½6½6¾6½6¾6½6½6¾6½6¾6½6¾6¾6½:½6¾6½6½:½6½6½6¾6½6¾:½6½6½6½:½6¾:½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:¾6½6½6½6½6½6½6¾6½6½6½:½6½6½6½6½6½6½6¾6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½:½6½6½6½6½6½:½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½:Ý>\x1eO~c¿sß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿s~cþF½:½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½:½:½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½:½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½:½:½:½6½:½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½:½:½6½:½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½:½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:þF~_ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{kþFÞ:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½:½6½6½6½:½6½6½6½:½6½6½:½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½6½6½6½:½:½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6Ý:\x1eKkßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f~cþB½:½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½:½6½:½6½6½:½:½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½:ÞBgß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ßwß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw^[½:½6½6½6½6½6½6½6½6½6½:½6½6½:½:½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½6½:½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½:½6½:½6½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6Ý:\x1eKßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿o^_¿sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¿oþF½6½6½6½6½:½:½6½6½6½6½6½:½6½:½6½6½:½6½6½:½:½:½6½6½6½:½:½6½:½:½:½6½6½:½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½:½6½6½6½6½:½:½:½6½:½6½6½6½6½6½6½6½6½6½:½:½6½:½6½6½6½6½6½6½:½:½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½:½6½6½:½:½:½6½:½6½6½6½6½6½6½6½:½:½:½6½6½6½6½6½:½6½:½6½6½6½:½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:ÝB~gßwÿ\x7fÿ\x7fÿ{ÿ{ÿ{ßw^_þJoß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{^[Ý>½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½:½6½:½6½:½:½6½6½6½:½6½6½6½6½6½:½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½:½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½:½6½6½:½6½6½6½:½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:ÝB\x1eS^[~ck¿o¿s~cþFÝ>>W¿oßwß{ÿ{ÿ\x7fÿ\x7fÿ{~gÝB½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½:½6½:½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½:½6½:½6½:½:½6½:½6½6½6½6½6½6½6½:½6½:½:½:½6½6½6½:½6½6½:½6½:½6½6½:½:½6½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½:½6½:½:½6½:½:½6½6½6½:½6½6½6½:½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½:½:Ý>ÝBÝBÝBÝBÝ>½:½:Ý>\x1eO>W^[^_~gkk\x1eOÝ>½6½6½:½6½:½6½6½6½6½:½6½6½:½6½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½:½:½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½6½6½:½6½6½6½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½:½6½:½6½6½:½:½6½6½6½:½6½6½6½6½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½:½:½6½6½:½6½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½:½6½6½:½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½:½:½6½6½6½:½6½6½:½6½6½:½6½:½6½6½:½6½6½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½:½:½6½6½6½6½:½6½6½6½:½6½:½6½6½6½:½6½:½6½6½:½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½:½6½:½6½:½6½6½:½6½6½:½:½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½:½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:ÝBÝBÝB½:½6½6½6½6½6½6½6½:½6½6½:½:½6½:½6½6½:½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½:½:½:½6½:½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½:½6½:½:½6½:½6½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½:½6½6½:½6½6½:½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½:½:½:½:½6½6½6½6½6½6½:½6½6½6½6½6½:½6½:½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½:½6½:½:½:½:½6½6½:½6½:½6½6½6½6½:½6½:½6½:½:½6½:½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½:½6½6½:½:½:½6½:>S¿og\x1eOÝ>½6½6½:½6½:½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½:½:½:½6½6½:½6½6½:½6½6½:½6½6½6½:½6½6½6½6½:½6½6½6½6½:½6½:½:½6½6½6½6½6½:½:½:½:½6½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½:½:½6½6½:½6½6½6½6½6½6½6½:½:½6½:½6½6½6½:½6½6½:½:½:½6½:½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½:½6½:½6½6½6½6½6½6½:½:½:½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½:½:Ý>oÿ{ÿ{ßw^[ýF½:½6½6½6½:½:½6½6½6½6½6½6½6½6½6½:½6½6½:½:½:½:½:½6½:½6½:½6½6½:½6½6½6½6½:½6½6½6½:½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½6½:½6½6½6½6½:½6½6½:½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½:½6½6½:½:½6½6½:½6½6½:½6½6½:½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½:½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½:½6½6½6½6½6½6½:½6½6½:½6½6½:½6½6½6½6½6½6½6½:½:½6½6½:Ý>~gÿ\x7fÿ\x7fÿ\x7fßw~cýF½6½6½6½6½6½6½:½:½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½:½6½:½6½6½6½6½:½:½6½6½:½6½6½6½6½:½6½:½:½6½6½6½6½6½6½:½6½6½6½6½:½:½:½6½6½6½6½:½6½:½6½6½6½:½6½6½:½6½:½6½6½6½:½6½:½6½:½6½6½6½:½6½:½6½6½:~cß{ÿ\x7fÿ\x7fÿ\x7fßw^[½>½6½6½6½6½:½:½6½6½6½6½6½:½:½6½6½6½:½:½6½6½6½6½6½6½:½6½6½:½:½:½:½6½6½6½6½:½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½6½:½6½:½:½:½:½6½6½6½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½:½6½6½6½6½:½:½6½6½6½:½6½:½6½:½:½6½:½6½6½6½6½:½6½6½:½:½6½:½:½6½6½6½:½6½6½6½:½:½6½6½6½6½6½:½6½6½6½:½:½:½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½:½:½:½6½6½6½6½6½6½:½6½6½:½:½6½6½6½:½:½:½6½:½:\x1eSÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7f^[½:½:½:½6½:½6½6½:½6½:½6½6½6½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½:½6½6½:½6½6½6½6½6½:½6½6½6½6½6½6½:½:½:½:½6½6½:½6½6½6½6½6½:½6½6½6½:½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:½6½6½:½6½6½6½6½:½6½6½:½6½6½6½6½:½6½6½:½6½:½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½:½6½6½6½6½6½6½6½:½:½6½:½6½6½6½6½6½6½6½:½:½6½:½6½6½6½:½6½6½:½6½:½:½6½:½6½6½6½6½6½6½6½:½6½6½6½6½:½:½:½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½:½6½6½6½6½6½6½6½6½:½6½:½6½6½6½6½6½6½:½6½6½:ýF>S>WýFÝB½:½:ýFkÿ\x7fÿ\x7fÿ\x7fßw=S>W^[\x1dOÝB½6½:½6½6½6½6½6½6½6½6½6½6½6½6½6½:½:½6½6½6½6½6½6½:½6½6½:½6½:½:½6½6½6½:½:½6½6½6½:½:½6½:½6½6½6½:½:½6½:½6½6½6½6½6½:½:½6½6½:½6½6½6½:½6½6½6½6½6½6½:½6½6½6½6½:½:½:½:½6½:½6½:½6½6½6½6½6½6½6½6½:½6½6½6½6½6½:½6½:½6½6½6½:½:½6½:½:½6½6½:½6½6½:½:½6½6½:½:½6½6½:½6½:½6½6½6½:½:½:½6½6½:½6½6½:½6½:½:½:½6½:½6½6½6½6½:½6½6½:½6½6½:½:½6½6½:½6½6½6½6½6½6½6½6½6½6½:½:½6½6½:½6½6½6½:½6½6½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6½:½6½6½:½:½:½6½:½6½:½6½6½6½:½6½6½6½6½6½:½:½:½6½6½6½:½:½:^[ÿ\x7fßw¿s~cýJÝ>\x1dK~gß{ÿ\x7fÿ\x7fß{¿o¿sÿ{¿s^_ÝB½:½:½6½6½6½6½:½:½6½6½:½:½6½6½6½:½6½6½6½6½6½6½6½6½6½:½6½6½6½6½6½6½6½:½6½6½6½6½6½6½:¼6½6½6½6½6½6¼6½6½:½:½:½6½6½6½6½6½6½:½6½:½6½6½6½6½:½6½6½6½:½6½6½6½6½6½6½6½6¼6¼6½:½6½6½6½6½6½6½6¼6½6¼6¼:½:½6½6½:½6½6½:½6½6½6½:½6½6½6½6½:½:½6½6½6½6½6½6½:½:½6½:½6½6½:½:½6½6½6½6½:¼:¼6½:½6½6½6½6½6½6¼6½:½6½6½6½6½6½:½6½:½6½6½6½6½6½6½6½:½:½:½6½6½:½:½6½6½6½:½6½:½:½:½6½6½6½6¼6½6½6¼6½6½6½6½6½6½6½6½:½:½6½:½6½:½6¼:¼6½6¼6½6¼:¼6¼:½6¼6¼6½6½6½6½:¼6½6¼6½:¼6¼6¼6¼6½6½6¼6½6¼:¼6½:~_ÿ{ÿ\x7fÿ\x7fß{¿s>W^_kß{ÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ\x7fßw~gÝB½:½6½6½6½6½6½6½6½6½6½:¼6¼6¼6½6¼6½6½:¼6¼6¼6½6½:¼6½6½6¼6¼6½:½6½6¼:½6½6¼6¼:½6¼:¼:¼6½:¼6½6¼:¼6½6¼6¼6½:½6¼6½:¼6½6½:½6½6½6½6¼6½:¼6½:½:¼6¼6½6½6½6½6½6½6¼6½6¼:½6½:½:½6¼6½6¼6¼6¼6¼:¼6½6½6¼6½6½6¼:¼6½6¼6½:¼6½:½:¼6¼6½6¼6½:½6½6¼6¼6¼6½6½6½:¼:½6½:½6½6½6½6¼6¼6½:½:¼6¼:½6½6¼:¼6¼6¼:¼6¼:¼6¼:¼6½6¼6¼:½:¼:½6¼6½6¼6½:¼:½6¼:½6¼6½6½:¼6¼6½6¼:½6¼:½6¼6½6½:½6¼6¼6¼6½:¼6½6¼:½6½:½6¼6½6½6¼6¼6½6½6½6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6½6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6½6¼6½6½:\x1dOßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw¿oßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fkÝF¼6¼6¼:½:¼6¼6¼:½6¼:¼6¼6½:¼6¼6¼6¼:¼:½6¼6¼:¼:¼:¼6¼:½6¼6¼6¼:¼6¼6¼6¼:¼6¼6½:¼:¼6¼6¼6¼:¼6¼:¼6¼:¼6¼6½6¼6¼6¼6½:¼6¼:½:¼6¼6¼6½:¼6¼:¼6¼6¼6¼6¼6¼:¼:¼:¼:¼6¼:¼6½:¼6¼6¼:¼:¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼:¼:¼6¼6½6¼6¼:¼6¼6¼6¼6½6¼6½6¼6¼6¼:¼6¼6½:¼6½6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6½6½6¼:¼6¼6¼6¼:¼:¼6¼6¼:¼:¼6¼:¼:¼6½6¼6¼6¼:¼6¼6½6¼:¼6¼6¼6½6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼:¼:¼:¼6½:¼6¼:¼6¼6¼6¼6¼:¼:¼6½6¼6¼:¼6¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6ýFgÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fßw\x1dS¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼:¼:¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼:¼:¼:¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼:¼:¼6¼:¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼:¼:¼6¼:¼:¼6¼:¼6¼6¼6¼:¼:¼:¼6¼6¼6¼6¼:¼6¼:¼:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼:¼6¼6¼6¼:¼6¼:¼6¼:¼6¼6¼:¼:¼6¼:¼6¼6¼:¼6¼:¼:¼6¼:¼:¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼6¼:¼6¼6¼6¼:¼:¼6¼:¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:>[ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{~c~coßwß{ß{ßwßwo^_ýJ¼6¼6¼6¼:¼:¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼:¼:¼:¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼:¼:¼:¼6¼6¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼:¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼:¼6¼6¼:¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼:¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼:¼:¼6¼:¼6¼6ÝBkßwß{ß{ÿ\x7fÿ\x7fÿ\x7fßw\x1dS¼>ýF\x1dS=W^[=S\x1dOÝB¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼:¼:¼6¼6¼6¼:¼6¼6¼:¼6¼6¼6¼6¼:¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼:¼6¼:¼6¼6¼:¼6¼:¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼:¼:¼6¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼6¼:¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼:¼:¼:¼:¼6¼6¼6¼6¼6¼:¼6¼:¼:¼6¼:¼:¼6¼6¼:¼6¼6¼:¼6¼:¼6¼6¼6¼:¼6¼6¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼:¼6¼6¼66¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼:¼:¼6¼6¼:¼:¼6¼:ÝF\x1dS\x1dSkÿ{ÿ\x7fÿ\x7fßw\x1dO¼:¼:¼:¼:¼:¼:¼6¼:¼6¼6¼:6¼6¼6¼6¼:¼:¼6¼:¼:¼:¼:¼6¼:¼:¼:¼6¼6¼6¼:¼6¼:¼6¼6¼6¼6¼:¼6¼:¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼6:¼6¼6¼6¼:¼:¼6¼:¼6¼:6¼:¼66¼6¼6¼:¼:¼6¼6¼6¼6¼:¼6¼6¼6¼:¼6¼:¼:¼6¼6¼6¼6¼:6¼6¼6¼6¼6¼:¼6¼:¼:¼6¼:¼:¼6¼:6¼:¼6¼66¼6¼6¼::¼66:¼6¼:6¼6¼6¼:¼6¼6¼6¼6¼:¼6¼:¼6¼:¼:¼6¼6¼6¼:¼6¼:¼6¼:¼6¼6¼6¼6¼6¼6¼:¼6¼6¼:¼6¼66¼6¼6¼6¼6¼6¼66¼:6¼6¼6:¼6¼:¼6¼6¼66¼6¼6¼:¼:¼6¼6¼:¼:¼6¼:¼6¼6¼6¼6¼6¼6¼:¼:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼:¼6¼6:¼6¼6::66¼6¼6¼6¼66¼66¼:¼6¼666¼6¼:¼6¼66¼6¼:¼666¼::¼6¼6¼:¼66¼:=S¾oÿ{ÿ\x7fÿ\x7fßw=W¼:¼6:¼6¼6:6¼6¼6¼6¼6¼6¼6¼:6¼:¼:¼6¼:¼6¼:¼6¼:666¼6¼6¼6:6¼6¼6¼66¼:¼:¼:¼6¼6::6:¼66¼:¼6¼:6¼:¼66¼66¼:¼:¼6¼6¼6¼66¼6¼:¼6¼:¼::¼6¼6¼66¼:¼:¼:¼6¼6:¼:¼6¼:6¼::6¼:¼6¼:¼:¼6¼::¼:6¼6¼66:6¼:¼:¼6¼6¼66¼:6¼6¼:¼:¼6¼6¼66¼6:¼66:¼:6¼:¼6¼6¼6¼66¼6:¼6¼6¼6¼6¼66¼6¼:¼6¼:¼:¼6¼6¼6¼6¼666¼6¼6¼6¼:6¼6¼6666¼6¼:¼6¼:¼:6¼6¼6¼66:¼:¼6¼6¼6¼66:¼6¼6¼6¼6¼6¼6¼6¼:¼6¼6::¼:¼666¼6¼666¼6¼6¼666:¼6¼66:¼:¼6¼6¼6¼66¼6¼66¼6¼:¼:¼6¼666¼:6¼6666:6:¼6¼6Ü>~cÿ{ÿ\x7fÿ\x7fÿ\x7fß{\x1dS¼::6¼6¼:¼:6¼:¼666:¼6¼66¼66¼6¼:::¼6:¼:6¼6¼:¼6¼:¼6¼6:¼::¼:66¼6¼6¼6¼66¼66¼6:¼6¼:¼6¼:66¼:¼:6¼6¼66¼6¼6¼6¼6¼66¼:¼:6¼6¼::66¼:¼:¼6¼6¼666¼66¼:6¼:66¼6¼6¼:¼666::¼6¼66:¼6¼6¼::¼:666¼:¼:66¼66:6¼6¼6666666¼:6¼6¼666666¼66¼:¼666¼:¼66:¼6¼6¼6¼:¼::¼:¼6666:¼66¼:¼6¼66¼6¼6¼6:¼:¼6¼6¼6:¼:66:¼6¼6¼666¼:¼666¼6¼666¼:¼:666¼6:6¼66¼66¼6¼666::666¼6:66¼666¼6¼6¼::::66:¼:66¼6::¼6666Ü>kß{ÿ\x7fÿ\x7fÿ\x7fßw\x1dS¼:6:6¼6¼666:¼666:::¼6¼:66¼:6666:6::¼6:¼6::¼66:66::66:6:¼66¼6¼6666::6:6¼66::¼66¼66:66:6:¼::66:6666666¼:¼666::66¼6:¼:66666666¼666::6¼6:6:6666¼::¼66:::::66:66¼6¼666666:6666¼66:66666666:¼6666¼:¼666¼::66¼6:¼66666¼6:¼6:¼::666¼6¼:::¼::666¼:¼6¼:¼:66::¼:6:6666¼6¼6¼:6::6:66:::6::6:¼6666:66:¼6\x1dSßwÿ\x7fÿ\x7fÿ\x7foÝB:66666:66:666:¼666:666:¼:66666:::::6¼::6:66¼6:666:6:6¼66:::6:::66:6:66¼66:66:66::6:6¼6¼66¼:6::666::6¼:6::6¼666::6¼6:6666666:6:6:6¼66::666¼:6:¼66:66:6¼66:¼6:::6666¼:6:6:¼:66:66¼6:66666::6::6:6::6¼::66:66¼6¼6:666666:6:66::::6666:6:6666666:666666:66:6:66:6666¼>~cÿ\x7fÿ\x7fß{^_¼>666:6666666::666:6:6::66666666::66::6:6666:66::6:66666:::6666::6:6666::6::66::::66:6666::6:::66666666666::6666:66:6666666:6:::6::66666666666:66666:66666:6::6666::66::666:::666666::66::66:666666:6666::666:66::6:66666::6::666:6666:66:6¼:\x1dSßwÿ\x7f¾oÝF:6:6666:6:66::66:66::6:6666:66:6::6:6:::6:66:::66:6::::66666666:66:6666:66:666:666666666::6666666:66::66:6:666::66::666::666666::6:66666:6:6:6666:6666:6:66:666:66666666666666666:6:66::6:::6:6:6:6::6::66:::666:6666:66:666666:6::66:6666:ýF~go=W::6::::6:::6666:6:66::6:666:666666:66:66:66:6:6:6:66:66666:::666:::6:6:6666:6:6666:6666:66::666:6666:666666::66:::6666:::66:6::666:6:66:6:666::6666:66666:66:6666666:66:66666:66:66:66:6:6:66:66:::666:66:666666666:66:66:::6:6::666::6::6::6ÜFýJ6666:666:6:666::::::::::6:6:66::6:66666::6::::666::666:66666::6666:::666:6:66666:66:::66666:6:6:666666:666666::6:666666:6:6666:666::66:666::6:6:66666::::6:6:6::66:6:6666::6::6:6666:6:666666::6::6:66:::666::::66::6::6:::6:66666666::66:6:666:::::66:66:6::6:6:6666:6:66::66666::66:666:66:::::666666666:6:666:66666:666666:666:66:66:666:6666::666666::6666666:6:::66::6:66:66:6:::6::66:6:::6666:666:6::666:6:66:6::::6::6:666::66:::66:6:666:6:6::6:6:6:6666:66666:6666::66:6:6:6:66666:6:6:6666::6::::6666:6::66666:::6666:6666:6:::66666:6:66666::66::66:66::6:::666:6:66:66::66:66::6666:::6::66::666666666:6::66::6:6:66::66:666:6:666:6666:66:6:6666::6:66:6:6:::6:6:666:6:::66::66::66666::6:::666::6:6:66:66::6:6:66:66:6::666666666:6:66:6::6:6:666:::66666:666:6666::66666::66:66:6:6::6666::66:::6666666:66666:6:66:66::66::6:::::6:666666666666:666:6:6666:::::66:::66666:6::66::66666:::66:66:66:66666666:6666::66::66:66::66:66:66:::::6::666:6666:66:6:6666666::::666:66:66:666:66:666:66:6:6:66:66:66666::6:6::6:666:666::6666::666666666:666:6:66:666:6:::6::66666:66:::66:6:6666::6:66:::6666:6666666::66666:6::6:666:66666:6::66666::6666:66:::::6:::::6:6::66:6666:6666:66:6:666:66:666666:66::6:66::6:66:66::66:6:6::::666:666666:::6666:::6:66:6:6:666:6:666:6:666:666::6:6:::66:66:6:::6:666:6666:666::66:66:666:666666666:6:66:6:666::6666666:6:::66::66666666666666:6:66::::6:6::6::66666666:6::66:6:6:66:66:::66:6666:66:66::6::66::6::::6666:6:6::::6::::66:6:66:666::66666:6::6:66::6:6::66:6666:6:66:66::6::666666:666666::6:6:66666:6::66666:6:666666::66:666::666666:66:::6::6:6::6:66::66::666:::6:6::6666666666:666:66:6666:6:6666::666:6:66:666:6:::6666:6:::666666:66:66666:6:6::666:66666:6:6666666666:::66::6666666666:66::6666666:::6:6:6:666::6:6::6:6666:6::666:6::6:666:6:6666:6::6:66:::66::666:666:66::666::::6::6666666::::666:66:666::6666:6:6:6:66666666666:6::6666:6::::66::666:666:666:66666::6:66:6::666:6::66:6666:6666:::66:::66:66:666:::66::666666:::66::6:::66666:6666666:6:6:6:6:6::::6:6:66:66::666666:66:666:::::6:666666:66::66::::6:6::66:66:6:66::::66:6:::666:6::6:6:6::::666666::::6:66666666:6:6:66666::6:6:6:6:666::66:::6:6666:6::66:66:::::6::66::::::6:6:::6::::6:666:::666::6:66:6::66666:666666666::666666666:::666::66666:6666666666666::6666:6:66::66:6666::6666:66:6:666:66:66::66666:6:666666:::6:6666:6::66:66::6:666:::6::666666666:66666::66:66:6::6:6:66::::6:6::6666:66666::6:666:666666::::6:66:::66:66:66666::6:6:66:6::6:66::6:6:6666::6::6:6::6666:66:666:6::6:6666::66666::66666::66:66666:66666:6:::6:6666:::6666::6:666:::::666::6666:6::66::66:6:666:66666:6:6:6666666:6:6::6::::66:666::6:66:666666:66:66:666:666:::6::6:6:::66:66:6666:::66:6:6::666:::666666:6::6:6:6::6:66:66:6666:66:6666:6:6::6666:66:::66:66:66:66666:6:66:::66:6:6:666::6::6:66::::6:::666:666::6:::66:66::66::::66:666:666:::6:6:6666::::66:66::66:66666666:66:66::666666:66666:66666:::::6::::666:6::6666:6::66:::6::66:666:6:66:66:66:6::6:::6:66:66:6::::6:6::6:6:66666::6::66:6:6:666:6:::666:6:6::::::66::66::666666666:66:6:666:6:6:6::66:6:6:6:::666:666::66:666:::66666:6:66:::::666::6666:666:666::6:66666:6666666:6:6:66:6::6:::66:6:::::666::66666:666:6:6::::6::6:6666::6:::6::66::66:66::6666666:6:6:66666:6:66:66::666::6:6:6666::::6:6:6::6:666::::666::66:6::::6::66::666::66::66:66:666:66666666:6666::66:::6::::66:6:666:66::::6:6:66666:6:66:::66::6:6:::666:66:6666::66:::6:6:::6666666::6:66:6666:666:6:::6::6:666:6:66::::666:666::::::6:6::6:::::6::66::6:6:66:666:66666::666:6666:6::6:6:::6::6:66:6:66:666:6:666::6:66:::66:666:6:66:::666:::6::6:666:::6:66:::6:66:6::66:666::::6::6:6:6:666::666:6::6::6::66:66:66:6:6::::6:66::6::66:6::6::66:66666:6::6::666666666::66::::::666:6::66:666666:6:::666666666:66:6:6::6666::666666::6::66:66:66::6:666::6:::66:666:6:6::6::6:66:6:6:66:6::6:66:::666::::66666:66:66:666::666:6:::6:6666:66666:::6:6666:66::6:::6666:666:66:66:66:6666:::6666:666:::::6:6:66:6:6666:66:6:66::6:6:6:6:::666666:::6:6:::6666:66:666666:6::::6::6:6:::6666:::::6:6:6:6666::66::66::66666:6:666::6::::66:66:66666:6::66::66666:::::6::66:::666:::::66:6:::66:66:::666:6::6::6::6:6::66:6:::::::6::6::6666::6:6::66::6::6:666:666666:6:66:66:6:66:6:6:::6:666:66:::::6::::6:::6::6:6:6:66:::6::::6:::66666::::::::6:66:6:666::6:::6:6::6:6:666:6::666::6:6:666:::66:6:666:6::6:6::::6666::6::::::6666:6:666:66:::66:66::66:66:6:666:::6::666::666666:::6::::::6666::6:6666:666:6:6666:6:6:6::::6666:6666:66:::666:666:::66:::66:6::6::::6666666:6666::66:6:66::66:66:66666::6:6::6::::6666:6:6:::6666:::::6::6666666::66:6:6666:666:::6:6:666::::6666:66:::::6:666::::66:6:::666666:6:::66:66:6:6::6:::666::::::::66:::6:::66::66:66:6666::::6:66:666::::6:::6:::66:6:6::6666666:66:::::66::::::::::::::6:66::::::6666:666:66:666:::::6:6:::66::6:::::666666::6::6666:6:666::66:6::::6:666::66:::6:666:6666::66::6:666:66:::666:::6:66::6:::6:66:66::::::66:666:6:::666::6:::6:6:::::6:::6::6:666::::::6:66:::::66::6::::66:::66:6:::::6:66::::6:66:::666:66:666:6666::6:6:666:6666:::66:::6:666:::66666:6:::666::6666::6:::66666:66::6:6:6666:66::6:6:66::6:6:666::::666:::66::6::66666:6:6::66:66:::66:6:::666::::::::6:6:6:66:6666::6:6:6::6:6:6666:::66666666::6:::66::6:6:66:666:::6:66:6::6::666::66:::::6:6::6::66:6:6:66666:6666:666::::66::666:66:6:::6:6:::666:6:666::::66:::66:::6:6:6666666:6:666:6:::6::6:6:::6::6:66:6:6::::666:6::::6:6::666:6:6:6666::66:66::66::6:6666:::66:6:66:66:::6:6666666666:::6:::66:::6::::6:6666:6:66666::6::6:::66::6666:::::666:666::66666::666:::::6:::6:666:::6::6:::6666:::666:6:66:6:6::6:::6:::66:6:6::::6666:666::6::::::::6:::6::6:6:666::6:6:6666:6:6::6::6:6::66:::6:666::::6::6666:6:6:::6:66::66:666:6:66:6:66:66:66:6666:::::6:666:6:::66:6:6::66:66:::::66:66::6:6:66:6:66:6:66:66:::666666::6::6:6::6::66:66:6:::66:::66:6:666:66:6::6666::6:66::666:6:::6:::6:6::66::6:66666::::::66:6666:6:6:6:6::6::6:6:666::6::::6:66:6:::6:::6::::6:::::666::6::::66::6::666:::6:::::::6::6::::66::::::66:66::::::::66::66:666::6:::6:6:666:66666::66:6:666:6:::6::666666:6:6:::6:66:66666:6:666::6::66666::6666666:::6:6:666::::6::::66:6:::6:::6:666:::6::::::66:::66::::::6::6::::6:6::6:6:::6::6:6:::::6:66:6666:::::66:6::6:6::66:6::::6:::::666:6::6666:666:::66:6:::6:::::6::::6::::::6:66:::666:6::6:6::»B»B»B:::6:666::::::66:::6::6:6::6:6::::6::::6:6:6::6:66::::::66666:666:6:666::6666:66:::6::66::6:6:66666666:6:6::6666:666:66666:::6:6:6:66:6:66::6:666:::6666:666:6:::::6:666::6666:66::6:6:666666:6666::6:::666:::::666:66666:66666:::6::66:::6:»B]_o}cüN»>:::6::6::::6:66666:6:::::666:666:6::6:::66:::::6:6666666:6:::6:66:6:6::66::6::6::6::666:::6::6:66:66666666:66::6:66:6:::::66:6:6:66:6666:::::6:6:::666:6:6:66::6::::::::::::666:6:::66:66:666:6666::6::666::::6:666:::::66:66:666:::6:6:6:\x1cSÞwÿ\x7fß{ßw]_»B>::66:6:6:6::66::6::66:::66:::6:::6:::66:66::6666:::6:66:6:66::666:::::66:66::::::66:6666::6:::::::6:66:::::66::66:::66666:::::666666:666666:6::66:::6::66::6::6:66666:6::66:66:::6::666:::6:6:::666::66::66:::::6::6:6::6::6666:66::::::=[ÿ{ÿ\x7fÿ\x7fÿ\x7fß{kûJ>66::6::666:6::666:6:::::666::6:6:::6::::::6:66::::66:::6:666::6:::66:::::6::::66:66:::66666::666::66:::6:::6::6::6666:6:66::6::::6:::6:::::6::::::6::6:::6:6::666:666:6::6::66:6:6:6:::666:6:6::::::6:66:::6:6:6:6::::666::6:6:66::::::=[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{k\x1cW>:::666666:6:6:666::666:::6:::::66:6:66::6:66:6:6::::6:::6:6z6:6z:666::z:::6:6::::66:z66:::z:z:6::66:6:666:::z666:z::6:z:::z6:z:6:66z66::66z:6z6:z:::6::z6:66:z::::6:z6:::66:6:6:6:666z6:z66:66::6:::66:6z6z6::::::::::z6:66:6:z:6:6:z:6:6:6z66666:666z6666666z6:::\x1cWßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{¾o\x1cW::6::z:z6:z6::::z:6:6:6::::::::::66z:z:z::6z666::6:z::66z666z6:6:6z:::z66z6:z::z::66z:::z:z6z:6:z6z66z6z6z:66:6:6::6:z6z6z6z666z6:z:z:z6z::z6z:66z::z:z6:z6:z::z::z6:::66z:z:z::z6::z:6z:z66::z6z6z::z6:z6:666z6:6:z:z66z66:z:::::z6:z6z:z6z6z66z:z:z:z6:6z6z6:z::z:z:6:z:z::z6z::z:z6z:z6z6::::z6::z666::z6z6z:z66z66z66:::z::z66::ûJßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}g»B:66z6z:6z6:z66z666z6z:z6:::z66:6z:z6:::6:z:6:z:6z:z::6:6::6z66666:6z6z6:z6::z:z6z::z6z6z6:z:::6z:z:6z6z:z6z::z:z:z:z:z::z6z:z6z:z66::::6:z6z:6:z:z::::z:z:6z:z:z6:z:z::z:z:z:z:6::z6z6z6z:z::z:z:z66:6:z::z66z::::z6z66z6:z:z66z:z:z:z6z:z6z6:z:z:66:z:6z6z::z6z6666z6:z6:::z:6z::z:z:z::66::z6z:z:z::z:z:z6z:z:z6z6z:z6z:6z:::6z::z::::z:z:z6:z:6::::z6:»Fkÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f}k>z6::z:z6z:z6z:6z6z:z6z6z6z6:::z:6z:z6z6:6z6z6:::z66z6z6z:6z6z:z6z::z:z:z6z66z:z6z:z:z::z6z6z6z6z:z:z:z6z6:z:z6z6z:z::z:z:z:z::z:z6z6z:z6z6z6z:z::z6z:z:z6z6z6z6z:z66z6z6z6:z:z:z:z:z6z6z6z66z6z6z:z:z:z6z:z:z:z:z6z6z66z6z6z6z:z6z:z:z6z66z:z6z:z:z6z::z6z6z6:z6z::z6z:z:z:z6z6z:z:z:z:z:z:z:6z6z:z::z6:z:z6z6z6z:z6:6z6z6z:z666:z6z6z6:z:z6z6z:z:z:z6z6z6z:z6::z6z:z66z:z:z66z:z6z:z:z:z:z:z:z6z6z:z6z6z:z:z:>:>::z:z:z::>=[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{]_>>ÛF>>:z:z:z6:z:z6z6z6z::z6z:z:z:z:z:z:6z:z:z:z:z:z:z:z:z6z6z:z6z:z:z:z6z6z6z:z:z:z6z:z:z6z6z:z:z:z:z66z6z:z:z6z:z:z:z6z6z:z:z:z:z:z:z:z6z:z:z:z6z:z:z:z:z6z:z6z6z6z6z:z:z6z:z:z:z:z6z6z:z:z:z6z:z:z:z:z6z6z:z:z6z:z6z:z:z6z6z6z:z:z:z:z:z6z:z6z6z:z:z:z6z:z:z:z:z:z:z:z6z6z:z:z6z6z:z:z:z6z6z:z6z:z:z6z:z6z:z:z6z6z:z:z:z6z:z6z6z:z:z6z:z6z:z:z6z6z6z:z6z:z6z:z:z6z:z6z:z6z:z:z:z:z:z:z:z:z:z6z:z6z:z6z:z:z:z:z:z6z6z:z6z:z6z6z6z:z:z:z:z6z6:»F<W}c}c\x1cW»B>z:z6z::ûJ¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞw<WûJ}ck}g\x1cS>z6z:z:z6z:z:z:z:z6z:z6z6z:z:z6z6z:z:z:z6z:z:z:z:z:z:z:z:z6z:z:z6z:z:z6z:z6z6z6z:z:z6z:z:z:z:z:z:z:z:z:z6z6z:z6z6z:z6z:z6z:z6z:z:z:z:z:z:z:z6z6z6z:z:z:z6z6z:z:z:z6z6z6z6z:z:z:z:z:z6z:z6z6z:z:z6z:z:z6z:z:z:z:z:z:z6z6z:z6z:z:z6z6z:z:z6z6z:z:z6z:z6z6z6z:z6z:z:z:z6z6z6z:z6z6z:z:z:z:z:z6z:z:z6z6z6z6z6z6z:z6z:z6z:z:z6z:z6z6z:z6z6z6z6z:z:z6z:z:z6z:z6z:z:z:z:z6z:z:z:z6z6z:z6z6z:z6z:z6z6z:z6z:z:z:z:z6z6z:z6z:z6z6z:z:z:z:z6z:z6z:z6z::\x1cWÞwÿ\x7fß{ßwk=_ÛF::»B»Bkß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÞw}cÞwßwÿ{ÿ{¾o=[»B:z:z:z:z:z:z6z6z:z6z6z6z:z:z:z6z6z:z6z:z6z:z6z:z6z:z6z6z:z6z:z:z6z6z:z6z:z6z:z6z6z:z:z6z:z:z:z6z:z:z:z6z6z:z6z6z:z6z:z6z:z:z6z6z6z6z:z:z:z6z:z:z:z6z:z:z:z6z6z:z6z:z:z6z6z:z6z:z:z6z6z:z:z:z:z:z6z:z:z6z:z:z:z:z:z:z6z:z6z6z6z:z6z:z:z6z6z:z:z6z6z:z:z:z:z6z6z6z:z6z6z6z6z:z:z:z:z:z:z6z:z:z:z6z:z6z6z6z:z:z6z:z:z:z:z:z:z:z6z6z6z:z:z:z:z:z6z6z:z6z:z:z:z:z6z:z:z:z6z:z6z:z:z6z6z:z:z:z6z:z:z6z:z:z6z:z:z:z:z:z:z:z6z:z:z6z:z:z:z6z:z:>]_ß{ÿ\x7fÿ\x7fÿ\x7fÿ{ß{k\x1cS»B\x1cS}c<[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ{Þw]_ÛF:z:z6z:z6z6z6z:z6z6z6z:z:z6z6z:z6z:z6z6z:z:z:z:z:z:z:z6z6z6z6z6z:z:z6z6z:z:z6z:z6z:z:z6z6z:z6z6z:z:z:z:z:z:z6z:z:z:z6z6z:z6z6z6z6z:z:z6z:z:z:z6z6z6z:z6z6z:z:z:z6z6z6z6z:z:z:z6z6z:z6z6z:z6z6z:z:z:z6z:z6z6z:z6z6z:z6z6z:z:z:z:z:z6z6z:z6z:z6z:z6z6z6z:z:z:z:z6z:z6z6z6z:z6z6z:z6z:z:z:z:z:z6z6z6z:z6z6z6z:z:z:z:z6z:z6z:z:z6z:z6z:z6z6z:z:z:z:z:z6z6z:z6z6z:z:z:z:z6z:z:z:z:z:z:z:z:z:z6z:z6z:z:z:z6z:z6z:z6z6z6z:z6z:z6z:z:z6z:z:z::\x1cWß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾s]_<[}goßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ß{kûN:z:z:z:z:z:z6z:z:z:z:z6z:z6z:z:z6z:z6z:z6z:z:z6z6z6z:z6z:z:z6z6z:z:z:z:z:z:z6z:z:z6z6z6z:z6z:z6z:z6z6z:z:z:z6z:z:z:z:z:z:z:z:z6z6z6z:z6z:z:z6z:z:z6z6z:z:z6z:z:z:z:z6z:z6z6z:z:z6z6z:z:z6z6z:z:z:z:z:z:z:z:z:z6z6z:z6z:z6z6z:z6z6z:z6z6z:z6z6z:z:z:z:z:z6z:z6z:z6z:z:z:z:z:z:z:z:z:z6z:z6z:z6z:z6z:z6z:z:z6z:z6z6z6z:z:z:z:z6z:z6z6z:z6z6z6z:z:z6z:z:z:z6z:z:z:z6z6z6z6z:z:z6z:z6z6z:z:z:z:z:z:z6z:z:z:z:z:z:z:z6z:z:z6z:z:z:z:z:z6:ÛF¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{ooßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾wÛF:z:z6z6z6z:z6z6z6z6z:z:z:z:z:z:z:z:z:z:z6z6z6z:z6z:z6z6z:z:z:z:z6z6z6z:z:z:z:z6z:z6z6z6z6z:z:z6z6z:z6z:z6z6z6z:z:z:z:z6z6z:z:z:z:z:z6z:z:z6z:z6z6z6z:z:z:z:z:z:z:z:z:z6z:z:z:z:z6z:z:z6z:z:z:z:z6z:z:z6z:z:z:z:z6z6z6z:z:z:z:z:z:z:z6z:z:z:z:z:z6z6z6z6z:z:z:z:z6z:z6z:z6z:z:z:z:z:z:z:z6z:z:z:z6z:z:z:z6z:z:z:z:z:z:z6z6z6z6z:z:z6z:z6z:z:z6z:z6z6z6z:z:z:z:z:z:z6z6z:z:z:z:z6z:z:z:z:z6z6z:z:z6z:z:z:z:z:z:z:z:z6z:z:z6z:z6z6z::ºB]_ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fk:z6z6z:z6z6z:z:z:z:z6z:z:z:z6z:z:z6z:z:z:z:z:z6z6z6z:z6z6z6z6z6z6z6z6z:z6z6z6z:z:z:z6z:z:z:z:z:z:z6z:z:z6z:z:z6z:z6z:z:z6z6z6z:z6z:z:z:z6z:z:z:z:z:z:z:z6z:z:z:z:z:z6z:z:z:z:z:z:z:z:z:z:z:z:z:z6z:z6z6z:z6z6z:z6z:z:z6z:z6z:z:z6z:z:z:z:z:z6z:z:z:z6z:z:z:z:z6z:z:z:z:z:z:z6z:z:z:z6z:z:z6z6z6z6z:z:z:z:z:z:z:z:z:z6z:z:z:z:z6z:z6z6z6z6z6z:z:z:z:z:z:z:z6z:z:z:z:z:z:z:z6z:z6z:z6z:z:z:z6z:z:z:z:z:z:z:z6z6z:z:z:z6z6z:z:z6z6z6z::\x1cS¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{ß{ÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{}gºBz:z:z:z6z6z6z:z:z:z:z6z:z:z:z6z:z:z:z6z6z:z:z:z:z:z6z6z:z6z:z:z:z:z:z:z:z:z:z:z6z:z:z:z:z:z:z:z:z:z6z6z:z:z:z6z6z:z6z6y6z:z:z:z:y:z:z:y6z6z:z:z6z:z6z:z6z:z:z:z:z:z:z6z:z:z6z:z:z6z6z6z:z:y:z6z:z:z:z:z:z6y:z6z:z:z6z:y:z6z6z6z:z:z6z6y:z6z6z:z:z:z:z:z:z6z6z6z:y:z:z6z:z:z:z:z6z:z6z:z6z6y6z6z:z6z:z6z:y6z:z:z6y6z:z:z:z6z:y6z:z6z:z6z6z:z6z:z:z6z:z:z:z:z:y:z6z:z:z6z:z6z6y:z6z6z:z6z:z6y:z6z:z:z:z:z6z:z6z:z:z6z:z:z:y:z6z:y:z:z6>}gß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾s}g<_oÞwÿ{ÿ{ÿ\x7fÿ\x7fÿ\x7fß{ß{Þw¾s]cûNz:z6z6z6z:z:z6z:z6z:y6z6z:z6z:z6z6z:z6z:z:z:z:z6z:z:z:z:z6y6z6z6z6z:z:z:z:y:z6z:z:z:z:z6z:z:y:y6z:z:y:y:z:y:y6z:y:z:y6y6z:z6z6y6y:y:y6z:y6y6y6z6y6y:z:y6y:z:y:y:z6y6y:y:y6z6z6z:y:y6y:y6z:y:y:y:z:z:z:z6z:y:z:y:y6y6y:y6y:z:y6y:y6y6z:y:y:z:y:z:y:y6z:z6y:z:y6z:y:z6y:z:z:y:y6y:y6y:y6y:z6z6z6y:z:y:z:z:y:y6y:y:y6y:y:y:z6y6y:y:y:y:y6z:y:z:z6z6z:y6y:z:y6z6y:z:z6z:y:y6y:y:z:z6z6y:z:y6z6y6z:y:y:y:y6y6y6z:z6y:y:z:z:y6y6z6z6y:y:y6y:z:ÛJßwß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{kûNºBÛJûN<_}ko¾s¾s}g\_\x1cSºFz:z:y6y:z:z:y6y:y6y:y:z6z:z:y:z:y:z:y6y:y6z:y:z6y:y6y:z:y6z:z:z:y:y6z6y:z6z:y6y:y:z:y:y:z:y:z:y6y:y:y:y6y:y6y6y:y:y6y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y:y6y:y:y6y6y6y:y6y:y:y6y6y:y6y6y6y:y6y:y6y:y:y6y:y:y:y:y:y:y:y:y:y:y6y6y6y:y:y6y6y6y6y:y6y6y6y:y6y:y:y6y6y6y:y:y:y:y:y6y6y:y:y:y:y6y:y:y:y:y6y:y:y:y6y6y6y:y:y6y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y6y:y:y:y6y6y:y:y:y:y:y6y:y6y6y:y6y:y:y:y:y6y6y:y:y:y6y6y6y6y:y:y:y:y:y:y6y:y:><[¾sß{ß{Þwß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ{}kÛF::>ºBºBºF»FºBºB>z:y6y:y6y:y6y:y:y:y:y:y6y6y6y6y:y:y6y:y6y6y:y:y6y6y6y6y:y:y6y:y:y:y:y6y6y6y:y:y:y:y6y:y6y:y6y6y:y:y:y:y:y:y6y:y:y:y:y:y6y6y:y6y6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y:y:y6y6y6y:y:y6y:y6y6y6y:y:y:y:y:y:y6y6y6y:y:y:y:y6y:y:y:y6y:y:y:y:y6y:y6y:y:y:y:y:y:y:y6y6y6y:y:y:y:y:y:y:y6y:y6y6y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y6y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y6y:y6y6y:y6y:y:y:y6y:y:y:y6y:y:y:y:ºBûNûRûN<[}kÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛF:y6y:z:z:y:y:y:y:y:y:y:y:y6y:y6y:y:y:y:y:y:y6y:y6y:y6y6y:y6y6y:y:y6y6y:y6y6y6y:y:y:y6y6y6y:y:y:y:y6y:y:y6y:y6y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y6y:y:y:y:y:y6y6y6y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y6y:y6y:y6y6y:y6y6y6y:y6y:y6y:y:y:y:y:y:y:y6y:y6y6y6y6y6y:y:y:y6y6y:y:y6y6y:y:y6y6y6y6y:y:y6y:y6y:y:y:y:y6y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y6y6y6y:y:y6y6y:y:y:y6y6y6y:y6y6y:y:y6y:y:y6y:y:y6y6y6y:y:y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y:y6y:y6y6y:y:y:y:y6y:y6y6y:y6y:y:y6:y:ºB\_ßwÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛJ>y:y:y6y6y:y:y:y:y:y6y6y6y6y:y:y6y:y:y:y6y6y:y:y6y6y6y6y6y:y6y:y6y:y6y:y6y6y:y:y6y:y6y6y:y6y:y6y:y:y6y:y:y6y6y6y:y:y:y:y:y6y:y:y6y:y6y6y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y6y:y:y:y:y:y:y6y:y:y6y6y:y:y:y:y:y6y6y:y6y:y:y:y:y:y6y:y6y:y:y6y6y6y6y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y6y6y6y:y6y6y6y:y:y6y6y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y6y:y:y:y6y:y6y:y:y:y:y6y:y:y:y:y:y6y6y:y:y:y6y6y6y:y:y6y6y:y6y6y6y6y6y:y:y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y6y:y:y:y:y:><[¾sÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sûN>y:y6y6y6y:y:y:y:y:y:y6y6y6y:y:y:y:y:y6y6y6y6y:y:y:y:y:y:y:y6y6y6y:y:y:y6y:y:y:y6y:y6y:y:y6y:y:y:y6y:y6y:y:y6y6y:y:y6y:y6y6y:y:y6y:y6y:y:y:y6y:y:y6y6y:y:y6y6y6y:y:y:y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y6y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y6y6y:y:y6y:y:y6y:y:y:y6y:y6y:y6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y6y:y6y6y:y6y6y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y:y6y:y6y:y:y:y:y:y6y:y:y6y:y:y:y6y:y:y:y:y:y6y6y6y:y6y6y:y:y6y:y:y:>}kß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛJy:y:y6y6y6y:y:y:y6y6y:y6y:y:y:y:y:y6y:y:y:y:y6y:y:y:y6y:y:y:y:y6y:y:y:y6y6y6y:y:y:y:y6y6y:y:y6y6y:y:y:y6y6y6y:y:y:y:y:y:y:y:y6y:y6y:y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y:y:y:y:y6y6y6y:y6y:y:y:y:y6y:y6y:y:y6y:y:y6y6y6y:y:y6y:y:y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y6y6y:y6y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y6y:y:y6y:y6y6y:y6y6y6y:y:y:y:y6y6y:y6y:y6y6y6y:y:y:y:y:y6y:y6y:y:y6y6y:y:ºB}kß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛJy:y:y:y6y:y:y:y:y:y:y:y6y6y6y:y6y:y6y:y6y:y:y:y6y:y:y6y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y:y6y:y:y6y:y6y6y:y:y:y6y:y:y6y6y:y:y:y6y:y6y6y:y:y:y6y:y:y:y:y:y:y:y6y6y6y6y:y:y6y:y:y:y:y6y:y6y:y:y:y6y:y:y6y:y:y:y:y:y:y:y:y:y:y:y6y6y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y:y:y:y6y6y6y:y6y6y6y6y:y6y6y6y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y6y6y:y:y:y6y6y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y6y:y:y6y6y:y:y:y:y:y6y:y:y6y:y6y:y6y:y6y:y:y:y6><[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fÿ\x7fkºBy:y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y6y6y:y:y:y6y:y:y6y:y6y6y6y:y:y:y:y6y6y:y6y:y:y:y:y6y:y6y6y:y:y6y6y:y:y6y:y:y6y:y:y6y:y:y:y:y6y:y:y:y6y:y6y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y6y6y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y6y6y6y:y:y:y:y6y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y6y6y6y:y:y6y6y:y6y:y:y6y:y:y6y6y:y:y6y6y:y:y:y6y:y:y:y:y6y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y6y:y:y:y:y6y6y6y:y:y:y6y6y:y6y:y6y6y:y:y:y:y6y:y6y:y:y:y6y6y:y:y6y6y:y6y6y:y:y:y6y:y:y6y6y:y:ÚFoÿ{ÿ\x7fÿ\x7fÿ\x7fÿ\x7fß{<[:y:y:y6y:y6y:y6y:y6y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y6y:y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y6y:y6y:y:y:y:y6y:y:y6y:y:y:y6y:y:y:y:y6y:y:y:y:y6y:y6y6y:y6y:y:y:y:y:y:y6y:y6y:y:y:y6y:y6y:y:y:y6y:y:y6y:y6y:y:y:y6y:y:y6y6y6y:y6y6y6y:y:y6y:y:y6y6y:y:y:y:y:y:y:y6y:y6y6y:y:y:y:y:y6y:y6y:y:y:y:y:y6y:y:y:y6y:y6y:y:y:<[ß{ÿ\x7fÿ\x7fÿ\x7fÿ\x7f¾sÛNy:y:y6y:y:y:y:y:y:y6y:y:y6y:y:y6y:y6y:y:y6y:y:y6y6y:y:y:y6y:y6y:y:y6y6y6y:y:y6y:y6y6y:y6y6y6y:y:y:y:y6y6y:y:y6y:y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y6y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y6y6y6y6y:y6y:y:y6y:y:y:y6y:y:y:y6y6y:y:y:y:y:y6y6y:y:y6y6y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y6y6y6y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:ºB¾sÿ\x7fÿ\x7fÿ\x7fÿ\x7f\c>y:y:y:y:y:y:y6y6y:y6y:y:y6y:y:y:y:y:y:y:y:y6y:y:y6y:y:y:y6y6y:y:y:y:y:y:y:y6y:y:y:y:y6y:y6y:y:y6y6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y6y:y:y6y:y:y:y:y6y:y6y:y:y:y:y:y:y:y6y6y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y:y6y:y6y:y:y:y6y:y:y6y6y:y6y:y:y:y6y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y:y:y6y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y6y6y6y:y:y:y:y:y:y:y6y:y:y:y:y:B\cß{ÿ\x7fÿ\x7f¾wÛJy:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y6y6y:y:y:y:y:y:y6y:y:y:y:y:y:y6y:y6y:y:y:y:y6y:y:y6y:y6y:y:y:y6y:y6y6y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y6y:y6y6y:y:y:y6y:y:y:y6y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y:y6y6y:y:y6y:y:y:y6y6y:y:y:y:y6y:y:y:y:y:y6y6y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y6y:y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y6y:y6ûRoß{¾w<[By6y:y:y:y6y:y6y6y:y:y6y:y:y6y6y:y:y6y:y:y:y6y:y6y:y:y:y6y6y6y:y:y6y:y6y:y6y:y6y:y:y6y:y:y6y6y:y6y:y:y:y:y:y6y6y:y:y6y:y:y:y6y:y6y:y:y:y:y6y6y6y:y:y:y:y6y:y6y:y6y:y:y:y:y:y6y6y:y6y:y:y:y:y:y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y6y6y6y:y:y6y6y:y:y6y:y6y:y6y:y6y:y6y:y6y:y6y:y:y6y:y:y:y6y:y:y:y6y:y:y:y6y6y6y:y:y:y6y:y:y:y6y:y:y:y:y6y6y6y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y:y:y:y:y6y:y6y:y:y6y6y6y6y6y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y6y:y:y:y6y6y6y:y:y:y:y:y:y:y:y6y:y:y:y:^[S\c\_y:y:y:y:y6y:y6y:y:y6y:y:y6y6y6y:y6y6y:y6y:y:y:y:y:y:y:y6y:y:y:y6y:y6y:y6y6y:y6y6y:y:y:y:y:y:y6y6y:y6y6y:y6y:y:y6y:y:y:y6y:y:y:y6y:y:y:y:y:y6y:y:y6y6y:y:y:y:y6y:y6y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y:y:y:y:y6y:y:y6y6y:y6y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y:y6y:y6y6y:y6y:y6y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y6y6y:y:y6y:y:y6y:y6y6y6y:y6y:y:y6y:y:y6y:y:y6y:y:y:y:y6y:y:y:y:y6y:y:y6y6y6y:y6y:y:y6y:y6y:y:y:>>y6y:y6y:y6y6y:y6y:y:y:y:y6y:y:y6y6y:y6y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y6y:y6y:y6y:y6y:y6y:y:y:y:y6y6y6y:y:y:y:y6y6y:y:y6y6y:y:y:y6y6y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y:y:y6y:y6y6y:y6y:y:y6y:y6y:y:y:y6y:y:y:y:y:y6y6y6y:y6y6y:y:y6y:y:y:y6y:y6y:y:y:y:y:y:y:y6y:y:y:y:y6y:y:y:y:y:y:y6y:y6y:y6y:y:y:y:y:y6y:y:y:y:y6y6y:y6y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y6y6y6y:y:y:y6y6y:y:y:y:y6y:y6y:y:y6y:y6y:y:y6y:y:y6y6y:y:y:y:y:y6y:y6y:y:y:y:y:y:y6y:y:y:y:y:y:y:y6y6y:y:y:y:y:y:y6y6y:y6y:y6y:y:y:y6y:y:y:y6y:y:y6y:y:y:y:y6y6y:y:y:y:y6y6y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y:y:y:y:y6y6y6y6y:y:y6y:y6y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y:y6y:y6y:y:y:y:y6y6y:y:y6y:y6y:y:y:y:y:y:y6y6y:y:y:y:y:y6y:y:y:y:y:y:y:y:y6y6y:y:y:y6y6y:y6y:y:y:y:y6y:y:y:y:y:y:y6y:y:y:y:y6y6y:y:y:y:y:y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y6y6y6y6y6y:y:y:y:y:y:y6y6y:y:y:y:y:y:y:y:y:y6y6y6y6y:y:y:y6y:y:y:y:y:y6y:y:y:y:y6y:y:y6y:y:y:y:y6y:y:y6y:y6y:y:y:y:y6y6y:y:y:y:y6y:y:y6y:y:y:y:y:y:y:y6y:y6y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:y:y:y:y:y:y:y:y:y6y:y6y6y:y:y:y6y:y:y6y:y6y6y6y:y:y:y:y:y:y:x:y6y:y:y:y6y:y:y:y:y:y6y:y:y6y:y6y:y:y:y:y:y:x:y:y:x:x:y:y:y:y:y:y:y6x:y6y6y:y:y:x:x:x:y:y:y:y6y6y:y:y:y:y:y6y:x:y:y:y:y:y:y:y:y:y6y:x6y:y:y:y6y:y:y:y:y:x:x:y:y:y:y:y:y:y:y:y:y:x6y:y:y:y:y:y:y:y:y:y:y6y:y:y:y:x:x:x:y:y:y6y:x:y:y:y:y:y:y:y:y:y:y:y:y6y:y:y6y:x:y:x:y6y:y:y6x:y:y:y6y:y6y:x6y:y:y:y:y6y:y:y:x:y:y:y:y:y:y6y:y:y:y6y:x:y:y:y:y:y:y:y:y:y:y:y:y:y:y:y6x:y:y6y6y:y6y6x:y6y6y:y:x:y:y:y:y6y:y:y:y6y:x:y6y:y:y:y6y:y6y:x:y6y6x:y:y6y6x:y:y6y:y:x6y:x:x:y:y:x6y6y:x6x:y:x:x:x6x:y:y:y:x6x:x:x:y:y:y:y6y:x:y:y:y:x:x:x:y:y:x:x:x:x:x:x6y:y:x:y:y6y:y:x:x:x6x:y:x:x:y:y6y:x:x:y:x:x:y:x:x:y6x6x:x:y6y:y6y:x:x:x:x:x:y:y:x:x6y:y:y6y:y:y6y:x6x6y:y6x:x:x:y:y:x:x6y:x:y:y:x:x6x6x:y:x:x:x:y:y6x:y6x:x:y:y:x:y:x6y:y6x6x:x6y:x6y:x:y:y:x:y6x6y:x:y:y:y:y6y:y:y:y:y6x:y:x6y:x:x6y6y:y6x6x6x:y6x:y:x6x:x:y:y:y:x:x6x:y:x:x:x:x6y:x6x:y:x6x:x:y:x:x6y:y:x:y:x:x6x:x6y:y6x:y:x:y6x:x:y:y:y:y:x6y:x:x:x6y:x:x:x6y6y6x:y:y:y6x6x:x:x:y6x6y:y:x:y:y:x6y6x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:y:x6x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x6x6x:x:x6x:x:x6x:x:x6x6x:x:x:x:x:x:x:x6x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x6x6x6x6x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x6x6x:x:x:x6x6x6x:x:x6x:x:x:x6x:x:x:x6x:y:x:x6x6x6x:x:x:x6x6x:x:x:x:x6x:x6y:x6x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:y:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x6x6x:x:x6y6x:x:x6x:x:x:x:x:x:x:x:x:x6x6x:y:y:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:y6x:x:x:x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x6x6x:x:x:x:x:x:x:x:x:x:x6x:x6x6x6x:x:x6x:x6x:x:x6x:x6x6x:x:x:x:x:x:x6x6x:x:x:x:x:x6x:x6x6x:x:x:x:x6x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x6x6x6x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x6x6x:x:x:x:x:x:x6x:x6x6x:x:x6x:x:x:x6x:x6x:x6x6x:x:x:x6x:x6x:x:x:x6x:x6x6x:x6x:x:x6x:x6x:x:x:x6x6x6x6x6x6x6x:x:x:x:x:x:x:x:x:x6x6x:x6x6x6x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x6x:x:x:x:x6x:x6x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x6x:x6x6x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x6x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x6x:x:x6x:x6x6x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x6x:x:x:x6x:x:x:x6x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x6x6x6x:x6x6x:x6x:x6x:x6x6x:x6x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x6x6x6x:x:x:x6x:x:x:x:x:x6x6x:x:x:x:x:x6x6x6x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x6x:x:x:x6x:x:x:x:x6x:x:x:x:x:x:x6x6x:x6x6x:x6x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x6x:x:x:x:x:x6x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x6x:x6x6x:x6x:x6x:x:x:x:x6x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x6x:x6x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x6x6x:x:x:x:x:x:x6x:x:x:x6x6x:x:x:x:x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x:x6x:x6x:x6x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x6x:x:x:x:x:x6x:x:x6x:x:x:x6x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x6x6x:x:x:x6x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x6x:x:x:x:x6x:x:x:x:x6x:x6x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x6x:x:x:x6x6x:x:x:x:x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x6x6x:x:x:x:x6x:x:x:x:x:x:x:x6x:x6x:x:x:x:x6x:x:x6x6x6x:x:x:x:x6x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x6x6x:x6x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x6x:x:x:x:x6x:x:x:x:x6x:x:x:x:x6x:x6x:x:x6x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x6x:x:x:x:x:x6x6x:x:x:x6x:x6x:x6x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x6x:x:x:x:x:x6x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x:x6x:x6x:x6x:x:x6x:x6x6x6x6x:x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x:x:x6x:x6x:x:x:x:x:x:x:x:x6x6x:x:x6x:x:x:x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x6x6x:x:x:x:x:x:x:x6x6x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x6x:x:x:x:x:x6x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x6x:x:x6x:x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x6x6x:x:x:X:x6x:x:x:x6x:x:x6x:x6X:x:x:x:x6x:X:x:x:x:x6x:x6x:x6x:X:x:x:X:x6x:x:x:x:X6x:x:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x:x:X:x:x:x6x6x:x:x:x:x:x:x:x:x:x:x6x:x:x:x:x:X:x6x:x:x:x:x6x:x:X:x:x:x6x:x:x:x:x:x:x:x:x6x:x:x:x:x:x:x6x:x:x6x:x:x:x:x:x:x:x:x:x6x6x:x:x:x:x6x6x:x6X:x:x:x:x6x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x:x6x6x:x:x:x6x:x:x:x:x:x:x6x:x:x:x6x:x:x6x:x:x:x:x6x:x6x:x:x:x:x:x:x:x:x:x6x:x:x6x:x:x6x6x:X6x:X:x6X:x:x:x6x:x:x:x:x6x:x:x:x:x:x6x:x:x:x:x:X:x:x:x:x:x:x:x:x:x:x:x:x6x:X6x:x:X:X:x:x:x:x:X:x:X:x:x6x:x:x6x:X:x6x:x6X6x:x:x:x6x:x6x:x6x:x:x:X:x:x:X:X:x:X:x:X6x:x:x:x:x:x:x:x:X:X:x:x6x:x6x6x6x:x:X:x6x:x:X:x6x:X:x6x:x:x:x:X:x6x6x:x6x6x:x6x6X:x6X6x:X:X:x:X:x:X:X:x:x:x:x:x6x:x:x:x:x6x:x:x:x:x:X:x6x:x:x:X:x:x:x:x:x:x:X:X:x:x6X:x6x:X:x:X:X:X:x:X:x:x:X6x:x:X:x:x6X:x:x:x6x:X:x:x:x:x:X:x:x:X:X:X:x:X:x:x:X6x:X:x:x:x:x:x:x6x:X:x:X:X:x:X:x6x:x:x:X:x:x6X:X:x6X:x:x:x:x:x6x:x:x:x:x:x:X:x:x:x:x:x:x6x:x:x:X:x6X6x:X:x:X:x:X:x:x:x:x:X:x:x:x:x6x:X:x6X6X:x:X:X6x:x:x6X:X:x6x:X:x:X:x:x:X6x:X6X:x:x6X:x:X:x:x:X:x6x:X:X:X:X:x:X:x:X6X:x6X:x:x:x:X6x6x:X6X:X:X6X:X6x6X:X:X:X:X:X:x6x:X:x:X:x:X:x:x:x:X:x:X:x:x:X6x:X6X:X:x:X:x:x:X:X:X:x:X:x:x:x:x6x:X6X:X:x6x6X6X:x:X:X:X:x:X:x:x:x:x:x:x:x:X:x:x:x:x:X:x:X6X6x6x6X:x6x:x:X:X:X:x:x:x:X:x:X:x:x:X:X6X:X:X:X6X:X:X:X:x:X:X6X:x6X:X6x:X:x:X:X:x:X:x:x:X:X:X6x:x:X:x:X:x:X:x:X6X:x:X6X:X:x:X6x:x:x:x:x:X:X:x:x:x:x6x:X6X:X:X:X:x:X:X:x:X6X:X:x:x:X:x6X6X6x:x:X:x:X:X:x:x:X:x:X:X:x:x:X:x:x:X:X6x:x:X6X:X:X:x:X:x:X:X:x:x:X:X:X:X:X:X:X:X:X:X:x:X:X:x:x:X:X:X:X:X:X:X:x:X:x:X:X:X:x6X:x:X:X6X:x:X:X:x:X:x:x:X:x6X:X:X6X:x:X:x:x:X:X:X:x:X:x:x:X:x:X:X:X6x:X:x:X:X6X:X:x6X:X:X:X:x6X:X:x6x:x6X:X:x6x:X6X:X:X:X:X:X6x:X:X:x:x:X:X:X:x:x:x:X:X:x:x:X6X:X:X:X6X6X:x6x6x:x6X:X:X:x:X:X6x:X:X:X:x6x:X:X:X:X:x:X:x:X6X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:x:x6X6X:X:X6x:X:x:x:x:x:X:X:x:x:X:X:X:x6X:X:X:x:X:X:X:x:X:X:X:X6X:x:x:X:x:X:X:x:X:X:x:x:X:x:x6X:X:x:x6X:x:X:x:x:X:X:X6X6x:X:X:X:x:x:x:x:X:x:x:x:x:X:X:X:X6X:X:x:X:X:X:X:x:x6X:X:X:X:X:X:x:X:x:X:X6x:x:X:x:x:x:X:X:X:X:X:X:X:X:X6X:X:X6X:x:X:x:X:X:X:X6X:x:X:X:X6X:X:X:x:X6x:X:X:X:X:X6X:X:X:X:X:X:X:X:x:X:X:x:X:X:X:x6X6x:X:X:X:X:X:X:X:X:X:X:x:X:X:X:x:X:X:X:X:x:x6X6X6X:x:X:X:X:x:X:X:x:X:X:X:X:x:x:X6X:X:X:x6X6X:X6X:X:X6X:x:X:x6X:X6X:X:X:X:X:x:X:x:X:X:X6X:X:X:X:x:x:x6X:X:X:X:X6X:X:X:X:X:X:X:x:X:x6X6X:X6X:X:X:X:X6x:X6X:X6X:X:x:X6X:X:X6X:X:X:X:x:x:X:x:X6X:X:X:X:X:X:x6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:x:X:X:X6X:X:X:X:X:X:X:X:x:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X6X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X6X6X:X6X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X6X:X:X:X:X:X6X:x:X:X:X6X6X:X:X:X:X6X6X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X6X:X6X:X:X:X:x:X:X:X:X:X:X:x:X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X:X6X:X6X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X6X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X6X:X:X6X:X6X:X6X:X6X:X:X6X:X6X:X:X6X:X:X:X:X:X6X6X6X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X6X6X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X6X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X6X:X:X6X6X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X:X:X6X6X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X6X:X:X:X:X:X6X6X:X:X:X:X6X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X:X6X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X6X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X6X6X:X:X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X6X:X:X6X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X6X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X6X6X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X6X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X6X:X6X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X6X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X6X:X6X:X:X:X6X6X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X6X:X6X:X:X:X:X:X:X6X6X:X:X6X:X:X:X:X6X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X6X6X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X6X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X6X:X:X6X:X6X6X:X:X:X:X6X:X:X:X6X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X6X:X:X:X:X:X:X:X:X:X:X6X:X:X:X6X:X:X:X:X:X:X:X:X6X:X:X6X:X6X:X:X:X6X:X6X6X:X:X:X6X:X:X:X:X6X:X:X:X:X6X:X:X:X6X:X:X:X:X6X:X:X:X:X:X6X:X:X:X:\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/linux_200_100_565.bmp u-boot-2008.10/tools/logos/linux_200_100_565.bmp
+--- u-boot-2008.10_original/tools/logos/linux_200_100_565.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/linux_200_100_565.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1,2 @@
++BM\0\0\0\0\0\0F\0\0\08\0\0\0È\0\0\0d\0\0\0\x01\0\x10\0\x03\0\0\0B\0\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0\0ø\0\0à\a\0\0\x1f\0\0\0\0\0\0\0ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[\r[-[-[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[\r[-[-[-[-[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[Mcnckkkknc-c\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìR\r[-[Mcnck¯k¯kkkNc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[McnckÏs\x10|1QQ1|ðs¯knc-[\r[\f[ìRìRìRìRìRìRìRìRìR\r[-[nc¯s\x10|QrrQ1|ÐskNc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[NcnckÏs\x10|R³\x145¥U¥4¥4Ór\x10|¯kncNc-[-[-[\r[\r[\r[-[-[-cnc¯k\x10|rôU¥uuU¥\x14²1|¯snc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[Ncnck¯sðs1|r³\x14u¥¶µsµ\x0eµª´`«j´Sµvôr1|ðsÏs¯kkkkkk¯kÏs\x10|róuï¬i´ £@£H´Í´t\x14rðsk-[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[Mcnk¯kðs1|QÓ4v×µµ½0½ëÄ Ä Ì Ì Ì@ļR½\x18¾\x14Ó²rrQQQRr²ôU¥÷½\x0fµ`³\0¼@Ä`Ä`Ä\0Äh´µU¥²\x10|kMc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[Nc¯k\x10|rÓ\x14u¥¶µÖ½½0½Ë¼ ÄÀÔ`åÀíàíàíÀí@Ý`Ä ³
++ó\x18¾ø½·µvu¥U¥U¥v·µ÷½×µ\x13¥´@ÄÀÔ Ý@Ý`å@Ý Ì¼µ½Ó1¯snc-[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[Mck\x11|³U¥¶µ³½Å,Å\0¼Ì\0Ý`åÀí ö`þaþaþ`þ`þ\0ö@Ý Ì ³ \0\0A\bëZ,cmk®s\x10|QQ0Ïs\x10\0\0\09à»ÀÔå\0ö þAþ!öàõå(ͽ׵\x14rð{kMc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[ncðs³½aå@å`å íÀõ\0ö þ@þ`þaþcþeþ
þeþdþbþ`þ ö`åà»\01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`I Ä@Ý öbþdþ
þ
þþþaþÀõjÍÖ½vÓ1Ïsnc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[kQT¥`öþþ`þ`þaþbþcþdþeþþþþþþþeþaþ`þ íÀ³`\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 9 Äåaþdþþþþþþ
þþþæí6Î×µ\x14ð{kMc\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯kr`ö@þAþdþeþeþfþþþþþþþþþþeþAþ`þÀõ §90Uu4¥qs(Bb\x10\0\0\0\0\0\0\0\0\0\0À(À³íaþeþþþþþþþþþ¦þdþéÝ6Æv³\x10|kMc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s¶µ"öaþeþþþþþþþþþþþþþþeþAþþàÌ}çÿÿÿÿÿÿÿÿÿÿÿÿ÷ÚÖ²iJa\b\0\0\0\0`\x18@£`åaþeþþþþþþþþþþþ¦þhî0Þ²ðsnc-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s·µ\vÞþfþþþþþþþþþþþþþþdþ`þàí.µß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8Æ\bB\0\0\0\b ÝAþeþþþþþþþþþþþþþþöµ1k-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s·µîÕ`þeþþþþþþþþþþþþþþcþ`þ¨Õ~ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\çJ\0\0 jàÜ þcþþþþþþþþþþþþþþfþ\x0eÖR¯k-c\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s¶µîÝ`þdþþþþþþþþþþþþþeþ¡þÝ¥9Mc8Æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ}ïÈ9`I Ô\0öaþeþþþfþfþþþþþþþþþdþðÍQ¯k-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯kÊÝ`þeþþþþþþþþþþþþþbþÀþÀj\0\0\0\0\bBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x18¾dj@Ä ö`þAþbþbþaþbþfþþþþþþþî4ÎÓ\x10|k-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯krv¢åbþþþþþþþþþþþþþdþÀþà¼@\b\0\0\0\0IJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=ß,`Ì@þ`þ`þ`þ`þ`þ`þdþþþþþþöXÆ5¥Q¯sNc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[k14áíþdþdþdþdþfþþþþþþþeþþ@î9\0\0\0\0!\bUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÖ,ÀÔ`þ`þ ö í`åå\0öbþþþþþöyÎU¥rÏsnc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[ncð{³Í\0ö`þ`þþ`þbþþþþþþþcþÀþ\0\0\0\0Ã\x18UÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzÆ\v@Ýþ ö Ý`Ìà»À³ÌÀíþeþfþgöÙÞ²ðsnc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[Mc¯k1ôÕ½1ÖìÝ"ÝÀí`þeþþþþþeþ þ`Í`\x10\0\0§9XÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÖm¤íþ`åà»@r\09À(`I`\0öþAþö8Æ\x14\x10|nk-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[nc¯s1|³5¥×µÎÑÕ\0öþþþþfþþ`ö`9\0\0ËZ]ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÕÀíþ\0ÝQ\0\0\0\0\0\0\0\0 \bàþbþ¯î¶µÏs-c\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[-[NckðsQÓvYÆìÝþþþþ
þÀþ\0{\0\0¯s¾÷ÿÿÿÿÿÿÿÿÿÿ¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôî\x01ö¥þÃíÀ(\0\0\0\0\0\0\0\0\0\0 \b´%ÿ±îu¥Qk-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[nckð{²vÎ!öþfþþâþ@¬!\brÿÿÿÿÿÿÿÿÿÿÿÿïÖßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6÷"þeþäþ R\0\0\0\0\0\0\0\0\0\0\0\0¡Ab͸ÖU¥1k\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[ncð{Ó÷µ´Þ þÂþâþ`Õc1\x15ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ^[ß\x18Æßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ1ÿ\fÿFÅ\0) \0\0\0\0\0\0\0\0\0$!F)`\x10yÎ5¥1nk\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[kRU¥ÎÀrà´\0Á Ð{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµB\b$!ã\x18!\bÃ\x18$!¦1¢\x10\0\0¶µU¥1k\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc\x11|\x14¶µ\0\0 \b\0\0Ä\x18ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞXÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10b\x10f1Ã\x18\x10\x10\0\0\0\0\0\0\x10U¥Qk\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[NcðsÓó\0\0\0\0Ã\x18\x04!0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10\0\0b\x10e)\0\0\0\0\0\0\0\0\0\0ËZU¥Qk\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s¶µ \0\0\0%)¢\x10ï{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÞb\x10\0\0\0\0f1A\b\0\0\0\0\0\0\0\0ëZU¥Qk\r[ìRìRìRìRìRìR\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\f[\f[\f[\f[\f[\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[kQU¥q\0\0$!b\x10ëZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<ç\x18ÆßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10\0\0\0\0£\x18A\b\0\0\0\0\0\0\0\0ð{U¥Qk\r[ìRìR\f[\f[\r[\r[\r[\r[\r[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\f[\r[\r[\r[\r[\r[\r[\r[\f[\f[ìR\f[\f[\r[\r[\r[\r[\r[\r[\f[\f[\f[\f[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\f[ìRìRìRìRìRìR\f[\r[\r[\r[-[-[-[-[-[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[ncð{Ó\x18¾!\b¢\x10A\b§9ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿï8ÆÞ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎa\b\0\0\0\0 \0 \0\0\0\0\0\0\0\0\0U41|nc\r[ìR\f[\r[-[-[-[McMc-c-[-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[-cMcMc-c-[-[\r[\r[\r[\r[-[-[-[-c-c-[-[-[\r[\r[-[-[-[-[-[-[-[-[-[-[-[\r[\r[ìRìRìRìR\f[\r[-[-[McMcNcNcNcMcMc-c-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[McMcMcMc-c-[-[-[-[-[-[-[-[-[-[-[-[-[-[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[¯krv4¥\0\0\0\0£\x18yÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿ^[ßßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×½A\b\0\0\0\0a\ba\b\0\0\0\0\0\0\0\0·µôð{Nc\r[\f[\r[-[McNcncncncncNc-c-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[McNcncncncncNcMc-c-[-[-[McNcncncncncNcMc-c-[McMcNcNcMcMcMcMcNcNcMc-[\r[\f[ìRìR\f[\r[-[McncnkkkkknkncncNcNcNcNcNcNcNcNcNcNcNcMcMcMcMcNcNcNcMcMcMcNcncncnknknkncncncNcNcNcNcNcNcNcNcncncNcMc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc\x10|ô\x18¾a\ba\b\0\0\x14¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó\0\0\0\0\0\0Ã\x18¢\x10\0\0\0\0\0\0\0\0×µ³ÏsMc\r[\r[-[Nc°kl}u}u}u}u·lÑkMc-[\r[\f[ìRìRìR\f[\r[\r[\r[\r[\r[\r[\f[ìRìRìR\f[\r[-[Nc°kul}u}u}u}uùt\x13lNcNcNcnckul\u}u}u\uulkncncnc;u}u}u·lncnc·l}u}u}uNc-[\r[ìRìR\r[-[Mcùt}u}u}u}u}u}u}u}u}uulkùt}u}uùtkk;u}u}u·lncnc·l}u}u}unknckl}u}u;uTtut}u}u;ukl}u}u}u\x12lkkul}u}u}uvl-[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[¯kqA\b!\bRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿmk\0\0\0\0\0\0E)¢\x10\0\0\0\0\0\0\fcvrk-[\r[-[NcÐk\u}u}u}u}u}u}u}uòkMc-[\f[ìRìR\f[\r[-[-[-c-c-[-[\r[\f[ìRìR\r[-[Ncñk\u}u}u}u}u}u}u}ulncnkÐk;u}u}u}u}u}u}u;uÑkkk;u}u}u·tkk·t}u}u}unc-c\r[ìRìR\r[-[ncùt}u}u}u}u}u}u}u}u}uul¯kùt}u}uùt¯k¯k;u}u}u·tkk·t}u}u}u¯k¯kt}u}u}u}u}u\x19u}u}u;uk°k;u}u}u;uÏsñs}u}u}u;uoc-[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc1|\x14\x18ÆA\bÃ\x18A\b8Æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷èAA\b\x10!\b1A\b\0\0\0\0\0\0÷½\x14\x10|nc-[\r[-cncùt}u}u\x1auðsÏs\x19u}u}u\uoc-[\r[\f[\f[\r[-[-cNcncncNc-c-[\r[\f[\f[\r[-cnc;u}u}u;uñs¯kùt}u}u}u\x12lkùt}u}u;uðsðs;u}u}u\x19u¯sÏs;u}u}u×t¯k¯k×t}u}u}unkMc-[\f[ìR\r[-cncùt}u}u}u}u}u}u}u}u}uul¯k\x19u}u}u\x19uÏsÏs;u}u}u×t¯k¯k×t}u}u}uÏsÏs\x1au}u}u}u}u}u}u}u}u;u¯k¯kTt}u}u}u·t×t}u}u}u\x12lNc-[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[McÏs³×µ$!Ã\x18 \0ªRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎÃ\x18Ã\x18\x04!¢\x10ã\x18\0\0\0\0\0\0$!·µ²ÏsMc\r[-[Mcñk}u}u}uTtÏsÏsÏsÏsÏsknc-[\r[\f[\f[\r[-[l}u}u}u}ul-[\r[\f[\r[-[Mcñk}u}u}utÏs¯kÑk\uul3lk\x12l}u}u}uutÏsÏst}u}u}u\x12tÏs;u}u}u×tÏsÏs×t}u}u}ukNc-[\f[ìR\r[Mck\x19u}u}u}u3tÏs¯kknknkk¯k\x19u}u}u\x19uÏsÏs;u}u}u×tÏsÏs×t}u}u}uÏsÏs\u}u}u;uðs\x12t\u}u}u;u¯k¯k¯køt}u}u}u}u}u}u×tkMc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[kQU¥\x14A\bÃ\x18!\bÖµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÛÞÓ\0\0a\b\x10a\b \0\0\0\0\0\0\0u5¥Qk-[\r[-[Nc3l}u}u}u}u}u}u}u}u}u}uTlMc-[\r[\f[\r[-[·l}u}u}u}u·l-[\r[\f[\r[-[NcTl}u}u}u3t¯s¯kkkkkkut}u}u}u3tÏsÏs3t}u}u}uTtÏs;u}u}u×tÏsÏs×t}u}u}ukNc-[\f[ìR\r[Mck\x19u}u}u}u3t¯kkncNcNcnkk\x19u}u}u\x19uÏsÏs;u}u}u×tÏsÏs×t}u}u}uÏsÏs}u}u}u×tÏsÏsøt}u}u;u¯k¯k¯kðs\u}u}u}u}u;uÐskMc\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[ncð{Ó\x18¾A\b\x10\0\0\bB\çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<çu\x18Æ\bB\0\0a\bä !\b\0\0\0\0\0\0E)×µ³ðsNc\r[\f[-[Nc3l}u}u}u}u}u}u}u}u}u}uTlMc-[\r[\f[\r[-[l}u}u}u}ul-[\r[\f[\r[-[NcTl}u}u}u3t¯s¯kkkkkkTt}u}u}u3tÏsÏs3t}u}u}uTtÏs;u}u}uøtÏsÏs×t}u}u}ukMc-[\f[ìR\r[Mck\x19u}u}u}u3tkNc-[-[-cnck\x19u}u}u\x19uÏsÏs;u}u}uøtÏsÏs×t}u}u}uÏsÏs}u}u}u×tÏsÏs×t}u}u;u¯k¯k¯kÏsøt}u}u}u}uøt¯snkMc\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[¯krv®s\0\0\0\0 \00]ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]ïYÎÓ¶µ\x14¥\0\0¢\x10f1\x10\0\0\0\0\0\0\0\0÷½5¥1k-[ìR\f[-[Mcñk}u}u}uTtÏsÏs\x12t}u}u}uñkMc-[\f[\f[\r[-[-cNcncncNc-c-[\r[\f[\f[-[Mcñk}u}u}utÏs¯k\x12l;uulñkk\x12l}u}u}uutÏsÏsut}u}u}u\x12tÏs;u}u}u\u\x12tðs;u}u}u;ukMc\r[ìRìR\r[Mck\x19u}u}u}u3lnc-c\r[\r[-[Mckùt}u}u\x19uÏsÏs;u}u}u\u\x12tðs;u}u}u;uÏsÏs}u}u}u×tÏsÏs×t}u}u;u¯k¯k¯kut}u}u}u}u}u}uTtnkMc\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc\x10|ô÷½\0\0\0\0\0\0èAóyξ÷ÿÿÿÿÿÿ^[ß]ïÿÿÿÿÿÿÿÿ¾÷<çYε\x14¥q\x13<çÇ9\0\0Ã\x18A\b\0\0\0\0\0\0\0\0ëZ²ÏsNc\r[ìR\f[\r[-[ncùt}u}u\x1auðsÏs\x19u}u}u;unc-[\r[\f[ìR\f[\r[-[-[-c-c-[-[\r[\f[ìR\f[\r[-cnc;u}u}u;uñs¯kùt}u}u\u¯kkùt}u}u;uñsðs;u}u}u\x19u¯sÏs;u}u}u}u}u}u}u}u}u\x1aunc-[\r[ìRìR\r[Mck\x19u}u}u}u3lnc-[\r[\f[\r[Mcncùt}u}u\x19uÏsÏs;u}u}u}u}u}u}u}u}u\x1auÏsÏs}u}u}u×t¯k¯k×t}u}u;u¯kkñk\u}u}u;u\x1au}u}u\ukMc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[Mc¯krvÏ{\0\0\0\0\x04!Ó<çÿÿÿÿÿÿ¾÷ûÞ^[ß¾÷ÿÿÿÿÿÿ¾÷ûÞ\x18ƵUU]ïµ \0\0\0\0\0\0\0\0\0\0\0\0\0A\b\x18¾ô\x10|k-[ìRìRìR\r[-[Mc°k;u}u}u}u}u}u}u\uñkNc-[\r[ìRìRìR\f[\r[\r[\r[\r[\r[\r[\f[ìRìRìR\r[-[Ncñk\u}u}u}u}u}u}u}uTlncncÐk;u}u}u}u}u}u}u;uÑkkk;u}u}u\x19u}u}u}u}u}uulNc-[\r[ìRìR\r[Mck\x19u}u}u}u3lnc-[\r[\f[\r[-cncùt}u}u\x19u¯k¯k;u}u}u\x19u}u}u}u}u}ut¯k¯k}u}u}u·tkk·t}u}u;ukkØt}u}u}uTt\x12t}u}u}uØlMc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[ncð{Ó÷µ¢\x10\0\0\0\0óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷÷¾÷ÿÿiJ\0\0\0\0\0\0\0\0\0\0\0\0\0\0÷½U¥r¯kMc\f[ìRìRìR\f[\r[-[Nckul}u}u}u}ul°kNc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[Nckul}u}u}u}uØlòkNcMcMcNcncul\u}u}u\uulkncncnc;u}u}uutTt;u}u}uulnc-[\r[\f[ìRìR\r[Mck\x19u}u}u}u\x12lnc-[\r[\f[\r[-[ncùt}u}uùtkk;u}u}uutTt;u}u}uulkncnk}u}u}u·lncnc·l}u}u;unkul}u}u}uùt¯k¯kt}u}u}uóc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[kQ48Æ \0\0\0MkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÆ\x10\0\0\0\0\0\0\0\0\0\0\0\0ËZ·µ³ðsnc\r[ìRìRìRìRìR\f[\r[-[McNcncncncncNcMc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[McNcncncncncNcMc-[-[-[-[McNcncncncncNcMc-c-[McNcncncnknknkncncNc-[-[\r[ìRìRìR\r[-cncùt}u}u}u\x12lNc-[\f[ìR\r[-[NcnkkkknkncncncncnknknkncncNcMcMcMcNcNcNcMcMcMcMcNcNcNcNcNcNcNcncncncncncncNcMc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[NcÏsvv\0\0\x04!^[ßÿÿÿÿÿÿÿÿßÿÞ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQ\0\0\0\0\0\0\0\0\0\0\0\0a\b\x18¾\x141|k-[\f[ìRìRìRìRìRìR\f[\r[-[-[-[-cMc-[-[-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[-[McMc-c-[-[\r[\r[\r[\r[-[-[-[-c-c-[-[-[\r[\r[-[-[-[-cMcMcMc-c-[-[\r[\r[\f[ìRìRìR\r[-[ncùt}u}u}u\x12lMc-[\f[ìR\r[-[Mcùl}u}uùtNcMc-c-[-cMcMcMc-c-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[\r[\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[ncðs³·µ®s\0\0MkÿÿÿÿÿÿÞ÷ÛÞºÖ\çßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷\bB\0\0\0\0\0\0\0\0\0\0\0\0÷½U¥R¯kMc\r[ìRìRìRìRìRìRìRìR\f[\f[\r[\r[\r[\r[\r[\r[\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\f[\r[\r[\r[\r[\r[\r[\r[\f[ìRìR\f[\f[\r[\r[\r[\r[\r[\r[\f[\f[\f[\f[\r[\r[\r[\r[\r[\r[\r[\r[\r[\f[ìRìRìRìRìR\r[-[Mcùt}u}u}uòk-[\r[\f[ìR\f[\r[-[ùl}u}uùlMc-[-[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\r[\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[k1|\x14\x18¾e)!\bUÿÿÿÿÚÞvvø½ÛÖ¾÷ÿÿÿÿÿÿÿÿÿÿÿÿ×½!\b\0\0\0\0\0\0\0\0\0\0¶µ²ÐsNc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[McNcNcNc-[-[\r[ìRìR\f[\r[-[-[-c-c-[-[\r[\f[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[Mc¯krvyÎ\0\0Ç9¾÷\çU¥ïÍ.ò¤Zƾ÷ÿÿÿÿÿÿÿÿ÷\bB\0\0\0\0\0\0\0\0\0\0$!\x18¾ô\x10|k-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[-[-[-[\r[\f[ìRìRìR\f[\r[\r[-[-[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc\x10|ô\x18¾Ç9$!yÎØµÌ\x02´¡Ì¡ÌBÄH¬÷Åïÿÿÿÿÿÿ\x14¥\0\0\0\0\0\0 \0\0\0\0\08ÆU¥r¯k-c\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[\r[\r[\r[\f[\f[ìRìRìRìRìR\f[\r[\r[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[Ïs¶µU\x04!V¥\rá³ í\0î\0î þÀí£ÄQ½ÜÖ¿ï}ïiJ\0\0 \0§9ªR!\b\bB×µÓðsNc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[krv×µ£\x18Ëá³ Ýåå@Ý@ÝåàíåGͰÍÓÃ\x18\0\0e)®sëZ\0\08ÆU¥Qk-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[kQU¥và0`Ì\0ö`þ`þ`þaþCöâí\0Õ@Ý@ö ö\x03\0\0 \0IJ(BA\b1\x18¾Óð{Nc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[kQU¥ô@r@þþ`þ`þaþ`þbþþþ`ÝÀÌ îÀÄ@\x10\0\0A\b\0\0\0\0\x10|¯k-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[kRv1Àa õþ`þ`þcþAþ@þcþþ¤þàí@ÝÝÀ \0\0\0\0\0\0\0\0µU¥Qk\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯krs\0\0¤Bþþ`þdþdþ`þ@þ£þÄþÂþþa \0\0\0\0\0\0\0 \08Æ\x14\x10|nc\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯k¶µªRb\b9ÆÀÌíþcþ`å þÀå i¤üÿR\0\0\0\0\0\0\0\0\x10\x18¾óðsNcìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[Ïs²×µ$!«Zó\x01\0¢I$Ý\0îÀí Ì(î$R\0\0"\0×µ^[çä \0\0\0\0\0\0e)ø½ÓÐsMcìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[Ïs³×µa\b\x10\bBÃ\x18ìZ\x16Æá(á()kÞÿF)\0\0\0\0s¾÷èA\0\0\0\0\0\0\bB×µ³Ïs-cìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-cÏs³÷µ \0q(B\x04!QÖb\b£\x10NkÿÿÇ9\0\0§9¶µ÷Ç9\0\0\0\0\0\0f1×µ³Ïs-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-cÏs³÷½\0\0ï{yÎï{^[ß\x18Æ \0\0\0\bBÿÿ8ÆmkUÿÿ\x18Æa\b\0\0\0\0\0\0Ã\x18·µ¯s-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-cÏs³÷½!\bE)ºÖÿÿ}ï(B\0\0\0\0A\b4¥ÿÿÿÿÿÿ\çiJ\0\0\0\0\0\0\0\0$!¯k-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[Ïs³×µa\b\0\0ç9sIJE)A\b\0\0\0\0Ã\x18Qu\x14¥ëZE)\x10\0\0\0\0\0\0\fcvRk-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯s·µ¢\x10\0\0\0\0\0\0\x04!ã\x18\0\0\0\0\0\0\0\0a\b\x04!ä ¦11 \0\0\0\0\0\0\04¥51|nk\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[¯kr\bB\0\0\0\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0b\x10\0\0\0\0\0\0\0\0\0\0\x18¾ÓðsNc\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[kQU¥\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0e)¯s-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[nc\x10|ôv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0!\b\0\0\0\0\0\0\0\0\0\0v\x141|k-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[McÏs!\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!\bÇ9¦1Ã\x18!\b\0\01ÏsNc\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR-[k1|\x14\x14¥\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0iJÏ{Ç9 \0a\b÷½ô\x10|k-[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[NcÏsrU¥\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0E)1\0\0\x10÷½\x14Q¯kMc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[ncðsU¥u¢\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ËZ×µ\x14Q¯sNc\r[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[-[kðsr\x14¶µU¥ëZb\x10\0\0\0\0 \0f1q×µu¥Ó1¯sNc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\r[-[ncÏs1|²\x14U¥×µ×µ·µ5¥Órð{kNc-[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[-[NckÏs\x10|Q²²r1ðs¯knc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[Mcnck¯kÏsÏs¯s¯kknc-[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\f[\r[-[-[-[-[-[-[\r[\r[\f[ìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìRìR\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/linux_200_100_8bit.bmp u-boot-2008.10/tools/logos/linux_200_100_8bit.bmp
+--- u-boot-2008.10_original/tools/logos/linux_200_100_8bit.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/linux_200_100_8bit.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1 @@
++BMXR\0\0\0\0\0\06\x04\0\0(\0\0\0È\0\0\0d\0\0\0\x01\0\b\0\0\0\0\0"N\0\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ÀÜÀ\0ðʦ\0ª?*\0ÿ?*\0\0_*\0U_*\0ª_*\0ÿ_*\0\0\x7f*\0U\x7f*\0ª\x7f*\0ÿ\x7f*\0\0*\0U*\0ª*\0ÿ*\0\0¿*\0U¿*\0ª¿*\0ÿ¿*\0\0ß*\0Uß*\0ªß*\0ÿß*\0\0ÿ*\0Uÿ*\0ªÿ*\0ÿÿ*\0\0\0U\0U\0U\0ª\0U\0ÿ\0U\0\0\x1fU\0U\x1fU\0ª\x1fU\0ÿ\x1fU\0\0?U\0U?U\0ª?U\0ÿ?U\0\0_U\0U_U\0ª_U\0ÿ_U\0\0\x7fU\0U\x7fU\0ª\x7fU\0ÿ\x7fU\0\0U\0UU\0ªU\0ÿU\0\0¿U\0U¿U\0ª¿U\0ÿ¿U\0\0ßU\0UßU\0ªßU\0ÿßU\0\0ÿU\0UÿU\0ªÿU\0ÿÿU\0\0\0\x7f\0U\0\x7f\0ª\0\x7f\0ÿ\0\x7f\0\0\x1f\x7f\0U\x1f\x7f\0ª\x1f\x7f\0ÿ\x1f\x7f\0\0?\x7f\0U?\x7f\0ª?\x7f\0ÿ?\x7f\0\0_\x7f\0U_\x7f\0ª_\x7f\0ÿ_\x7f\0\0\x7f\x7f\0U\x7f\x7f\0ª\x7f\x7f\0ÿ\x7f\x7f\0\0\x7f\0U\x7f\0ª\x7f\0ÿ\x7f\0\0¿\x7f\0U¿\x7f\0ª¿\x7f\0ÿ¿\x7f\0\0ß\x7f\0Uß\x7f\0ªß\x7f\0ÿß\x7f\0\0ÿ\x7f\0Uÿ\x7f\0ªÿ\x7f\0ÿÿ\x7f\0\0\0ª\0U\0ª\0ª\0ª\0ÿ\0ª\0\0\x1fª\0U\x1fª\0ª\x1fª\0ÿ\x1fª\0\0?ª\0U?ª\0ª?ª\0ÿ?ª\0\0_ª\0U_ª\0ª_ª\0ÿ_ª\0\0\x7fª\0U\x7fª\0ª\x7fª\0ÿ\x7fª\0\0ª\0Uª\0ªª\0ÿª\0\0¿ª\0U¿ª\0ª¿ª\0ÿ¿ª\0\0ߪ\0Uߪ\0ªßª\0ÿߪ\0\0ÿª\0Uÿª\0ªÿª\0ÿÿª\0\0\0Ô\0U\0Ô\0ª\0Ô\0ÿ\0Ô\0\0\x1fÔ\0U\x1fÔ\0ª\x1fÔ\0ÿ\x1fÔ\0\0?Ô\0U?Ô\0ª?Ô\0ÿ?Ô\0\0_Ô\0U_Ô\0ª_Ô\0ÿ_Ô\0\0\x7fÔ\0U\x7fÔ\0ª\x7fÔ\0ÿ\x7fÔ\0\0Ô\0UÔ\0ªÔ\0ÿÔ\0\0¿Ô\0U¿Ô\0ª¿Ô\0ÿ¿Ô\0\0ßÔ\0UßÔ\0ªßÔ\0ÿßÔ\0\0ÿÔ\0UÿÔ\0ªÿÔ\0ÿÿÔ\0U\0ÿ\0ª\0ÿ\0\0\x1fÿ\0U\x1fÿ\0ª\x1fÿ\0ÿ\x1fÿ\0\0?ÿ\0U?ÿ\0ª?ÿ\0ÿ?ÿ\0\0_ÿ\0U_ÿ\0ª_ÿ\0ÿ_ÿ\0\0\x7fÿ\0U\x7fÿ\0ª\x7fÿ\0ÿ\x7fÿ\0\0ÿ\0Uÿ\0ªÿ\0ÿÿ\0\0¿ÿ\0U¿ÿ\0ª¿ÿ\0ÿ¿ÿ\0\0ßÿ\0Ußÿ\0ªßÿ\0ÿßÿ\0Uÿÿ\0ªÿÿ\0ÿÌÌ\0ÿÌÿ\0ÿÿ3\0ÿÿf\0ÿÿ\0ÿÿÌ\0\0\x7f\0\0U\x7f\0\0ª\x7f\0\0ÿ\x7f\0\0\0\0\0U\0\0ª\0\0ÿ\0\0\0¿\0\0U¿\0\0ª¿\0\0ÿ¿\0\0\0ß\0\0Uß\0\0ªß\0\0ÿß\0\0Uÿ\0\0ªÿ\0\0\0\0*\0U\0*\0ª\0*\0ÿ\0*\0\0\x1f*\0U\x1f*\0ª\x1f*\0ÿ\x1f*\0\0?*\0U?*\0ðûÿ\0¤ \0\0\0\0ÿ\0\0ÿ\0\0\0ÿÿ\0ÿ\0\0\0ÿ\0ÿ\0ÿÿ\0\0ÿÿÿ\0111111111121111111121111111111111211121111111112111111112111112112111111111121112111111111111111121111111111211112111112112111211211111111111211211111111111211121111211121111111111111121111121112111111111121111111121111111111111111111111111112111111121111111111111111111211111111111111111112111111111111111111111111111111111111111111121111111111112111111111111111211111111111211111111111211111111111111211111111121111211121111121121111111112111111111111211111211111111111112111111111121121111121111121111121111121112111111111111111111111121111111111121121111111111111111121111112111111111111111111121111111112111111111111111211111111121111111111211111111111111111121121111111112111211111111111111111111211111111111111121111121112112111111112111111111111111112111111112111111111111211211111112111211111111211111111111111111111111111111111121111111121112111112111211111112111111111111111111121111112111111111111211111111111211111111111111211111121121111111121111121121111111112111111111111121111111111111111111112111121121121111111112111121111121111111111112111111111111111121111111111111111111211111121111112111111211111111111111111112111111111111111211111111111111111111211111121111111211111111111111112111211111121111111111121121111111111111111111111111111111111112111111111211211112112111111111111111121111111111112112111112111211111111121111111111112111111211111111211111111111121111111111211112111111111111111111111111111111111111211112111112112111211111121121111111111111111121111111111111111111111111111112111111111121111111111111211111111211111111112111111112111111121111111111111112111121111111111111121111111211111211111121111111111211111111111111211111111111121112111111111111112112112112111211111121111111111111111112111121111111112111112111111111111121111111111111111211111121111111111111111112111111211111112111111111111111211111111111111111111111111111121111111112111111211111111111111111111121111111211211111111111111111111112111111111121111111111111111112111111211111211111111111111111121111111111112111111111121111121111111111211211121121111112111121111111111111112111111111111111112111121111111211111112111121111211121111111112111111111211112111121112111112111111111111111211211112111112111211111111111111111112111111111121111111111111111121111111111112111211111111111121111121111111111111112111111111111211111111111111211111111111111111121111111111111111111111121111112111111111111111111111112111111211211211111111112111111111111211111111111111211111111111111121112111111211111211111211111111111112111111111121111111111111211111211211111111112111111111121112111111121111111111121111111111111111121111111111111111211111111121111111111111\a11111211111211111111211111111111111111111111111111211111111111121111111111111211111111111111111112111111111111121111111111111111111111111121111111211112111111111111111111\a\a\a\a511\a1112111111211111\a\a\a\a\a111211111111111121111111111111211111111211121111111111121121111111112111112111111211111121111111111111211111211111121111111211111111121121111111111112111111111111211\a11\a\a\a\a\a\a\a\a\a\a111111111111121\a\a\a\a^\a^\a\a\a1111111211111112111111121111112112111111111211211111111111111111111211111211111112111112111111111111121111121111111121111121111211111111111211111111111121121111111\a\a\a\a÷÷÷÷\a\a\a\a11111111111\a\a\a÷÷÷÷\a\a111211111121111111121111111111111111111111111111121111111211112111111111111111111111111121121111211111111111111111111111111211111111112111111111111111111111\a1\a\a\a\a\a÷÷x÷^\a\a\a\a\a\a\a\a\a\a\a\a\a÷÷xx}÷\a\a\a1111111111111112111111121111111111112111111111111111121111211111111211111211111112111111111121111111121111112111111121111111111111111111111112111121111\a1\a\a\a\a^÷÷÷¦ ¤¤¤ }¦÷^÷Z^\aZ\a^\a÷÷\bx ¤¤ }÷÷\a\a1\a112111121121111111211112111112111111211111211112111111111111211111112111121121111111111111111121111111211111211111111111112112111112111111112111121\a1\a\a÷÷÷ª¦ ¤¤ÊÊÊʤ¤|}÷\bª\b ¤¤¤¤¤¤ª÷÷\a\a1111111111111111211111111112111121111111211111111111111111111111111111111111111111211121111111111111111111111112111112112111111121111121111111111111\a\a÷ªª|¤¤¤ÊÊÎÊÊÎÊʤ¤|ð\0\0111\a\a\a\a\a\a\0\0𠤨ÊÊÎÊʤ¥ª÷Z\a\a11121111111111111111111111111111111111111111211111211211211112111211111111111111111111121121111211121112111111121111111111111111111111111111111111\a÷¨¤¨ÆÊÊÊÊÎÎÊÊÎÏÊÎÊʤ|ð\0\0\0\0\0\0\0\0\0\0\0\0\0(|¤ÊÎÊËÊÎÎÊÊ¥÷\a\a\a11111111121111112112111111111112111111111111111111111111111111111111211211121111111111111111111111111111211111111111111121111112111111121111211\a\aÎÊÎÊÎÎÎÊÎÊËÎÏËÎËÎÊÎÊ|ì\0\0\0\0\0\0\0\0\0\0\0\0\0ð ÊÊÊÏÎÏËÎËÎÎË\b^\a\a1121121111112111111112111211111112112112111121111111111211112111121111111111112111211111121111211111111111111121111121111121111111211111211112\a\aÊÎÊÊÏÊËÊÏËÎÏËÎËÏËÎÊÊTõ\a\a\aõì\0\0\0\0\0ð|¨ÊÏÎËËÎËÎÏËÎÊ©ª÷\a\a111111111111111111111111112111111111111111111111211111111111111111111111111111111111111111111111112111111211111121111111111111111111111111111\aZÊÊÏÎÊÏÎÏËÎÏËÎËÏÊÎÊΤ\aöÿÿÿÿÿÿö\b÷-\0\0\0ðxÊÊÎËÏÎËÏËÊÏÎËÎÏ©\a\a\a11111111211111121111111111121111111111112111211111211112111121111112111211211121111121111211112111112111111111111111112111121121111111111111\a÷©ÎËÏÏËËÎÏËÊÏËÎËÏËÎÊÿÿÿÿÿÿÿÿÿÿÿÿª-\0\0T¤ÎËÎËÏÊÏÎËËÏÎËÎÏÏ\a\a12111211111121111121112111111121112111111111111111111111111111111111111111111111112111111111111111111111112111111111111111111111111121111211\a\a©ÊÎËÊÎÏËÊÏÏÊÎÏÎËÎÊ¥¯ÿÿÿÿÿÿÿÿÿÿÿÿÿ¯1\0,¤ÊÎËÎÊÏÊÏÎÏÊÏÏËÎË©^\a11111111111111111111111111111111111112111111111121112111112111121111121111111111111111211111211121111121111112112112111112111111111111211112\a^ªÊÏÊÏÏËÎÏÎÊÏËËËÎʨô\aªÿÿÿÿÿÿÿÿÿÿÿÿÿöñ(¤ÊÊÏËÏÏËÎËÊÏÊËÎËΪ\a111111111112111111111121112111111111111111211121111111111111111111211111111112112111111111111111111111111111111111111111111111111211111111111\a\a©ÎÊÏÏÊÎËÏËÏÊÏÎÏÊÎT\0\0õÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b, ÊÎÊÎÊÊÎËÏÎËÏÎËϪ÷\a\a12112112111111211211111111121111211111111111111111111111211112111111111112111111111211111121111111121111121111111111111211111211111111111111\aZ¨ÊÏÊËÏËÎËÎËÏÊËÎΤ\0\0\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿö¯}¤ÊÊÎÊÎÊÊÎËÏÎËÏË\b÷Z\a\a11111111111111111111111111111121111211211111111111211121111111111111211211111111111111112111112111111111111121111211121111121111111121111211\a\a÷ÊÎÊÏÎËÎËÎËÎËÏÏÊÊô\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯}¤ÎÊÊʤ¨ÊÊÏÊËÎË\bZ\a1111111111111211111112111211111111111111111121112111111111111211112111111111111211121112111111111112111121111111121111111111111111111111211112\a\a^©ÊÊÎÊÊÎÏËÎÏËÎÊÎX\0\0ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b}¤Êʤ¤| ¤¨ÎËÏÏ\b^\a1\a1211211112111121111111111111111111111111111111111211111111111111111111111112111111111111111112111111111111111111111111111211111121111111111111\a\a÷ª©¤ÊÊËÎÏÊÎËΤð\0ñ\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¯}¨Î¨|Pðð(xÊÎÊË\b÷\a\a1111111121111111111211112111112111211211111211121111111211121111211112111211111111111111111121111111111211121121111111121111111211111111111111111\a\a^\bªÊÎËËÏËÎÎð\01öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÊʤ(\0\0\0\0\0TÎÊÏ^\a21111111111111111111111111111211111111111211111111111111111111111111111111111111111121121111111111121111111111111121112111111111111111112111121112\a\a\a\a^\b©ÊÏÎËÎÎT\0\aöÿÿÿÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÐÊÏÊð\0\0\0\0\0\0ÏÐ\a\a1121121111121112112111211111111111111111111111111112111111211121111211111111211112111111112111111211112111111111111111111121111111211111112111121111\a\a\aZ\bÊÎËÏÎ|\0Zÿÿÿÿÿÿö\bÿÿÿÿÿÿÿÿÿÿÿÿÿÐÊÎÎ,\0\0\0\0\0\0ô¤\b\a\a111111111111111111111111111211112111121111111121111111211111111111111111211111211111111111111121111111111121111111111111111112111111111111111111112111\a\a÷\b®ÊÎΤð÷ÿÿÿÿÿÿö¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿöÐÏ¥ð\0\0\0\0\0ðñ\0\b÷Z11111111121111111111111112111111111211111211211111211111111111111211112111111111111111121111111111111111111111211211121121111111211111111111111111111111\aZ\bT|ð\aÿÿÿÿÿÿÿö«\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ðð\0ñðõð\0\a\a21111111111112112111211111111211111111111111111111111111211121111111111111121112111211111211111111112112111111111111111111211111111111112111121121112111\a÷\0\0\0ð^ÿÿÿÿÿÿÿÿ¯\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ì\0õð\0ð\0\0\0\aZ51121121111211111111111111111111111112111111111111111211111111111111211121111111111111111111121121121111111121111111111111111111112112111112111111111111\a\a^÷\0\0ðñ\aÿÿÿÿÿÿÿÿ\bªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0ñ\0\0\0\0\01\a\a11111111111111111111111112112111211111111121121111111111111111111111111111111111111111111111111111111111111111111121111111111211111111111111111111111121\a^\0\0ðð\aÿÿÿÿÿÿÿö¯\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¯ð\0\0õ\0\0\0\0\01\a\a11111112111111211112112111111111111111121111111211211121111211211211111111112111121121112111111111111111121111121111211211111111111111111111112111211111\a\a\a\0ñ\01ÿÿÿÿÿÿÿÿ¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯\0\0\0ð\0\0\0\0\0\a÷Z1211211111\a11111112111111111111111112111111111111111111112111111111111211121111121111112111\a1211121121\a121111121111111111112111112111111121111111111111111\a÷\b\0ð\0õÑÿÿÿÿÿÿÿö\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\0\0\0÷\a\a11111\a1\a11121111111111111111111211111\a1\a121\a11211\a1\a1\a1111\a1\a1\a1\a1\a111111111\a1\a11\a1\a1111\a11111\a11111111111\a1\a11\a1\a1\a1\a1\a111121\a11112111111211111121112112\a\a\0\0ð\bÿÿÿÿÿÿÿÿ¯öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0\0\0\0\0\0\0÷\a11111\a115U1\a11\a1111111211211211111121\a11111111\a11\a1515111\a15111111511\a111211\a151\a\a15U1\a1\a111\a1\a111\a11\a11\a12151\a\a1\a15111111\a1\a1111\a111111111111211111111111\a\a÷\b\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0\0ñ\0\0\0\0\0^\a\a11215^;_?_:\a11121121111111111211\a1\aZ>_cc^Z1\a11\a^:_c_6\a\a11__c:2\a:___11111112:__c;b;c;c6\a:_c^12^;c:2\a6_c_1\a1^_c^\a:_;_\a:_?cZ1\a6b_c611111111111111111111111111\aZZ\0\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\a\0\0\0ðð\0\0\01Z\a1111\a_cc__c_c61111111\a1\a1\a11111111Z>_c;_;c?^1\a6^_c;;c_^6\a5^;_^1\a^?c_\a121111\a^>__c_c_c_6\a^?_;\a5___^1\a:c;c1\a^;c_?_^c_:\a\a___:\a\ac;c_\a121111112112111211112111211\a÷\b\0ð\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑõ\0\0\0õ\0\0\0\0\b÷\a\a121\a:_;^6\a:_;_\a11111\a1115112111\a1\a:__;\a\a^___65^_?_\a\a_;c:\a\a_c_:\a\a:__?1\a112111__c;_?_;c;^\a^__:\a\a^?_:\a\a^___\a\a^__?__?_c;\a16c?_^^_c_6111121111111111111211111111\a\a^ðñ\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\bððñ\0ð\0\0\0ð^\a1111\a_ccZY5\a\a\a51\a12111^_?__^1111116_?c^\a16_:6\a\a_?_\a\a\a6c_c\a\a;_?^\a\a6_?_\a111112\a^c;c\a\a1\a1\a1\a;c?^\a\a;_c^\a1:_?c5\a;b?_\a6_c;b\a\a\a:__c;c;^1\a111111111111111111111121111\aZ÷\0ð\0öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\b÷\0\0ð\0\0\0\0\0\a\a121\a6c;^;_cc:c_Z1111216c_?c6\a1121\a^__;\a\a\a\a11\a\a6c_?Z\a\a6_>_6\a^c_^5\a^c_c1\a1111\a1;_b_6\a\a1\a1\a\a:__^\a5_c_:\a\a^c_;\a\a___:\a\a:___1\a1\a_?_b__6\a12111111112111211111111111121\a÷\b\0\0\0õöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\b-\0\0ð\0\0\0\0ñ^\a\a1111\a_ccc;__c;c6\a1111\a6c__;^1211116bc_6\a1\a\a\a1\a6b__65\a\ac_cZ5_>_;\a\a:_c;\a121211\a^?_cZ1\a1121\a^?_;\a\a^;c;\a\a:_c_\a5c;cZ\a\a^>c_\a\a\a\a^_?_c:\a\a11121111111111111211211111111\a\a\a\0\0\0\aöÿÿÿÿÿöÿÿÿÿÿÿÿÿÿö\b÷÷\0\0õ\0\0\0\0\0\b÷\a\a1111\a2c;_6\a\a6_c_61\a1111\a11\a\a1111112\a;_?^\a\a6^6\a\a\a_?_^\a\aZ_?_6\a__c^\a\a_c;_1\a1111\a1^_c;6\a1211\a1__c^\a\a;c_^\a\a^c;_5\a_c_:\a\a:__;5\a1^;c_c;_\a1\a1111111111111111111111112111\a\a^\b\0\0\0õ÷\böÿÿÿ¯ööÿÿÿö¯ª÷\a÷¯-\0ð\0\0\0\0\01^\a112111\a:_c^\a5^?_:\a11112111\a11121121\a1_c_^\a5^_c;\a1;_c:\a\a:c_^\a\a;c;_c;b;_^\a111111\a;_?_\a\a111\a1\a^?_:\a\a:_;c?_;_c^\a\a;_?^\a1__?^\a\a6__b;^cc_\a1\a1111111121121111111121111121\aZ÷\a\0\0ð÷¯ÿÿÿö\b¯öÿÿÿö¯\b÷ö\0\0\0\0\0\0\0\0\b÷\a\a111121\a\a_;c__c__Z1121111121121111111\a6_;ccc_?_Z1\a\a;c_cc_?_6\a1^_c:_c_cc61\a11121\a^c_?\a1111111____\a\a_cc^_c_?_6\a\acc_:\a\a:c__1\a^_?_Z6;_c:111121111111111121111111111111\a\a÷\b\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööÿ-\0\0\0\0\0\0\0\a\a211111111\aZ;c;_^61\a11111111111111111111\aZ;_;_^61\a1\a1Z;;_;Z\a1\a\a;c_^6_;_6\a112111\a1;_b_6\a121121:c;:\a5_;_6Z;c_^1\a1_;c6\a1^;c_\a6;c_;\a\a^;_cZ111111111111111111211111121111\a\a÷\b\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\01^\a\a112111121\a1\a1\a121\a11112112112112112111\a1\a1\a1\a1\a2111\a1\a\a1\a11\a11\a121\a\a1\a1\a1111111\a^_;c6\a11111\a\a1\a\a1\a1\a1\a1\a1\a1\a1\a1\a1\a1\a1\a121\a\a11\a1\a1\a1112111111121111111111111211111121\aZ\0ð¯ÿÿÿÿöÿÿÿÿÿÿÿÿÿÿÿ\a\0\0\0\0\0\0\0\b÷\a\a1111112111121\a11\a1112111111111111111112111\a1\a121112121\a11\a121121\a1\a11\a1211211121\a:cc_\a111121\a:_c^21\a12\a1\a121111\a1111121\a1\a111\a11\a111\a11121111111121121111111111112111\a\a^\a\0Uÿÿÿö¯\b¯öÿÿÿÿÿÿÿöõ\0\0\0\0\0\0\b\a121111111111111121111111111111111111111111121111111111111121111111111121111111111\a1_;_;Z1211111_;_:\a11111211121211121211111112112111211211111111111111111211111111111111\a\a÷\bñ\0ÿö¯ª¯Ñÿÿÿÿÿÿª\0\0\0\0\0\0ZZ\a\a11112111112112111112111112111112111112111111211112111112111112111112111112111111111\a1\a111111111\a1\a1211111111111121111111112111111211111111111111111111111112112111111211\a\a\b\0õÿÑ÷\a\a\a\bÿÿÿÿÿöõ\0\0\0\0\0ð\b÷\a\a1112111112111111121111121111121111121111121111121111121111121111121111121111121121211\a12112112111111112111211111111111121111112111111211121121112111121111111111111111112\a\a÷\bõð\b\a ¤¤|}ÿÿÿÿ÷\0\0\0\0\0\0\b\a\a121111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111111121111111111111211111211112111111111111111111111111211111211111111211211111\aZñ\a|¨ÊÊÊʤ¦\bö³-\0\0õ1\0-^\a\a111111112111112111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111111111211111111111111121111111111111111111111111211111111111111\a^ðY|¤Ê¤¨¤¨Ê¨¥ª÷ð\0ð\a1\0\b÷\a\a1111111111111111112112112112112112112112112112112112112112112112112112112112112112112112112112112112111211121111111111111111112111111121112111111111112111111111211111112111\a\að ÊÎÊÎÊÊʤ¤ÊÊT\0\0--\0õª÷\a\a12112112111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111111211211111121111111111121111211111111111111121111111121\a÷PÊÎÊÎÊÊÎËΤ¤Ê¤\0\0\0\0\0\aZ\a11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211121111111111111111111111111111111111112112111111112111111\aZ\a,ÊÎÊÊÎÎÊÎËÏʤ¨ð\0\0\0\0÷\a\a11111111111211121121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111211111111111111111121111112111121111111111121111111112111111112111\a\a\a\0|ÊÎÊËÊÎÊÎÎÎÎT\0\0\0\0\0\b÷\a211111121111111111111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111211111111112111111121111112111121111111111111111111111211111111\a^1\0\bU¤¨Îʨʨ|}ö\a\0\0\0\0ð\bZ\a\a11211111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121112111112111111111111111111111121111121111111111111111111\aZñ1÷\0,¥Ê¨¤Ë,\0\0¯ð\0\0\0ñ÷\a111112111111112111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111111111111211111121121121112111121\a^ª\0\aõð1ªððUöñ\0\0\aö-\0\0\0-÷\a111111111111111112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112111211111211111211111111121112111111111111111111111111112111\aZ\b\0\a-ð\a¯\0ð1ÿõ\0õöõ\0\0\0ðZ\a212111111211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111112111111111111112111111111111111111111\a÷\0\a\b\a¯ª\0\0-ÿ\bUÿ\b\0\0\0\0ñ÷\a11111121111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111111211121111111111112111112111121111121111111\a\a^\0ñ®ÿöõ\0\0\0ÿÿÿö-\0\0\0\0ð^1111111111111112111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111111112111111111111112111111111111111211111211112111211\aZ\b\0\0õ\a-ñ\0\0\0ðZ1ð\0\0\0\01÷Z\a111121112111111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121112111111211121111111112111111121111111111111111111111\a÷\0\0\0\0ðð\0\0\0\0\0ððõõ\0\0\0\0÷÷\a\a121111111112111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112111211111111111111111111111111111111\a\a-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\b÷\a\a1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112111111111111111111111211111211211211211211211121Z÷\a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0õ\a\a1111111211121112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112112111211111121112111111111111111211111111111111111111111\a\a÷\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0÷\a\a11112111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112111121111111111111111111111111111111\a^\0\0\0\0\0\0\0\0\0\0\0õñð\0\0ñZ\a211211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111111111112111111111121111121111121111121111\a\a÷÷\0\0\0\0\0\0\0\0\0\0-\aõ\0\0\b^\a\a1111111112111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111111111211111111111111112111111211111211111211112112\a\a\a\0\0\0\0\0\0\0\0\0ðõ\0ì\b÷\a\a11111112111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111121111211211111112112111111111111111111111111111111111111111\a\aZð\0\0\0\0\0\0\0\0\01÷\a\a1211211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111111211112111111121111111111111111111111111\a\aZ÷1\0\0\0\0õ\a^\a\a\a111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111111211112112112112112112112112111\a\a^÷\b÷^Z\a\a12112111211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211121111121111111111111111111111111111111111111111111112\a\a\a\a\a\a^Z\a\a\a\a\a1211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111121111111111111111111111111111111111111111111112\a\a\a\a\a\a\a\a1\a1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121111211121111211111211111211111211111211111121112121111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211112111121111111111211111111211112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111111111211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211112111121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121121112112111211112111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211111211112111121111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111112111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/linux_white_bk_200_100_565.bmp u-boot-2008.10/tools/logos/linux_white_bk_200_100_565.bmp
+--- u-boot-2008.10_original/tools/logos/linux_white_bk_200_100_565.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/linux_white_bk_200_100_565.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1 @@
++BM\0\0\0\0\0\0F\0\0\08\0\0\0È\0\0\0d\0\0\0\x01\0\x10\0\x03\0\0\0B\0\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0\0ø\0\0à\a\0\0\x1f\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x17¾\x18Æ9Æø½µ2µ\ï¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷½\x18Æ×½3µð¬ð¬÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYÎ8Æ\x17¾×½×½÷½v¤è££`«`«A£+¤\x18ÆÎyÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎ8Æ\x18Æ×½¶µ×µ\x12!£ £@£@££®¬8ÆYÎyÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖyÎYÆ\x18¾×µvÒ¤\v¤£À³ Ä Ì Ì Ì@Ä`³ÈTYκֺֺֺֺֺÖÖyÎYÎ\x18Æ÷½Öµ×µUe`³\0¼@Ä`Ä`Ä\0Ä`«m¤9ÆYÆYÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZÆ×½Sµ¤é « ÄÀÔ`åÀíàíàíÀí@Ý`Ä ³zIJ1\x14¥4¥Uµ¶µ÷½\x17¾÷½¶µUk¨j`«@ÄÀÔ Ý@Ý`å@Ý Ì ³L¤ø½zÎyÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷Øæ´%´á³\0¼Ì\0Ý`åÀí ö`þaþaþ`þ`þ\0ö@Ý Ì ³ \0\0A\b\x10¢\x10ã\x18\x04!e)1¦11$!\x10\0\0\09à»ÀÔå\0ö þAþ!öàõåÌG¬TµÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷æaå@å`å íÀõ\0ö þ@þ`þaþcþeþ
þeþdþbþ`þ ö`åà»\01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`I Ä@Ý öbþdþ
þ
þþþaþÀõÁÌî´ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿ`öþþ`þ`þaþbþcþdþeþþþþþþþeþaþ`þ íÀ³`\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 9 Äåaþdþþþþþþ
þþþÁísÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿ`ö@þAþdþeþeþfþþþþþþþþþþeþAþ`þÀõ §90Uu4¥qs(Bb\x10\0\0\0\0\0\0\0\0\0\0À(À³íaþeþþþþþþþþþ¦þdþ*æ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"öaþeþþþþþþþþþþþþþþeþAþþàÌ}çÿÿÿÿÿÿÿÿÿÿÿÿ÷ÚÖ²iJa\b\0\0\0\0`\x18@£`åaþeþþþþþþþþþþþ¦þ¨öóîÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMæþfþþþþþþþþþþþþþþdþ`þàí.µß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8Æ\bB\0\0\0\b ÝAþeþþþþþþþþþþþþþþÉþ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpæ`þeþþþþþþþþþþþþþþcþ`þ¨Õ~ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\çJ\0\0 jàÜ þcþþþþþþþþþþþþþþfþSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpæ`þdþþþþþþþþþþþþþeþ¡þÝ¥9Mc8Æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ}ïÈ9`I Ô\0öaþeþþþfþfþþþþþþþþþdþvÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\væ`þeþþþþþþþþþþþþþbþÀþÀj\0\0\0\0\bBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x18¾dj@Ä ö`þAþbþbþaþbþfþþþþþþþíþºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢åbþþþþþþþþþþþþþdþÀþà¼@\b\0\0\0\0IJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=ß,`Ì@þ`þ`þ`þ`þ`þ`þdþþþþþþËþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáíþdþdþdþdþfþþþþþþþeþþ@î9\0\0\0\0!\bUÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÖ,ÀÔ`þ`þ ö í`åå\0öbþþþþþªþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿoî\0ö`þ`þþ`þbþþþþþþþcþÀþ\0\0\0\0Ã\x18UÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzÆ\v@Ýþ ö Ý`Ìà»À³ÌÀíþeþfþþÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼ÿôîNæ"ÝÀí`þeþþþþþeþ þ`Í`\x10\0\0§9XÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÖm¤íþ`åà»@r\09À(`I`\0öþAþÊþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿsæ\0öþþþþfþþ`ö`9\0\0ËZ]ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÕÀíþ\0ÝQ\0\0\0\0\0\0\0\0 \bàþbþ1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-îþþþþ
þÀþ\0{\0\0¯s¾÷ÿÿÿÿÿÿÿÿÿÿ¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôî\x01ö¥þÃíÀ(\0\0\0\0\0\0\0\0\0\0 \b´%ÿSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!öþfþþâþ@¬!\brÿÿÿÿÿÿÿÿÿÿÿÿïÖßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6÷"þeþäþ R\0\0\0\0\0\0\0\0\0\0\0\0¡AbÍÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW÷ þÂþâþ`Õc1\x15ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ^[ß\x18Æßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ1ÿ\fÿFÅ\0) \0\0\0\0\0\0\0\0\0$!F)`\x10ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷Àrà´\0Á Ð{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµB\b$!ã\x18!\bÃ\x18$!¦1¢\x10\0\0ÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞ\0\0 \b\0\0Ä\x18ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞXÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10b\x10f1Ã\x18\x10\x10\0\0\0\0\0\0²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8Æ\0\0\0\0Ã\x18\x04!0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10\0\0b\x10e)\0\0\0\0\0\0\0\0\0\0\fcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷ \0\0\0%)¢\x10ï{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÞ8ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÞb\x10\0\0\0\0f1A\b\0\0\0\0\0\0\0\0Mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x14¥\0\0$!b\x10ëZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<ç\x18ÆßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÞb\x10\0\0\0\0£\x18A\b\0\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!\b¢\x10A\b§9ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿï8ÆÞ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎa\b\0\0\0\0 \0 \0\0\0\0\0\0\0\0\0YÎÿÿÿÿÿÿÿÿÿÿÿÿï¶}u}u}u}u~®\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÞ¾}u}u}u}u\x1e\x1eÏÿÿÿÿÿÿÿÿß÷Þ¾}}u}u}Þ¾ß÷ÿÿÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u}u}u}u}u}u}uÞ¾ÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿ¶}u}uÝ
\x1eÏþÆ}u}uÝ
ÿÿ¶}u}u}u_ßÿÿÿÿÞ¾}u}u}u¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷½\0\0\0\0£\x18yÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿ^[ßßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×½A\b\0\0\0\0a\ba\b\0\0\0\0\0\0\0\0<çÿÿÿÿÿÿÿÿÿÿï}}u}u}u}u}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç}}u}u}u}u}u}u}u¶ÿÿÿÿïÝ
}u}u}u}u}u}uÝ
ïÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u}u}u}u}u}u}uÞ¾ÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÞ¾}u}u}u}u}u\x1e}u}uÝ
ÿÿß÷Ý
}u}uÝ
ÿÿï}u}u}uÝ
ß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿa\ba\b\0\0\x14¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó\0\0\0\0\0\0Ã\x18¢\x10\0\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}uýß÷ÿÿ\x1e}u}u}ß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ
}u}uÝ
ïÿÿ\x1e}u}u}u_ßÿÿ\x1e}u}uÝ
ß÷ß÷Ý
}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u}u}u}u}u}u}uÞ¾ÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿý}u}u}u}u}u}u}u}uÝ
ÿÿÿÿ\x1eÏ}u}u}u¶~®}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x13A\b!\bRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿmk\0\0\0\0\0\0E)¢\x10\0\0\0\0\0\0mkÿÿÿÿÿÿÿÿÿÿ\x7fç}u}u}u\x1eÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~®}u}u}u}u~®ÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç}u}u}uÞ¾ÿÿÿÿï}Þ¾\x1eÏÿÿ\x7fç}u}u}uþÆÿÿÿÿÞ¾}u}u}u\x7fçÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿ}}u}uÝ
ß÷\x7fç}}u}uÝ
ÿÿÿÿÿÿ^¦}u}u}u}u}u}u~®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷A\bÃ\x18A\b8Æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷èAA\b\x10!\b1A\b\0\0\0\0\0\0]ïÿÿÿÿÿÿÿÿÿÿ\x1eÏ}u}u}u}u}u}u}u}u}u}uþÆÿÿÿÿÿÿÿÿÿÿÿÿ~®}u}u}u}u~®ÿÿÿÿÿÿÿÿÿÿÿÿþÆ}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÆ}u}u}u_ßÿÿÿÿ_ß}u}u}u\x1eÏÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u~®ÿÿÿÿ~®}u}u}uÿÿÿÿ}u}u}u~®ÿÿÿÿ^¦}u}uÝ
ÿÿÿÿÿÿß÷}}u}u}u}uÝ
ß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%)Ã\x18 \0ªRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎÃ\x18Ã\x18\x04!¢\x10ã\x18\0\0\0\0\0\0$!ÿÿÿÿÿÿÿÿÿÿÿÿ\x1eÏ}u}u}u}u}u}u}u}u}u}uþÆÿÿÿÿÿÿÿÿÿÿÿÿ~®}u}u}u}u~®ÿÿÿÿÿÿÿÿÿÿÿÿþÆ}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1eÏ}u}u}u_ßÿÿÿÿ_ß}u}u}u\x1eÏÿÿÝ
}u}u^¦ÿÿÿÿ~®}u}u}uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u^¦ÿÿÿÿ~®}u}u}uÿÿÿÿ}u}u}u~®ÿÿÿÿ~®}u}uÝ
ÿÿÿÿÿÿÿÿ^¦}u}u}u}u^¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×½A\bÃ\x18!\bÖµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÛÞÓ\0\0a\b\x10a\b \0\0\0\0\0\0\0yÎÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç}u}u}u\x1eÏÿÿÿÿ\x7fç}u}u}u\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç}u}u}uÞ¾ÿÿÿÿ_ßÝ
Þ¾\x7fçÿÿ\x7fç}u}u}uþÆÿÿÿÿþÆ}u}u}u\x7fçÿÿÝ
}u}u}\x7fçß÷Ý
}u}uÝ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u}\x7fçß÷Ý
}u}uÝ
ÿÿÿÿ}u}u}u~®ÿÿÿÿ~®}u}uÝ
ÿÿÿÿÿÿþÆ}u}u}u}u}u}u\x1eÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA\b\x10\0\0\bB\çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<çu\x18Æ\bB\0\0a\bä !\b\0\0\0\0\0\0E)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}uýß÷ÿÿ\x1e}u}uÝ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ
}u}uÝ
ïÿÿ\x1e}u}u}ß÷ÿÿ\x1e}u}uÝ
ïß÷Ý
}u}u\x1eÿÿÿÿÝ
}u}u}u}u}u}u}u}uýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u}u}u}u}u}u}uýÿÿÿÿ}u}u}u~®ÿÿÿÿ~®}u}uÝ
ÿÿÿÿï}}u}uÝ
ý}u}u}ß÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0\0\0\0\0 \00]ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]ïYÎÓ¶µ\x14¥\0\0¢\x10f1\x10\0\0\0\0\0\0\0\0\çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÝ
}u}u}u}u}u}u}\x7fçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x7fç}}u}u}u}u}u}u}uþÆÿÿÿÿïÝ
}u}u}u}u}u}uÝ
ïÿÿÿÿÝ
}u}u\x1e}u}u}u}u}uÞ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}u\x1e}u}u}u}u}uÞ¾ÿÿÿÿ}u}u}u~®ÿÿÿÿ~®}u}uÝ
ÿÿÿÿ^¦}u}u}u\x1eÏ\x7fç}u}u}u^¦ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0\0\0\0\0èAóyξ÷ÿÿÿÿÿÿ^[ß]ïÿÿÿÿÿÿÿÿ¾÷<çYε\x14¥q\x13<çÇ9\0\0Ã\x18A\b\0\0\0\0\0\0\0\0Mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß÷Þ¾}u}u}u}u¶ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß÷Þ¾}u}u}u}u^¦_ßÿÿÿÿÿÿÿÿÿÿÞ¾}}u}u}Þ¾ß÷ÿÿÿÿÿÿÝ
}u}uþÆ\x1eÏÝ
}u}uÞ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÝ
}u}uþÆ\x1eÏÝ
}u}uÞ¾ÿÿÿÿÿÿ}u}u}u~®ÿÿÿÿ~®}u}uÝ
ÿÿÞ¾}u}u}u\x1eÿÿÿÿ¶}u}u}u\x1eÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQ\0\0\0\0\x04!Ó<çÿÿÿÿÿÿ¾÷ûÞ^[ß¾÷ÿÿÿÿÿÿ¾÷ûÞ\x18ƵUU]ïµ \0\0\0\0\0\0\0\0\0\0\0\0\0A\bßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢\x10\0\0\0\0óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷÷¾÷ÿÿiJ\0\0\0\0\0\0\0\0\0\0\0\0\0\0^[ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷ \0\0\0MkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÆ\x10\0\0\0\0\0\0\0\0\0\0\0\0\fcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u}u_ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x1e}u}u\x1eÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyÎ\0\0\x04!^[ßÿÿÿÿÿÿÿÿßÿÞ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQ\0\0\0\0\0\0\0\0\0\0\0\0a\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0\0\0MkÿÿÿÿÿÿÞ÷ÛÞºÖ\çßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ÷\bB\0\0\0\0\0\0\0\0\0\0\0\0<çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1!\bUÿÿÿÿÚÞvvø½ÛÖ¾÷ÿÿÿÿÿÿÿÿÿÿÿÿ×½!\b\0\0\0\0\0\0\0\0\0\0\x14¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾÷\0\0Ç9¾÷\çU¥ïÍ.ò¤Zƾ÷ÿÿÿÿÿÿÿÿ÷\bB\0\0\0\0\0\0\0\0\0\0%)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç9$!yÎØµÌ\x02´¡Ì¡ÌBÄH¬÷Åïÿÿÿÿÿÿ\x14¥\0\0\0\0\0\0 \0\0\0\0\0]ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x18Æ\x04!V¥\rá³ í\0î\0î þÀí£ÄQ½ÜÖ¿ï}ïiJ\0\0 \0§9ªR!\bIJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÖ£\x18Ëá³ Ýåå@Ý@ÝåàíåGͰÍÓÃ\x18\0\0e)®sëZ\0\0}ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYÆà0`Ì\0ö`þ`þ`þaþCöâí\0Õ@Ý@ö ö\x03\0\0 \0IJ(BA\b¦1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶µ@r@þþ`þ`þaþ`þbþþþ`ÝÀÌ îÀÄ@\x10\0\0A\b\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³Àa õþ`þ`þcþAþ@þcþþ¤þàí@ÝÝÀ \0\0\0\0\0\0\0\0Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\x10\0\0¤Bþþ`þdþdþ`þ@þ£þÄþÂþþa \0\0\0\0\0\0\0 \0¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëZb\b9ÆÀÌíþcþ`å þÀå i¤üÿR\0\0\0\0\0\0\0\0\x10ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%)«Zó\x01\0¢I$Ý\0îÀí Ì(î$R\0\0"\0×µ^[çä \0\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿa\b\x10\bBÃ\x18ìZ\x16Æá(á()kÞÿF)\0\0\0\0s¾÷èA\0\0\0\0\0\0IJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \0q(B\x04!QÖb\b£\x10NkÿÿÇ9\0\0§9¶µ÷Ç9\0\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0ï{yÎï{^[ß\x18Æ \0\0\0\bBÿÿ8ÆmkUÿÿ\x18Æa\b\0\0\0\0\0\0Ã\x18ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!\bE)ºÖÿÿ}ï(B\0\0\0\0A\b4¥ÿÿÿÿÿÿ\çiJ\0\0\0\0\0\0\0\0$!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿa\b\0\0ç9sIJE)A\b\0\0\0\0Ã\x18Qu\x14¥ëZE)\x10\0\0\0\0\0\0mkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢\x10\0\0\0\0\0\0\x04!ã\x18\0\0\0\0\0\0\0\0a\b\x04!ä ¦11 \0\0\0\0\0\0\0\x17¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIJ\0\0\0\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0b\x10\0\0\0\0\0\0\0\0\0\0Þ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÖ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0!\b\0\0\0\0\0\0\0\0\0\0ºÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!\bÇ9¦1Ã\x18!\b\0\0§9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÆ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0iJÏ{Ç9 \0a\bßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0E)1\0\0\x10¾÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÖ¢\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\fcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYÎMkb\x10\0\0\0\0 \01\x14¥÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/linux_white_bk_200_100_8bit.bmp u-boot-2008.10/tools/logos/linux_white_bk_200_100_8bit.bmp
+--- u-boot-2008.10_original/tools/logos/linux_white_bk_200_100_8bit.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/linux_white_bk_200_100_8bit.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1 @@
++BMXR\0\0\0\0\0\06\x04\0\0(\0\0\0È\0\0\0d\0\0\0\x01\0\b\0\0\0\0\0"N\0\0\x12\v\0\0\x12\v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ÀÜÀ\0ðʦ\0ª?*\0ÿ?*\0\0_*\0U_*\0ª_*\0ÿ_*\0\0\x7f*\0U\x7f*\0ª\x7f*\0ÿ\x7f*\0\0*\0U*\0ª*\0ÿ*\0\0¿*\0U¿*\0ª¿*\0ÿ¿*\0\0ß*\0Uß*\0ªß*\0ÿß*\0\0ÿ*\0Uÿ*\0ªÿ*\0ÿÿ*\0\0\0U\0U\0U\0ª\0U\0ÿ\0U\0\0\x1fU\0U\x1fU\0ª\x1fU\0ÿ\x1fU\0\0?U\0U?U\0ª?U\0ÿ?U\0\0_U\0U_U\0ª_U\0ÿ_U\0\0\x7fU\0U\x7fU\0ª\x7fU\0ÿ\x7fU\0\0U\0UU\0ªU\0ÿU\0\0¿U\0U¿U\0ª¿U\0ÿ¿U\0\0ßU\0UßU\0ªßU\0ÿßU\0\0ÿU\0UÿU\0ªÿU\0ÿÿU\0\0\0\x7f\0U\0\x7f\0ª\0\x7f\0ÿ\0\x7f\0\0\x1f\x7f\0U\x1f\x7f\0ª\x1f\x7f\0ÿ\x1f\x7f\0\0?\x7f\0U?\x7f\0ª?\x7f\0ÿ?\x7f\0\0_\x7f\0U_\x7f\0ª_\x7f\0ÿ_\x7f\0\0\x7f\x7f\0U\x7f\x7f\0ª\x7f\x7f\0ÿ\x7f\x7f\0\0\x7f\0U\x7f\0ª\x7f\0ÿ\x7f\0\0¿\x7f\0U¿\x7f\0ª¿\x7f\0ÿ¿\x7f\0\0ß\x7f\0Uß\x7f\0ªß\x7f\0ÿß\x7f\0\0ÿ\x7f\0Uÿ\x7f\0ªÿ\x7f\0ÿÿ\x7f\0\0\0ª\0U\0ª\0ª\0ª\0ÿ\0ª\0\0\x1fª\0U\x1fª\0ª\x1fª\0ÿ\x1fª\0\0?ª\0U?ª\0ª?ª\0ÿ?ª\0\0_ª\0U_ª\0ª_ª\0ÿ_ª\0\0\x7fª\0U\x7fª\0ª\x7fª\0ÿ\x7fª\0\0ª\0Uª\0ªª\0ÿª\0\0¿ª\0U¿ª\0ª¿ª\0ÿ¿ª\0\0ߪ\0Uߪ\0ªßª\0ÿߪ\0\0ÿª\0Uÿª\0ªÿª\0ÿÿª\0\0\0Ô\0U\0Ô\0ª\0Ô\0ÿ\0Ô\0\0\x1fÔ\0U\x1fÔ\0ª\x1fÔ\0ÿ\x1fÔ\0\0?Ô\0U?Ô\0ª?Ô\0ÿ?Ô\0\0_Ô\0U_Ô\0ª_Ô\0ÿ_Ô\0\0\x7fÔ\0U\x7fÔ\0ª\x7fÔ\0ÿ\x7fÔ\0\0Ô\0UÔ\0ªÔ\0ÿÔ\0\0¿Ô\0U¿Ô\0ª¿Ô\0ÿ¿Ô\0\0ßÔ\0UßÔ\0ªßÔ\0ÿßÔ\0\0ÿÔ\0UÿÔ\0ªÿÔ\0ÿÿÔ\0U\0ÿ\0ª\0ÿ\0\0\x1fÿ\0U\x1fÿ\0ª\x1fÿ\0ÿ\x1fÿ\0\0?ÿ\0U?ÿ\0ª?ÿ\0ÿ?ÿ\0\0_ÿ\0U_ÿ\0ª_ÿ\0ÿ_ÿ\0\0\x7fÿ\0U\x7fÿ\0ª\x7fÿ\0ÿ\x7fÿ\0\0ÿ\0Uÿ\0ªÿ\0ÿÿ\0\0¿ÿ\0U¿ÿ\0ª¿ÿ\0ÿ¿ÿ\0\0ßÿ\0Ußÿ\0ªßÿ\0ÿßÿ\0Uÿÿ\0ªÿÿ\0ÿÌÌ\0ÿÌÿ\0ÿÿ3\0ÿÿf\0ÿÿ\0ÿÿÌ\0\0\x7f\0\0U\x7f\0\0ª\x7f\0\0ÿ\x7f\0\0\0\0\0U\0\0ª\0\0ÿ\0\0\0¿\0\0U¿\0\0ª¿\0\0ÿ¿\0\0\0ß\0\0Uß\0\0ªß\0\0ÿß\0\0Uÿ\0\0ªÿ\0\0\0\0*\0U\0*\0ª\0*\0ÿ\0*\0\0\x1f*\0U\x1f*\0ª\x1f*\0ÿ\x1f*\0\0?*\0U?*\0ðûÿ\0¤ \0\0\0\0ÿ\0\0ÿ\0\0\0ÿÿ\0ÿ\0\0\0ÿ\0ÿ\0ÿÿ\0\0ÿÿÿ\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\bª\bööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª\b÷÷öÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\b\bªª÷}|xxx}\b\b\bÿöÿÿÿÿÿÿ\bª ªyxxxx|÷\b«ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b«\bª÷\a||| ¤¤ |}\b\b¯\b¯\b¯\bÔ\b\bª||| ¤ |}\b\b\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b÷}x| ¤¤ÊÊÊʤ |P1\aªª÷÷\a1x ¤¤¤¨¤¤x}\b\b\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®}}||¤¤¨ÊÊÎÊÎÊÎʤ¤|ì\0\0\0ððñðõõðñ\0\0𠤤ÊÊÊÊʨ¤}¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®¨¤ÊÊÊÊÊÊÎÊÎÊÎËÎÊÎʤ|ð\0\0\0\0\0\0\0\0\0\0\0\0\0(|¤ÊÎÊÏÎÊÎÊʤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÊÎÊÎÊÎÊÎËÎËÏËÎËÎÊÎÊ|ì\0\0\0\0\0\0\0\0\0\0\0\0\0ð ÊÊÏËÎËÏÊÏÎÊÊ®ÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÊÎÊÎÊÏÊÏÎËÎËÎÏËÏÊÊÊTõ\a\a\a-\0\0\0\0\0\0ð|¨ÎÊÏÊÏÊÏÊËÏÎÊ©ööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÎÊÏËÏÊÏËËÎÏËÎËÎÎÊΤ\aöÿÿÿÿÿÿö\b÷-\0\0\0ìxÊÊÎËÏËÎËÏÎËÏÏÎÏÐöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©ÊÏËÎÊÏÊÏÎÏËÎËÏÊËÎÊÿÿÿÿÿÿÿÿÿÿÿÿ\b-\0\0T¤ÊÏÊÏÎËÏÎËÎËÊÏËÏÏÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÎËÎËÏËÏÊÏËÎËÎËÏÎÊ©öÿÿÿÿÿÿÿÿÿÿÿÿÿ¯-\0P¤ÊÎÏËÊÏÎËÏÊÏÏÊÏÊÏÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÊÎÏÊÏÎÊÏÊÏËÎËÎËΤõ1ªÿÿÿÿÿÿÿÿÿÿÿÿÿöõ(¤ÊÊÎÏÏËËÎËÏÊÏÏÎËÎÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÎÊËÏÊÏÏËÏÎÎËÏÏÊÎT\0\0õÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b,¤ÊÎÊÊÊÎÎËÎËÏÊÏËÏöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ÊÏÏÎËÏÊÏÊËËÏÊÊΤ\0\0\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯} ÊÊÎÊÎÊÊÊÏÏÊÏÊÏöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÎÏÊËÎËÏÊÏÎÏÊÏÎÊð\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯}¤ÎÎÊʤ¨ÊÎËÊÏËÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©ÊÊÎÎÊÎÊÏËÊÏÏÊÎ\x03\0\0ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b}¤Êʤ¤ | ÊÎÏÊÏöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöЩ¤ÊÊÏÊÏÏËÊΤ\0\0õªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯}ÊΨ|Pðð(|ÊÊÎÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÊÎËÎËÎÎÊô\01öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª¨Ê¤(\0\0\0\0\0TÎÊÐöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÎÏËÎËÎT\0\aöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÊÎÊð\0\0\0\0\0\0ÏÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÎËÏÎ\0\aÿÿÿÿÿÿö\bÿÿÿÿÿÿÿÿÿÿÿÿÿÐÊÏÎ,\0\0\0\0\0\0ô¤öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÎÎΤð÷ÿÿÿÿÿÿÿ¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿöÐÏ¥ð\0\0\0\0\0ðñ\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöT|ð\aÿÿÿÿÿÿÿÿ¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ñð\0\0ñõð\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¯\0\0\0\0÷ÿÿÿÿÿÿÿÿ\b\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¯\0\0ññð\0\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0ñð\aÿÿÿÿÿÿÿö¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ð\0\0ô\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0ðð\aÿÿÿÿÿÿÿÿ¯\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0ñ\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0ñ\01ÿÿÿÿÿÿÿÿ¯ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ì\0\0ð\0\0\0\0\0÷öÿÿÿÿÿÿÿöööööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööööÿÿÿÿÿÿööööÿÿÿÿÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööööööÿÿöÿÿÿööÿÿÿöÿöÿÿÿÿÿÿÿÿÿÿÿöööööÿööÿÿÿÿÿöÿÿÿöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ð\0õÑÿÿÿÿÿÿÿö\böÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\0\0\0\bÿÿÿÿÿÿö ;c_c ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö:_c; ¯ÿÿÿÿö _c;c öÿÿÿcc_ ÿÿ ;b;ÿÿÿÿÿÿÿÿ ;__c_c^_c ÿ __ ÿÿcc_ ÿÿ ;b;ÿÿÿ __c¯¯_ccÿ _^c¯ÿÿÔc;_ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0ð\bÿÿÿÿÿÿÿö¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0\0\0\0\0\0\0¯ÿÿÿÿÿ³cc_?__?_¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯c_c;_c_c ÿÿöcc_c__c_³ÿöc:c ÿÿ c_cÿÿÿÿÿÿÿö c?^;c;c;cÔÿ c; ÿöc:c ÿÿ c_cÿö cc;c; :_cÿöc?_cÿ³b_ccÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0\0ð\0\0\0\0\0ÿÿÿÿÿö _; öÿ _ccöÿÿÿÿÿÿÿööööÿÿÿÿÿÿÿöc__cöÿc_?_¯ö ?_cöÿc_> ÿöcc_ ÿÿ _;_öÿÿÿÿÿÿÿc__cc_c_c_ÿ ;c ÿÿcc_ ÿÿ _;_öÿc_:c_c_c_cöÿ¯c_c _?_¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿU\0\0\0ðð\0\0\0\aÿÿÿÿÿ³_>c¯öööööÿöÿÿÿÿÿÿ c;c_ ÿÿÿÿÿÿ¯c:cÿÿÿcÔ¯ÿ¯_^cÿÿc_c¯ÿc__ ÿÿ cccöÿÿÿÿÿÿÿ _c;¯öÿÿÿÿÿÿcc^cÿÿc__ ÿÿ cccöÿc_ccö¯c_?cöÿÿ _?^cc_ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\0ð\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ\0\0\0õ\0\0\0\0öÿÿÿÿö¯c__;c;c;c;¯ÿÿÿÿÿÿ _c;c ÿÿÿÿÿö¯c__¯ÿÿÿÿÿÿö¯c?_¯ÿÿ¯_?_¯öc;c ÿÿ _;_ÿÿÿÿÿÿÿÿ ?_c¯ÿÿÿÿÿÿÿ _? ÿöc;c ÿÿ _;_ÿÿ_?_ ÿÿ c_cÿÿÿöc_;_;cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñð\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\bððñðð\0\0\0ðÿÿÿÿÿÿ¯;cc_c_c_b_¯ÿÿÿÿÿÿ c_c_ ÿÿÿÿÿÿ¯;cc¯ÿÿöÿÿÿÿ¯__c¯ÿÿ¯b_c¯öcc_ öÿ bc_ÿÿÿÿÿÿÿÿ _>_¯ÿÿÿÿÿÿö __ ÿöcc_ öÿ bc_ÿöc_c ÿÿ >_cÿÿÿö ccc_ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ð\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöö¯÷\0\0ð\0\0\0\0\0\bÿÿÿÿÿÿ¯c_:¯ÿÿ¯_?_³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯c_:Ôöÿ¯c\b³ÿ¯c?^¯öÿÔ;c;¯ÿc^?c¯öc_;cöÿÿÿÿÿÿÿcc_c¯ÿÿÿÿÿÿÿcc; ÿÿc^?c¯öc_;cöÿ;b; ÿÿ __cöÿÿ_:_;c^¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ð\0-ööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ª-\0\0ð\0\0\0\0ðÿÿÿÿÿÿÿÿc_ccöö c_cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿc_ccöö _?_öÿc__cööcc_ ÿÿc_c_c_>_c ÿÿÿÿÿÿÿÿ _c;³öÿÿÿÿÿÿ _c ÿÿc_c_c_>_c ÿÿ_c_ ÿÿ cccöÿöc_cc _?cöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\a\0\0\0\aöÿÿÿÿÿÿÿÿÿÿÿÿöÿÿÑ\b÷÷\0\0õ\0\0\0\0\0öÿÿÿÿÿÿÿÿöc_c;c;_c¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯c__?_?_c¯ÿÿöcc;_?__cÿÿöc_; ;c_?_ÿÿÿÿÿÿÿÿ ;c_¯ÿÿÿÿÿÿÿ ;_cÿöc_; ;c_?_ÿöc;c ÿÿ ;_cÿÿ _?_¯³_c; ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\0\0\0õ÷\böÿÿÿ\böÿÿÿÿö¯\b÷\a÷öõ\0ð\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿ_c_c ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿc_c_ ¯ÿÿÿÿÿÔcc_cÿÿÿÿcc_¯¯c_cÔÿÿÿÿÿÿÿÿÿ c:c¯ÿÿÿÿÿÿÿ c_ ÿÿcc_¯¯c_cÔÿÿÿ_c_ ÿÿ c_cÿ_c_ ÿÿ _c_¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\a\0\0ð÷¯öÿÿö¯¯öÿÿÿö¯ªö\0\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ __c¯ÿÿÿÿÿÿÿöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööÿ-\0\0\0\0\0\0\0¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿc_?_¯ÿÿÿÿÿÿÿc_? ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\0\0\aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ c_c¯ÿÿÿÿÿÿÿ c_ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0ð¯ÿÿÿÿöÿöÿÿÿÿÿÿÿÿÿ\a\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\a\0Uÿÿÿÿ¯\bÑöÿÿÿÿÿÿÿÿõ\0\0\0\0\0\0¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ\0ÿÿ\b\b¯öÿÿÿÿÿÿ\0\0\0\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö\0õÿ¯\a\a\a\bÿÿÿÿÿö-\0\0\0\0\0ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõð\bª\a|¤¤|}ªÿÿÿÿ÷\0\0\0\0\0\0öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªñ\a|ÊÊÊÊʤ\bö¯-\0\0õ1\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔðY|¤¨¤¤¤¨Ê¤¥ª÷ð\0õY1\0öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\bð¤ÊÊÎÊÎÊʤ¨ÊÊT\0\0--\0ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPÊÊÎÊÊÎÊÏΤ¤Ê¤\0\0\0\0\0÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷,ÊÎÊÎÎÊÊÎËÏʤ¨ð\0\0\0\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\a\0xÊÎÊÊËÎÊÎÎÎÎT\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1\0\bU¤ÊÎΤʨ|}ö\a\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð1÷\0,¥Ê¨¤Ë-\0\0¯ð\0\0\0ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\aõð1ªððUöð\0\0\aöõ\0\0\0-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0÷-ð\a\b\0ð1ÿõ\0õÑõ\0\0\0õöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\a\b\a¯\0\0-ÿ\b\aÿ\b\0\0\0\0ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0ð\böö-\0\0\0÷ÿÿÿÑ1\0\0\0\0ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0õ\a-ñ\0\0\0ðZ1ð\0\0\0\0Uÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0\0ðð\0\0\0\0\0ððõõ\0\0\0\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0\0\0\0\0\0\0\0\0\0õôð\0\0õöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\b\0\0\0\0\0\0\0\0\0\0-\aõ\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷\0\0\0\0\0\0\0\0\0ðõ\0\0öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\bð\0\0\0\0\0\0\0\0\01ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\bU\0\0\0\0õ÷öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\0
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/logos/test1_565.bmp u-boot-2008.10/tools/logos/test1_565.bmp
+--- u-boot-2008.10_original/tools/logos/test1_565.bmp 1970-01-01 05:30:00.000000000 +0530
++++ u-boot-2008.10/tools/logos/test1_565.bmp 2009-08-12 18:21:20.000000000 +0530
+@@ -0,0 +1 @@
++\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\x03ËyÎ\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È\0È
+\ No newline at end of file
+diff -Naur u-boot-2008.10_original/tools/Makefile u-boot-2008.10/tools/Makefile
+--- u-boot-2008.10_original/tools/Makefile 2008-10-19 01:00:31.000000000 +0530
++++ u-boot-2008.10/tools/Makefile 2009-08-12 18:21:20.000000000 +0530
+@@ -47,6 +47,7 @@
+ ifeq ($(VENDOR),atmel)
+ LOGO_BMP= logos/atmel.bmp
+ endif
++LOGO_BMP= logos/linux_white_bk_200_100_8bit.bmp
+
+
+ #-------------------------------------------------------------------------
diff --git a/recipes/u-boot/u-boot_2008.10.bb b/recipes/u-boot/u-boot_2008.10.bb
new file mode 100644
index 0000000..ad5935d
--- /dev/null
+++ b/recipes/u-boot/u-boot_2008.10.bb
@@ -0,0 +1,16 @@
+require u-boot.inc
+
+PV = "2008.10"
+
+DEFAULT_PREFERENCE = "-1"
+
+DEFAULT_PREFERENCE_regulus = "1"
+
+PR = "r0"
+
+SRC_URI = "ftp://ftp.denx.de/pub/u-boot/u-boot-${PV}.tar.bz2"
+
+SRC_URI_append_regulus = "\
+ file://regulus_u-boot-2008.10.patch;patch=1 \
+ "
+
--
1.6.0.4
[-- Attachment #5: 0004-regulus-demo-image-Regulus-image-is-added.patch --]
[-- Type: text/x-patch, Size: 2899 bytes --]
From f7b4184fc3eb0ada48af50f1181dda104c96b996 Mon Sep 17 00:00:00 2001
From: balakrishnan <balakrishnan@e-consystems.com>
Date: Wed, 17 Mar 2010 19:16:53 +0530
Subject: [PATCH] regulus-demo-image: Regulus image is added
* Regulus is a pxa270 based machine
* Angstrom distribution image created
Signed-off-by: balakrishnan <balakrishnan@e-consystems.com>
---
recipes/images/regulus-demo-image.bb | 28 ++++++++++++++++++++
recipes/tasks/task-regulus-demo.bb | 46 ++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 0 deletions(-)
create mode 100644 recipes/images/regulus-demo-image.bb
create mode 100644 recipes/tasks/task-regulus-demo.bb
diff --git a/recipes/images/regulus-demo-image.bb b/recipes/images/regulus-demo-image.bb
new file mode 100644
index 0000000..2964fa0
--- /dev/null
+++ b/recipes/images/regulus-demo-image.bb
@@ -0,0 +1,28 @@
+# Demo image for regulus
+
+IMAGE_LINGUAS = "de-de fr-fr en-gb en-us pt-br es-es kn-in ml-in ta-in"
+
+XSERVER ?= "xserver-xorg \
+ xf86-input-evdev \
+ xf86-input-mouse \
+ xf86-video-fbdev \
+ xf86-input-keyboard \
+"
+
+ANGSTROM_EXTRA_INSTALL ?= ""
+
+export IMAGE_BASENAME = "regulus-demo-image"
+
+DEPENDS = "task-base"
+IMAGE_INSTALL = "\
+ ${XSERVER} \
+ ${ANGSTROM_EXTRA_INSTALL} \
+ task-regulus-demo \
+"
+
+IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp"
+
+#zap root password for release images
+ROOTFS_POSTPROCESS_COMMAND += '${@base_conditional("DISTRO_TYPE", "release", "zap_root_password; ", "",d)}'
+
+inherit image
diff --git a/recipes/tasks/task-regulus-demo.bb b/recipes/tasks/task-regulus-demo.bb
new file mode 100644
index 0000000..b463720
--- /dev/null
+++ b/recipes/tasks/task-regulus-demo.bb
@@ -0,0 +1,46 @@
+DESCRIPTION = "Task for Regulus-demo-image"
+
+PR = "r0"
+
+inherit task
+
+ECONFIG ?= "places e-wm-config-angstrom e-wm-config-default"
+
+RDEPENDS_${PN} = "\
+ task-proper-tools \
+ task-base-extended \
+ angstrom-x11-base-depends \
+ angstrom-gpe-task-base \
+ angstrom-gpe-task-settings \
+ angstrom-zeroconf-audio \
+ angstrom-led-config \
+ gpe-scap \
+ psplash \
+ mime-support e-wm ${ECONFIG} \
+ xterm xmms \
+ firefox midori \
+ swfdec-mozilla \
+ hicolor-icon-theme gnome-icon-theme \
+ jaaa nmap iperf gnuplot \
+ abiword \
+ powertop oprofile \
+ pidgin \
+ mplayer \
+ gnome-mplayer \
+ rt73-firmware zd1211-firmware \
+ stalonetray \
+ synergy \
+ x11vnc angstrom-x11vnc-xinit \
+ angstrom-gnome-icon-theme-enable \
+ openssh-scp openssh-ssh \
+ picodlp-control \
+ connman-gnome \
+ exhibit gnumeric \
+ gimp gnome-games \
+"
+
+# Install all kernel modules
+RRECOMMENDS_${PN} += "kernel-modules"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
--
1.6.0.4
next parent reply other threads:[~2010-03-17 14:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.5.1268823603.27114.openembedded-devel@lists.openembedded.org>
2010-03-17 14:14 ` balakrishnan [this message]
2010-03-16 12:12 [PATCH] Add pxa270 based Regulus Board balakrishnan
2010-03-17 9:20 ` Ruud Althuizen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1268835281.28188.19.camel@balakrishnan-desktop \
--to=balakrishnan@e-consystems.com \
--cc=openembedded-devel@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox