[oe] [PATCH] oxnas: remove support for oxnas machine

Steffen Sledz sledz at dresearch.de
Mon Feb 1 16:10:54 UTC 2010


OXNAS machine was only used as prototyp for HIPOX machine and is not
needed any longer. Because of constant build problems support is
finished.

Signed-off-by: Steffen Sledz <sledz at dresearch.de>
---
 conf/machine/oxnas.conf                            |   20 -
 recipes/linux/linux-2.6.24/oxnas/defconfig         | 1232 -
 .../oxnas/oxnas-pci-config-delay.patch             |   56 -
 .../linux-2.6.24/oxnas/oxnas-pci-max-size.patch    |   21 -
 recipes/linux/linux-2.6.24/oxnas/oxnas-uart.patch  |  176 -
 recipes/linux/linux-2.6.24/oxnas/oxnas.diff        |57804 --------------------
 recipes/linux/linux_2.6.24.bb                      |    8 -
 recipes/u-boot/u-boot-1.1.2/oxnas.patch            | 7257 ---
 recipes/u-boot/u-boot_1.1.2.bb                     |    2 -
 9 files changed, 0 insertions(+), 66576 deletions(-)
 delete mode 100644 conf/machine/oxnas.conf
 delete mode 100644 recipes/linux/linux-2.6.24/oxnas/defconfig
 delete mode 100644 recipes/linux/linux-2.6.24/oxnas/oxnas-pci-config-delay.patch
 delete mode 100644 recipes/linux/linux-2.6.24/oxnas/oxnas-pci-max-size.patch
 delete mode 100644 recipes/linux/linux-2.6.24/oxnas/oxnas-uart.patch
 delete mode 100644 recipes/linux/linux-2.6.24/oxnas/oxnas.diff
 delete mode 100644 recipes/u-boot/u-boot-1.1.2/oxnas.patch

diff --git a/conf/machine/oxnas.conf b/conf/machine/oxnas.conf
deleted file mode 100644
index 0821329..0000000
--- a/conf/machine/oxnas.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-#@TYPE: Machine
-#@NAME: OXE810(D)SE NAS devices
-#@DESCRIPTION: Machine configuration for Oxford OXE810(D)SE NAS devices http://www.oxsemi.com/products/storage/nas.html
-
-TARGET_ARCH = "arm"
-
-MACHINE_FEATURES = "kernel26 ext2 pci usbhost ethernet serial raid uboot"
-
-SERIAL_CONSOLE = "115200 ttyS0"
-
-PREFERRED_PROVIDER_virtual/kernel = "linux"
-
-KERNEL_IMAGETYPE = "uImage"
-
-PREFERRED_VERSION_u-boot = "1.1.2"
-UBOOT_LOADADDRESS = "0x48008000"
-UBOOT_ENTRYPOINT = "0x48008000"
-UBOOT_ARCH = "arm"
-
-require conf/machine/include/tune-arm926ejs.inc
diff --git a/recipes/linux/linux-2.6.24/oxnas/defconfig b/recipes/linux/linux-2.6.24/oxnas/defconfig
deleted file mode 100644
index 5382e30..0000000
--- a/recipes/linux/linux-2.6.24/oxnas/defconfig
+++ /dev/null
@@ -1,1232 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24.4
-# Fri Oct 17 14:41:04 2008
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
-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_ZONE_DMA=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_USER_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-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 is not set
-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=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# 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_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# 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_OXNAS=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Oxford Semiconductor NAS Options
-#
-# CONFIG_ARCH_OXNAS_FPGA is not set
-CONFIG_NOMINAL_PLL400_FREQ=733333333
-CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-# CONFIG_OXNAS_VERSION_0X800 is not set
-CONFIG_OXNAS_VERSION_0X810=y
-# CONFIG_OXNAS_VERSION_0X850 is not set
-# CONFIG_ARCH_OXNAS_UART1 is not set
-CONFIG_ARCH_OXNAS_UART2=y
-# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-# CONFIG_ARCH_OXNAS_UART3 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-# CONFIG_OXNAS_PCI_RESET is not set
-# CONFIG_OXNAS_SATA_POWER_1 is not set
-# CONFIG_OXNAS_SATA_POWER_2 is not set
-CONFIG_FORCE_MAX_ZONEORDER=10
-CONFIG_SRAM_NUM_PAGES=32
-CONFIG_SUPPORT_LEON=y
-CONFIG_LEON_PAGES=2
-CONFIG_LEON_COPRO=y
-CONFIG_LEON_OFFLOAD_TX=y
-# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-CONFIG_LEON_OFFLOAD_TSO=y
-# CONFIG_LEON_START_EARLY is not set
-CONFIG_LEON_POWER_BUTTON_MONITOR=m
-CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-# CONFIG_OXNAS_DDR_MON is not set
-# CONFIG_OXNAS_AHB_MON is not set
-# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-# CONFIG_DO_MEM_TEST is not set
-# CONFIG_CRYPTO_OXAESLRW is not set
-CONFIG_DESCRIPTORS_PAGES=6
-CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-CONFIG_TACHO_THERM_AND_FAN=m
-# CONFIG_GPIO_TEST is not set
-CONFIG_OXNAS_RTC=y
-# CONFIG_I2S is not set
-# CONFIG_DPE_TEST is not set
-# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-# CONFIG_OXNAS_DMA_COPIES is not set
-# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-# CONFIG_OXNAS_USB_TEST_MODES is not set
-# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-# CONFIG_OXNAS_LED_TEST is not set
-CONFIG_OXNAS_I2C_SDA=6
-CONFIG_OXNAS_I2C_SCL=7
-# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-# CONFIG_WDC_FAN_OXNAS800 is not set
-# CONFIG_OXNAS_MAP_SRAM is not set
-# CONFIG_OXNAS_SUID_INHERIT is not set
-# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-
-#
-# Bus support
-#
-CONFIG_ARM_AMBA=y
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# 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=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_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_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE 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_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETLABEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES 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_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT=y
-# 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=y
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 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=10240
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
-# 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 is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# 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_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-CONFIG_ATA=y
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_ATA_PIIX is not set
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_OX810=y
-# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-# CONFIG_MD_RAID0 is not set
-CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=y
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_UEVENT is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O 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_ARCNET is not set
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=y
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_IP1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-CONFIG_SYNOPSYS_GMAC=y
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_TR is not set
-
-#
-# 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_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER 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 is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD 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 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=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_AMBA_PL010 is not set
-# CONFIG_SERIAL_AMBA_PL011 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_NVRAM is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOOXSEMI is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-CONFIG_I2C_OXNAS_BITBASH=m
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 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_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON 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
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# 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 is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# 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_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_UHCI_HCD is not set
-# 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=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# 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_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
-#
-
-#
-# USB Serial Converter support
-#
-# 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_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-CONFIG_USB_TEST=m
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget 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=m
-
-#
-# 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=m
-# 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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_DS1742 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_PL031 is not set
-# CONFIG_DMADEVICES 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 is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=y
-
-#
-# 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=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# 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=m
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-# CONFIG_NFS_FS is not set
-CONFIG_NFSD=m
-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_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-# 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=y
-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=y
-# CONFIG_LDM_DEBUG 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=y
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-# 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=m
-# 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=y
-# CONFIG_DLM is not set
-# CONFIG_INSTRUMENTATION is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-CONFIG_SECURITY=y
-# CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_CAPABILITIES is not set
-CONFIG_SECURITY_TRUSTEES=y
-# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-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=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS 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=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-CONFIG_CRYPTO_MICHAEL_MIC=m
-# 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_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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff --git a/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-config-delay.patch b/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-config-delay.patch
deleted file mode 100644
index 5936b5b..0000000
--- a/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-config-delay.patch
+++ /dev/null
@@ -1,56 +0,0 @@
---- linux-2.6.24.org/arch/arm/mach-oxnas/pci.c	2009-03-09 14:26:43.000000000 +0100
-+++ linux-2.6.24/arch/arm/mach-oxnas/pci.c	2009-03-09 14:31:12.000000000 +0100
-@@ -25,6 +25,7 @@
- #include <linux/interrupt.h>
- #include <linux/init.h>
- #include <linux/delay.h>
-+#include <linux/jiffies.h>
- 
- #include <asm/io.h>
- #include <asm/hardware.h>
-@@ -71,6 +72,12 @@
- 
- extern spinlock_t oxnas_gpio_spinlock;
- 
-+#ifdef CONFIG_OXNAS_PCI_RESET
-+static unsigned long pci_trhfa_startwait = 0;
-+static unsigned long pci_trhfa_msec = 0;
-+static unsigned long pci_trhfa_timeout = 0;
-+#endif // CONFIG_OXNAS_PCI_RESET
-+
- #define PCI_BUS_NONMEM_START			0x00000000
- #define PCI_BUS_NONMEM_SIZE	    		0x00080000
-                                
-@@ -505,6 +512,15 @@
- struct pci_bus *oxnas_pci_scan_bus(int nr, struct pci_sys_data *sys)
- {
- //	printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus\n");
-+
-+#ifdef CONFIG_OXNAS_PCI_RESET
-+	printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus now it's %lu, still waiting till %lu to become ready for config\n", jiffies, pci_trhfa_timeout);
-+	if (time_after_eq(jiffies + msecs_to_jiffies(pci_trhfa_msec), pci_trhfa_timeout))  /* ensure not wrap */
-+		while(time_before(jiffies, pci_trhfa_timeout)) 
-+       			udelay(100);
-+	printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus waited from %lu to %lu to become ready for config\n", pci_trhfa_startwait, jiffies);
-+#endif // CONFIG_OXNAS_PCI_RESET
-+
- 	return pci_scan_bus(sys->busnr, &oxnas_pci_ops, sys);
- }
- 
-@@ -651,6 +667,16 @@
- 
- static int __init oxnas_pci_init(void)
- {
-+#ifdef CONFIG_OXNAS_PCI_RESET
-+	// CPU has reset PCI bus via GPIO.
-+	// According to PCI spec, we have to wait for 2^25 PCI clocks to meet
-+	// the PCI timing parameter Trhfa (RST# high to first access).
-+	pci_trhfa_startwait = jiffies;
-+	pci_trhfa_msec = 1000; // 1 sec should be fine for 33MHz
-+	pci_trhfa_timeout = jiffies + msecs_to_jiffies(pci_trhfa_msec);
-+	printk(KERN_DEBUG "PCI: oxnas_pci_init now it's %lu, will wait till %lu to become ready for config\n", pci_trhfa_startwait, pci_trhfa_timeout);
-+#endif // CONFIG_OXNAS_PCI_RESET
-+
-     pci_common_init(&oxnas_pci);
- 	return 0;
- }
diff --git a/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-max-size.patch b/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-max-size.patch
deleted file mode 100644
index 89af49b..0000000
--- a/recipes/linux/linux-2.6.24/oxnas/oxnas-pci-max-size.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff -Nurd linux-2.6.24.orig//arch/arm/mach-oxnas/pci.c linux-2.6.24/arch/arm/mach-oxnas/pci.c
---- linux-2.6.24.orig//arch/arm/mach-oxnas/pci.c	2009-03-10 20:29:02.000000000 +0100
-+++ linux-2.6.24/arch/arm/mach-oxnas/pci.c	2009-03-10 21:10:47.000000000 +0100
-@@ -78,12 +78,14 @@
- static unsigned long pci_trhfa_timeout = 0;
- #endif // CONFIG_OXNAS_PCI_RESET
- 
-+// processor allows up to 8MB PCI address ranges maximum by design
-+// we split this up to 4MB prefetchable and 4MB non-prefetchable
-+
- #define PCI_BUS_NONMEM_START			0x00000000
--#define PCI_BUS_NONMEM_SIZE	    		0x00080000
--                               
-+#define PCI_BUS_NONMEM_SIZE	    		0x00400000
-                                
- #define PCI_BUS_PREMEM_START			PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
--#define PCI_BUS_PREMEM_SIZE	    		0x00080000
-+#define PCI_BUS_PREMEM_SIZE	    		0x00400000
- 
- #define SYNOPSYS_PCI_MEMORY_BASE_ADDRESS        PCI_BASE_ADDRESS_0
- #define SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS    PCI_BASE_ADDRESS_2
diff --git a/recipes/linux/linux-2.6.24/oxnas/oxnas-uart.patch b/recipes/linux/linux-2.6.24/oxnas/oxnas-uart.patch
deleted file mode 100644
index e72b0db..0000000
--- a/recipes/linux/linux-2.6.24/oxnas/oxnas-uart.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_dse_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig
---- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_dse_defconfig	2009-02-05 12:06:15.000000000 +0100
-+++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig	2009-02-05 12:08:36.000000000 +0100
-@@ -160,6 +160,8 @@
- # CONFIG_OXNAS_VERSION_0X850 is not set
- # CONFIG_ARCH_OXNAS_UART1 is not set
- CONFIG_ARCH_OXNAS_UART2=y
-+CONFIG_ARCH_OXNAS_UART2_DEBUG=y
-+CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
- # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
- # CONFIG_ARCH_OXNAS_UART3 is not set
- # CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig
---- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig	2009-02-05 12:06:15.000000000 +0100
-+++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig	2009-02-05 12:08:36.000000000 +0100
-@@ -152,6 +152,8 @@
- # CONFIG_OXNAS_VERSION_0X850 is not set
- # CONFIG_ARCH_OXNAS_UART1 is not set
- CONFIG_ARCH_OXNAS_UART2=y
-+CONFIG_ARCH_OXNAS_UART2_DEBUG=y
-+CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
- # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
- # CONFIG_ARCH_OXNAS_UART3 is not set
- # CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig
---- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig	2009-02-05 12:06:15.000000000 +0100
-+++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig	2009-02-05 12:08:36.000000000 +0100
-@@ -160,6 +160,8 @@
- # CONFIG_OXNAS_VERSION_0X850 is not set
- # CONFIG_ARCH_OXNAS_UART1 is not set
- CONFIG_ARCH_OXNAS_UART2=y
-+CONFIG_ARCH_OXNAS_UART2_DEBUG=y
-+CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
- # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
- # CONFIG_ARCH_OXNAS_UART3 is not set
- # CONFIG_ARCH_OXNAS_UART4 is not set
-diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig
---- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig	2009-02-05 12:06:15.000000000 +0100
-+++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig	2009-02-05 12:08:36.000000000 +0100
-@@ -158,6 +158,8 @@
- # CONFIG_OXNAS_VERSION_0X850 is not set
- # CONFIG_ARCH_OXNAS_UART1 is not set
- CONFIG_ARCH_OXNAS_UART2=y
-+CONFIG_ARCH_OXNAS_UART2_DEBUG=y
-+CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
- # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
- # CONFIG_ARCH_OXNAS_UART3 is not set
- # CONFIG_ARCH_OXNAS_UART4 is not set
-diff -Nurd linux-2.6.24.org/arch/arm/mach-oxnas/Kconfig linux-2.6.24/arch/arm/mach-oxnas/Kconfig
---- linux-2.6.24.org/arch/arm/mach-oxnas/Kconfig	2009-02-05 12:06:15.000000000 +0100
-+++ linux-2.6.24/arch/arm/mach-oxnas/Kconfig	2009-02-05 12:08:34.000000000 +0100
-@@ -66,6 +66,20 @@
- 		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
- 		including those UARTs selected to be present
- 
-+config ARCH_OXNAS_UART1_DEBUG
-+	bool "Use UART1 as debug channel"
-+	depends on ARCH_OXNAS_UART1
-+	default n
-+	help
-+		This enables UART1 to be usable as debug channel.
-+
-+config ARCH_OXNAS_UART1_BOOTPROGRESS
-+	bool "Display boot progress over UART1"
-+	depends on ARCH_OXNAS_UART1
-+	default n
-+	help
-+		This enables displaying boot progress over UART1.
-+
- config ARCH_OXNAS_UART1_MODEM
- 	bool "Support UART1 modem control lines"
- 	depends on ARCH_OXNAS_UART1
-@@ -81,6 +95,20 @@
- 		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
- 		including those UARTs selected to be present
- 
-+config ARCH_OXNAS_UART2_DEBUG
-+	bool "Use UART2 as debug channel"
-+	depends on ARCH_OXNAS_UART2
-+	default n
-+	help
-+		This enables UART2 to be usable as debug channel.
-+
-+config ARCH_OXNAS_UART2_BOOTPROGRESS
-+	bool "Display boot progress over UART2"
-+	depends on ARCH_OXNAS_UART2
-+	default n
-+	help
-+		This enables displaying boot progress over UART2.
-+
- config ARCH_OXNAS_UART2_MODEM
- 	bool "Support UART2 modem control lines"
- 	depends on ARCH_OXNAS_UART2
-@@ -96,6 +124,20 @@
- 		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
- 		including those UARTs selected to be present
- 
-+config ARCH_OXNAS_UART3_DEBUG
-+	bool "Use UART3 as debug channel"
-+	depends on ARCH_OXNAS_UART3
-+	default n
-+	help
-+		This enables UART3 to be usable as debug channel.
-+
-+config ARCH_OXNAS_UART3_BOOTPROGRESS
-+	bool "Display boot progress over UART3"
-+	depends on ARCH_OXNAS_UART3
-+	default n
-+	help
-+		This enables displaying boot progress over UART3.
-+
- config ARCH_OXNAS_UART3_MODEM
- 	bool "Support UART3 modem control lines"
- 	depends on ARCH_OXNAS_UART3
-@@ -114,6 +156,20 @@
- 		UART4 always has its modem control lines available on external pins
- 		when selected (overlaying PCI functions)
- 
-+config ARCH_OXNAS_UART4_DEBUG
-+	bool "Use UART4 as debug channel"
-+	depends on ARCH_OXNAS_UART4
-+	default n
-+	help
-+		This enables UART4 to be usable as debug channel.
-+
-+config ARCH_OXNAS_UART4_BOOTPROGRESS
-+	bool "Display boot progress over UART4"
-+	depends on ARCH_OXNAS_UART4
-+	default n
-+	help
-+		This enables displaying boot progress over UART4.
-+
- config ARCH_OXNAS_PCI_REQGNT_0
- 	bool "Enable req/gnt for PCI device 0"
- 	depends on PCI
-diff -Nurd linux-2.6.24.org/include/asm-arm/arch-oxnas/debug-macro.S linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S
---- linux-2.6.24.org/include/asm-arm/arch-oxnas/debug-macro.S	2009-02-05 12:06:19.000000000 +0100
-+++ linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S	2009-02-05 12:08:34.000000000 +0100
-@@ -14,13 +14,13 @@
- 		.macro  addruart,rx
- 		mrc		p15, 0, \rx, c1, c0
- 		tst		\rx, #1					@ MMU enabled?
--#ifdef CONFIG_ARCH_OXNAS_UART1
-+#ifdef CONFIG_ARCH_OXNAS_UART1_DEBUG
- 		ldreq	\rx, =UART_1_BASE_PA	@ physical base address
- 		ldrne	\rx, =UART_1_BASE		@ virtual address
--#elif CONFIG_ARCH_OXNAS_UART2
-+#elif CONFIG_ARCH_OXNAS_UART2_DEBUG
- 		ldreq	\rx, =UART_2_BASE_PA	@ physical base address
- 		ldrne	\rx, =UART_2_BASE		@ virtual address
--#elif CONFIG_ARCH_OXNAS_UART3
-+#elif CONFIG_ARCH_OXNAS_UART3_DEBUG
- 		ldreq	\rx, =UART_3_BASE_PA	@ physical base address
- 		ldrne	\rx, =UART_3_BASE		@ virtual address
- #else
-diff -Nurd linux-2.6.24.org/include/asm-arm/arch-oxnas/uncompress.h linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h
---- linux-2.6.24.org/include/asm-arm/arch-oxnas/uncompress.h	2009-02-05 12:06:19.000000000 +0100
-+++ linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h	2009-02-05 12:08:34.000000000 +0100
-@@ -12,13 +12,13 @@
- 
- static inline void putc(int c)
- {
--#ifdef CONFIG_ARCH_OXNAS_UART1
-+#ifdef CONFIG_ARCH_OXNAS_UART1_BOOTPROGRESS
-     static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
--#elif defined(CONFIG_ARCH_OXNAS_UART2)
-+#elif defined(CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS)
-     static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
--#elif defined(CONFIG_ARCH_OXNAS_UART3)
-+#elif defined(CONFIG_ARCH_OXNAS_UART3_BOOTPROGRESS)
-     static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
--#elif defined(CONFIG_ARCH_OXNAS_UART4)
-+#elif defined(CONFIG_ARCH_OXNAS_UART4_BOOTPROGRESS)
-     static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
- #else
- #define NO_UART
diff --git a/recipes/linux/linux-2.6.24/oxnas/oxnas.diff b/recipes/linux/linux-2.6.24/oxnas/oxnas.diff
deleted file mode 100644
index 3f3dc66..0000000
--- a/recipes/linux/linux-2.6.24/oxnas/oxnas.diff
+++ /dev/null
@@ -1,57804 +0,0 @@
-diff -Nurd linux-2.6.24/.gitignore linux-2.6.24-oxe810/.gitignore
---- linux-2.6.24/.gitignore	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/.gitignore	1970-01-01 01:00:00.000000000 +0100
-@@ -1,54 +0,0 @@
--#
--# NOTE! Don't add files that are generated in specific
--# subdirectories here. Add them in the ".gitignore" file
--# in that subdirectory instead.
--#
--# Normal rules
--#
--.*
--*.o
--*.o.*
--*.a
--*.s
--*.ko
--*.so
--*.so.dbg
--*.mod.c
--*.i
--*.lst
--*.symtypes
--
--#
--# Top-level generic files
--#
--tags
--TAGS
--vmlinux*
--!vmlinux.lds.S
--System.map
--Module.symvers
--!.gitignore
--
--#
--# Generated include files
--#
--include/asm
--include/asm-*/asm-offsets.h
--include/config
--include/linux/autoconf.h
--include/linux/compile.h
--include/linux/version.h
--include/linux/utsrelease.h
--
--# stgit generated dirs
--patches-*
--
--# quilt's files
--patches
--series
--
--# cscope files
--cscope.*
--
--*.orig
--*.rej
-diff -Nurd linux-2.6.24/.mailmap linux-2.6.24-oxe810/.mailmap
---- linux-2.6.24/.mailmap	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/.mailmap	1970-01-01 01:00:00.000000000 +0100
-@@ -1,98 +0,0 @@
--#
--# This list is used by git-shortlog to fix a few botched name translations
--# in the git archive, either because the author's full name was messed up
--# and/or not always written the same way, making contributions from the
--# same person appearing not to be so or badly displayed.
--#
--# repo-abbrev: /pub/scm/linux/kernel/git/
--#
--
--Aaron Durbin <adurbin at google.com>
--Adam Oldham <oldhamca at gmail.com>
--Adam Radford <aradford at gmail.com>
--Adrian Bunk <bunk at stusta.de>
--Alan Cox <alan at lxorguk.ukuu.org.uk>
--Alan Cox <root at hraefn.swansea.linux.org.uk>
--Aleksey Gorelov <aleksey_gorelov at phoenix.com>
--Al Viro <viro at ftp.linux.org.uk>
--Al Viro <viro at zenIV.linux.org.uk>
--Andreas Herrmann <aherrman at de.ibm.com>
--Andrew Morton <akpm at osdl.org>
--Andrew Vasquez <andrew.vasquez at qlogic.com>
--Andy Adamson <andros at citi.umich.edu>
--Arnaud Patard <arnaud.patard at rtp-net.org>
--Arnd Bergmann <arnd at arndb.de>
--Axel Dyks <xl at xlsigned.net>
--Ben Gardner <bgardner at wabtec.com>
--Ben M Cahill <ben.m.cahill at intel.com>
--Björn Steinbrink <B.Steinbrink at gmx.de>
--Brian Avery <b.avery at hp.com>
--Brian King <brking at us.ibm.com>
--Christoph Hellwig <hch at lst.de>
--Corey Minyard <minyard at acm.org>
--David Brownell <david-b at pacbell.net>
--David Woodhouse <dwmw2 at shinybook.infradead.org>
--Domen Puncer <domen at coderock.org>
--Douglas Gilbert <dougg at torque.net>
--Ed L. Cashin <ecashin at coraid.com>
--Evgeniy Polyakov <johnpol at 2ka.mipt.ru>
--Felipe W Damasio <felipewd at terra.com.br>
--Felix Kuhling <fxkuehl at gmx.de>
--Felix Moeller <felix at derklecks.de>
--Filipe Lautert <filipe at icewall.org>
--Franck Bui-Huu <vagabon.xyz at gmail.com>
--Frank Zago <fzago at systemfabricworks.com>
--Greg Kroah-Hartman <greg at echidna.(none)>
--Greg Kroah-Hartman <gregkh at suse.de>
--Greg Kroah-Hartman <greg at kroah.com>
--Henk Vergonet <Henk.Vergonet at gmail.com>
--Henrik Kretzschmar <henne at nachtwindheim.de>
--Herbert Xu <herbert at gondor.apana.org.au>
--Jacob Shin <Jacob.Shin at amd.com>
--James Bottomley <jejb at mulgrave.(none)>
--James Bottomley <jejb at titanic.il.steeleye.com>
--James E Wilson <wilson at specifix.com>
--James Ketrenos <jketreno at io.(none)>
--Jean Tourrilhes <jt at hpl.hp.com>
--Jeff Garzik <jgarzik at pretzel.yyz.us>
--Jens Axboe <axboe at suse.de>
--Jens Osterkamp <Jens.Osterkamp at de.ibm.com>
--John Stultz <johnstul at us.ibm.com>
--Juha Yrjola <at solidboot.com>
--Juha Yrjola <juha.yrjola at nokia.com>
--Juha Yrjola <juha.yrjola at solidboot.com>
--Kay Sievers <kay.sievers at vrfy.org>
--Kenneth W Chen <kenneth.w.chen at intel.com>
--Koushik <raghavendra.koushik at neterion.com>
--Leonid I Ananiev <leonid.i.ananiev at intel.com>
--Linas Vepstas <linas at austin.ibm.com>
--Matthieu CASTET <castet.matthieu at free.fr>
--Michael Buesch <mb at bu3sch.de>
--Michael Buesch <mbuesch at freenet.de>
--Michel Dänzer <michel at tungstengraphics.com>
--Mitesh shah <mshah at teja.com>
--Morten Welinder <terra at gnome.org>
--Morten Welinder <welinder at anemone.rentec.com>
--Morten Welinder <welinder at darter.rentec.com>
--Morten Welinder <welinder at troll.com>
--Nguyen Anh Quynh <aquynh at gmail.com>
--Paolo 'Blaisorblade' Giarrusso <blaisorblade at yahoo.it>
--Patrick Mochel <mochel at digitalimplant.org>
--Peter A Jonsson <pj at ludd.ltu.se>
--Praveen BP <praveenbp at ti.com>
--Rajesh Shah <rajesh.shah at intel.com>
--Ralf Baechle <ralf at linux-mips.org>
--Ralf Wildenhues <Ralf.Wildenhues at gmx.de>
--Rémi Denis-Courmont <rdenis at simphalempin.com>
--Rudolf Marek <R.Marek at sh.cvut.cz>
--Rui Saraiva <rmps at joel.ist.utl.pt>
--Sachin P Sant <ssant at in.ibm.com>
--Sam Ravnborg <sam at mars.ravnborg.org>
--Simon Kelley <simon at thekelleys.org.uk>
--Stéphane Witzmann <stephane.witzmann at ubpmes.univ-bpclermont.fr>
--Stephen Hemminger <shemminger at osdl.org>
--Tejun Heo <htejun at gmail.com>
--Thomas Graf <tgraf at suug.ch>
--Tony Luck <tony.luck at intel.com>
--Tsuneo Yoshioka <Tsuneo.Yoshioka at f-secure.com>
--Valdis Kletnieks <Valdis.Kletnieks at vt.edu>
-diff -Nurd linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885
---- linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885	2008-06-11 17:47:23.000000000 +0200
-@@ -1,5 +1,5 @@
-   0 -> UNKNOWN/GENERIC                                     [0070:3400]
-   1 -> Hauppauge WinTV-HVR1800lp                           [0070:7600]
--  2 -> Hauppauge WinTV-HVR1800                             [0070:7800,0070:7801]
-+  2 -> Hauppauge WinTV-HVR1800                             [0070:7800,0070:7801,0070:7809]
-   3 -> Hauppauge WinTV-HVR1250                             [0070:7911]
-   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
-diff -Nurd linux-2.6.24/Makefile linux-2.6.24-oxe810/Makefile
---- linux-2.6.24/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/Makefile	2008-06-11 17:50:34.000000000 +0200
-@@ -1,8 +1,8 @@
- VERSION = 2
- PATCHLEVEL = 6
- SUBLEVEL = 24
--EXTRAVERSION =
--NAME = Arr Matey! A Hairy Bilge Rat!
-+EXTRAVERSION = .4
-+NAME = Err Metey! A Heury Beelge-a Ret!
- 
- # *DOCUMENTATION*
- # To see a list of typical targets execute "make help"
-@@ -190,8 +190,8 @@
- # Default value for CROSS_COMPILE is not to prefix executables
- # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
- 
--ARCH		?= $(SUBARCH)
--CROSS_COMPILE	?=
-+ARCH		?= arm
-+CROSS_COMPILE	?= arm-linux-uclibcgnueabi-
- 
- # Architecture as present in compile.h
- UTS_MACHINE 	:= $(ARCH)
-diff -Nurd linux-2.6.24/arch/arm/Kconfig linux-2.6.24-oxe810/arch/arm/Kconfig
---- linux-2.6.24/arch/arm/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/Kconfig	2008-06-11 17:47:58.000000000 +0200
-@@ -409,6 +409,10 @@
- 	help
- 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
- 
-+config ARCH_OXNAS
-+	bool "Oxford Semiconductor NAS SoC"
-+	help
-+	  This enables support for Oxsemi NAS SoC
- endchoice
- 
- source "arch/arm/mach-clps711x/Kconfig"
-@@ -461,6 +465,8 @@
- 
- source "arch/arm/mach-versatile/Kconfig"
- 
-+source "arch/arm/mach-oxnas/Kconfig"
-+
- source "arch/arm/mach-aaec2000/Kconfig"
- 
- source "arch/arm/mach-realview/Kconfig"
-@@ -537,7 +543,7 @@
- 	bool
- 
- config PCI
--	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
-+	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_OXNAS
- 	help
- 	  Find out whether you have a PCI motherboard. PCI is the name of a
- 	  bus system, i.e. the way the CPU talks to the other stuff inside
-@@ -653,11 +659,13 @@
- 	  to have accurate timekeeping with dynamic tick.
- 
- config HZ
--	int
-+	int "Kernel timer tick rate"
- 	default 128 if ARCH_L7200
- 	default 200 if ARCH_EBSA110 || ARCH_S3C2410
- 	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
- 	default 100
-+	help
-+		Sets the number of timer tick interrupts per second
- 
- config AEABI
- 	bool "Use the ARM EABI to compile the kernel"
-@@ -1010,7 +1018,7 @@
- if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
- 	|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
- 	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
--	|| ARCH_IXP23XX
-+	|| ARCH_IXP23XX || ARCH_OXNAS
- source "drivers/ide/Kconfig"
- endif
- 
-diff -Nurd linux-2.6.24/arch/arm/Makefile linux-2.6.24-oxe810/arch/arm/Makefile
---- linux-2.6.24/arch/arm/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/Makefile	2008-06-11 17:47:58.000000000 +0200
-@@ -127,6 +127,7 @@
-  machine-$(CONFIG_ARCH_VERSATILE)  := versatile
-  machine-$(CONFIG_ARCH_IMX)	   := imx
-  machine-$(CONFIG_ARCH_H720X)	   := h720x
-+ machine-$(CONFIG_ARCH_OXNAS)	   := oxnas
-  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
-  machine-$(CONFIG_ARCH_REALVIEW)   := realview
-  machine-$(CONFIG_ARCH_AT91)	   := at91
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig	2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1233 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Mon Jun  2 12:34:33 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+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_ZONE_DMA=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+# CONFIG_FAIR_USER_SCHED is not set
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+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 is not set
-+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=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
-+
-+#
-+# 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_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# 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_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-+# CONFIG_OXNAS_PCI_RESET is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=6
-+CONFIG_OXNAS_I2C_SCL=7
-+# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-+# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_PCI=y
-+CONFIG_PCI_SYSCALL=y
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+CONFIG_PCI_LEGACY=y
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# 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=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES 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_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_SX8 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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 is not set
-+# CONFIG_CHR_DEV_SCH is not set
-+
-+#
-+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-+#
-+CONFIG_SCSI_MULTI_LUN=y
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+# 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_BLK_DEV_3W_XXXX_RAID is not set
-+# CONFIG_SCSI_3W_9XXX is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_AIC79XX is not set
-+# CONFIG_SCSI_AIC94XX is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_ARCMSR is not set
-+# CONFIG_MEGARAID_NEWGEN is not set
-+# CONFIG_MEGARAID_LEGACY is not set
-+# CONFIG_MEGARAID_SAS is not set
-+# CONFIG_SCSI_HPTIOP is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_IPS is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_STEX is not set
-+# CONFIG_SCSI_SYM53C8XX_2 is not set
-+# CONFIG_SCSI_IPR is not set
-+# CONFIG_SCSI_QLOGIC_1280 is not set
-+# CONFIG_SCSI_QLA_FC is not set
-+# CONFIG_SCSI_QLA_ISCSI is not set
-+# CONFIG_SCSI_LPFC is not set
-+# CONFIG_SCSI_DC395x is not set
-+# CONFIG_SCSI_DC390T is not set
-+# CONFIG_SCSI_NSP32 is not set
-+# CONFIG_SCSI_DEBUG is not set
-+# CONFIG_SCSI_SRP is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+# CONFIG_SATA_AHCI is not set
-+# CONFIG_SATA_SVW is not set
-+# CONFIG_ATA_PIIX is not set
-+# CONFIG_SATA_MV is not set
-+# CONFIG_SATA_NV is not set
-+# CONFIG_PDC_ADMA is not set
-+# CONFIG_SATA_QSTOR is not set
-+# CONFIG_SATA_PROMISE is not set
-+# CONFIG_SATA_SX4 is not set
-+# CONFIG_SATA_SIL is not set
-+# CONFIG_SATA_SIL24 is not set
-+# CONFIG_SATA_SIS is not set
-+# CONFIG_SATA_ULI is not set
-+# CONFIG_SATA_VIA is not set
-+# CONFIG_SATA_VITESSE is not set
-+# CONFIG_SATA_INIC162X is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+# CONFIG_PATA_ALI is not set
-+# CONFIG_PATA_AMD is not set
-+# CONFIG_PATA_ARTOP is not set
-+# CONFIG_PATA_ATIIXP is not set
-+# CONFIG_PATA_CMD640_PCI is not set
-+# CONFIG_PATA_CMD64X is not set
-+# CONFIG_PATA_CS5520 is not set
-+# CONFIG_PATA_CS5530 is not set
-+# CONFIG_PATA_CYPRESS is not set
-+# CONFIG_PATA_EFAR is not set
-+# CONFIG_ATA_GENERIC is not set
-+# CONFIG_PATA_HPT366 is not set
-+# CONFIG_PATA_HPT37X is not set
-+# CONFIG_PATA_HPT3X2N is not set
-+# CONFIG_PATA_HPT3X3 is not set
-+# CONFIG_PATA_IT821X is not set
-+# CONFIG_PATA_IT8213 is not set
-+# CONFIG_PATA_JMICRON is not set
-+# CONFIG_PATA_TRIFLEX is not set
-+# CONFIG_PATA_MARVELL is not set
-+# CONFIG_PATA_MPIIX is not set
-+# CONFIG_PATA_OLDPIIX is not set
-+# CONFIG_PATA_NETCELL is not set
-+# CONFIG_PATA_NS87410 is not set
-+# CONFIG_PATA_NS87415 is not set
-+# CONFIG_PATA_OPTI is not set
-+# CONFIG_PATA_OPTIDMA is not set
-+# CONFIG_PATA_PDC_OLD is not set
-+# CONFIG_PATA_RADISYS is not set
-+# CONFIG_PATA_RZ1000 is not set
-+# CONFIG_PATA_SC1200 is not set
-+# CONFIG_PATA_SERVERWORKS is not set
-+# CONFIG_PATA_PDC2027X is not set
-+# CONFIG_PATA_SIL680 is not set
-+# CONFIG_PATA_SIS is not set
-+# CONFIG_PATA_VIA is not set
-+# CONFIG_PATA_WINBOND is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+# CONFIG_FUSION is not set
-+
-+#
-+# IEEE 1394 (FireWire) support
-+#
-+# CONFIG_FIREWIRE is not set
-+# CONFIG_IEEE1394 is not set
-+# CONFIG_I2O 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_ARCNET is not set
-+# CONFIG_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
-+# CONFIG_E1000E is not set
-+# CONFIG_IP1000 is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
-+# CONFIG_SIS190 is not set
-+# CONFIG_SKGE is not set
-+# CONFIG_SKY2 is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_VIA_VELOCITY is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_BNX2 is not set
-+# CONFIG_QLA3XXX is not set
-+# CONFIG_ATL1 is not set
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+# CONFIG_TR is not set
-+
-+#
-+# 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_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_SHAPER 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 is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_EVBUG is not set
-+
-+#
-+# Input Device Drivers
-+#
-+# CONFIG_INPUT_KEYBOARD 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 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=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_PCI=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+# CONFIG_SERIAL_JSM is not set
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_DEVPORT=y
-+CONFIG_I2C=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+# CONFIG_I2C_ALI1535 is not set
-+# CONFIG_I2C_ALI1563 is not set
-+# CONFIG_I2C_ALI15X3 is not set
-+# CONFIG_I2C_AMD756 is not set
-+# CONFIG_I2C_AMD8111 is not set
-+# CONFIG_I2C_I801 is not set
-+# CONFIG_I2C_I810 is not set
-+# CONFIG_I2C_PIIX4 is not set
-+# CONFIG_I2C_NFORCE2 is not set
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_PROSAVAGE is not set
-+# CONFIG_I2C_SAVAGE4 is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_SIS5595 is not set
-+# CONFIG_I2C_SIS630 is not set
-+# CONFIG_I2C_SIS96X is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_TINY_USB is not set
-+# CONFIG_I2C_VIA is not set
-+# CONFIG_I2C_VIAPRO is not set
-+# CONFIG_I2C_VOODOO3 is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 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_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON 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
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_DRM is not set
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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 is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# 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_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# CONFIG_USB_UHCI_HCD is not set
-+# 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=m
-+# CONFIG_USB_STORAGE_DEBUG is not set
-+# 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_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
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_SISUSBVGA is not set
-+# CONFIG_USB_LD is not set
-+# CONFIG_USB_TRANCEVIBRATOR is not set
-+# CONFIG_USB_IOWARRIOR is not set
-+CONFIG_USB_TEST=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget 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=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 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_PL031 is not set
-+# CONFIG_DMADEVICES 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 is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=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_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# 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=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW 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=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+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_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# 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=y
-+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=y
-+# CONFIG_LDM_DEBUG 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=y
-+# CONFIG_SYSV68_PARTITION is not set
-+CONFIG_NLS=y
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# 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=m
-+# 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+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=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS 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=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# 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_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_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig	2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,901 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Thu May 15 10:43:48 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+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_ZONE_DMA=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_BSD_PROCESS_ACCT is not set
-+# CONFIG_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+CONFIG_FAIR_GROUP_SCHED=y
-+CONFIG_FAIR_USER_SCHED=y
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+CONFIG_SLABINFO=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_MODULES is not set
-+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=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
-+
-+#
-+# 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_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# 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_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-+# CONFIG_OXNAS_PCI_RESET is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+# CONFIG_LEON_COPRO is not set
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=y
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+# CONFIG_TACHO_THERM_AND_FAN is not set
-+# CONFIG_GPIO_TEST is not set
-+# CONFIG_OXNAS_RTC is not set
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=6
-+CONFIG_OXNAS_I2C_SCL=7
-+# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-+# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_PCI=y
-+CONFIG_PCI_SYSCALL=y
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+CONFIG_PCI_LEGACY=y
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# 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=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+CONFIG_VFP=y
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_POSSIBLE=y
-+
-+#
-+# Networking
-+#
-+# CONFIG_NET 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_SYS_HYPERVISOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-+# CONFIG_BLK_DEV_SX8 is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_COUNT=1
-+CONFIG_BLK_DEV_RAM_SIZE=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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 is not set
-+# CONFIG_CHR_DEV_SCH is not set
-+
-+#
-+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-+#
-+CONFIG_SCSI_MULTI_LUN=y
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+# CONFIG_SCSI_SCAN_ASYNC is not set
-+
-+#
-+# SCSI Transports
-+#
-+# CONFIG_SCSI_SPI_ATTRS is not set
-+# CONFIG_SCSI_FC_ATTRS is not set
-+# CONFIG_SCSI_SAS_LIBSAS is not set
-+# CONFIG_SCSI_SRP_ATTRS is not set
-+CONFIG_SCSI_LOWLEVEL=y
-+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-+# CONFIG_SCSI_3W_9XXX is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_AIC79XX is not set
-+# CONFIG_SCSI_AIC94XX is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_ARCMSR is not set
-+# CONFIG_MEGARAID_NEWGEN is not set
-+# CONFIG_MEGARAID_LEGACY is not set
-+# CONFIG_MEGARAID_SAS is not set
-+# CONFIG_SCSI_HPTIOP is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_IPS is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_STEX is not set
-+# CONFIG_SCSI_SYM53C8XX_2 is not set
-+# CONFIG_SCSI_IPR is not set
-+# CONFIG_SCSI_QLOGIC_1280 is not set
-+# CONFIG_SCSI_QLA_FC is not set
-+# CONFIG_SCSI_LPFC is not set
-+# CONFIG_SCSI_DC395x is not set
-+# CONFIG_SCSI_DC390T is not set
-+# CONFIG_SCSI_NSP32 is not set
-+# CONFIG_SCSI_DEBUG is not set
-+# CONFIG_SCSI_SRP is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+# CONFIG_SATA_AHCI is not set
-+# CONFIG_SATA_SVW is not set
-+# CONFIG_ATA_PIIX is not set
-+# CONFIG_SATA_MV is not set
-+# CONFIG_SATA_NV is not set
-+# CONFIG_PDC_ADMA is not set
-+# CONFIG_SATA_QSTOR is not set
-+# CONFIG_SATA_PROMISE is not set
-+# CONFIG_SATA_SX4 is not set
-+# CONFIG_SATA_SIL is not set
-+# CONFIG_SATA_SIL24 is not set
-+# CONFIG_SATA_SIS is not set
-+# CONFIG_SATA_ULI is not set
-+# CONFIG_SATA_VIA is not set
-+# CONFIG_SATA_VITESSE is not set
-+# CONFIG_SATA_INIC162X is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+# CONFIG_PATA_ALI is not set
-+# CONFIG_PATA_AMD is not set
-+# CONFIG_PATA_ARTOP is not set
-+# CONFIG_PATA_ATIIXP is not set
-+# CONFIG_PATA_CMD640_PCI is not set
-+# CONFIG_PATA_CMD64X is not set
-+# CONFIG_PATA_CS5520 is not set
-+# CONFIG_PATA_CS5530 is not set
-+# CONFIG_PATA_CYPRESS is not set
-+# CONFIG_PATA_EFAR is not set
-+# CONFIG_ATA_GENERIC is not set
-+# CONFIG_PATA_HPT366 is not set
-+# CONFIG_PATA_HPT37X is not set
-+# CONFIG_PATA_HPT3X2N is not set
-+# CONFIG_PATA_HPT3X3 is not set
-+# CONFIG_PATA_IT821X is not set
-+# CONFIG_PATA_IT8213 is not set
-+# CONFIG_PATA_JMICRON is not set
-+# CONFIG_PATA_TRIFLEX is not set
-+# CONFIG_PATA_MARVELL is not set
-+# CONFIG_PATA_MPIIX is not set
-+# CONFIG_PATA_OLDPIIX is not set
-+# CONFIG_PATA_NETCELL is not set
-+# CONFIG_PATA_NS87410 is not set
-+# CONFIG_PATA_NS87415 is not set
-+# CONFIG_PATA_OPTI is not set
-+# CONFIG_PATA_OPTIDMA is not set
-+# CONFIG_PATA_PDC_OLD is not set
-+# CONFIG_PATA_RADISYS is not set
-+# CONFIG_PATA_RZ1000 is not set
-+# CONFIG_PATA_SC1200 is not set
-+# CONFIG_PATA_SERVERWORKS is not set
-+# CONFIG_PATA_PDC2027X is not set
-+# CONFIG_PATA_SIL680 is not set
-+# CONFIG_PATA_SIS is not set
-+# CONFIG_PATA_VIA is not set
-+# CONFIG_PATA_WINBOND is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+# CONFIG_DM_CRYPT is not set
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+# CONFIG_FUSION is not set
-+
-+#
-+# IEEE 1394 (FireWire) support
-+#
-+# CONFIG_FIREWIRE is not set
-+# CONFIG_IEEE1394 is not set
-+# CONFIG_I2O 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 is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_EVBUG is not set
-+
-+#
-+# Input Device Drivers
-+#
-+# CONFIG_INPUT_KEYBOARD 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 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=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_PCI=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+# CONFIG_SERIAL_JSM is not set
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=y
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_DEVPORT=y
-+CONFIG_I2C=y
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=y
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+# CONFIG_I2C_ALI1535 is not set
-+# CONFIG_I2C_ALI1563 is not set
-+# CONFIG_I2C_ALI15X3 is not set
-+# CONFIG_I2C_AMD756 is not set
-+# CONFIG_I2C_AMD8111 is not set
-+# CONFIG_I2C_I801 is not set
-+# CONFIG_I2C_I810 is not set
-+# CONFIG_I2C_PIIX4 is not set
-+# CONFIG_I2C_NFORCE2 is not set
-+CONFIG_I2C_OXNAS_BITBASH=y
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_PROSAVAGE is not set
-+# CONFIG_I2C_SAVAGE4 is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_SIS5595 is not set
-+# CONFIG_I2C_SIS630 is not set
-+# CONFIG_I2C_SIS96X is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_VIA is not set
-+# CONFIG_I2C_VIAPRO is not set
-+# CONFIG_I2C_VOODOO3 is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 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_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON 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
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+CONFIG_DAB=y
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_DRM is not set
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=y
-+# 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 is not set
-+# CONFIG_USB_SUPPORT is not set
-+# CONFIG_MMC is not set
-+# 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 is not set
-+
-+#
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 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_PL031 is not set
-+# CONFIG_DMADEVICES 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 is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=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_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+# CONFIG_INOTIFY is not set
-+# CONFIG_QUOTA is not set
-+# CONFIG_DNOTIFY 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_MSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# 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_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS 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 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=y
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+# CONFIG_ENABLE_WARN_DEPRECATED is not set
-+# CONFIG_ENABLE_MUST_CHECK is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER 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_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 is not set
-+CONFIG_CRYPTO_CBC=y
-+# CONFIG_CRYPTO_PCBC is not set
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS 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_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_AUTHENC is not set
-+# CONFIG_CRYPTO_HW is not set
-+
-+#
-+# 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_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig	2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1096 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Mon Jun  2 12:33:10 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+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_ZONE_DMA=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+# CONFIG_FAIR_USER_SCHED is not set
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+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 is not set
-+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=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
-+
-+#
-+# 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_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# 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_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_UART4 is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=28
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=3
-+CONFIG_OXNAS_I2C_SCL=2
-+CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
-+CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+# CONFIG_PCI is not set
-+# CONFIG_PCI_SYSCALL is not set
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# 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=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES 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_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD 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 is not set
-+# 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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 is not set
-+# CONFIG_CHR_DEV_SCH is not set
-+
-+#
-+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-+#
-+CONFIG_SCSI_MULTI_LUN=y
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+# 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=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT 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_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+
-+#
-+# 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 is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_SHAPER 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 is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_EVBUG is not set
-+
-+#
-+# Input Device Drivers
-+#
-+# CONFIG_INPUT_KEYBOARD 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 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=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# 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=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# 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_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 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_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON 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
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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 is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# 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_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# 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=m
-+# CONFIG_USB_STORAGE_DEBUG is not set
-+# 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_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
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_SISUSBVGA is not set
-+# CONFIG_USB_LD is not set
-+# CONFIG_USB_TRANCEVIBRATOR is not set
-+# CONFIG_USB_IOWARRIOR is not set
-+CONFIG_USB_TEST=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
-+# CONFIG_MMC is not set
-+CONFIG_NEW_LEDS=y
-+CONFIG_LEDS_CLASS=y
-+
-+#
-+# LED drivers
-+#
-+CONFIG_WDC_LEDS_OXNAS800=m
-+# CONFIG_OXNAS_WD810_LEDS is not set
-+
-+#
-+# LED Triggers
-+#
-+CONFIG_LEDS_TRIGGERS=y
-+# CONFIG_LEDS_TRIGGER_TIMER is not set
-+CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
-+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-+CONFIG_RTC_LIB=y
-+CONFIG_RTC_CLASS=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 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_PL031 is not set
-+# CONFIG_DMADEVICES 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 is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=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_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# 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=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW 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=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+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_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# 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=y
-+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=y
-+# CONFIG_LDM_DEBUG 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=y
-+# CONFIG_SYSV68_PARTITION is not set
-+CONFIG_NLS=y
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# 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=m
-+# 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+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=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS 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=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# 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_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_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig	2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1108 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Thu Jun  5 16:08:07 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+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_ZONE_DMA=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# CONFIG_KALLSYMS_EXTRA_PASS is not set
-+CONFIG_HOTPLUG=y
-+CONFIG_PRINTK=y
-+CONFIG_BUG=y
-+CONFIG_ELF_CORE=y
-+CONFIG_BASE_FULL=y
-+CONFIG_FUTEX=y
-+CONFIG_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+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 is not set
-+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=y
-+# CONFIG_DEFAULT_DEADLINE is not set
-+# CONFIG_DEFAULT_CFQ is not set
-+# CONFIG_DEFAULT_NOOP is not set
-+CONFIG_DEFAULT_IOSCHED="anticipatory"
-+
-+#
-+# 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_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# 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_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_UART4 is not set
-+CONFIG_OXNAS_SATA_POWER_1=y
-+CONFIG_OXNAS_SATA_POWER_GPIO_1=31
-+CONFIG_OXNAS_SATA_POWER_2=y
-+CONFIG_OXNAS_SATA_POWER_GPIO_2=32
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=0
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=4
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=3
-+CONFIG_OXNAS_I2C_SCL=2
-+CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
-+CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+CONFIG_OXNAS_USB_HUB_SUPPORT=y
-+CONFIG_OXNAS_USB_CKOUT=y
-+CONFIG_OXNAS_USB_HUB_RESET_CONTROL=y
-+CONFIG_OXNAS_USB_HUB_RESET_GPIO=27
-+CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH=0
-+CONFIG_OXNAS_USB_HUB_RESET_TOGGLE=y
-+CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS=100
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+# CONFIG_PCI is not set
-+# CONFIG_PCI_SYSCALL is not set
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ 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=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC 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
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES 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_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD 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 is not set
-+# 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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 is not set
-+# CONFIG_CHR_DEV_SCH is not set
-+
-+#
-+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-+#
-+CONFIG_SCSI_MULTI_LUN=y
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+# 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=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+CONFIG_MD_RAID0=y
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT 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_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+
-+#
-+# 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 is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_SHAPER 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 is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_EVBUG is not set
-+
-+#
-+# Input Device Drivers
-+#
-+# CONFIG_INPUT_KEYBOARD 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 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=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+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=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# 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_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 is not set
-+# CONFIG_SENSORS_PCA9539 is not set
-+# CONFIG_SENSORS_PCF8591 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_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON 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
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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 is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# 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_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# 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=m
-+# CONFIG_USB_STORAGE_DEBUG is not set
-+# 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_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
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_SISUSBVGA is not set
-+# CONFIG_USB_LD is not set
-+# CONFIG_USB_TRANCEVIBRATOR is not set
-+# CONFIG_USB_IOWARRIOR is not set
-+CONFIG_USB_TEST=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
-+# CONFIG_MMC is not set
-+CONFIG_NEW_LEDS=y
-+CONFIG_LEDS_CLASS=y
-+
-+#
-+# LED drivers
-+#
-+# CONFIG_WDC_LEDS_OXNAS800 is not set
-+CONFIG_OXNAS_WD810_LEDS=m
-+
-+#
-+# LED Triggers
-+#
-+CONFIG_LEDS_TRIGGERS=y
-+# CONFIG_LEDS_TRIGGER_TIMER is not set
-+CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
-+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-+CONFIG_RTC_LIB=y
-+CONFIG_RTC_CLASS=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 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_PL031 is not set
-+# CONFIG_DMADEVICES 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 is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=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=y
-+# 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_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_QUOTACTL=y
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# 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=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW 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=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+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_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# 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=y
-+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=y
-+# CONFIG_LDM_DEBUG 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=y
-+# CONFIG_SYSV68_PARTITION is not set
-+CONFIG_NLS=y
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# 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=m
-+# 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+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=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS 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=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# 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_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_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/kernel/armksyms.c linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c
---- linux-2.6.24/arch/arm/kernel/armksyms.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c	2008-06-11 17:47:43.000000000 +0200
-@@ -114,9 +114,15 @@
- EXPORT_SYMBOL(__strncpy_from_user);
- 
- #ifdef CONFIG_MMU
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+EXPORT_SYMBOL(__copy_from_user_alt);
-+EXPORT_SYMBOL(__copy_to_user_alt);
-+EXPORT_SYMBOL(__clear_user_alt);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- EXPORT_SYMBOL(__copy_from_user);
- EXPORT_SYMBOL(__copy_to_user);
- EXPORT_SYMBOL(__clear_user);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 
- EXPORT_SYMBOL(__get_user_1);
- EXPORT_SYMBOL(__get_user_2);
-diff -Nurd linux-2.6.24/arch/arm/kernel/bios32.c linux-2.6.24-oxe810/arch/arm/kernel/bios32.c
---- linux-2.6.24/arch/arm/kernel/bios32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/bios32.c	2008-06-11 17:47:43.000000000 +0200
-@@ -616,7 +616,7 @@
- 	}
- }
- 
--char * __init pcibios_setup(char *str)
-+char * __devinit pcibios_setup(char *str)
- {
- 	if (!strcmp(str, "debug")) {
- 		debug_pci = 1;
-diff -Nurd linux-2.6.24/arch/arm/kernel/calls.S linux-2.6.24-oxe810/arch/arm/kernel/calls.S
---- linux-2.6.24/arch/arm/kernel/calls.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/calls.S	2008-06-11 17:47:43.000000000 +0200
-@@ -362,6 +362,7 @@
- /* 350 */	CALL(sys_timerfd)
- 		CALL(sys_eventfd)
- 		CALL(sys_fallocate)
-+		CALL(sys_samba_reserve)
- #ifndef syscalls_counted
- .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
- #define syscalls_counted
-diff -Nurd linux-2.6.24/arch/arm/kernel/head.S linux-2.6.24-oxe810/arch/arm/kernel/head.S
---- linux-2.6.24/arch/arm/kernel/head.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/head.S	2008-06-11 17:47:43.000000000 +0200
-@@ -59,6 +59,34 @@
- #define KERNEL_END	_end
- #endif
- 
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+	.macro	course_pgtbl, rd
-+	ldr	\rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4400))
-+	.endm
-+
-+	.globl	SMALL_AP
-+	.equ	SMALL_AP, 0xAA
-+
-+	.globl	COURSE_DOMAIN
-+	.equ	COURSE_DOMAIN, 0x04
-+
-+	.globl	SRAM_CODE_START
-+	.globl	CODE_COPY_LEN
-+
-+#ifdef CONFIG_SUPPORT_LEON
-+	/*
-+	 * Allow 2 pages after GMAC/DMA descriptors for ARM/Leon TSO workspace
-+	 * May have to change if Leon code is built to use more Tx descriptors, but
-+	 * current 2 pages is easily enough for 54 descriptors
-+	 */
-+	.equ	SRAM_CODE_START, SRAM_PA+((CONFIG_DESCRIPTORS_PAGES+2)*4096)
-+	.equ	CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_LEON_PAGES-(CONFIG_DESCRIPTORS_PAGES+2))*4096)
-+#else // CONFIG_SUPPORT_LEON
-+	.equ	SRAM_CODE_START, SRAM_PA+(CONFIG_DESCRIPTORS_PAGES*4096)
-+	.equ	CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_DESCRIPTORS_PAGES)*4096)
-+#endif // CONFIG_SUPPORT_LEON
-+#endif // CONFIG_OXNAS_MAP_SRAM
-+
- /*
-  * Kernel startup entry point.
-  * ---------------------------
-@@ -82,6 +110,27 @@
- ENTRY(stext)
- 	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
- 						@ and irqs disabled
-+
-+#ifdef CONFIG_OXNAS_CACHE_LOCKDOWN	
-+	/*
-+	 * Lock down ICache - do not care what ends up in locked down ways - 
-+	 * eventually context switch etc will flush out anything that gets loaded
-+	 * next
-+	 */
-+	mrc p15,0,r2,c9,c0,1
-+	orr r2,r2,#CONFIG_OXNAS_CACHE_I_MASK
-+	mcr p15,0,r2,c9,c0,1
-+
-+	/*
-+	 * Lock down DCache - do not care what ends up in locked down ways - 
-+	 * eventually context switch etc will flush out anything that gets loaded
-+	 * next
-+	 */
-+	mrc p15,0,r2,c9,c0,0
-+	orr r2,r2,#CONFIG_OXNAS_CACHE_D_MASK
-+	mcr p15,0,r2,c9,c0,0
-+#endif // CONFIG_OXNAS_CACHE_LOCKDOWN	
-+
- 	mrc	p15, 0, r9, c0, c0		@ get processor id
- 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
- 	movs	r10, r5				@ invalid processor (r5=0)?
-@@ -231,7 +280,33 @@
- 	teq	r0, r6
- 	bne	1b
- 
--	ldr	r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
-+	ldr	r7, [r10, #PROCINFO_MM_MMUFLAGS]	@ mmuflags
-+                                                                                                                  
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+	/*
-+	 * Create the contents of the first descriptor in the course table which
-+	 * is to describe the first MB of the kernel with 256 4K small descriptors.
-+	 * The descriptors' are composed of the top 20 bits of the physical
-+	 * address plus the appropriate AP, cacheable and bufferable flags
-+	 */
-+	mov	r3, #PHYS_OFFSET
-+	mov	r3, r3, lsr #12
-+	mov	r3, r3, lsl #12
-+	mov	r6, #SMALL_AP		@ TBC: AP values
-+	orr	r3, r3, r6, lsl #4
-+	orr	r3, r3, #0xe		@ Cachable, bufferable and small desc
-+
-+	/*
-+	 * Fill all 256 entries in the course page table with descriptors for
-+	 * contiguous pages
-+	 */
-+	course_pgtbl	r0
-+	add	r6, r0, #0x0400
-+1:	str	r3, [r0], #4
-+	add	r3, r3, #1 << 12
-+	teq	r0, r6
-+	bne	1b
-+#endif // CONFIG_OXNAS_MAP_SRAM
- 
- 	/*
- 	 * Create identity mapping for first MB of kernel to
-@@ -243,12 +318,26 @@
- 	orr	r3, r7, r6, lsl #20		@ flags + kernel base
- 	str	r3, [r4, r6, lsl #2]		@ identity mapping
- 
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+	/*
-+	 * Write a course descriptor pointing to the small page mapping table
-+	 * setup to map the first MB of kernel with 4K small pages
-+	 */
-+	course_pgtbl	r6
-+	mov	r0, #COURSE_DOMAIN		@ TBC SBZ, Domain etc
-+	orr	r6, r6, r0, lsl #2
-+	orr	r6, r6, #1			@ Course descriptor identifier
-+
-+	add	r0, r4,  #(KERNEL_START & 0xff000000) >> 18
-+	str	r6, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
-+#else // CONFIG_OXNAS_MAP_SRAM
- 	/*
- 	 * Now setup the pagetables for our kernel direct
- 	 * mapped region.
- 	 */
- 	add	r0, r4,  #(KERNEL_START & 0xff000000) >> 18
- 	str	r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
-+#endif // CONFIG_OXNAS_MAP_SRAM
- 	ldr	r6, =(KERNEL_END - 1)
- 	add	r0, r0, #4
- 	add	r6, r4, r6, lsr #18
-@@ -276,6 +365,64 @@
- 	bls	1b
- #endif
- 
-+#ifdef CONFIG_OXNAS_COPY_CODE_TO_SRAM
-+	/*
-+	 * Copy smallest/most-used kernel code into SRAM
-+	 */
-+
-+	/* Get start of kernel code to copy */
-+	ldr	r0, =(_text)
-+	mvn	r3, #0xff000000
-+	and	r0, r0, r3
-+	mov	r6, #PHYS_OFFSET
-+	mov	r3, #0xff000000
-+	and	r6, r6, r3
-+	orr	r0, r0, r6
-+
-+	/* Get start of SRAM region to copy into */
-+	ldr	r3, =(SRAM_CODE_START)
-+
-+	/* Get amount of code to copy */
-+	ldr	r6, =(CODE_COPY_LEN)
-+
-+	/* NB r7 is corrupted here, but opt. debug code below needs it */
-+	add	r6, r0, r6
-+1:	ldr	r7, [r0], #4
-+	str	r7, [r3], #4
-+	teq	r0, r6
-+	bne	1b
-+
-+	/*
-+	 * Map SRAM resident code into kernel virtual address space by altering
-+	 * course page table entries covering the smallest/most-used code
-+	 */
-+
-+	/* Get the address of the first page table entry to modify */
-+	course_pgtbl r3
-+	ldr	r0, =(_text)
-+	sub r0, r0, #PAGE_OFFSET
-+	add	r3, r3, r0, lsr #10
-+
-+	/* Get the address after the last entry in the page table to be altered */
-+	ldr	r6, =(CODE_COPY_LEN)
-+	add	r6, r3, r6, lsr #10
-+
-+	/* Form the first small descriptor contents */
-+	ldr	r0, =(SRAM_CODE_START)
-+	mov	r0, r0, lsr #12
-+	mov	r0, r0, lsl #12
-+	mov	r7, #SMALL_AP
-+	orr	r0, r0, r7, lsl #4
-+	orr	r0, r0, #0xe
-+
-+	/* Modify the page table entries for all SRAM pages filled with code */
-+1:	str	r0, [r3], #4
-+	add	r0, r0, #1 << 12
-+	teq	r3, r6
-+	bne	1b
-+
-+#else // CONFIG_OXNAS_COPY_CODE_TO_SRAM
-+#ifndef CONFIG_ARCH_OXNAS
- 	/*
- 	 * Then map first 1MB of ram in case it contains our boot params.
- 	 */
-@@ -285,6 +432,8 @@
- 	orr	r6, r6, #(PHYS_OFFSET & 0x00f00000)
- 	.endif
- 	str	r6, [r0]
-+#endif // !CONFIG_ARCH_OXNAS
-+#endif // CONFIG_OXNAS_COPY_CODE_TO_SRAM
- 
- #ifdef CONFIG_DEBUG_LL
- 	ldr	r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
-diff -Nurd linux-2.6.24/arch/arm/kernel/process.c linux-2.6.24-oxe810/arch/arm/kernel/process.c
---- linux-2.6.24/arch/arm/kernel/process.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/process.c	2008-06-11 17:47:43.000000000 +0200
-@@ -117,7 +117,7 @@
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
- 
--void (*pm_power_off)(void);
-+void (*pm_power_off)(void) = arch_poweroff;
- EXPORT_SYMBOL(pm_power_off);
- 
- void (*arm_pm_restart)(char str) = arm_machine_restart;
-diff -Nurd linux-2.6.24/arch/arm/kernel/vmlinux.lds.S linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S
---- linux-2.6.24/arch/arm/kernel/vmlinux.lds.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S	2008-06-11 17:47:43.000000000 +0200
-@@ -86,8 +86,659 @@
- #endif
- 	}
- 
--	.text : {			/* Real text segment		*/
--		_text = .;		/* Text and read-only data	*/
-+	.text : {			/* Real text segment        */
-+        	_text = .; 		/* Text and read-only data  */
-+            *(.text.arm926_dma_clean_range)
-+            *(.text.arm926_dma_inv_range)
-+            *(.text.arm926_dma_flush_range)
-+            *(.text.__irq_svc)
-+            *(.text.__arch_copy_to_user)
-+            *(.text.__arch_copy_from_user)
-+            *(.text.__kmalloc)
-+            *(.text.OXNAS_unmask_irq)
-+            *(.text.local_bh_enable)
-+            *(.text.do_level_IRQ)
-+            *(.text.__memzero)
-+            *(.text.irq_exit)
-+            *(.text.__do_irq)
-+            *(.text.pfifo_fast_dequeue)
-+            *(.text.preempt_return)
-+            *(.text.cpu_arm926_switch_mm)
-+            *(.text.check_irq_lock)
-+            *(.text.tcp_init_tso_segs)
-+            *(.text.kfree_skbmem)
-+            *(.text.consistent_sync)
-+            *(.text.__alloc_skb)
-+            *(.text.skb_release_data)
-+            *(.text.OXNAS_mask_irq)
-+            *(.text.Ldiv0)
-+            *(.text.__do_softirq)
-+            *(.text.kmem_cache_free)
-+            *(.text.__kfree_skb)
-+            *(.text.kmem_cache_alloc)
-+            *(.text.radix_tree_lookup)
-+            *(.text.kfree)
-+            *(.text.asm_do_IRQ)
-+            *(.text.skb_clone)
-+            *(.text.qdisc_restart)
-+            *(.text.sock_wfree)
-+            *(.text.unlock_page)
-+            *(.text.tcp_cwnd_validate)
-+            *(.text.free_hot_cold_page)
-+            *(.text.memcpy)
-+            *(.text.velocity_free_tx_buf)
-+            *(.text.wake_up_bit)
-+            *(.text.cond_resched)
-+            *(.text.pfifo_fast_enqueue)
-+            *(.text.raise_softirq_irqoff)
-+            *(.text.tcp_push_one)
-+            *(.text.__modsi3)
-+            *(.text.update_send_head)
-+            *(.text.tcp_set_skb_tso_segs)
-+            *(.text.tcp_snd_test)
-+            *(.text.svc_preempt)
-+            *(.text.__tcp_select_window)
-+            *(.text.dev_queue_xmit)
-+            *(.text.oxnas_gettimeoffset)
-+            *(.text.__wake_up_bit)
-+            *(.text.mod_timer)
-+            *(.text.do_simple_IRQ)
-+            *(.text.velocity_xmit)
-+            *(.text.ip_output)
-+            *(.text.net_tx_action)
-+            *(.text.ip_queue_xmit)
-+            *(.text.tcp_cong_avoid)
-+            *(.text.sk_reset_timer)
-+            *(.text.velocity_intr)
-+            *(.text.pci_dma_sync_single_for_device)
-+            *(.text.process_backlog)
-+            *(.text.tcp_v4_send_check)
-+            *(.text.tcp_transmit_skb)
-+            *(.text.file_send_actor)
-+            *(.text.tcp_current_mss)
-+            *(.text.__netif_rx_schedule)
-+            *(.text.__muldi3)
-+            *(.text.release_sock)
-+            *(.text.do_softirq)
-+            *(.text.pfifo_fast_reset)
-+            *(.text.netif_rx)
-+            *(.text.kernel_sendmsg)
-+            *(.text.rt_hash_code)
-+            *(.text.mod_page_state_offset)
-+            *(.text.preempt_schedule)
-+            *(.text.inet_sendmsg)
-+            *(.text.page_waitqueue)
-+            *(.text.bictcp_acked)
-+            *(.text.__sk_dst_check)
-+            *(.text.blk_rq_map_sg)
-+            *(.text.tcp_mtu_to_mss)
-+            *(.text.__delay)
-+            *(.text.sock_sendmsg)
-+            *(.text.sock_sendpage)
-+            *(.text.ip_local_deliver)
-+            *(.text.bio_add_page)
-+            *(.text.tcp_sendmsg)
-+            *(.text.sock_no_sendpage)
-+            *(.text.__remove_from_page_cache)
-+            *(.text.net_rx_action)
-+            *(.text.eth_type_trans)
-+            *(.text.find_get_page)
-+            *(.text.netif_receive_skb)
-+            *(.text.verify_chain)
-+            *(.text.radix_tree_delete)
-+            *(.text.mpage_readpages)
-+            *(.text.velocity_rx_refill)
-+            *(.text.mpage_end_io_read)
-+            *(.text.radix_tree_insert)
-+            *(.text.ip_rcv)
-+            *(.text.register_gifconf)
-+            *(.text.dma_mmap)
-+            *(.text.tcp_rtt_estimator)
-+            *(.text.ox800sata_get_bbp_base)
-+            *(.text.mark_page_accessed)
-+            *(.text.update_process_times)
-+            *(.text.__pagevec_free)
-+            *(.text.read_page_state_offset)
-+            *(.text.__bio_add_page)
-+            *(.text.__pagevec_lru_add)
-+            *(.text.ox800sata_scr_read)
-+            *(.text.bio_add_pc_page)
-+            *(.text.__rcu_pending)
-+            *(.text.free_sg_entry)
-+            *(.text.put_page)
-+            *(.text.lock_timer_base)
-+            *(.text.radix_tree_tagged)
-+            *(.text.__lshrdi3)
-+            *(.text.lock_sock)
-+            *(.text.__udivsi3)
-+            *(.text.zone_watermark_ok)
-+            *(.text.klist_children_put)
-+            *(.text.sock_aio_dtor)
-+            *(.text.ata_qc_prep)
-+            *(.text.oxnas_dma_free)
-+            *(.text.rcu_pending)
-+            *(.text.free_cold_page)
-+            *(.text.get_page_from_freelist)
-+            *(.text.alloc_sg_entry)
-+            *(.text.ret_fast_syscall)
-+            *(.text.add_to_page_cache)
-+            *(.text.__mod_timer)
-+            *(.text.velocity_free_td_ring)
-+            *(.text.__do_div64)
-+            *(.text.remove_mapping)
-+            *(.text.fast_work_pending)
-+            *(.text.cond_resched_softirq)
-+            *(.text.tcp_v4_rcv)
-+            *(.text.kernel_recvmsg)
-+            *(.text.isolate_lru_pages)
-+            *(.text.klist_children_get)
-+            *(.text.sys_getpid)
-+            *(.text.mempool_free_slab)
-+            *(.text.kobject_get)
-+            *(.text.__tcp_push_pending_frames)
-+            *(.text.sk_stop_timer)
-+            *(.text.bictcp_state)
-+            *(.text.tcp_check_space)
-+            *(.text.kmem_cache_zalloc)
-+            *(.text.get_device)
-+            *(.text.work_pending)
-+            *(.text.tcp_ack)
-+            *(.text.do_edge_IRQ)
-+            *(.text.page_referenced)
-+            *(.text.profile_tick)
-+            *(.text.ox800sata_get_link_base)
-+            *(.text.__pagevec_release_nonlru)
-+            *(.text.blk_recount_segments)
-+            *(.text.__mod_page_state_offset)
-+            *(.text.linear_mergeable_bvec)
-+            *(.text.recalc_task_prio)
-+            *(.text.mempool_kmalloc)
-+            *(.text.do_mpage_readpage)
-+            *(.text.ksoftirqd)
-+            *(.text.__generic_unplug_device)
-+            *(.text.rt_cpu_seq_start)
-+            *(.text.bio_alloc)
-+            *(.text.tasklet_action)
-+            *(.text.effective_prio)
-+            *(.text.OXNAS_timer_interrupt)
-+            *(.text.__wake_up_common)
-+            *(.text.free_poll_entry)
-+            *(.text.vector_swi)
-+            *(.text.do_sock_read)
-+            *(.text.alloc_sg_controller)
-+            *(.text.tcp_rcv_established)
-+            *(.text.oxnas_dma_set_callback)
-+            *(.text.run_local_timers)
-+            *(.text.sock_rmalloc)
-+            *(.text.__rmqueue)
-+            *(.text.ox800sata_bmdma_start)
-+            *(.text.fget_light)
-+            *(.text.queue_work)
-+            *(.text.mempool_alloc_slab)
-+            *(.text.__wake_up)
-+            *(.text.default_idle)
-+            *(.text.fput)
-+            *(.text.add_wait_queue)
-+            *(.text.memcpy_toiovec)
-+            *(.text.rw_verify_area)
-+            *(.text.internal_add_timer)
-+            *(.text.hrtimer_run_queues)
-+            *(.text.tcp_v4_do_rcv)
-+            *(.text.raise_softirq)
-+            *(.text.del_timer)
-+            *(.text.try_to_wake_up)
-+            *(.text.__do_page_cache_readahead)
-+            *(.text.__alloc_pages)
-+            *(.text.sock_aio_read)
-+            *(.text.timer_tick)
-+            *(.text.ox800sata_check_status)
-+            *(.text.do_generic_mapping_read)
-+            *(.text.__ox800sata_scr_read)
-+            *(.text.elv_queue_empty)
-+            *(.text.do_select)
-+            *(.text.free_pages_bulk)
-+            *(.text.remove_wait_queue)
-+            *(.text.dma_bh)
-+            *(.text.__irq_usr)
-+            *(.text.vfs_read)
-+            *(.text.run_timer_softirq)
-+            *(.text.radix_tree_preload)
-+            *(.text.ptrace_getrn)
-+            *(.text.tcp_dsack_set)
-+            *(.text.__switch_to)
-+            *(.text.bio_hw_segments)
-+            *(.text.__const_udelay)
-+            *(.text.nr_running)
-+            *(.text.oxnas_dma_device_set_prd)
-+            *(.text.kref_put)
-+            *(.text.enqueue_task)
-+            *(.text.dequeue_task)
-+            *(.text.elv_next_request)
-+            *(.text.profile_hit)
-+            *(.text.slab_destroy)
-+            *(.text.schedule)
-+            *(.text.end_that_request_first)
-+            *(.text.cfq_find_next_crq)
-+            *(.text.__freed_request)
-+            *(.text.adjtime_adjustment)
-+            *(.text.bictcp_cong_avoid)
-+            *(.text.kthread_should_stop)
-+            *(.text.__activate_task)
-+            *(.text.account_system_time)
-+            *(.text.bio_fs_destructor)
-+            *(.text.mempool_alloc)
-+            *(.text.elv_set_request)
-+            *(.text.schedule_work)
-+            *(.text.wake_up_state)
-+            *(.text.encode_control_status)
-+            *(.text.alloc_skb_from_cache)
-+            *(.text.qdisc_lock_tree)
-+            *(.text.kref_get)
-+            *(.text.init_timer)
-+            *(.text.oxnas_dma_is_active)
-+            *(.text.shrink_slab)
-+            *(.text.poll_freewait)
-+            *(.text.sys_fstat64)
-+            *(.text.__pollwait)
-+            *(.text.cfq_queue_empty)
-+            *(.text.linear_issue_flush)
-+            *(.text.__tasklet_schedule)
-+            *(.text.ox800sata_get_io_base)
-+            *(.text.deactivate_task)
-+            *(.text.cleanup_rbuf)
-+            *(.text.nr_free_zone_pages)
-+            *(.text.ip_route_input)
-+            *(.text.__lock_page)
-+            *(.text.sock_poll)
-+            *(.text.__pskb_trim_head)
-+            *(.text.sys_read)
-+            *(.text.__arch_copy_to_user)
-+            *(.text.generic_make_request)
-+            *(.text.scsi_end_request)
-+            *(.text.bio_init)
-+            *(.text.pipefs_delete_dentry)
-+            *(.text.ox800sata_post_set_mode)
-+            *(.text.sock_common_recvmsg)
-+            *(.text.put_device)
-+            *(.text.tcp_syn_build_options)
-+            *(.text.scheduler_tick)
-+            *(.text.__sys_trace)
-+            *(.text.ox800sata_qc_new)
-+            *(.text.elv_latter_request)
-+            *(.text.do_sync_read)
-+            *(.text.ox800sata_spot_the_end)
-+            *(.text.get_dirty_limits)
-+            *(.text.bio_phys_segments)
-+            *(.text.vfs_fstat)
-+            *(.text.scsi_finish_command)
-+            *(.text.wake_up_process)
-+            *(.text.wdc_ledtrig_sata_activity)
-+            *(.text.__elv_add_request)
-+            *(.text.sock_common_setsockopt)
-+            *(.text.elv_may_queue)
-+            *(.text.rb_first)
-+            *(.text.dnotify_parent)
-+            *(.text.get_writeback_state)
-+            *(.text.__blk_put_request)
-+            *(.text.sock_mmap)
-+            *(.text.throttle_vm_writeout)
-+            *(.text.drive_stat_acct)
-+            *(.text.dlci_ioctl_set)
-+            *(.text.sys_send)
-+            *(.text.default_wake_function)
-+            *(.text.cfq_resort_rr_list)
-+            *(.text.bio_put)
-+            *(.text.scsi_done)
-+            *(.text.kobject_put)
-+            *(.text.release_pages)
-+            *(.text.ata_qc_issue)
-+            *(.text.cfq_dispatch_insert)
-+            *(.text.run_workqueue)
-+            *(.text.delayed_work_timer_fn)
-+            *(.text.scsi_init_cmd_errh)
-+            *(.text.alloc_sock_iocb)
-+            *(.text.blk_done_softirq)
-+            *(.text.do_timer)
-+            *(.text.scsi_10_lba_len)
-+            *(.text.scsi_device_unbusy)
-+            *(.text.bio_get_nr_vecs)
-+            *(.text.cfq_find_cfq_hash)
-+            *(.text.ata_dev_select)
-+            *(.text.blk_remove_plug)
-+            *(.text.end_that_request_last)
-+            *(.text.shrink_dcache_memory)
-+            *(.text.elv_put_request)
-+            *(.text.sys_sendto)
-+            *(.text.scsi_put_command)
-+            *(.text._clear_bit_le)
-+            *(.text.ata_rwcmd_protocol)
-+            *(.text.kobject_cleanup)
-+            *(.text.do_sendfile)
-+            *(.text.worker_thread)
-+            *(.text.elv_dispatch_sort)
-+            *(.text.tcp_fast_parse_options)
-+            *(.text.ox800sata_irq_on)
-+            *(.text.scsi_request_fn)
-+            *(.text.ox800sata_irq_handler)
-+            *(.text.nr_context_switches)
-+            *(.text.oxnas_dma_request)
-+            *(.text.sys_sendfile64)
-+            *(.text.cfq_add_crq_rb)
-+            *(.text.ata_scsi_queuecmd)
-+            *(.text.sock_def_readable)
-+            *(.text.inet_sendpage)
-+            *(.text.cfq_set_request)
-+            *(.text.init_request_from_bio)
-+            *(.text.tcp_v4_conn_request)
-+            *(.text.requeue_task)
-+            *(.text.cache_alloc_refill)
-+            *(.text.scsi_get_command)
-+            *(.text.blk_complete_request)
-+            *(.text.scsi_add_timer)
-+            *(.text.sk_stream_rfree)
-+            *(.text.__umodsi3)
-+            *(.text.ox800sata_tf_load)
-+            *(.text.tcp_recvmsg)
-+            *(.text.cfq_insert_request)
-+            *(.text.tcp_sendpage)
-+            *(.text.bio_alloc_bioset)
-+            *(.text.__tcp_ack_snd_check)
-+            *(.text.kthread_bind)
-+            *(.text.scsi_delete_timer)
-+            *(.text.ox800sata_dev_config)
-+            *(.text.add_wait_queue_exclusive)
-+            *(.text.ox800sata_bmdma_setup)
-+            *(.text.ox800sata_exec_command)
-+            *(.text.clear_queue_congested)
-+            *(.text.generic_file_sendfile)
-+            *(.text.get_io_context)
-+            *(.text.swap_buf_le16)
-+            *(.text._set_bit_be)
-+            *(.text.led_trigger_event)
-+            *(.text.current_io_context)
-+            *(.text.bio_free)
-+            *(.text.pipe_poll)
-+            *(.text.freed_request)
-+            *(.text.cfq_choose_req)
-+            *(.text.ox800sata_RAID_faults)
-+            *(.text.rb_prev)
-+            *(.text.blk_run_queue)
-+            *(.text.mpage_alloc)
-+            *(.text.__get_zone_counts)
-+            *(.text.mpage_bio_submit)
-+            *(.text.generic_fillattr)
-+            *(.text.kswapd)
-+            *(.text.preempt_schedule_irq)
-+            *(.text.mempool_free)
-+            *(.text.elv_dequeue_request)
-+            *(.text.add_interrupt_randomness)
-+            *(.text.poll_initwait)
-+            *(.text.__put_user_bad)
-+            *(.text.vfs_getattr)
-+            *(.text.scsi_free_sgtable)
-+            *(.text.laptop_sync_completion)
-+            *(.text.submit_bio)
-+            *(.text.sock_from_file)
-+            *(.text.add_disk_randomness)
-+            *(.text.scsi_kill_request)
-+            *(.text.free_hot_page)
-+            *(.text.bio_endio)
-+            *(.text.scsi_dispatch_cmd)
-+            *(.text.oxnas_dma_start)
-+            *(.text.cfq_remove_request)
-+            *(.text.do_gettimeofday)
-+            *(.text.skb_copy_datagram_iovec)
-+            *(.text.ext3_get_blocks_handle)
-+            *(.text.__down_read_trylock)
-+            *(.text.cfq_activate_request)
-+            *(.text.recalc_sigpending)
-+            *(.text.ext3_readpage)
-+            *(.text.ox800sata_dev_select)
-+            *(.text.ret_to_user)
-+            *(.text.elv_completed_request)
-+            *(.text.read_cache_page)
-+            *(.text.touch_atime)
-+            *(.text.cfq_update_next_crq)
-+            *(.text.no_work_pending)
-+            *(.text.recalc_sigpending_tsk)
-+            *(.text.end_that_request_chunk)
-+            *(.text.cp_new_stat64)
-+            *(.text.rb_next)
-+            *(.text.__wake_up_sync)
-+            *(.text.subsys_create_file)
-+            *(.text.rcu_needs_cpu)
-+            *(.text.sys_select)
-+            *(.text.oxnas_dma_device_set)
-+            *(.text.ata_sg_init)
-+            *(.text.__put_user_8)
-+            *(.text.ox800sata_port_disable)
-+            *(.text.scsi_next_command)
-+            *(.text.__scsi_done)
-+            *(.text.ata_scsi_qc_complete)
-+            *(.text.__wake_up_locked)
-+            *(.text.lru_add_drain)
-+            *(.text.bio_check_pages_dirty)
-+            *(.text.cascade)
-+            *(.text.tcp_poll)
-+            *(.text.oxnas_dma_set_common)
-+            *(.text.__pagevec_release)
-+            *(.text.ata_scsi_translate)
-+            *(.text.oxnas_dma_interrupt)
-+            *(.text.sys_newfstat)
-+            *(.text.tcp_send_delayed_ack)
-+            *(.text.scsi_decide_disposition)
-+            *(.text.ox800sata_qc_free)
-+            *(.text.scsi_softirq_done)
-+            *(.text.netlink_group_mask)
-+            *(.text.__brelse)
-+            *(.text.do_sock_write)
-+            *(.text.mempool_create_node)
-+            *(.text.ox800sata_qc_issue)
-+            *(.text.__scsi_release_request)
-+            *(.text.blockable_page_cache_readahead)
-+            *(.text.get_index)
-+            *(.text.walk_page_buffers)
-+            *(.text.__queue_work)
-+            *(.text.ret_from_fork)
-+            *(.text.mb_cache_shrink_fn)
-+            *(.text.sys_socketcall)
-+            *(.text.blk_congestion_wait)
-+            *(.text.put_io_context)
-+            *(.text.elevator_find)
-+            *(.text._set_bit_le)
-+            *(.text.generic_write_checks)
-+            *(.text.datagram_poll)
-+            *(.text.ext3_block_to_path)
-+            *(.text.scsi_prep_fn)
-+            *(.text.fget)
-+            *(.text.blk_plug_device)
-+            *(.text.disk_round_stats)
-+            *(.text.get_request)
-+            *(.text.page_cache_readahead)
-+            *(.text.__bread)
-+            *(.text.tcp_rcv_space_adjust)
-+            *(.text.ox800sata_tf_read)
-+            *(.text.add_timer_randomness)
-+            *(.text.sockfd_lookup_light)
-+            *(.text.__find_get_block)
-+            *(.text.split_page)
-+            *(.text.cfq_dispatch_requests)
-+            *(.text.cfq_kick_queue)
-+            *(.text.cfq_may_queue)
-+            *(.text.cfq_put_request)
-+            *(.text.get_request_wait)
-+            *(.text.default_callback)
-+            *(.text.cpu_arm926_set_pte)
-+            *(.text.tcp_event_data_recv)
-+            *(.text.ata_scsi_qc_new)
-+            *(.text.SetRoundingMode)
-+            *(.text.make_ahead_window)
-+            *(.text.inotify_inode_queue_event)
-+            *(.text.__make_request)
-+            *(.text.finish_wait)
-+            *(.text.cfq_completed_request)
-+            *(.text.__cfq_slice_expired)
-+            *(.text.sd_init_command)
-+            *(.text.find_lock_page)
-+            *(.text.pipefs_get_sb)
-+            *(.text.ata_qc_new_init)
-+            *(.text.task_timeslice)
-+            *(.text.sk_dst_check)
-+            *(.text.set_queue_congested)
-+            *(.text.prepare_to_wait)
-+            *(.text.sys_write)
-+            *(.text.swap_io_context)
-+            *(.text.sys_alarm)
-+            *(.text.mempool_resize)
-+            *(.text.__cond_resched)
-+            *(.text.scsi_16_lba_len)
-+            *(.text.autoremove_wake_function)
-+            *(.text.inotify_dentry_parent_queue_event)
-+            *(.text.cfq_init_prio_data)
-+            *(.text.group_send_sig_info)
-+            *(.text.ata_qc_issue_prot)
-+            *(.text.cfq_put_queue)
-+            *(.text.__set_irq_handler)
-+            *(.text.__generic_file_aio_read)
-+            *(.text.ox800sata_eng_timeout)
-+            *(.text.rb_erase)
-+            *(.text.generic_file_aio_read)
-+            *(.text.default_llseek)
-+            *(.text.blk_unplug_work)
-+            *(.text.linear_make_request)
-+            *(.text.elv_insert)
-+            *(.text.velocity_init_registers)
-+            *(.text.vfs_permission)
-+            *(.text.alloc_inode)
-+            *(.text.mii_ethtool_sset)
-+            *(.text.blk_rq_map_kern)
-+            *(.text.tcp_urg)
-+            *(.text.__ata_qc_complete)
-+            *(.text.io_schedule_timeout)
-+            *(.text.run_posix_cpu_timers)
-+            *(.text.ox800sata_irq_clear)
-+            *(.text.put_tty_driver)
-+            *(.text.free_sg_controller)
-+            *(.text.__sk_stream_mem_reclaim)
-+            *(.text.elv_merge)
-+            *(.text.scsi_run_queue)
-+            *(.text.elv_former_request)
-+            *(.text.blk_requeue_request)
-+            *(.text.__end_that_request_first)
-+            *(.text.ext3_get_block)
-+            *(.text.ox800sata_phy_reset)
-+            *(.text.schedule_timeout)
-+            *(.text.grab_cache_page_nowait)
-+            *(.text.bio_map_kern_endio)
-+            *(.text.__up_read)
-+            *(.text.tcp_data_queue)
-+            *(.text.set_bdev_super)
-+            *(.text.ext3_readpages)
-+            *(.text.scsi_exit_queue)
-+            *(.text.ext3_get_branch)
-+            *(.text.cfq_forced_dispatch_cfqqs)
-+            *(.text.bioset_free)
-+            *(.text.blk_execute_rq_nowait)
-+            *(.text.scsi_eh_wakeup)
-+            *(.text.tcp_delack_timer)
-+            *(.text.shrink_icache_memory)
-+            *(.text.mpage_end_io_write)
-+            *(.text.scsi_io_completion)
-+            *(.text.verify_iovec)
-+            *(.text.credit_entropy_store)
-+            *(.text.blk_unplug_timeout)
-+            *(.text.work_resched)
-+            *(.text.sys_sendfile)
-+            *(.text.do_bad_IRQ)
-+            *(.text.sd_rw_intr)
-+            *(.text.set_task_comm)
-+            *(.text.blk_do_ordered)
-+            *(.text.rb_last)
-+            *(.text.drop_buffers)
-+            *(.text.ata_scsi_rw_xlat)
-+            *(.text.oxnas_dma_shutdown)
-+            *(.text.__group_send_sig_info)
-+            *(.text.led_trigger_set_default)
-+            *(.text.blk_queue_bounce)
-+            *(.text.cfq_var_store)
-+            *(.text.rb_insert_color)
-+            *(.text.__remove_hrtimer)
-+            *(.text.sys_sysinfo)
-+            *(.text.tcp_simple_retransmit)
-+            *(.text.it_real_fn)
-+            *(.text.sk_send_sigurg)
-+            *(.text.sys_statfs64_wrapper)
-+            *(.text.alloc_page_buffers)
-+            *(.text.bio_pair_release)
-+            *(.text.__dequeue_signal)
-+            *(.text.kblockd_schedule_work)
-+            *(.text.wakeup_kswapd)
-+            *(.text.process_timeout)
-+            *(.text.__getblk)
-+            *(.text.blk_get_request)
-+            *(.text.sync_buffer)
-+            *(.text.sk_stream_mem_schedule)
-+            *(.text.vfs_stat)
-+            *(.text.rb_replace_node)
-+            *(.text.signal_wake_up)
-+            *(.text.ata_std_ports)
-+            *(.text.tcp_send_ack)
-+            *(.text.send_signal)
-+            *(.text._atomic_dec_and_lock)
-+            *(.text.set_bh_page)
-+            *(.text.mutex_trylock)
-+            *(.text.sys_sigaltstack_wrapper)
-+            *(.text.sig_ignored)
-+            *(.text.net_family_write_lock)
-+            *(.text.radix_tree_node_alloc)
-+            *(.text.may_open)
-+            *(.text.account_user_time)
-+            *(.text.udp_seq_start)
-+            *(.text.ll_front_merge_fn)
-+            *(.text.laptop_flush)
-+            *(.text.__tasklet_hi_schedule)
-+            *(.text.__und_usr)
-+            *(.text.do_signal)
-+            *(.text.wake_bit_function)
-+            *(.text.mutex_lock_interruptible)
-+            *(.text.cfq_merged_request)
-+            *(.text.scsi_init_cmd_from_req)
-+            *(.text.elv_requeue_request)
-+            *(.text.force_sigsegv)
-+            *(.text.elv_merge_requests)
-+            *(.text.cp_new_stat)
-+            *(.text.prepare_to_wait_exclusive)
-+            *(.text.ioc_set_batching)
-+            *(.text.check_kill_permission)
-+            *(.text.scsi_queue_insert)
-+            *(.text.__csum_ipv6_magic)
-+            *(.text.wb_kupdate)
-+            *(.text.__down_write_trylock)
-+            *(.text.elv_register_queue)
-+            *(.text.sys_getitimer)
-+            *(.text.ox800sata_pio_task)
-+            *(.text.hrtimer_try_to_cancel)
-+            *(.text.find_pid)
-+            *(.text.oxnas_dma_raw_isactive)
-+            *(.text.cmp_ex)
-+            *(.text.__mpage_writepage)
-+            *(.text.sk_stream_wait_memory)
-+            *(.text.sys_sched_yield)
-+            *(.text.background_writeout)
-+            *(.text.rotate_reclaimable_page)
-+            *(.text.do_sigaction)
-+            *(.text.sock_def_write_space)
-+            *(.text.sched_exit)
-+            *(.text.inode_change_ok)
-+            *(.text.wait_for_completion_interruptible)
-+            *(.text.device_initialize)
-+            *(.text.journal_set_revoke)
-+            *(.text.try_to_free_pages)
-+            *(.text.tcp_write_timer)
-+            *(.text.dev_ioctl)
-+            *(.text.skb_copy_expand)
-+            *(.text.invalidate_complete_page)
-+            *(.text.*)
- 			__exception_text_start = .;
- 			*(.exception.text)
- 			__exception_text_end = .;
-diff -Nurd linux-2.6.24/arch/arm/lib/Makefile linux-2.6.24-oxe810/arch/arm/lib/Makefile
---- linux-2.6.24/arch/arm/lib/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/Makefile	2008-06-11 17:47:47.000000000 +0200
-@@ -29,6 +29,10 @@
- endif
- endif
- 
-+ifeq ($(CONFIG_OXNAS_DMA_COPIES),y)
-+  lib-y	+= oxnas_copies.o
-+endif
-+
- lib-$(CONFIG_MMU) += $(mmu-y)
- 
- ifeq ($(CONFIG_CPU_32v3),y)
-diff -Nurd linux-2.6.24/arch/arm/lib/clear_user.S linux-2.6.24-oxe810/arch/arm/lib/clear_user.S
---- linux-2.6.24/arch/arm/lib/clear_user.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/clear_user.S	2008-06-11 17:47:47.000000000 +0200
-@@ -18,7 +18,11 @@
-  *          : sz   - number of bytes to clear
-  * Returns  : number of bytes NOT cleared
-  */
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__clear_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- ENTRY(__clear_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 		stmfd	sp!, {r1, lr}
- 		mov	r2, #0
- 		cmp	r1, #4
-diff -Nurd linux-2.6.24/arch/arm/lib/copy_from_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S
---- linux-2.6.24/arch/arm/lib/copy_from_user.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S	2008-06-11 17:47:47.000000000 +0200
-@@ -83,7 +83,12 @@
- 
- 	.text
- 
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__copy_from_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
-+.section ".text.__copy_from_user"
- ENTRY(__copy_from_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 
- #include "copy_template.S"
- 
-diff -Nurd linux-2.6.24/arch/arm/lib/copy_to_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S
---- linux-2.6.24/arch/arm/lib/copy_to_user.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S	2008-06-11 17:47:47.000000000 +0200
-@@ -86,7 +86,12 @@
- 
- 	.text
- 
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__copy_to_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
-+.section ".text.__copy_to_user"
- ENTRY(__copy_to_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 
- #include "copy_template.S"
- 
-diff -Nurd linux-2.6.24/arch/arm/lib/memcpy.S linux-2.6.24-oxe810/arch/arm/lib/memcpy.S
---- linux-2.6.24/arch/arm/lib/memcpy.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/memcpy.S	2008-06-11 17:47:47.000000000 +0200
-@@ -53,6 +53,7 @@
- 
- /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
- 
-+.section ".text.memcpy"
- ENTRY(memcpy)
- 
- #include "copy_template.S"
-diff -Nurd linux-2.6.24/arch/arm/lib/memzero.S linux-2.6.24-oxe810/arch/arm/lib/memzero.S
---- linux-2.6.24/arch/arm/lib/memzero.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/memzero.S	2008-06-11 17:47:47.000000000 +0200
-@@ -30,6 +30,7 @@
-  * memzero again.
-  */
- 
-+.section ".text.__memzero"
- ENTRY(__memzero)
- 	mov	r2, #0			@ 1
- 	ands	r3, r0, #3		@ 1 unaligned?
-diff -Nurd linux-2.6.24/arch/arm/lib/oxnas_copies.c linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c
---- linux-2.6.24/arch/arm/lib/oxnas_copies.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c	2008-06-11 17:47:47.000000000 +0200
-@@ -0,0 +1,261 @@
-+/*
-+ * linux/arch/arm/lib/nas_copies.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/compiler.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/mm.h>
-+#include <linux/pagemap.h>
-+#include <asm/scatterlist.h>
-+#include <asm/semaphore.h>
-+#include <asm/arch/dma.h>
-+
-+static DECLARE_MUTEX(copy_mutex);
-+static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0);
-+
-+static void dma_callback(
-+    oxnas_dma_channel_t         *channel,
-+    oxnas_callback_arg_t         arg,
-+    oxnas_dma_callback_status_t  error_code,
-+    u16                          checksum,
-+    int                          interrupt_count)
-+{
-+    up(&callback_semaphore);
-+}
-+
-+unsigned long oxnas_copy_from_user(void *to, const void __user *from, unsigned long count)
-+{
-+    int pages_mapped, i;
-+    unsigned long transfered = 0;
-+    struct page *pages[2];
-+    oxnas_dma_channel_t *channel;
-+    unsigned long uaddr = (unsigned long)from;
-+    unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+    unsigned long start_page = uaddr >> PAGE_SHIFT;
-+    int nr_pages = end_page - start_page;
-+//printk("F 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
-+
-+    might_sleep();
-+
-+    BUG_ON(nr_pages > 2);
-+
-+    // Only support a single concurrent copy operation, as only using a single
-+    // DMA channel for now
-+    while (down_interruptible(&copy_mutex));
-+
-+    // Get kernel mappings for the user pages
-+    down_read(&current->mm->mmap_sem);
-+    pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 0, 0, pages, NULL);
-+    up_read(&current->mm->mmap_sem);
-+
-+    if (pages_mapped != nr_pages) {
-+        // Didn't get mappings for all pages requested, so release any we did get
-+        for (i=0; i < pages_mapped; ++i) {
-+            page_cache_release(pages[i]);
-+        }
-+        pages_mapped = 0;
-+    }
-+
-+    if (pages_mapped) {
-+        int i;
-+        struct scatterlist sl;
-+        struct scatterlist gl[2];
-+
-+        // Fill gathering DMA descriptors
-+        gl[0].page = pages[0]; 
-+        gl[0].offset = uaddr & ~PAGE_MASK;
-+        if (pages_mapped > 1) {
-+            gl[0].length = PAGE_SIZE - gl[0].offset;
-+            gl[1].offset = 0;
-+            gl[1].page = pages[1]; 
-+            gl[1].length = count - gl[0].length;
-+        } else {
-+            gl[0].length = count;
-+        }
-+
-+        // Create DMA mappings for all the user pages
-+        for (i=0; i < pages_mapped; ++i) {
-+            gl[i].dma_address = dma_map_single(0, page_address(gl[i].page) + gl[i].offset, gl[i].length, DMA_TO_DEVICE);
-+        }
-+
-+        // Create a DMA mapping for the kernel memory range
-+        sl.dma_address = dma_map_single(0, to, count, DMA_FROM_DEVICE);
-+        sl.length = count;
-+
-+        // Allocate a DMA channel
-+        channel = oxnas_dma_request(1);
-+        BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
-+
-+        // Do DMA from user to kernel memory
-+        oxnas_dma_set_sg(
-+            channel,
-+            gl,
-+            pages_mapped,
-+            &sl,
-+            1,
-+            OXNAS_DMA_MODE_INC,
-+            OXNAS_DMA_MODE_INC,
-+            0);
-+
-+        // Using notification callback
-+        oxnas_dma_set_callback(channel, dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+        oxnas_dma_start(channel);
-+
-+        // Sleep until transfer complete
-+        while (down_interruptible(&callback_semaphore));
-+        oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+        transfered += count;
-+
-+        // Release the DMA channel
-+        oxnas_dma_free(channel);
-+
-+        // Release kernel DMA mapping
-+        dma_unmap_single(0, sl.length, count, DMA_FROM_DEVICE);
-+        // Release user DMA mappings
-+        for (i=0; i < pages_mapped; ++i) {
-+            dma_unmap_single(0, gl[i].dma_address, gl[i].length, DMA_TO_DEVICE);
-+        }
-+
-+        // Release user pages
-+        for (i=0; i < pages_mapped; ++i) {
-+            page_cache_release(pages[i]);
-+        }
-+    }
-+
-+    up(&copy_mutex);
-+
-+    return count - transfered;
-+}
-+
-+//unsigned long oxnas_copy_to_user(void __user *to, const void *from, unsigned long count)
-+//{
-+//    int pages_mapped, i;
-+//    unsigned long transfered = 0;
-+//    struct page *pages[2];
-+//    oxnas_dma_channel_t *channel;
-+//    unsigned long uaddr = (unsigned long)to;
-+//    unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+//    unsigned long start_page = uaddr >> PAGE_SHIFT;
-+//    int nr_pages = end_page - start_page;
-+////printk("T 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
-+//
-+//    might_sleep();
-+//
-+//    BUG_ON(nr_pages > 2);
-+//
-+//    // Only support a single concurrent copy operation, as only using a single
-+//    // DMA channel for now
-+//    while (down_interruptible(&copy_mutex));
-+//
-+//    // Get kernel mappings for the user pages
-+//    down_read(&current->mm->mmap_sem);
-+//    pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 1, 0, pages, NULL);
-+//    up_read(&current->mm->mmap_sem);
-+//
-+//    if (pages_mapped != nr_pages) {
-+//        // Didn't get mapping for all the pages we requested, so release any
-+//        // user page mappings we did get
-+//        for (i=0; i < pages_mapped; ++i) {
-+//            page_cache_release(pages[i]);
-+//        }
-+//        pages_mapped = 0;
-+//    }
-+//
-+//    if (pages_mapped) {
-+//        int i;
-+//        struct scatterlist gl;
-+//        struct scatterlist sl[2];
-+//
-+//        // Fill scattering DMA descriptors for writing to user space
-+//        sl[0].page = pages[0]; 
-+//        sl[0].offset = uaddr & ~PAGE_MASK;
-+//        if (pages_mapped > 1) {
-+//            sl[0].length = PAGE_SIZE - sl[0].offset;
-+//            sl[1].offset = 0;
-+//            sl[1].page = pages[1]; 
-+//            sl[1].length = count - sl[0].length;
-+//        } else {
-+//            sl[0].length = count;
-+//        }
-+//
-+//        // Create DMA mappings for all the user pages
-+//        for (i=0; i < pages_mapped; ++i) {
-+//            sl[i].__address = page_address(sl[i].page) + sl[i].offset;
-+//            sl[i].dma_address = dma_map_single(0, sl[i].__address, sl[i].length, DMA_FROM_DEVICE);
-+//        }
-+//
-+//        // Create a DMA mapping for the kernel memory range
-+//        gl.dma_address = dma_map_single(0, (void*)from, count, DMA_TO_DEVICE);
-+//        gl.length = count;
-+//
-+////        {
-+//////flush_cache_all();
-+////          // Do copy with CPU to test
-+////            const char* src = from;
-+//////printk("T Copying...\n");
-+////            for (i=0; i < pages_mapped; ++i) {
-+////                void* kadr = kmap(sl[i].page) + sl[i].offset;
-+////                memcpy(kadr, src, sl[i].length);
-+////                kunmap(sl[i].page);
-+////                src += sl[i].length;
-+////                transfered += sl[i].length;
-+////            }
-+////        }
-+//
-+//flush_cache_all();
-+//        // Allocate a DMA channel
-+//        channel = oxnas_dma_request(1);
-+//        BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
-+//
-+//        // Do DMA from kernel to user memory
-+//        oxnas_dma_set_sg(
-+//            channel,
-+//            &gl,
-+//            1,
-+//            sl,
-+//            pages_mapped,
-+//            OXNAS_DMA_MODE_INC,
-+//            OXNAS_DMA_MODE_INC,
-+//            0);
-+//        oxnas_dma_start(channel);
-+//        while (oxnas_dma_is_active(channel));
-+//        transfered += count;
-+//
-+//        // Release the DMA channel
-+//        oxnas_dma_free(channel);
-+////flush_cache_all();
-+//
-+//        // Release kernel DMA mapping
-+//        dma_unmap_single(0, gl.dma_address, count, DMA_TO_DEVICE);
-+//        // Release user DMA mappings
-+//        for (i=0; i < pages_mapped; ++i) {
-+//            dma_unmap_single(0, sl[i].dma_address, sl[i].length, DMA_FROM_DEVICE);
-+//        }
-+//
-+//        // Release user pages
-+//        for (i=0; i < pages_mapped; ++i) {
-+//            SetPageDirty(pages[i]);
-+//            page_cache_release(pages[i]);
-+//        }
-+//    }
-+//
-+//    up(&copy_mutex);
-+//
-+//   return count - transfered;
-+//}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Kconfig linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig
---- linux-2.6.24/arch/arm/mach-oxnas/Kconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,574 @@
-+if ARCH_OXNAS
-+
-+menu "Oxford Semiconductor NAS Options"
-+
-+config ARCH_OXNAS_FPGA
-+	bool "FPGA platform"
-+	default n
-+	help
-+	  This enables support for Oxsemi NAS SoC FPGA development platform
-+
-+config OXNAS_CORE_CLK
-+	int "Integrator core module processor clock frequency in MHz"
-+	depends on ARCH_OXNAS_FPGA
-+	default 175
-+	help
-+		Maximum reliable frequency 175MHz
-+
-+config OXNAS_CORE_BUS_CLK_DIV
-+	int "Integrator core module bus clock divider"
-+	depends on ARCH_OXNAS_FPGA
-+	default 4
-+	help
-+		Must be greater than 0
-+
-+config NOMINAL_PLL400_FREQ
-+	int "The master clock frequency of the Soc"
-+	default 400000000
-+	help
-+		The PLL400 clock is divided by 2 to drive the ARM clock and by
-+		4 to drive the AHB clock
-+
-+config NOMINAL_RPSCLK_FREQ
-+	int "The input clock frequency to the RPS"
-+	default 25000000
-+	help
-+		The RPS clock feeds into a prescaler and from there feeds the
-+		RPS timers
-+
-+choice
-+	prompt "OXNAS system type"
-+	default OXNAS_VERSION_0X800
-+
-+config OXNAS_VERSION_0X800
-+	bool "0X800"
-+	select ARM_AMBA
-+	help
-+	  Support for the 0X800 SoC
-+
-+config OXNAS_VERSION_0X810
-+	bool "0X810"
-+	select ARM_AMBA
-+	help
-+	  Support for the 0X810 SoC
-+
-+config OXNAS_VERSION_0X850
-+	bool "0X850"
-+	help
-+	  Support for the 0X850 SoC
-+endchoice
-+
-+config ARCH_OXNAS_UART1
-+	bool "Support UART1"
-+	default n
-+	help
-+		This enables UART1 to be accessible to Linux.
-+		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+		including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART1_MODEM
-+	bool "Support UART1 modem control lines"
-+	depends on ARCH_OXNAS_UART1
-+	default n
-+	help
-+		Multiplex the modem control lines from UART1 onto external pins
-+
-+config ARCH_OXNAS_UART2
-+	bool "Support UART2"
-+	default n
-+	help
-+		This enables UART2 to be accessible to Linux
-+		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+		including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART2_MODEM
-+	bool "Support UART2 modem control lines"
-+	depends on ARCH_OXNAS_UART2
-+	default n
-+	help
-+		Multiplex the modem control lines from UART2 onto external pins
-+
-+config ARCH_OXNAS_UART3
-+	bool "Support UART3"
-+	default n
-+	help
-+		This enables UAR3 to be accessible to Linux
-+		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+		including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART3_MODEM
-+	bool "Support UART3 modem control lines"
-+	depends on ARCH_OXNAS_UART3
-+	default n
-+	help
-+		Multiplex the modem control lines from UART3 onto external pins
-+
-+config ARCH_OXNAS_UART4
-+	bool "Support UART4"
-+	depends on !PCI
-+	default n
-+	help
-+		This enables UART4 to be accessible to Linux
-+		UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+		including those UARTs selected to be present
-+		UART4 always has its modem control lines available on external pins
-+		when selected (overlaying PCI functions)
-+
-+config ARCH_OXNAS_PCI_REQGNT_0
-+	bool "Enable req/gnt for PCI device 0"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_REQGNT_1
-+	bool "Enable req/gnt for PCI device 1"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_REQGNT_2
-+	bool "Enable req/gnt for PCI device 2"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_REQGNT_3
-+	bool "Enable req/gnt for PCI device 3"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_0
-+	bool "Enable PCI clock output 0"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_1
-+	bool "Enable PCI clock output 1"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_2
-+	bool "Enable PCI clock output 2"
-+	depends on PCI
-+	default n
-+	help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_3
-+	bool "Enable PCI clock output 3"
-+	depends on PCI
-+	default n
-+	help
-+
-+config OXNAS_PCI_RESET
-+	bool "Allow PCI reset to be toggled after power up"
-+	depends on PCI
-+	default n
-+	help
-+		The SoC requires that the PCI bus reset be toggled after the
-+		rest of the SoC has emerged from reset
-+
-+config OXNAS_PCI_RESET_GPIO
-+	int "GPIO line connected to PCI reset"
-+	depends on OXNAS_PCI_RESET
-+	default 12
-+	help
-+		The PCI bus requires a separate reset to be asserted after the
-+		reset of the SoC has emerged from reset. This defines the GPIO
-+		line which is connected to the PCI reset
-+
-+config OXNAS_SATA_POWER_1
-+	bool "Allow control of SATA 1 disk power via GPIO"
-+	default n
-+	help
-+		Allow SATA disk 1 power to be turned off via GPIO lines
-+
-+config OXNAS_SATA_POWER_GPIO_1
-+	int "GPIO line connected to SATA power control for disk 1"
-+	depends on OXNAS_SATA_POWER_1
-+	default 15
-+	help
-+		The GPIO line that controls SATA disk 1 power
-+
-+config OXNAS_SATA_POWER_2
-+	bool "Allow control of SATA disk 2 power via GPIO"
-+	default n
-+	help
-+		Allow SATA disk 2 power to be turned off via GPIO lines
-+
-+config OXNAS_SATA_POWER_GPIO_2
-+	int "GPIO line connected to SATA power control for disk 2"
-+	depends on OXNAS_SATA_POWER_2
-+	default 18
-+	help
-+		The GPIO line that controls SATA disk 2 power
-+
-+config FORCE_MAX_ZONEORDER
-+	int "Max order of zoned buddy allocator"
-+	default 11
-+	help
-+		The value to be assigned to MAX_ORDER
-+
-+config SRAM_NUM_PAGES
-+	int "The number of SRAM memory pages present in the system"
-+	default 8
-+	help
-+		Determines the number of pages of SRAM that are assumed to exist in the
-+		system memory map
-+
-+config SUPPORT_LEON
-+	bool "Include support for Leon"
-+	default n
-+
-+config LEON_PAGES
-+	int "The number of 4K pages of SRAM to reserve for the LEON program"
-+	depends on SUPPORT_LEON
-+	default 2
-+	help
-+		Determines the number of 4K pages of SRAM that are reserved for the
-+		LEON program
-+
-+config LEON_COPRO
-+	bool "Load LEON networking acceleration program"
-+	depends on SUPPORT_LEON && OXNAS_VERSION_0X810
-+	default n
-+
-+config LEON_OFFLOAD_TX
-+	bool "Whether network Tx operations should be offloaded to the LEON"
-+	depends on LEON_COPRO
-+	default n
-+
-+config LEON_RESERVE_DMA_CHANNEL
-+	bool "Whether to reserve the last DMA channel for the CoPro's use"
-+	depends on LEON_OFFLOAD_TX
-+	default n
-+
-+config LEON_OFFLOAD_TSO
-+	bool "Whether network TSO operations should be offloaded to the LEON"
-+	depends on LEON_OFFLOAD_TX
-+	default n
-+
-+config LEON_START_EARLY
-+	bool "Load LEON early startup program"
-+	depends on SUPPORT_LEON
-+	default n
-+	help
-+		For situations where the LEON is to run some code unrelated to
-+		its normal network acceleration functions, this options causes
-+		the LEON code to be loaded and the LEON started early in the
-+		boot process
-+
-+config LEON_POWER_BUTTON_MONITOR
-+	tristate "Load LEON power button monitoring program"
-+	depends on SUPPORT_LEON
-+	default n
-+	help
-+		Support powering down the system via a GPIO button and when the
-+		system is powered down load a LEON program that will monitor the
-+		button for attempts to power the system back on
-+
-+config OXNAS_POWER_BUTTON_GPIO
-+	int "GPIO line connected to power button"
-+	depends on LEON_POWER_BUTTON_MONITOR
-+	default 33
-+	help
-+		Specifies the GPIO line to which the power button is connected
-+
-+config USER_RECOVERY_BUTTON_MONITOR
-+	tristate "Load user recovery button monitoring program"
-+	default n
-+	help
-+		Support User recovery of the system via a GPIO button. When the
-+		system is power cycled after the use of this button, the admin
-+		password and network settings are set to factory values.
-+
-+config OXNAS_USER_RECOVERY_BUTTON_GPIO
-+	int "GPIO line connected to user recovery button"
-+	depends on USER_RECOVERY_BUTTON_MONITOR
-+	default 32
-+	help
-+		Specifies the GPIO line to which the user recovery button is 
-+		connected.
-+
-+config OXNAS_DDR_MON
-+	bool "Poll the DDR core bus monitors from timer tick interrupt"
-+	default n
-+
-+config OXNAS_AHB_MON
-+	bool "Include support for AHB monitors"
-+	default n
-+
-+config OXNAS_MONITOR_SUBSAMPLE
-+	int "Jiffy subsample factor for AHB monitor sampling"
-+	depends on OXNAS_AHB_MON || OXNAS_DDR_MON
-+	default 10
-+	help
-+		The factor by which to subsample the jiffy count to produce AHB monitor
-+		sampling events
-+
-+config OXNAS_CACHE_LOCKDOWN
-+	bool "Allow locking down part of the caches"
-+	default n
-+
-+config OXNAS_CACHE_I_MASK
-+	int "Bit mask for I cache lockdown"
-+	depends on OXNAS_CACHE_LOCKDOWN
-+	default 0
-+	help
-+		Allowable values are:
-+		0 - No ways locked down
-+		1 - One way locked down
-+		3 - Two ways locked down
-+		7 - Three ways locked down
-+
-+config OXNAS_CACHE_D_MASK
-+	int "Bit mask for D cache lockdown"
-+	depends on OXNAS_CACHE_LOCKDOWN
-+	default 0
-+	help
-+		Allowable values are:
-+		0 - No ways locked down
-+		1 - One way locked down
-+		3 - Two ways locked down
-+		7 - Three ways locked down
-+
-+config DO_MEM_TEST
-+	bool "Perform memory copy throughput test during boot"
-+	default 0
-+
-+config CRYPTO_OXAESLRW
-+	tristate "LRW-AES hardware support"
-+	help
-+	  Driver for controlling the Ox-Semi OX800 cipher core for LRW-AES
-+	  encryption
-+
-+config DESCRIPTORS_PAGES
-+	int "The number of SRAM memory pages to reserve for DMA descriptors"
-+	default 1
-+	help
-+		Determines the number of pages of SRAM that are reserved for DMA
-+		descriptors
-+
-+config ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
-+	int "The number of GMAC descriptors to allocate"
-+	default 112
-+
-+config ARCH_OXNAS_MAX_SATA_SG_ENTRIES
-+	int "The max. number of SG DMA descriptors to use in the single transfer"
-+	default 64
-+
-+config TACHO_THERM_AND_FAN
-+	tristate "Include support for the temperature sensing, and automatic fan control"
-+	default n
-+
-+config GPIO_TEST
-+	tristate "Device driver for exercising GPIO block."
-+	default n
-+	help
-+	  Connect the I2C serial lines (SCLK, SCS, and SDT) together to run test
-+
-+config OXNAS_RTC
-+	tristate "Probe for m41t00 RTC"
-+	select I2C
-+	select I2C_ALGOBIT
-+	select I2C_OXNAS_BITBASH
-+	select RTC_CLASS
-+	select RTC_DRV_DS1307
-+	default n
-+	help
-+	  The M41T00 RTC provides basic time save and restore.
-+	  The device is probed for on the OXNAS bit-bash I2C bus.
-+
-+config I2S
-+	tristate "I2S test interface"
-+	default n
-+	help
-+	  Say Y here to use i2s
-+	  This support is also available as a module. If so, the module will be
-+	  called i2s.
-+
-+config PCI_OXNAS_CARDBUS
-+    bool "Switches from a PCI/Mini-PCI bus to a Cardbus bus."
-+    depends on PCI && ARCH_OXNAS_FPGA
-+    ---help---
-+      This option limits scanning of the bus to omit the Via SATA interface.
-+      This makes the bus compatible with cardbus cards that expect to be the 
-+      only PCI device on the bus.
-+
-+config DPE_TEST
-+	tristate "Test the DPE core"
-+	default n
-+
-+config OXNAS_EARLY_PRINTK
-+	bool "Whether to output to printascii from printk"
-+	depends on DEBUG_LL
-+	help
-+		If both CONFIG_DEBUG_LL and this option are selected, then each printk
-+		call will duplicate the message in a call to printascii to get very
-+		early console output
-+
-+config OXNAS_INSTRUMENT_COPIES
-+	bool "Instrument copy_to_user and copy_from_user"
-+	default n
-+
-+config OXNAS_INSTRUMENT_COPIES_THRESHOLD
-+	int "The threshold above which copies will be instrumented"
-+	depends on OXNAS_INSTRUMENT_COPIES
-+	default 0
-+
-+config OXNAS_INSTRUMENT_COPIES_TIME
-+	bool "Whether to print copy timing to console"
-+	depends on OXNAS_INSTRUMENT_COPIES
-+	default n
-+
-+config OXNAS_INSTRUMENT_COPIES_GPIO
-+	bool "Whether to toggle a GPIO around copies"
-+	depends on OXNAS_INSTRUMENT_COPIES
-+	default n
-+
-+config OXNAS_DMA_COPIES
-+	bool "Whether to use DMA for larger user-kernel copies"
-+	default n
-+	
-+config OXNAS_DMA_COPY_THRESHOLD
-+	int "The threshold above which DMA will be used for copies"
-+	depends on OXNAS_DMA_COPIES
-+	default 1024
-+
-+config OXNAS_AHB_MONITOR_MODULE
-+	tristate "Creates a loadable module to control the AHB monitors"
-+	default n
-+	help
-+		This module publishes the current values of the AHB
-+		monitors in the /proc filing system.
-+		The monitors can be controlled by writing into this
-+		filing system
-+
-+config OXNAS_USB_TEST_MODES
-+	tristate "Create a loadable module to control the USB port test modes"
-+	default n
-+	help
-+		This module reports the port status and allows setting
-+		of the test mode in the port register via the /proc 
-+		filing system.
-+
-+config OXNAS_FRONT_LAMP_CONTROL
-+	tristate "Front Panel LED control system"
-+	depends on LEDS_CLASS
-+	default n
-+	help
-+		This module reports drives a number of GPIOs as PWM signals to drive
-+		front panel LEDs. The pattern displayed is dependent on system state.
-+
-+config LEDS_TRIGGER_SATA_DISK
-+	tristate "Front Panel SATA disk activity lamp control system"
-+	default n
-+	help
-+		This module reports drives the SATA disk activity lamp.
-+
-+config OXNAS_LED_TEST
-+	bool "Exercise the WD LEDs"
-+	default n
-+
-+config OXNAS_I2C_SDA
-+	int "I2C bit-bash data line"
-+	default 2
-+
-+config OXNAS_I2C_SCL
-+	int "I2C bit-bash clock line"
-+	default 3
-+
-+config	OXNAS_USB_PORTA_POWER_CONTROL
-+	bool "Support USB port A power control lines"
-+	default n
-+	help
-+		Whether to support power switch out and monitor in via GPIOs
-+		for USB port A
-+
-+config	OXNAS_USB_PORTB_POWER_CONTROL
-+	bool "Support USB port B power control lines"
-+	default n
-+	help
-+		Whether to support power switch out and monitor in via GPIOs
-+		for USB port B
-+
-+config	OXNAS_USB_PORTC_POWER_CONTROL
-+	bool "Support USB port C power control lines"
-+	default n
-+	help
-+		Whether to support power switch out and monitor in via GPIOs
-+		for USB port C
-+
-+config OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+	bool "Set USB power monitor input polarity to negative"
-+	default n
-+	help
-+		n - Positive polarity
-+		y - Negative polarity
-+
-+config OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+	bool "Set USB power switch output polarity to negative"
-+	default n
-+	help
-+		n - Positive polarity
-+		y - Negative polarity
-+
-+config WDC_FAN_OXNAS800
-+	tristate "WD NetCenter/2NC Fan control driver"
-+	default n
-+	help
-+		This driver allows user-mode applications to control the cooling
-+		fan on Western Digital's NetCenter/2NC platform.
-+
-+config OXNAS_MAP_SRAM
-+	bool "Allow part of kernel to be mapped into SRAM"
-+	default n
-+
-+config OXNAS_COPY_CODE_TO_SRAM
-+	bool "Copy part of kernel to SRAM"
-+	depends on OXNAS_MAP_SRAM
-+	default n
-+
-+config OXNAS_SUID_INHERIT
-+	bool "Make SUID be inherited by subdirectories"
-+	default n
-+
-+config OXNAS_USB_HUB_SUPPORT
-+	bool "Enable support for on-board USB hub"
-+	default n
-+
-+config OXNAS_USB_CKOUT
-+	bool "Enable output of 12MHz USB clock on GPIO 10"
-+	depends on OXNAS_USB_HUB_SUPPORT
-+	default n
-+
-+config OXNAS_USB_HUB_RESET_CONTROL
-+	bool "Control the USB hub reset line"
-+	depends on OXNAS_USB_HUB_SUPPORT
-+	default n
-+
-+config OXNAS_USB_HUB_RESET_GPIO
-+	int "The GPIO connected to the USB hub reset"
-+	depends on OXNAS_USB_HUB_RESET_CONTROL
-+	default 27
-+
-+config OXNAS_USB_HUB_RESET_ACTIVE_HIGH
-+	int "Set to 1 for active high, 0 for active low reset"
-+	depends on OXNAS_USB_HUB_RESET_CONTROL
-+	default 1
-+
-+config OXNAS_USB_HUB_RESET_TOGGLE
-+	bool "Select to toggle reset, do not select to just deassert reset"
-+	depends on OXNAS_USB_HUB_RESET_CONTROL
-+	default y
-+
-+config OXNAS_USB_HUB_RESET_PERIOD_MS
-+	int "The period for which the USB hub reset should be asserted in milliseconds"
-+	depends on OXNAS_USB_HUB_RESET_TOGGLE
-+	default 100
-+
-+endmenu
-+
-+endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile
---- linux-2.6.24/arch/arm/mach-oxnas/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,43 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+# Object file lists.
-+
-+obj-y := oxnas.o irq.o time.o dma.o pci.o ahb_mon.o leon.o samba_reserve.o
-+
-+obj-$(CONFIG_SYNOPSYS_GMAC) += gmac.o
-+
-+gmac-objs := gmac-napi.o gmac_ethtool.o gmac_phy.o gmac_desc.o gmac_offload.o
-+
-+obj-$(CONFIG_OXNAS_IBW) += ibw.o
-+
-+obj-$(CONFIG_TACHO_THERM_AND_FAN) += thermAndFan.o
-+
-+obj-$(CONFIG_I2S) += i2s.o
-+
-+obj-$(CONFIG_CRYPTO_OXAESLRW) += cipher.o
-+
-+obj-$(CONFIG_GPIO_TEST)	+= gpioTest.o
-+
-+obj-$(CONFIG_I2S) += i2s.o
-+
-+obj-$(CONFIG_DPE_TEST) += dpe_test.o
-+
-+obj-$(CONFIG_OXNAS_AHB_MONITOR_MODULE) += oxnas-ahb-monitor.o
-+
-+obj-$(CONFIG_OXNAS_USB_TEST_MODES) += usb-test-mode.o
-+
-+obj-$(CONFIG_LEON_POWER_BUTTON_MONITOR) += power_button.o
-+
-+obj-$(CONFIG_USER_RECOVERY_BUTTON_MONITOR) += user_recovery_button.o
-+
-+obj-$(CONFIG_OXNAS_FRONT_LAMP_CONTROL) += leds.o
-+
-+obj-$(CONFIG_WDC_FAN_OXNAS800) += wdc-fan.o
-+
-+obj-$(CONFIG_WDC_LEDS_OXNAS800) += wdc-leds.o
-+
-+obj-$(CONFIG_OXNAS_WD810_LEDS) += oxnas-wd810-leds.o
-+
-+obj-$(CONFIG_WDC_LEDS_TRIGGER_SATA_DISK) += wdc-ledtrig-sata.o
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot
---- linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3 @@
-+initrd_phys-$(CONFIG_ARCH_OXNAS)	:= 0x48200000
-+params_phys-$(CONFIG_ARCH_OXNAS)	:= 0x48000100
-+zreladdr-$(CONFIG_ARCH_OXNAS)		:= 0x48008000
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/README linux-2.6.24-oxe810/arch/arm/mach-oxnas/README
---- linux-2.6.24/arch/arm/mach-oxnas/README	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/README	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,85 @@
-+
-+usb-test-modes 
-+
-+This is best built as a module which may be inserted into a running
-+Linux system only when needed.
-+The module can be built as part of the standard kernel module build
-+if the correct options are chosen in the config. 
-+
-+
-+How to use:
-+
-+copy the usb-test-mode.ko file somewhere convenient on the NAS and
-+insert the module into the system using
-+'modprobe usb-test-mode.ko'
-+
-+It should report successfull loading or an error message. Assuming it is
-+successful /proc will have an 'usb_test_mode' entry (verify with ls).
-+
-+Actions:
-+read the current port status:
-+cat /proc/usb_test_mode/read
-+
-+set port 1 into test mode 4:
-+echo 4 > /proc/usb_test_mode/write1
-+
-+
-+When testing is completed the module can be removed from the linux
-+system using:
-+rmmod usb_test_mode
-+
-+ahb_mon 
-+
-+This should be built as a module. 
-+
-+How to use:
-+
-+insert the module into a working system by typing 
-+'modprobe oxnas-ahb-monitor'
-+
-+When successfully installed a directory  entry will appear in /proc for
-+oxnas-ahb-monitor. In the directory will be a writeable file for each
-+AHB monitor and a control file. There will also be a readable file for
-+obtaining the counts stored in all the ahb monitors.
-+
-+
-+Actions:
-+set a monitor to a limited range, burst mode etc using
-+low addres, high address, mode, burst mode, burst mask, hprot, hprot mask
-+
-+Use the echo command to set data into the /proc/oxnas-ahb-monitor an example is
-+the following script to observe the activities of the ARM processor on the GMAC
-+core when pinging a remote machine:
-+---------------------------
-+#!/bin/sh -x
-+#
-+
-+# start montoring of ARM data bus to MAC
-+# format is "low high mode burst mask hprot mask"
-+# mode - 1 write 2 read 3 read write.
-+
-+echo 2 > /proc/oxnas-test/control
-+
-+echo 0 > /proc/oxnas-test/control
-+
-+
-+echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/ARM_Data
-+echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/Arm_Inst
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/CoPro
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_A
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_B
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/GMAC
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/PCI
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/USBHS
-+
-+echo 1 > /proc/oxnas-test/control
-+
-+ping -c 1 172.31.0.102
-+
-+echo 0 > /proc/oxnas-test/control
-+--------------------------------------
-+
-+When testing is commplete the module can be removed using 
-+rmmod oxnas-ahb-monitor
-+
-+
-Files linux-2.6.24/arch/arm/mach-oxnas/ThermCalc.xls and linux-2.6.24-oxe810/arch/arm/mach-oxnas/ThermCalc.xls differ
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c
---- linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,177 @@
-+/*
-+ *  linux/arch/arm/mach-oxnas/ahb_mon.c
-+ *
-+ * 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 <linux/kernel.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+static void start_ahb_monitors(void)
-+{
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON  + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB  + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC  + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI  + AHB_MON_MODE_REG_OFFSET);
-+}
-+
-+void init_ahb_monitors(
-+    AHB_MON_HWRITE_T ahb_mon_hwrite,
-+    unsigned hburst_mask,
-+    unsigned hburst_match,
-+    unsigned hprot_mask,
-+    unsigned hprot_match)
-+{
-+    u32 hburst_mask_value  = (hburst_mask  & ((1 << AHB_MON_HBURST_MASK_NUM_BITS)  - 1));
-+    u32 hburst_match_value = (hburst_match & ((1 << AHB_MON_HBURST_MATCH_NUM_BITS) - 1));
-+    u32 hprot_mask_value   = (hprot_mask   & ((1 << AHB_MON_HPROT_MASK_NUM_BITS)   - 1));
-+    u32 hprot_match_value  = (hprot_match  & ((1 << AHB_MON_HPROT_MATCH_NUM_BITS)  - 1));
-+
-+    u32 hburst_reg_value = (hburst_mask_value << AHB_MON_HBURST_MASK_BIT) | (hburst_match_value << AHB_MON_HBURST_MATCH_BIT);
-+    u32 hprot_reg_value  = (hprot_mask_value  << AHB_MON_HPROT_MASK_BIT)  | (hprot_match_value  << AHB_MON_HPROT_MATCH_BIT);
-+
-+printk("$Ghburst reg value = 0x%08x\n", hburst_reg_value);
-+printk("$Ghprot reg value  = 0x%08x\n", hprot_reg_value);
-+
-+    // Reset all the counters and set their operating mode
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_ARM_D + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_ARM_D + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_ARM_D + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_ARM_D + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_ARM_D + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_ARM_I + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_ARM_I + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_ARM_I + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_ARM_I + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_ARM_I + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_DMA_A + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_DMA_A + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_DMA_A + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_DMA_A + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_DMA_A + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_DMA_B + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_DMA_B + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_DMA_B + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_DMA_B + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_DMA_B + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON  + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_LEON  + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_LEON  + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_LEON  + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_LEON  + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_LEON  + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB   + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_USB   + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_USB   + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_USB   + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_USB   + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_USB   + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC   + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_MAC   + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_MAC   + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_MAC   + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_MAC   + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_MAC   + AHB_MON_HPROT_REG_OFFSET);
-+
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI   + AHB_MON_MODE_REG_OFFSET);
-+    writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT,  AHB_MON_PCI   + AHB_MON_HWRITE_REG_OFFSET);
-+    writel(0UL,                                         AHB_MON_PCI   + AHB_MON_HADDR_LOW_REG_OFFSET);
-+    writel(~0UL,                                        AHB_MON_PCI   + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+    writel(hburst_reg_value,                            AHB_MON_PCI   + AHB_MON_HBURST_REG_OFFSET);
-+    writel(hprot_reg_value,                             AHB_MON_PCI   + AHB_MON_HPROT_REG_OFFSET);
-+
-+    // Start all the counters
-+    start_ahb_monitors();
-+}
-+
-+void restart_ahb_monitors(void)
-+{
-+    // Reset the counters
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON  + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB   + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC   + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI   + AHB_MON_MODE_REG_OFFSET);
-+
-+    // Start the counters
-+    start_ahb_monitors();
-+}
-+
-+void read_ahb_monitors(void)
-+{
-+    // Prepare the counters for reading
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON  + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB   + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC   + AHB_MON_MODE_REG_OFFSET);
-+    writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI   + AHB_MON_MODE_REG_OFFSET);
-+
-+    // Read the counters
-+    printk("ARM-D: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_D + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_ARM_D + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_ARM_D + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("ARM-I: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_I + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_ARM_I + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_ARM_I + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("DMA-A: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_A + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_DMA_A + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_DMA_A + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("DMA-B: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_B + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_DMA_B + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_DMA_B + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("LEON:  B=%u, T=%u, W=%u\n", readl(AHB_MON_LEON  + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_LEON  + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_LEON  + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("USB:   B=%u, T=%u, W=%u\n", readl(AHB_MON_USB   + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_USB   + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_USB   + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("MAC:   B=%u, T=%u, W=%u\n", readl(AHB_MON_MAC   + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_MAC   + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_MAC   + AHB_MON_WAITS_REG_OFFSET));
-+
-+    printk("PCI:   B=%u, T=%u, W=%u\n", readl(AHB_MON_PCI   + AHB_MON_CYCLES_REG_OFFSET),
-+                                        readl(AHB_MON_PCI   + AHB_MON_TRANSFERS_REG_OFFSET),
-+                                        readl(AHB_MON_PCI   + AHB_MON_WAITS_REG_OFFSET));
-+}
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/cipher.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c
---- linux-2.6.24/arch/arm/mach-oxnas/cipher.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,362 @@
-+/* linux/arch/arm/mach-oxnas/cipher.c
-+ *
-+ * 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/types.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/highmem.h>
-+#include <asm/semaphore.h>
-+#include <asm/arch/cipher.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/dma-mapping.h>
-+#include <asm/arch/dma.h>
-+#include <asm-arm/page.h>
-+ 
-+
-+#if 0
-+#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
-+#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
-+#else
-+#define DPRINTK(fmt, args...)
-+#define VPRINTK(fmt, args...)
-+#endif
-+
-+//#define CIPHER_USE_SG_DMA
-+
-+/*****************************************************************************/
-+ 
-+typedef struct ox800_aeslrw_driver ox800_aeslrw_driver_t;
-+
-+struct ox800_aeslrw_driver {
-+    struct device dev;
-+    struct semaphore   core;
-+    int result;
-+    u8 cipher_key[OX800DPE_KEYSIZE];
-+    u8 tweak_key[OX800DPE_KEYSIZE];
-+};
-+
-+static ox800_aeslrw_driver_t ox800_aeslrw_driver;
-+ 
-+
-+/*****************************************************************************/
-+
-+/**
-+ * Sets the keys only if they have changed.
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key  16 byte array that is the I-Value tweak key
-+ */
-+static void ox800_aeslrw_setkeys(u8* cipher_key, u8* tweak_key)
-+{
-+    VPRINTK(KERN_INFO"\n");
-+
-+    /*
-+     * changing the keys can take a long time as the core will
-+     * compute internal values based on the keys
-+     */
-+    if (memcmp(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE) ||
-+        memcmp(&(ox800_aeslrw_driver.tweak_key[0]),  tweak_key,  OX800DPE_KEYSIZE) )
-+    {
-+        u32* key;
-+        unsigned int  i;
-+    
-+        DPRINTK(KERN_INFO"cipher key ="); 
-+        for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+            DPRINTK("%02x", cipher_key[i]);
-+        DPRINTK("\n");
-+        DPRINTK(KERN_INFO"tweak key ="); 
-+        for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+            DPRINTK("%02x", tweak_key[i]);
-+        DPRINTK("\n");
-+            
-+        /* update stored values */
-+        memcpy(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE);
-+        memcpy(&(ox800_aeslrw_driver.tweak_key[0]),  tweak_key,  OX800DPE_KEYSIZE);
-+        
-+        /* update hardware values */
-+        key = (u32* )cipher_key;
-+        writel(key[0], OX800DPE_KEY00 );
-+        writel(key[1], OX800DPE_KEY01 );
-+        writel(key[2], OX800DPE_KEY02 );
-+        writel(key[3], OX800DPE_KEY03 );
-+    
-+        key = (u32* )tweak_key;
-+        writel(key[0], OX800DPE_KEY10 );
-+        writel(key[1], OX800DPE_KEY11 );
-+        writel(key[2], OX800DPE_KEY12 );
-+        writel(key[3], OX800DPE_KEY13 );
-+    }
-+}
-+
-+/**
-+ * Generic LRW-AES en/decryption
-+ * @param encrypt non-zero to encrypt, zero to decrypt
-+ * @param in Source of data
-+ * @param out Location to place en/decrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ *              number of entries
-+ * @param iv 8 byte array containing the I-Value
-+ * @return error code or 0 for success
-+ */
-+static int ox800_aeslrw_gencrypt(  u8  encrypt,
-+                            struct scatterlist* in,
-+                            struct scatterlist* out,
-+                            unsigned int nents,
-+                            u8  iv[])
-+{
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    struct scatterlist* out_;
-+    char same_buffer;
-+    int status = 0;
-+
-+    /* get dma resources (non blocking) */
-+    dma_in = oxnas_dma_request(0);
-+    dma_out = oxnas_dma_request(0);
-+    
-+    VPRINTK("dma in %d out %d \n", 
-+        dma_in->channel_number_,  
-+        dma_out->channel_number_);  
-+
-+    if ((dma_in) && (dma_out)) {
-+        u32 reg;
-+        
-+        // shouldn't be busy or full
-+        reg = readl( OX800DPE_STATUS );
-+        if (! (reg & OX800DPE_STAT_IDLE) )
-+            printk("not idle after abort toggle");
-+        if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+            printk("tx fifo not empty after abort toggle");
-+        if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+            printk("rx not empty after abort toggle");
-+        
-+        /* check to see if the destination buffer is the same as the source */
-+        same_buffer = (in->page == out->page);
-+        
-+        /* map transfers */
-+        if (same_buffer) {
-+            dma_map_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
-+            out_ = in;
-+        } else {
-+            /* map transfers */
-+            dma_map_sg(NULL, in, nents, DMA_TO_DEVICE);
-+            dma_map_sg(NULL, out, nents, DMA_FROM_DEVICE);
-+            out_ = out;
-+        }
-+#ifdef CIPHER_USE_SG_DMA        
-+        /* setup DMA transfers */ 
-+        oxnas_dma_device_set_sg(
-+            dma_in,
-+            OXNAS_DMA_TO_DEVICE,
-+            in,
-+            nents,
-+            &oxnas_dpe_rx_dma_settings,
-+            OXNAS_DMA_MODE_INC);
-+            
-+        oxnas_dma_device_set_sg(
-+            dma_out,
-+            OXNAS_DMA_FROM_DEVICE,
-+            out_,
-+            nents,
-+            &oxnas_dpe_tx_dma_settings,
-+            OXNAS_DMA_MODE_INC);
-+
-+#else
-+        oxnas_dma_device_set(
-+            dma_in,
-+            OXNAS_DMA_TO_DEVICE,
-+            (unsigned char* )sg_dma_address(in),
-+            sg_dma_len(in),
-+            &oxnas_dpe_rx_dma_settings,
-+            OXNAS_DMA_MODE_INC,
-+            1 /*paused */ );
-+            
-+        oxnas_dma_device_set(
-+            dma_out,
-+            OXNAS_DMA_FROM_DEVICE,
-+            (unsigned char* )sg_dma_address(out_),
-+            sg_dma_len(out_),
-+            &oxnas_dpe_tx_dma_settings,
-+            OXNAS_DMA_MODE_INC,
-+            1 /*paused */ );
-+#endif
-+
-+        /* set dma callbacks */
-+        oxnas_dma_set_callback(
-+            dma_in,
-+            OXNAS_DMA_CALLBACK_ARG_NUL,
-+            OXNAS_DMA_CALLBACK_ARG_NUL);
-+        
-+        oxnas_dma_set_callback(
-+            dma_out,
-+            OXNAS_DMA_CALLBACK_ARG_NUL,
-+            OXNAS_DMA_CALLBACK_ARG_NUL);
-+        
-+        
-+        /* set for AES LRW encryption or decryption */
-+        writel( (encrypt ? OX800DPE_CTL_DIRECTION_ENC : 0 ) |
-+               OX800DPE_CTL_MODE_LRW_AES, 
-+               OX800DPE_CONTROL);
-+        wmb();
-+        
-+        /* write in I-value */
-+        writel(*((u32* )&(iv[0])), OX800DPE_DATA_LRW0 );
-+        writel(*((u32* )&(iv[4])), OX800DPE_DATA_LRW1 );
-+        
-+        wmb();
-+
-+        /* wait until done */
-+        while(  !(OX800DPE_STAT_IDLE & readl( OX800DPE_STATUS )) );
-+        
-+        /* start dma */
-+        oxnas_dma_start(dma_out);
-+        oxnas_dma_start(dma_in);
-+    
-+        /* wait (once for each channel) */
-+        while ( oxnas_dma_is_active( dma_out ) ||
-+                oxnas_dma_is_active( dma_in  ) )
-+        {
-+            schedule();
-+        }
-+        
-+        /* free any allocated dma channels */
-+        oxnas_dma_free( dma_in );
-+        oxnas_dma_free( dma_out );
-+
-+        /* unmap transfers */
-+        if (same_buffer) {
-+            dma_unmap_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
-+        } else {
-+            dma_unmap_sg(NULL, in, nents, DMA_TO_DEVICE);
-+            dma_unmap_sg(NULL, out, nents, DMA_FROM_DEVICE);
-+        }
-+        
-+        status = ox800_aeslrw_driver.result;
-+    } else {        
-+        /* free any allocated dma channels */
-+        if (dma_in) 
-+            oxnas_dma_free( dma_in );
-+        if (dma_out)
-+            oxnas_dma_free( dma_out );
-+        status = -EBUSY;        
-+    }
-+    /* return an indication of success */
-+    return status;
-+}
-+
-+/**
-+ * Performs LRW-AES encryption.
-+ * @param in Source of data
-+ * @param out Location to place encrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ *              number of entries
-+ * @param iv I-Value
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key  16 byte array that is the I-Value tweak key
-+ * @return error code or 0 for success
-+ */
-+int ox800_aeslrw_encrypt(   struct scatterlist* in,
-+                            struct scatterlist* out,
-+                            unsigned int nents,
-+                            u8* iv,
-+                            u8* cipher_key,
-+                            u8* tweak_key)
-+{
-+    int localresult;
-+    
-+    VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey %p\n",
-+        in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
-+
-+    /* get cipher core */
-+    while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
-+
-+    VPRINTK(KERN_INFO"got core\n");
-+
-+    ox800_aeslrw_setkeys(cipher_key, tweak_key);
-+    localresult = ox800_aeslrw_gencrypt( 1, in, out, nents, iv);
-+    
-+    up(&ox800_aeslrw_driver.core);
-+    VPRINTK(KERN_INFO"released\n");
-+    
-+    return localresult;
-+}
-+
-+/**
-+ * Performs LRW-AES decryption.
-+ * @param in Source of data
-+ * @param out Location to place decrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ *              number of entries
-+ * @param iv I-Value
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key  16 byte array that is the I-Value tweak key
-+ * @return error code or 0 for success
-+ */
-+int ox800_aeslrw_decrypt(   struct scatterlist* in,
-+                            struct scatterlist* out,
-+                            unsigned int nents,
-+                            u8* iv,
-+                            u8* cipher_key,
-+                            u8* tweak_key)
-+{
-+    int localresult;
-+    
-+    VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey%p\n",
-+        in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
-+
-+    /* get cipher core */
-+    while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
-+
-+    VPRINTK(KERN_INFO"got core\n");
-+
-+    ox800_aeslrw_setkeys(cipher_key, tweak_key);
-+    localresult = ox800_aeslrw_gencrypt( 0, in, out, nents, iv);
-+    
-+    up(&ox800_aeslrw_driver.core);
-+    VPRINTK(KERN_INFO"released core \n");
-+    
-+    return localresult;
-+}
-+
-+/** 
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox800_aeslrw_init( void )
-+{
-+    VPRINTK(KERN_INFO"\n");
-+    
-+    /* Enable the clock to the DPE block */
-+    writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    /* Bring out of reset */
-+    writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+    
-+    /* initialise in unlocked state */
-+    init_MUTEX(&ox800_aeslrw_driver.core);
-+    
-+    return 0;
-+}
-+
-+/** 
-+ * module cleanup
-+ */
-+static void __exit ox800_aeslrw_exit( void )
-+{
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800_aeslrw_init);
-+module_exit(ox800_aeslrw_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dma.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c
---- linux-2.6.24/arch/arm/mach-oxnas/dma.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,2849 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/dma.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <asm/dma.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/bitops.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/arch/desc_alloc.h>
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#include <asm/checksum.h>
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+//#define DMA_DEBUG
-+
-+#ifdef OXNAS_DMA_TEST
-+#define DMA_DEBUG
-+static void dma_test(unsigned long length);
-+#endif // OXNAS_DMA_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+#define DMA_DEBUG
-+static void dma_sg_test(void);
-+#endif // OXNAS_DMA_SG_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST_2
-+#define DMA_DEBUG
-+static void dma_sg_test2(void);
-+#endif // OXNAS_DMA_SG_TEST_2
-+
-+#ifdef DMA_DEBUG
-+#define DBG(args...) printk(args)
-+#else
-+#define DBG(args...) do { } while(0)
-+#endif
-+
-+// Normal (non-SG) registers
-+#define DMA_REGS_PER_CHANNEL 8
-+
-+#define DMA_CTRL_STATUS      0x0
-+#define DMA_BASE_SRC_ADR     0x4
-+#define DMA_BASE_DST_ADR     0x8
-+#define DMA_BYTE_CNT         0xC
-+#define DMA_CURRENT_SRC_ADR  0x10
-+#define DMA_CURRENT_DST_ADR  0x14
-+#define DMA_CURRENT_BYTE_CNT 0x18
-+#define DMA_INTR_ID          0x1C
-+#define DMA_INTR_CLEAR_REG   (DMA_CURRENT_SRC_ADR)
-+
-+// 8 quad-sized registers per channel arranged contiguously
-+#define DMA_CALC_REG_ADR(channel, register) (DMA_BASE + ((channel) << 5) + (register))
-+
-+#define DMA_CTRL_STATUS_FAIR_SHARE_ARB            (1 << 0)
-+#define DMA_CTRL_STATUS_IN_PROGRESS               (1 << 1)
-+#define DMA_CTRL_STATUS_SRC_DREQ_MASK             (0x0000003C)
-+#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT            2
-+#define DMA_CTRL_STATUS_DEST_DREQ_MASK            (0x000003C0)
-+#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT           6
-+#define DMA_CTRL_STATUS_INTR                      (1 << 10)
-+#define DMA_CTRL_STATUS_NXT_FREE                  (1 << 11)
-+#define DMA_CTRL_STATUS_RESET                     (1 << 12)
-+#define DMA_CTRL_STATUS_DIR_MASK                  (0x00006000)
-+#define DMA_CTRL_STATUS_DIR_SHIFT                 13
-+#define DMA_CTRL_STATUS_SRC_ADR_MODE              (1 << 15)
-+#define DMA_CTRL_STATUS_DEST_ADR_MODE             (1 << 16)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_A           (1 << 17)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_B           (1 << 18)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_MASK            (0x00380000)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT           19
-+#define DMA_CTRL_STATUS_DEST_WIDTH_MASK           (0x01C00000)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT          22
-+#define DMA_CTRL_STATUS_PAUSE                     (1 << 25)
-+#define DMA_CTRL_STATUS_INTERRUPT_ENABLE          (1 << 26)
-+#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED      (1 << 27)
-+#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
-+#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY       (1 << 29)
-+#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE         (1 << 30)
-+
-+#define DMA_BYTE_CNT_MASK                         ((1 << 21) - 1)
-+#define DMA_BYTE_CNT_INC4_SET_MASK                (1 << 28)
-+#define DMA_BYTE_CNT_HPROT_MASK                   (1 << 29)
-+#define DMA_BYTE_CNT_WR_EOT_MASK                  (1 << 30)
-+#define DMA_BYTE_CNT_RD_EOT_MASK                  (1 << 31)
-+
-+#define DMA_INTR_ID_GET_NUM_CHANNELS(reg_contents) (((reg_contents) >> 16) & 0xFF)
-+#define DMA_INTR_ID_GET_VERSION(reg_contents)      (((reg_contents) >> 24) & 0xFF)
-+#define DMA_INTR_ID_INT_BIT         0
-+#define DMA_INTR_ID_INT_NUM_BITS    (MAX_OXNAS_DMA_CHANNELS)
-+#define DMA_INTR_ID_INT_MASK        (((1 << DMA_INTR_ID_INT_NUM_BITS) - 1) << DMA_INTR_ID_INT_BIT)
-+
-+#define DMA_HAS_V4_INTR_CLEAR(version) ((version) > 3)
-+
-+// H/W scatter gather controller registers
-+#define OXNAS_DMA_NUM_SG_REGS 4
-+
-+#define DMA_SG_CONTROL  0x0
-+#define DMA_SG_STATUS   0x04
-+#define DMA_SG_REQ_PTR  0x08
-+#define DMA_SG_RESETS   0x0C
-+
-+#define DMA_SG_CALC_REG_ADR(channel, register) ((DMA_SG_BASE) + ((channel) << 4) + (register))
-+
-+// SG DMA controller control register field definitions
-+#define DMA_SG_CONTROL_START_BIT            0
-+#define DMA_SG_CONTROL_QUEUING_ENABLE_BIT   1
-+#define DMA_SG_CONTROL_HBURST_ENABLE_BIT    2
-+
-+// SG DMA controller status register field definitions
-+#define DMA_SG_STATUS_ERROR_CODE_BIT        0
-+#define DMA_SG_STATUS_ERROR_CODE_NUM_BITS   6
-+#define DMA_SG_STATUS_BUSY_BIT              7
-+
-+// SG DMA controller sub-block resets register field definitions
-+#define DMA_SG_RESETS_CONTROL_BIT 0
-+#define DMA_SG_RESETS_ARBITER_BIT 1
-+#define DMA_SG_RESETS_AHB_BIT	   2
-+
-+// oxnas_dma_sg_info_t qualifier field definitions
-+#define OXNAS_DMA_SG_QUALIFIER_BIT      0
-+#define OXNAS_DMA_SG_QUALIFIER_NUM_BITS 16
-+#define OXNAS_DMA_SG_DST_EOT_BIT        16
-+#define OXNAS_DMA_SG_DST_EOT_NUM_BITS   2
-+#define OXNAS_DMA_SG_SRC_EOT_BIT        20
-+#define OXNAS_DMA_SG_SRC_EOT_NUM_BITS   2
-+#define OXNAS_DMA_SG_CHANNEL_BIT        24
-+#define OXNAS_DMA_SG_CHANNEL_NUM_BITS   8
-+
-+// Valid address bits mask
-+#define OXNAS_DMA_ADR_MASK       ((1UL << (MEM_MAP_ALIAS_SHIFT)) - 1)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define OXNAS_DMA_CSUM_ADR_MASK  ((OXNAS_DMA_ADR_MASK) | (1UL << (OXNAS_DMA_CSUM_ENABLE_ADR_BIT)))
-+#else
-+#define OXNAS_DMA_CSUM_ADR_MASK (OXNAS_DMA_ADR_MASK)
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* The available buses to which the DMA controller is attached */
-+typedef enum oxnas_dma_transfer_bus
-+{
-+    OXNAS_DMA_SIDE_A,
-+    OXNAS_DMA_SIDE_B
-+} oxnas_dma_transfer_bus_t;
-+
-+/* Direction of data flow between the DMA controller's pair of interfaces */
-+typedef enum oxnas_dma_transfer_direction
-+{
-+    OXNAS_DMA_A_TO_A,
-+    OXNAS_DMA_B_TO_A,
-+    OXNAS_DMA_A_TO_B,
-+    OXNAS_DMA_B_TO_B
-+} oxnas_dma_transfer_direction_t;
-+
-+/* The available data widths */
-+typedef enum oxnas_dma_transfer_width
-+{
-+    OXNAS_DMA_TRANSFER_WIDTH_8BITS,
-+    OXNAS_DMA_TRANSFER_WIDTH_16BITS,
-+    OXNAS_DMA_TRANSFER_WIDTH_32BITS
-+} oxnas_dma_transfer_width_t;
-+
-+/* The mode of the DMA transfer */
-+typedef enum oxnas_dma_transfer_mode
-+{
-+    OXNAS_DMA_TRANSFER_MODE_SINGLE,
-+    OXNAS_DMA_TRANSFER_MODE_BURST
-+} oxnas_dma_transfer_mode_t;
-+
-+/* The available transfer targets */
-+typedef enum oxnas_dma_dreq
-+{
-+    OXNAS_DMA_DREQ_PATA     = 0,
-+    OXNAS_DMA_DREQ_SATA     = 0,
-+    OXNAS_DMA_DREQ_DPE_RX   = 1,
-+    OXNAS_DMA_DREQ_DPE_TX   = 2,
-+    OXNAS_DMA_DREQ_AUDIO_TX = 5,
-+    OXNAS_DMA_DREQ_AUDIO_RX = 6,    
-+    OXNAS_DMA_DREQ_MEMORY   = 15
-+} oxnas_dma_dreq_t;
-+
-+/* Pre-defined settings for known DMA devices */
-+oxnas_dma_device_settings_t oxnas_pata_dma_settings = {
-+    .address_              = 0,
-+    .fifo_size_            = 16,
-+    .dreq_                 = OXNAS_DMA_DREQ_PATA,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,
-+    .write_eot_policy_     = OXNAS_DMA_EOT_FINAL,
-+    .bus_                  = OXNAS_DMA_SIDE_A,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
-+    .address_              = SATA_DATA_BASE_PA,
-+    .fifo_size_            = 16,
-+    .dreq_                 = OXNAS_DMA_DREQ_SATA,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,
-+    .write_eot_policy_     = OXNAS_DMA_EOT_FINAL,
-+    .bus_                  = OXNAS_DMA_SIDE_A,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings = {
-+    .address_              = DPE_BASE_PA,
-+    .fifo_size_            = 16,
-+    .dreq_                 = OXNAS_DMA_DREQ_DPE_RX,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,
-+    .write_eot_policy_     = OXNAS_DMA_EOT_FINAL,
-+    .bus_                  = OXNAS_DMA_SIDE_A,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings = {
-+    .address_              = DPE_BASE_PA,
-+    .fifo_size_            = 16,
-+    .dreq_                 = OXNAS_DMA_DREQ_DPE_TX,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,
-+    .write_eot_policy_     = OXNAS_DMA_EOT_FINAL,
-+    .bus_                  = OXNAS_DMA_SIDE_A,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 0
-+};
-+
-+/* For use with normal memory to memory transfers as the settings for the source
-+ * of the transfer */
-+oxnas_dma_device_settings_t oxnas_ram_only_src_dma_settings = {
-+    .address_              = 0,
-+    .fifo_size_            = 0,
-+    .dreq_                 = OXNAS_DMA_DREQ_MEMORY,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,   // Won't interfere with checksumming transfers, as csum only latched if high order address bit set
-+    .write_eot_policy_     = OXNAS_DMA_EOT_NONE,
-+    .bus_                  = OXNAS_DMA_SIDE_A,      // Maximise performance with src on side A while dst in on side B
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 1
-+};
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+/* For use with checksumming transfers as the settings for the source of the
-+ * transfer */
-+oxnas_dma_device_settings_t oxnas_ram_csum_src_dma_settings = {
-+    .address_              = 0,
-+    .fifo_size_            = 0,
-+    .dreq_                 = OXNAS_DMA_DREQ_MEMORY,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_FINAL,   // To enable checksum accumulation
-+    .write_eot_policy_     = OXNAS_DMA_EOT_NONE,
-+    .bus_                  = OXNAS_DMA_SIDE_A,      // Checksumming happens on read from side A only
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 1
-+};
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* For use in all occasions not covered by oxnas_ram_only_src_dma_settings and
-+ * oxnas_ram_csum_src_dma_settings */
-+oxnas_dma_device_settings_t oxnas_ram_generic_dma_settings = {
-+    .address_              = 0,
-+    .fifo_size_            = 0,
-+    .dreq_                 = OXNAS_DMA_DREQ_MEMORY,
-+    .read_eot_policy_      = OXNAS_DMA_EOT_NONE,    // Don't interfere with any checksumming transfers
-+    .write_eot_policy_     = OXNAS_DMA_EOT_NONE,
-+    .bus_                  = OXNAS_DMA_SIDE_B,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 1
-+};
-+
-+static oxnas_dma_controller_t  dma_controller;
-+
-+/**
-+ * Acquisition of a SG DMA descriptor list entry
-+ * If called from non-atomic context the call could block.
-+ */
-+static oxnas_dma_sg_entry_t* alloc_sg_entry(int in_atomic)
-+{
-+    oxnas_dma_sg_entry_t* entry = 0;
-+    if (in_atomic) {
-+        if (down_trylock(&dma_controller.sg_entry_sem_)) {
-+            return (oxnas_dma_sg_entry_t*)0;
-+        }
-+    } else {
-+        // Wait for an entry to be available
-+        while (down_interruptible(&dma_controller.sg_entry_sem_));
-+    }
-+
-+    // Serialise while manipulating free list
-+    spin_lock_bh(&dma_controller.alloc_spinlock_);
-+
-+    // It's an error if there isn't a buffer available at this point
-+    BUG_ON(!dma_controller.sg_entry_head_);
-+
-+    // Unlink the head entry on the free list and return it to caller
-+    entry = dma_controller.sg_entry_head_;
-+    dma_controller.sg_entry_head_ = dma_controller.sg_entry_head_->next_;
-+    --dma_controller.sg_entry_available_;
-+
-+    // Finished manipulating free list
-+    spin_unlock_bh(&dma_controller.alloc_spinlock_);
-+
-+    return entry;
-+}
-+
-+static void free_sg_entry(oxnas_dma_sg_entry_t* entry)
-+{
-+	// Serialise while manipulating free list
-+	spin_lock(&dma_controller.alloc_spinlock_);
-+
-+	// Insert the freed buffer at the head of the free list
-+	entry->next_ = dma_controller.sg_entry_head_;
-+	dma_controller.sg_entry_head_ = entry;
-+	++dma_controller.sg_entry_available_;
-+
-+	// Finished manipulating free list
-+	spin_unlock(&dma_controller.alloc_spinlock_);
-+
-+	// Make freed buffer available for allocation
-+	up(&dma_controller.sg_entry_sem_);
-+}
-+
-+void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries)
-+{
-+	while (entries) {
-+		oxnas_dma_sg_entry_t* next = entries->next_;
-+		free_sg_entry(entries);
-+		entries = next;
-+	}
-+}
-+
-+/**
-+ * This implementation is not the most efficient, as it could result in alot
-+ * of alloc's only to decide to free them all as not sufficient available, but
-+ * in practice we would hope there will not be much contention for entries
-+ */
-+int oxnas_dma_alloc_sg_entries(
-+    oxnas_dma_sg_entry_t **entries,
-+    unsigned               required,
-+	int                    in_atomic)
-+{
-+	if (likely(required)) {
-+		oxnas_dma_sg_entry_t* prev;
-+		oxnas_dma_sg_entry_t* entry;
-+		unsigned acquired = 0;
-+
-+		*entries = alloc_sg_entry(in_atomic);
-+		if (!*entries) {
-+			return 1;
-+		}
-+
-+		(*entries)->next_ = 0;
-+		prev = *entries;
-+
-+		while (++acquired < required) {
-+			entry = alloc_sg_entry(in_atomic);
-+			if (!entry) {
-+				// Did not acquire the entry
-+				oxnas_dma_free_sg_entries(*entries);
-+				return 1;
-+			}
-+			entry->next_ = 0;
-+			prev->next_ = entry;
-+			prev = entry;
-+		}
-+	}
-+
-+    return 0;
-+}
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+/**
-+ * Blocking acquisition of the checksum engine
-+ */
-+static inline int alloc_csum_engine(int in_atomic)
-+{
-+#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+    // Checksum engine is allocated exclusively to the CoPro
-+    return 1;
-+#else
-+    if (in_atomic) {
-+        return down_trylock(&dma_controller.csum_engine_sem_);
-+    } else {
-+        while (1) {
-+            if (!down_interruptible(&dma_controller.csum_engine_sem_)) {
-+                return 0;
-+            }
-+        }
-+    }
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+}
-+
-+static inline void free_csum_engine(void)
-+{
-+    up(&dma_controller.csum_engine_sem_);
-+}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/**
-+ * Optionally blocking acquisition of a DMA channel
-+ * May be invoked either at task or softirq level
-+ */
-+oxnas_dma_channel_t* oxnas_dma_request(int block)
-+{
-+    oxnas_dma_channel_t* channel = OXNAS_DMA_CHANNEL_NUL;
-+    while (channel == OXNAS_DMA_CHANNEL_NUL) {
-+        if (block) {
-+            // Wait for a channel to be available
-+            if (down_interruptible(&dma_controller.channel_sem_)) {
-+                // Awoken by signal
-+                continue;
-+            }
-+        } else {
-+            // Non-blocking test of whether a channel is available
-+            if (down_trylock(&dma_controller.channel_sem_)) {
-+                // No channel available so return to user immediately
-+                break;
-+            }
-+        }
-+
-+        // Serialise while manipulating free list
-+        spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+        // It's an error if there isn't a channel available at this point
-+        BUG_ON(!dma_controller.channel_head_);
-+
-+        // Unlink the head entry on the free list and return it to caller
-+        channel = dma_controller.channel_head_;
-+        dma_controller.channel_head_ = dma_controller.channel_head_->next_;
-+
-+        // Finished manipulating free list
-+        spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
-+    }
-+    return channel;
-+}
-+
-+/**
-+ * May be invoked either at task or softirq level
-+ */
-+void oxnas_dma_free(oxnas_dma_channel_t* channel)
-+{
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_free() Freeing channel %u while active\n", channel->channel_number_);
-+    }
-+
-+    // Serialise while manipulating free list
-+    spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+    // Insert the freed buffer at the head of the free list
-+    channel->next_ = dma_controller.channel_head_;
-+    dma_controller.channel_head_ = channel;
-+
-+    // Finished manipulating free list
-+    spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+    // Make freed buffer available for allocation
-+    up(&dma_controller.channel_sem_);
-+}
-+
-+/** Shared between all DMA interrupts and run with interrupts enabled, thus any
-+ *  access to shared data structures must be sync'ed
-+ */
-+static irqreturn_t oxnas_dma_interrupt(int irq, void *dev_id)
-+{
-+    oxnas_dma_channel_t *channel = 0;
-+    unsigned channel_number = 0;
-+	int need_bh = 0;
-+
-+DBG("oxnas_dma_interrupt() from interrupt line %u\n", irq);
-+
-+    // Only acknowledge interrupts from the channel directly responsible for the
-+    // RPS interrupt line which caused the ISR to be entered, to get around the
-+    // problem that the SG-DMA controller can only filter DMA interrupts exter-
-+    // nally to the DMA controller, i.e. the DMA controller interrupt status
-+    // register always shows all active interrupts for all channels, regardless
-+    // of whether the SG-DMA controller is filtering them
-+
-+    // Find the DMA channel that can generate interrupts on the RPS interrupt
-+    // line which caused the ISR to be invoked.
-+	if (likely(irq == DMA_INTERRUPT_4)) {
-+		channel = &dma_controller.channels_[4];
-+	} else {
-+		channel = &dma_controller.channels_[irq - DMA_INTERRUPT_0];
-+	}
-+	channel_number = channel->channel_number_;
-+DBG("RPS interrupt %u from channel %u\n", irq, channel_number);
-+
-+    // Non-SG transfers have no completion status, so initialise
-+    // channel's error code to no-error. If transfer turns out to
-+    // have been SG, this status will be overwritten
-+    channel->error_code_ = OXNAS_DMA_ERROR_CODE_NONE;
-+
-+	// Must finish in bottom half if checksumming or need to invoke callback
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+	need_bh = channel->checksumming_ ||
-+#else // CONFIG_OXNAS_VERSION_0X800
-+	need_bh = 
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+			  (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL);
-+
-+    // Cope with the DMA controller's ability to have a pair of chained
-+    // transfers which have both completed, which causes the interrupt request
-+    // to stay active until both have been acknowledged, which is causing the SG
-+    // controller problems
-+    while (readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)) & (1 << channel_number)) {
-+DBG("Ack'ing interrupt for channel %u\n", channel_number);
-+        // Write to the interrupt clear register to clear interrupt
-+        writel(0, DMA_CALC_REG_ADR(channel_number, DMA_INTR_CLEAR_REG));
-+
-+        // Record how many interrupts are awaiting service
-+        atomic_inc(&channel->interrupt_count_);
-+    }
-+DBG("Left int ack'ing loop\n");
-+
-+	// If was a SG transfer, record the completion status
-+	if (channel->v_sg_info_->v_srcEntries_) {
-+		// Record the SG transfer completion status
-+		u32 error_code = readl(DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
-+		channel->error_code_ =
-+			((error_code >> DMA_SG_STATUS_ERROR_CODE_BIT) &
-+			 ((1UL << DMA_SG_STATUS_ERROR_CODE_NUM_BITS) - 1));
-+
-+		 if (channel->auto_sg_entries_) {
-+			 // Must finish in bottom half if we are to manage the SG entries
-+DBG("ISR channel %d is auto SG\n", channel->channel_number_);
-+			 need_bh = 1;
-+		 } else {
-+DBG("ISR channel %d not auto SG\n", channel->channel_number_);
-+			// Zeroise SG DMA descriptor info
-+			channel->v_sg_info_->p_srcEntries_ = 0;
-+			channel->v_sg_info_->v_srcEntries_ = 0;
-+			channel->v_sg_info_->p_dstEntries_ = 0;
-+			channel->v_sg_info_->v_dstEntries_ = 0;
-+		 }
-+
-+DBG("Return SG controller to idle, error_code = 0x%08x\n", error_code);
-+		// Return the SG DMA controller to the IDLE state and clear any SG
-+		// controller error interrupt
-+		writel(1, DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
-+	}
-+
-+	// Can we finish w/o invoking bottom half?
-+	if (likely(!need_bh)) {
-+DBG("ISR channel %d do not call bh\n", channel->channel_number_);
-+		atomic_set(&channel->interrupt_count_, 0);
-+		atomic_set(&channel->active_count_, 0);
-+	} else {
-+DBG("Marking channel %d as requiring its bottom half to run\n", channel_number);
-+		// Set a flag for the channel to cause its bottom half to be run
-+		set_bit(channel_number, (void*)&dma_controller.run_bh_);
-+
-+DBG("Scheduling tasklet\n");
-+		// Signal the bottom half to perform the notifications
-+		tasklet_schedule(&dma_controller.tasklet_);
-+	}
-+
-+DBG("Returning\n");
-+    return IRQ_HANDLED;
-+}
-+
-+static void fake_interrupt(int channel)
-+{
-+    // Set a flag to cause the bottom half handler to be run for the channel
-+    set_bit(channel, (void*)&dma_controller.run_bh_);
-+
-+    // Signal the bottom half to perform the notifications
-+    tasklet_schedule(&dma_controller.tasklet_);
-+}
-+
-+static void dma_bh(unsigned long data)
-+{
-+    // Check for any bottom halves having become ready to run
-+    u32 run_bh = atomic_read(&dma_controller.run_bh_);
-+    while (run_bh) {
-+        unsigned i;
-+
-+		// Free any checksumming or SG resources
-+		u32 temp_run_bh = run_bh;
-+        for (i = 0; i < dma_controller.numberOfChannels_; i++, temp_run_bh >>= 1) {
-+            if (temp_run_bh & 1) {
-+                oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
-+DBG("Bottom halve for channel %u\n", channel->channel_number_);
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+                // If this channel computed a checksum
-+                if (unlikely(channel->checksumming_)) {
-+                    // Read the result of the checksum calculation, clearing the
-+                    // result in the process
-+                    channel->checksum_ = readl(DMA_CHECKSUM_BASE);
-+                    channel->checksumming_ = 0;
-+
-+                    // Relinquish ownership of the checksum engine
-+                    free_csum_engine();
-+                }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+				if (channel->auto_sg_entries_) {
-+					// Free SG DMA source descriptor resources
-+					oxnas_dma_sg_entry_t* sg_entry = channel->v_sg_info_->v_srcEntries_;
-+DBG("Freeing SG resources for channel %d\n", channel->channel_number_);
-+					while (sg_entry) {
-+						oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+						free_sg_entry(sg_entry);
-+						sg_entry = next;
-+					}
-+
-+					// Free SG DMA destination descriptor resources
-+					sg_entry = channel->v_sg_info_->v_dstEntries_;
-+					while (sg_entry) {
-+						oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+						free_sg_entry(sg_entry);
-+						sg_entry = next;
-+					}
-+
-+					// Zeroise SG DMA source descriptor info
-+					channel->v_sg_info_->p_srcEntries_ = 0;
-+					channel->v_sg_info_->v_srcEntries_ = 0;
-+					channel->v_sg_info_->p_dstEntries_ = 0;
-+					channel->v_sg_info_->v_dstEntries_ = 0;
-+				}
-+            }
-+        }
-+
-+        // Mark that we have serviced the bottom halves. None of the channels
-+        // we have just serviced can interrupt again until their active flags
-+        // are cleared below
-+        atomic_sub(run_bh, &dma_controller.run_bh_);
-+
-+        // Notify all listeners of transfer completion
-+        for (i = 0; i < dma_controller.numberOfChannels_; i++, run_bh >>= 1) {
-+            if (run_bh & 1) {
-+                int interrupt_count;
-+                oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
-+
-+                // Clear the count of received interrupts for the channel now
-+                // that we have serviced them all
-+                interrupt_count = atomic_read(&channel->interrupt_count_);
-+                atomic_sub(interrupt_count, &channel->interrupt_count_);
-+
-+                // Decrement the count of active transfers, by the number of
-+                // interrupts we've seen. This must occur before we inform any
-+                // listeners who are awaiting completion notification. Should
-+                // only decrement if greater than zero, in case we see spurious
-+                // interrupt events - we can't be fully safe against this sort
-+                // of broken h/w, but we can at least stop the count underflowing
-+                // active_count_ is only shared with thread level code, so read
-+                // and decrement don't need to be atomic
-+                if (atomic_read(&channel->active_count_)) {
-+                    atomic_dec(&channel->active_count_);
-+                }
-+
-+                // If there is a callback registered, notify the user that the
-+                // transfer is complete
-+                if (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL) {
-+DBG("Notifying channel %u, %d outstanding interrupts\n", channel->channel_number_, interrupt_count);
-+                    (*channel->notification_callback_)(
-+                        &dma_controller.channels_[i],
-+                        channel->notification_arg_,
-+                        channel->error_code_,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+                        channel->checksum_,
-+#else // CONFIG_OXNAS_VERSION_0X800
-+						 0,
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+                        interrupt_count);
-+                }
-+            }
-+        }
-+
-+        // Check for any more bottom halves having become ready to run
-+        run_bh = atomic_read(&dma_controller.run_bh_);
-+    }
-+}
-+
-+void __init oxnas_dma_init()
-+{
-+    unsigned i;
-+    unsigned long intId;
-+    oxnas_dma_sg_info_t *v_info;
-+    dma_addr_t           p_info;
-+
-+    // Ensure the DMA block is properly reset
-+    writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Ensure the SG-DMA block is properly reset
-+    writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Enable the clock to the DMA block
-+    writel(1UL << SYS_CTRL_CKEN_DMA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Initialise the DMA controller
-+    atomic_set(&dma_controller.run_bh_, 0);
-+    spin_lock_init(&dma_controller.spinlock_);
-+    spin_lock_init(&dma_controller.alloc_spinlock_);
-+    spin_lock_init(&dma_controller.channel_alloc_spinlock_);
-+    sema_init(&dma_controller.csum_engine_sem_, 1);
-+
-+    // Initialise channel allocation management
-+    dma_controller.channel_head_ = 0;
-+    sema_init(&dma_controller.channel_sem_, 0);
-+    // Initialise SRAM buffer management
-+    dma_controller.sg_entry_head_ = 0;
-+    sema_init(&dma_controller.sg_entry_sem_, 0);
-+    dma_controller.sg_entry_available_ = 0;
-+
-+    tasklet_init(&dma_controller.tasklet_, dma_bh, 0);
-+
-+    // Discover the number of channels available
-+    intId = readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID));
-+    dma_controller.numberOfChannels_ = DMA_INTR_ID_GET_NUM_CHANNELS(intId);
-+    if (dma_controller.numberOfChannels_ > MAX_OXNAS_DMA_CHANNELS) {
-+        printk(KERN_WARNING "DMA: Too many DMA channels");
-+        dma_controller.numberOfChannels_ = MAX_OXNAS_DMA_CHANNELS;
-+    }
-+
-+    dma_controller.version_ = DMA_INTR_ID_GET_VERSION(intId);
-+    printk(KERN_INFO "Number of DMA channels = %u, version = %u\n",
-+        dma_controller.numberOfChannels_, dma_controller.version_);
-+
-+    if (!DMA_HAS_V4_INTR_CLEAR(dma_controller.version_)) {
-+        panic("DMA: Trying to use v4+ interrupt clearing on DMAC version without support\n");
-+    }
-+
-+#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+    // Reserve the last DMA channel for the CoPro's use
-+    --dma_controller.numberOfChannels_;
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+
-+    // Allocate coherent memory for array sg_info structs
-+    dma_controller.v_sg_infos_ = (oxnas_dma_sg_info_t*)DMA_DESC_ALLOC_START;
-+    dma_controller.p_sg_infos_ = DMA_DESC_ALLOC_START_PA;
-+
-+    if (!dma_controller.v_sg_infos_) {
-+        panic("DMA: Coherent alloc of SG info struct array");
-+    }
-+
-+    {
-+		// Initialise list of DMA descriptors
-+        unsigned long sg_info_alloc_size = (dma_controller.numberOfChannels_ * sizeof(oxnas_dma_sg_info_t));
-+        unsigned num_sg_entries = (DMA_DESC_ALLOC_SIZE - sg_info_alloc_size) / sizeof(oxnas_dma_sg_entry_t);
-+        oxnas_dma_sg_entry_t* entry_v = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START + sg_info_alloc_size);
-+        oxnas_dma_sg_entry_t* entry_p = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START_PA + sg_info_alloc_size);
-+printk("Allocating %u SRAM generic DMA descriptors\n", num_sg_entries);
-+        for (i=0; i < num_sg_entries; ++i, ++entry_v, ++entry_p) {
-+            entry_v->paddr_ = (dma_addr_t)entry_p;
-+            free_sg_entry(entry_v);
-+        }
-+    }
-+
-+    // Initialise all available DMA channels
-+    v_info = dma_controller.v_sg_infos_;
-+    p_info = dma_controller.p_sg_infos_;
-+    for (i=0; i < dma_controller.numberOfChannels_; i++) {
-+        oxnas_dma_channel_t *channel = &dma_controller.channels_[i];
-+
-+        channel->channel_number_ = i;
-+        channel->notification_callback_ = OXNAS_DMA_CALLBACK_NUL;
-+        channel->notification_arg_ = OXNAS_DMA_CALLBACK_ARG_NUL;
-+
-+        // Setup physical and virtual addresses of the SG info struct for this
-+        // channel
-+        channel->v_sg_info_ = v_info++;
-+        channel->p_sg_info_ = p_info;
-+        p_info += sizeof(oxnas_dma_sg_info_t);
-+
-+        // Initialise heads of src and dst SG lists to null
-+        channel->v_sg_info_->p_srcEntries_ = 0;
-+        channel->v_sg_info_->p_dstEntries_ = 0;
-+        channel->v_sg_info_->v_srcEntries_ = 0;
-+        channel->v_sg_info_->v_dstEntries_ = 0;
-+
-+        channel->error_code_ = 0;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        channel->checksumming_ = 0;
-+        channel->checksum_ = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        // Initialise the atomic variable that records the number of interrupts
-+        // for the channel that are awaiting service
-+        atomic_set(&channel->interrupt_count_, 0);
-+
-+        // Initialise the atomic variable maintaining the count of in-progress
-+        // transfers for the channel. Currently can be a maximum of two, as
-+        // the hardware can only queue details for a pair of transfers
-+        atomic_set(&channel->active_count_, 0);
-+
-+        // The binary semaphore for the default callback used when abort
-+        // requested without a user-registered callback being available
-+        sema_init(&channel->default_semaphore_, 0);
-+
-+        // Add channel to free list
-+        oxnas_dma_free(channel);
-+    }
-+
-+    // Connect the dma interrupt handler
-+    dma_controller.channels_[0].rps_interrupt_ = DMA_INTERRUPT_0;
-+    if (request_irq(DMA_INTERRUPT_0, &oxnas_dma_interrupt, 0, "DMA 0", 0)) {
-+        panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_0);
-+    }
-+    dma_controller.channels_[1].rps_interrupt_ = DMA_INTERRUPT_1;
-+    if (request_irq(DMA_INTERRUPT_1, &oxnas_dma_interrupt, 0, "DMA 1", 0)) {
-+        panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_1);
-+    }
-+    dma_controller.channels_[2].rps_interrupt_ = DMA_INTERRUPT_2;
-+    if (request_irq(DMA_INTERRUPT_2, &oxnas_dma_interrupt, 0, "DMA 2", 0)) {
-+        panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_2);
-+    }
-+    dma_controller.channels_[3].rps_interrupt_ = DMA_INTERRUPT_3;
-+    if (request_irq(DMA_INTERRUPT_3, &oxnas_dma_interrupt, 0, "DMA 3", 0)) {
-+        panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_3);
-+    }
-+#ifndef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+    dma_controller.channels_[4].rps_interrupt_ = DMA_INTERRUPT_4;
-+    if (request_irq(DMA_INTERRUPT_4, &oxnas_dma_interrupt, 0, "DMA 4", 0)) {
-+        panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_4);
-+    }
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+
-+#ifdef OXNAS_DMA_OVERALL_TEST_LOOPS
-+    {
-+        int j;
-+        for (j=0; j < OXNAS_DMA_OVERALL_TEST_LOOPS; ++j) {
-+#ifdef OXNAS_DMA_TEST
-+            {
-+                int i;
-+                for (i=0; i < OXNAS_DMA_TEST_ITERATIONS; ++i) {
-+                    dma_test(512);
-+                }
-+            }
-+#endif // OXNAS_DMA_TEST
-+#ifdef OXNAS_DMA_SG_TEST    
-+            {
-+                int i;
-+                for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
-+                    dma_sg_test();
-+                }
-+            }
-+#endif // OXNAS_DMA_SG_TEST    
-+#ifdef OXNAS_DMA_SG_TEST_2    
-+            {
-+                int i;
-+                for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
-+                    dma_sg_test2();
-+                }
-+            }
-+#endif // OXNAS_DMA_SG_TEST_2    
-+#ifdef OXNAS_DMA_TEST
-+            {
-+                int i;
-+                for (i=0; i < OXNAS_DMA_TEST_AFTER_SG_ITERATIONS; ++i) {
-+                    dma_test(512);
-+                }
-+            }
-+#endif // OXNAS_DMA_TEST
-+        }
-+    }
-+#endif // OXNAS_DMA_OVERALL_TEST_LOOPS
-+}
-+
-+void oxnas_dma_shutdown()
-+{
-+    dma_controller.sg_entry_head_ = 0;
-+}
-+
-+int oxnas_dma_is_active(oxnas_dma_channel_t* channel)
-+{
-+    return atomic_read(&channel->active_count_);
-+}
-+
-+/**
-+ * Get the transfer status directly from the hardware, so for instance the
-+ * end of a transfer can be polled for within interrupt context.
-+ *
-+ * NB If this function indicates the channel is inactive, it does NOT imply that
-+ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
-+ * the inactive state 
-+ */
-+int oxnas_dma_raw_isactive(oxnas_dma_channel_t* channel)
-+{
-+    unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+    return ctrl_status & DMA_CTRL_STATUS_IN_PROGRESS;
-+}
-+
-+/**
-+ * Get the SG transfer status directly from the hardware, so for instance the
-+ * end of a SG transfer can be polled for within interrupt context.
-+ *
-+ * NB If this function indicates the channel is inactive, it does NOT imply that
-+ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
-+ * the inactive state 
-+ */
-+int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t* channel)
-+{
-+    // Record the SG channel status
-+    u32 status = readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS));
-+    return status & (1UL << DMA_SG_STATUS_BUSY_BIT);
-+}
-+
-+int oxnas_dma_get_raw_direction(oxnas_dma_channel_t* channel)
-+{
-+    unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+    return (ctrl_status & DMA_CTRL_STATUS_DIR_MASK) >> DMA_CTRL_STATUS_DIR_SHIFT;
-+}
-+
-+static unsigned long encode_control_status(
-+    oxnas_dma_device_settings_t *src_settings,
-+    oxnas_dma_device_settings_t *dst_settings,
-+    int                          paused)
-+{
-+    unsigned long ctrl_status;
-+    oxnas_dma_transfer_direction_t direction;
-+
-+    ctrl_status  = paused ? DMA_CTRL_STATUS_PAUSE : 0;							// Paused if requested
-+    ctrl_status |= (DMA_CTRL_STATUS_INTERRUPT_ENABLE |							// Interrupts enabled
-+				    DMA_CTRL_STATUS_FAIR_SHARE_ARB   |							// High priority
-+					DMA_CTRL_STATUS_INTR_CLEAR_ENABLE);						// Use new interrupt clearing register
-+    ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT);	// Source dreq
-+    ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT);	// Destination dreq
-+
-+    // Setup the transfer direction and burst/single mode for the two DMA busses
-+    if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+        // Set the burst/single mode for bus A based on src device's settings
-+        if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+            ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+        }
-+
-+        if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+            direction = OXNAS_DMA_A_TO_A;
-+        } else {
-+            direction = OXNAS_DMA_A_TO_B;
-+
-+            // Set the burst/single mode for bus B based on dst device's settings
-+            if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+                ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+            } else {
-+                ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+            }
-+        }
-+    } else {
-+        // Set the burst/single mode for bus B based on src device's settings
-+        if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+            ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+        }
-+
-+        if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+            direction = OXNAS_DMA_B_TO_A;
-+
-+            // Set the burst/single mode for bus A based on dst device's settings
-+            if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+                ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+            } else {
-+                ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+            }
-+        } else {
-+            direction = OXNAS_DMA_B_TO_B;
-+        }
-+    }
-+    ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
-+
-+    // Setup source address mode fixed or increment
-+    if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+        // Fixed address
-+        ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
-+
-+        // Set up whether fixed address is _really_ fixed
-+        if (src_settings->address_really_fixed_) {
-+            ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+        }
-+    } else {
-+        // Incrementing address
-+        ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
-+        ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+    }
-+
-+    // Setup destination address mode fixed or increment
-+    if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+        // Fixed address
-+        ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
-+        
-+        // Set up whether fixed address is _really_ fixed
-+        if (dst_settings->address_really_fixed_) {
-+            ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+        }
-+    } else {
-+        // Incrementing address
-+        ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
-+        ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+    }
-+
-+    // Set up the width of the transfers on the DMA buses
-+    ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
-+    ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
-+
-+    // Setup the priority arbitration scheme
-+    ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY;    // !Starve low priority
-+
-+    return ctrl_status;
-+}
-+
-+static unsigned long encode_eot(
-+    oxnas_dma_device_settings_t* src_settings,
-+    oxnas_dma_device_settings_t* dst_settings,
-+    unsigned long length,
-+    int isFinalTransfer)
-+{
-+    // Write the length, with EOT configuration and enable INC4 tranfers and
-+    // HPROT. HPROT will delay data reaching memory for a few clock cycles, but
-+    // most unlikely to cause a problem for the CPU.
-+    unsigned long encoded = length |
-+                            DMA_BYTE_CNT_INC4_SET_MASK |    // Always enable INC4 transfers
-+                            DMA_BYTE_CNT_HPROT_MASK;        // Always enable HPROT assertion
-+
-+    // Encode the EOT setting for the src device based on its policy
-+    encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
-+    switch (src_settings->read_eot_policy_) {
-+        case OXNAS_DMA_EOT_FINAL:
-+            if (!isFinalTransfer) {
-+                break;
-+            }
-+            // Fall through in case of final transfer and EOT required for final
-+            // transfer
-+        case OXNAS_DMA_EOT_ALL:
-+            encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
-+            break;
-+        default:
-+            break;
-+    }
-+
-+    // Encode the EOT setting for the dst device based on its policy
-+    encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
-+    switch (dst_settings->write_eot_policy_) {
-+        case OXNAS_DMA_EOT_FINAL:
-+            if (!isFinalTransfer) {
-+                break;
-+            }
-+            // Fall through in case of final transfer and EOT required for final
-+            // transfer
-+        case OXNAS_DMA_EOT_ALL:
-+            encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
-+            break;
-+        default:
-+            break;
-+    }
-+
-+    return encoded;
-+}
-+
-+static unsigned long encode_start(unsigned long ctrl_status)
-+{
-+    ctrl_status &= ~DMA_CTRL_STATUS_PAUSE;
-+    return ctrl_status;
-+}
-+
-+static void oxnas_dma_set_common_lowlevel(
-+    oxnas_dma_channel_t *channel,
-+    unsigned long        ctrl_status,
-+    dma_addr_t           src_address,
-+    dma_addr_t           dst_address,
-+    unsigned long        lengthAndEOT)
-+{
-+    unsigned channel_number = channel->channel_number_;
-+
-+    spin_lock(&dma_controller.spinlock_);
-+
-+    // Write the control/status value to the DMAC
-+    writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+
-+    // Ensure control/status word makes it to the DMAC before we write address/length info
-+    wmb();
-+
-+    // Write the source addresses to the DMAC
-+    writel(src_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_SRC_ADR));
-+
-+    // Write the destination addresses to the DMAC
-+    writel(dst_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_DST_ADR));
-+
-+    // Write the length, with EOT configuration for the single transfer
-+    writel(lengthAndEOT, DMA_CALC_REG_ADR(channel_number, DMA_BYTE_CNT));
-+
-+    // Ensure adr/len info makes it to DMAC before later modifications to
-+    // control/status register due to starting the transfer, which happens in
-+    // oxnas_dma_start()
-+    wmb();
-+
-+    spin_unlock(&dma_controller.spinlock_);
-+
-+    // Increase count of in-progress transfers on this channel
-+    atomic_inc(&channel->active_count_);
-+}
-+
-+static int oxnas_dma_set_common(
-+    oxnas_dma_channel_t*         channel,
-+    unsigned long                length,
-+    oxnas_dma_device_settings_t *src_settings,
-+    oxnas_dma_device_settings_t *dst_settings,
-+    int                          isFinalTransfer,
-+    int                          paused)
-+{
-+    int status = 0;
-+
-+    if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+        printk(KERN_WARNING "oxnas_dma_set_common() length exceeds hardware allowed maximum\n");
-+        status = 1;
-+    } else {
-+        oxnas_dma_set_common_lowlevel(
-+            channel,
-+            encode_control_status(src_settings, dst_settings, paused),
-+            (dma_addr_t)src_settings->address_,
-+            (dma_addr_t)dst_settings->address_,
-+            encode_eot(src_settings, dst_settings, length, isFinalTransfer));
-+    }
-+    return status;
-+}
-+
-+int oxnas_dma_set(
-+    oxnas_dma_channel_t *channel,
-+    unsigned char       *src_adr,   // Physical address
-+    unsigned long        length,
-+    unsigned char       *dst_adr,   // Physical address
-+    oxnas_dma_mode_t     src_mode,
-+    oxnas_dma_mode_t     dst_mode,
-+    int                  do_checksum,
-+    int                  paused)
-+{
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_set() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    if (do_checksum) {
-+        // Arbitrate for ownership of the checksum engine
-+        if (alloc_csum_engine()) {
-+            // Did not obtain the csum engine, so return will failure status
-+            return 1;
-+        }
-+    }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+	BUG_ON(do_checksum);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+    {
-+        // Assemble complete memory settings, accounting for csum generation if
-+        // required
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        oxnas_dma_device_settings_t src_settings =
-+            do_checksum ? oxnas_ram_csum_src_dma_settings :
-+                          oxnas_ram_only_src_dma_settings;
-+#else // CONFIG_OXNAS_VERSION_0X800
-+        oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
-+
-+        // Assemble the source address
-+        src_settings.address_ = (unsigned long)src_adr;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        if (do_checksum) {
-+            // Record that we are checksumming, so that the result is read on
-+            // completion
-+            channel->checksumming_ = 1;
-+
-+            // To checksum set the high order address bit to enable the engine
-+            src_settings.address_ |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+        }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        // Ensure only use the valid src address bits are used
-+        src_settings.address_ &= OXNAS_DMA_CSUM_ADR_MASK;
-+        src_settings.address_mode_ = src_mode;
-+
-+        // Ensure only use the valid dst address bits are used
-+        dst_settings.address_ = ((unsigned long)dst_adr) & OXNAS_DMA_ADR_MASK;
-+        dst_settings.address_mode_ = dst_mode;
-+
-+        return oxnas_dma_set_common(channel, length, &src_settings, &dst_settings, 1, paused);
-+    }
-+}
-+
-+int oxnas_dma_device_set(
-+    oxnas_dma_channel_t         *channel,
-+    oxnas_dma_direction_t        direction,
-+    unsigned char               *mem_adr,   // Physical address
-+    unsigned long                length,
-+    oxnas_dma_device_settings_t *device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+    int                          paused)
-+{
-+    oxnas_dma_device_settings_t mem_settings;
-+
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_device_set() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+    // Assemble complete memory settings, ensuring addresses do not affect the
-+    // checksum enabling high order adr bit
-+    mem_settings = oxnas_ram_generic_dma_settings;
-+    mem_settings.address_ = ((unsigned long)mem_adr) & OXNAS_DMA_ADR_MASK;
-+    mem_settings.address_mode_ = mem_mode;
-+
-+    device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+
-+    return oxnas_dma_set_common(
-+        channel,
-+        length,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? &mem_settings : device_settings,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+        1,
-+        paused);
-+}
-+
-+int oxnas_dma_device_pair_set(
-+    oxnas_dma_channel_t*         channel,
-+    unsigned long                length,
-+    oxnas_dma_device_settings_t *src_device_settings,
-+    oxnas_dma_device_settings_t *dst_device_settings,
-+    int                          paused)
-+{
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_device_pair_set() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+    // Ensure addresses do not affect the checksum enabling high order adr bit
-+    src_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+    dst_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+    return oxnas_dma_set_common(channel, length, src_device_settings, dst_device_settings, 1, paused);
-+}
-+
-+static int oxnas_dma_set_sg_common(
-+    oxnas_dma_channel_t*         channel,
-+    struct scatterlist*          src_sg,
-+    unsigned                     src_sg_count,
-+    struct scatterlist*          dst_sg,
-+    unsigned                     dst_sg_count,
-+    oxnas_dma_device_settings_t* src_settings,
-+    oxnas_dma_device_settings_t* dst_settings,
-+	int                          in_atomic)
-+{
-+    int i;
-+    int failed = 0;
-+    oxnas_dma_sg_entry_t *sg_entry;
-+    oxnas_dma_sg_entry_t *previous_entry;
-+
-+    // Get reference to this channel's top level SG DMA descriptor structure
-+    oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
-+
-+	// SG entries have not been provided
-+	channel->auto_sg_entries_ = 1;
-+
-+    // Initialise list pointers to zero
-+    sg_info->v_srcEntries_ = 0;
-+    sg_info->p_srcEntries_ = 0;
-+    sg_info->v_dstEntries_ = 0;
-+    sg_info->p_dstEntries_ = 0;
-+
-+    sg_entry = 0;
-+    previous_entry = 0;
-+    for (i=0; i < src_sg_count; i++) {
-+        // Is this entry contiguous with the previous one and would the combined
-+        // lengths not exceed the maximum that the hardware is capable of
-+#if 0
-+        if (previous_entry &&
-+            ((previous_entry->addr_ + previous_entry->length_) == (src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+            ((previous_entry->length_ + src_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+            // Yes, so coalesce the pair
-+            previous_entry->length_ += src_sg[i].length;
-+        } else
-+#endif
-+        {
-+            // Allocate space for SG list entry from coherent DMA pool
-+            oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
-+            if (!new_sg_entry) {
-+                failed = 1;
-+                break;
-+            }
-+            sg_entry = new_sg_entry;
-+
-+            if (previous_entry) {
-+                // Link the previous SG list entry forward to this one        
-+                previous_entry->v_next_ = sg_entry;
-+                previous_entry->p_next_ = sg_entry->paddr_;
-+            } else {
-+                // Create a link from the SG info structure to the first SG list entry
-+                sg_info->v_srcEntries_ = sg_entry;
-+                sg_info->p_srcEntries_ = sg_entry->paddr_;
-+            }
-+            previous_entry = sg_entry;
-+
-+            // Fill in the SG list entry with start address, ensuring only valid
-+            // address bits are used, preserving the checksum enabling flag
-+            sg_entry->addr_ = src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK;
-+
-+            // Fill in the length, checking that it does not exceed the hardware
-+            // allowed maximum
-+            sg_entry->length_ = (src_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? src_sg[i].length : 0;
-+            if (!sg_entry->length_) {
-+                printk(KERN_WARNING "oxnas_dma_set_sg_common() Source entry too long, zeroing\n");
-+            }
-+        }
-+    }
-+    if (sg_entry) {
-+        // Mark the end of the source SG list with nulls
-+        sg_entry->p_next_ = 0;
-+        sg_entry->v_next_ = 0;
-+    }
-+
-+    if (failed) {
-+        // Failed to allocate all SG src entries, so free those we did get
-+        oxnas_dma_sg_entry_t* sg_entry = sg_info->v_srcEntries_;
-+        while (sg_entry) {
-+            oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+            free_sg_entry(sg_entry);
-+            sg_entry = next;
-+        }
-+        channel->v_sg_info_->p_srcEntries_ = 0;
-+        channel->v_sg_info_->v_srcEntries_ = 0;
-+        return 1;
-+    }
-+
-+    // Assemble destination descriptors
-+    sg_entry = 0;
-+    previous_entry = 0;
-+    for (i=0; i < dst_sg_count; i++) {
-+        // Is this entry contiguous with the previous one?
-+#if 0
-+        if (previous_entry &&
-+            ((previous_entry->addr_ + previous_entry->length_) == (dst_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+            ((previous_entry->length_ + dst_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+            // Yes, so coalesce the pair
-+            previous_entry->length_ += dst_sg[i].length;
-+        } else 
-+#endif
-+        {
-+            // Allocate space for SG list entry from coherent DMA pool
-+            oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
-+            if (!new_sg_entry) {
-+                failed = 1;
-+                break;
-+            }
-+            sg_entry = new_sg_entry;
-+
-+            if (previous_entry) {
-+                // Link the previous SG list entry forward to this one        
-+                previous_entry->v_next_ = sg_entry;
-+                previous_entry->p_next_ = sg_entry->paddr_;
-+            } else {
-+                // Create a link from the SG info structure to the first SG list entry
-+                sg_info->v_dstEntries_ = sg_entry;
-+                sg_info->p_dstEntries_ = sg_entry->paddr_;
-+            }
-+            previous_entry = sg_entry;
-+
-+            // Fill in the SG list entry with start address, ensuring address
-+            // does not affect the checksum enabling high order adr bit
-+            sg_entry->addr_   = dst_sg[i].dma_address & OXNAS_DMA_ADR_MASK;
-+
-+            // Fill in the length, checking that it does not exceed the hardware
-+            // allowed maximum
-+            sg_entry->length_ = (dst_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? dst_sg[i].length : 0;
-+            if (!sg_entry->length_) {
-+                printk(KERN_WARNING "oxnas_dma_set_sg_common() Destination entry too long, zeroing\n");
-+            }
-+        }
-+    }
-+    if (sg_entry) {
-+        // Mark the end of the destination SG list with nulls
-+        sg_entry->p_next_ = 0;
-+        sg_entry->v_next_ = 0;
-+    }
-+
-+    if (failed) {
-+        // Failed to allocate all SG dst entries, so free those we did obtain
-+        oxnas_dma_sg_entry_t* sg_entry = sg_info->v_dstEntries_;
-+        while (sg_entry) {
-+            oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+            free_sg_entry(sg_entry);
-+            sg_entry = next;
-+        }
-+        sg_info->p_dstEntries_ = 0;
-+        sg_info->v_dstEntries_ = 0;
-+
-+        // Free all the SG src entries which we did sucessfully obtain
-+        sg_entry = sg_info->v_srcEntries_;
-+        while (sg_entry) {
-+            oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+            free_sg_entry(sg_entry);
-+            sg_entry = next;
-+        }
-+        sg_info->p_srcEntries_ = 0;
-+        sg_info->v_srcEntries_ = 0;
-+        return 1;
-+    }
-+
-+    sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
-+                          (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
-+                          (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
-+                          (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
-+
-+    // Flags are the same for source and destination for each SG transfer component
-+    sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
-+
-+    // Increase count of in-progress transfers on this channel
-+    atomic_inc(&channel->active_count_);
-+
-+    return 0;
-+}
-+
-+int oxnas_dma_set_sg(
-+    oxnas_dma_channel_t* channel,
-+    struct scatterlist*  src_sg,
-+    unsigned             src_sg_count,
-+    struct scatterlist*  dst_sg,
-+    unsigned             dst_sg_count,
-+    oxnas_dma_mode_t     src_mode,
-+    oxnas_dma_mode_t     dst_mode,
-+    int                  do_checksum,
-+	int                  in_atomic)
-+{
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    if (do_checksum) {
-+        // Arbitrate for ownership of the checksum engine
-+        if (alloc_csum_engine()) {
-+            // Failed to obtain csum engine, so return with failure status
-+            return 1;
-+        }
-+    }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+	BUG_ON(do_checksum);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+    {
-+        // Assemble complete memory settings, accounting for csum generation if
-+        // required
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        oxnas_dma_device_settings_t src_settings =
-+            do_checksum ? oxnas_ram_csum_src_dma_settings :
-+                          oxnas_ram_only_src_dma_settings;
-+#else // CONFIG_OXNAS_VERSION_0X800
-+        oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
-+
-+        // Normal adr bits not used for SG transfers
-+        src_settings.address_ = 0;
-+        src_settings.address_mode_ = src_mode;
-+
-+        // Normal adr bits not used for SG transfers
-+        dst_settings.address_ = 0;
-+        dst_settings.address_mode_ = dst_mode;
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        if (do_checksum) {
-+            // Record that we are checksumming, so that the result is read on
-+            // completion
-+            channel->checksumming_ = 1;
-+
-+            // The high order address bit enabling the checksum engine will be
-+            // set by the caller in the passed scatterlist entries, for those
-+            // entries which are required to contribute to the checksum
-+            // calculation
-+        }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        return oxnas_dma_set_sg_common(
-+            channel,
-+            src_sg,
-+            src_sg_count,
-+            dst_sg,
-+            dst_sg_count,
-+            &src_settings,
-+            &dst_settings,
-+			in_atomic);
-+    }
-+}
-+
-+int oxnas_dma_device_set_sg(
-+    oxnas_dma_channel_t*         channel,
-+    oxnas_dma_direction_t        direction,
-+    struct scatterlist*          mem_sg,
-+    unsigned                     mem_sg_count,
-+    oxnas_dma_device_settings_t* device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+	int                          in_atomic)
-+{
-+    int i;
-+    struct scatterlist *sg;
-+    struct scatterlist  dev_sg;
-+
-+    oxnas_dma_device_settings_t mem_settings;
-+
-+    if (oxnas_dma_is_active(channel)) {
-+        printk(KERN_WARNING "oxnas_dma_device_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+    // Assemble complete memory settings
-+    mem_settings = oxnas_ram_generic_dma_settings;
-+    mem_settings.address_ = 0;  // Not used for SG transfers
-+    mem_settings.address_mode_ = mem_mode;
-+
-+    // Need to total all memory transfer lengths and assign as device single transfer length
-+    dev_sg.dma_address = device_settings->address_;
-+    for (i=0, sg=mem_sg, dev_sg.length = 0; i < mem_sg_count; i++, sg++) {
-+        dev_sg.length += sg->length;
-+    }
-+
-+    return oxnas_dma_set_sg_common(
-+        channel,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? mem_sg        : &dev_sg,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? mem_sg_count  : 1,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg        : &dev_sg,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg_count  : 1,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? &mem_settings : device_settings,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+		in_atomic);
-+}
-+
-+static int oxnas_dma_set_prd_common(
-+    oxnas_dma_channel_t         *channel,
-+    struct ata_prd              *src_prd,
-+    struct ata_prd              *dst_prd,
-+    oxnas_dma_device_settings_t *src_settings,
-+    oxnas_dma_device_settings_t *dst_settings,
-+	oxnas_dma_sg_entry_t		 *sg_entries)
-+{
-+    int i;
-+    int failed = 0;
-+    oxnas_dma_sg_entry_t *sg_entry, *previous_entry, *next_entry;
-+    u32 eot;
-+	u32 tot_src_len = 0, tot_dst_len = 0;
-+
-+    // Get reference to this channel's top level SG DMA descriptor structure
-+    oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
-+
-+	// SG entries have been provided
-+	channel->auto_sg_entries_ = 0;
-+
-+    // Initialise list pointers to zero
-+    sg_info->v_srcEntries_ = 0;
-+    sg_info->p_srcEntries_ = 0;
-+    sg_info->v_dstEntries_ = 0;
-+    sg_info->p_dstEntries_ = 0;
-+
-+	// Get pointer to first available SG entry
-+    sg_entry = previous_entry = 0;
-+    next_entry = sg_entries;
-+    i=0;
-+    do {
-+        u32 addr;
-+        u32 length;
-+        u32 flags_len;
-+
-+        addr = src_prd[i].addr;
-+        flags_len = le32_to_cpu(src_prd[i++].flags_len);
-+        length = flags_len & ~ATA_PRD_EOT;
-+        eot = flags_len & ATA_PRD_EOT;
-+
-+		// Zero length field means 64KB
-+        if (!length) length = 0x10000;
-+
-+		// Accumulate the total length of all source elements
-+		tot_src_len += length;
-+
-+        // Is this entry contiguous with the previous one and would the combined
-+        // lengths not exceed the maximum that the hardware is capable of
-+#if 0
-+        if (previous_entry &&
-+            ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+            ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+            // Yes, so coalesce the pair
-+            previous_entry->length_ += length;
-+        } else 
-+#endif
-+        {
-+			// Get the next available SG entry
-+			if (!next_entry) {
-+				failed = 1;
-+				break;
-+			}
-+			sg_entry = next_entry;
-+
-+            if (previous_entry) {
-+                // Link the previous SG list entry forward to this one
-+                previous_entry->v_next_ = sg_entry;
-+                previous_entry->p_next_ = sg_entry->paddr_;
-+            } else {
-+                // Create a link from the SG info structure to the first SG list entry
-+                sg_info->v_srcEntries_ = sg_entry;
-+                sg_info->p_srcEntries_ = sg_entry->paddr_;
-+            }
-+            previous_entry = sg_entry;
-+
-+            // Fill in the SG list entry with start address, ensuring only valid
-+            // address bits are used, preserving the checksum enabling flag
-+            sg_entry->addr_ = addr & OXNAS_DMA_CSUM_ADR_MASK;
-+
-+            // Fill in the length, checking that it does not exceed the hardware
-+            // allowed maximum
-+            if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+                printk(KERN_WARNING "oxnas_dma_set_prd_common() Source entry too long (0x%x), zeroing\n", length);
-+                sg_entry->length_ = 0;
-+            } else {
-+                sg_entry->length_ = length;
-+            }
-+
-+			// Get pointer to next available SG entry
-+			next_entry = sg_entry->next_;
-+        }
-+    } while (!eot);
-+    if (sg_entry) {
-+        // Mark the end of the source SG list with nulls
-+        sg_entry->p_next_ = 0;
-+        sg_entry->v_next_ = 0;
-+    }
-+
-+    if (failed) {
-+        // Failed to allocate all SG src entries
-+        channel->v_sg_info_->p_srcEntries_ = 0;
-+        channel->v_sg_info_->v_srcEntries_ = 0;
-+		printk(KERN_WARNING "Too few SG entries to satisfy source requirements\n");
-+        return 1;
-+    }
-+
-+    // Assemble destination descriptors
-+    sg_entry = previous_entry = 0;
-+    i=0;
-+    do {
-+        u32 addr;
-+        u32 length;
-+        u32 flags_len;
-+
-+        addr = dst_prd[i].addr;
-+        flags_len = le32_to_cpu(dst_prd[i++].flags_len);
-+        length = flags_len & ~ATA_PRD_EOT;
-+        eot = flags_len & ATA_PRD_EOT;
-+
-+		// Zero length field means 64KB
-+        if (!length) length = 0x10000;
-+
-+		// Accumulate the total length of all destination elements
-+		tot_dst_len += length;
-+
-+        // Is this entry contiguous with the previous one?
-+#if 0
-+        if (previous_entry &&
-+            ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+            ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+            // Yes, so coalesce the pair
-+            previous_entry->length_ += length;
-+        } else 
-+#endif
-+        {
-+			// Get the next available SG entry
-+			if (!next_entry) {
-+				failed = 1;
-+				break;
-+			}
-+			sg_entry = next_entry;
-+
-+            if (previous_entry) {
-+                // Link the previous SG list entry forward to this one        
-+                previous_entry->v_next_ = sg_entry;
-+                previous_entry->p_next_ = sg_entry->paddr_;
-+            } else {
-+                // Create a link from the SG info structure to the first SG list entry
-+                sg_info->v_dstEntries_ = sg_entry;
-+                sg_info->p_dstEntries_ = sg_entry->paddr_;
-+            }
-+            previous_entry = sg_entry;
-+
-+            // Fill in the SG list entry with start address, ensuring address
-+            // does not affect the checksum enabling high order adr bit
-+            sg_entry->addr_ = addr & OXNAS_DMA_ADR_MASK;
-+
-+            // Fill in the length, checking that it does not exceed the hardware
-+            // allowed maximum
-+            if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+                printk(KERN_WARNING "oxnas_dma_set_prd_common() Destination entry too long (0x%x), zeroing\n", length);
-+                sg_entry->length_ = 0;
-+            } else {
-+                sg_entry->length_ = length;
-+            }
-+
-+			// Get pointer to next available SG entry
-+			next_entry = sg_entry->next_;
-+        }
-+    } while (!eot);
-+    if (sg_entry) {
-+        // Mark the end of the destination SG list with nulls
-+        sg_entry->p_next_ = 0;
-+        sg_entry->v_next_ = 0;
-+    }
-+
-+    if (failed) {
-+        // Failed to allocate all SG dst entries
-+        sg_info->p_dstEntries_ = 0;
-+        sg_info->v_dstEntries_ = 0;
-+        sg_info->p_srcEntries_ = 0;
-+        sg_info->v_srcEntries_ = 0;
-+		printk(KERN_WARNING "Too few SG entries to satisfy destination requirements\n");
-+        return 1;
-+    }
-+
-+	// Fill in length of single device SG entry from the total length of all the
-+	// memory SG entries
-+	if ((sg_entry = sg_info->v_srcEntries_) && !sg_entry->v_next_) {
-+		sg_entry->length_ = tot_dst_len;
-+	} else if ((sg_entry = sg_info->v_dstEntries_) && !sg_entry->v_next_) {
-+		sg_entry->length_ = tot_src_len;
-+	}
-+
-+    sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
-+                          (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
-+                          (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
-+                          (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
-+
-+    // Flags are the same for source and destination for each SG transfer component
-+    sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
-+
-+    // Increase count of in-progress transfers on this channel
-+    atomic_inc(&channel->active_count_);
-+
-+    return 0;
-+}
-+
-+int oxnas_dma_device_set_prd(
-+    oxnas_dma_channel_t         *channel,
-+    oxnas_dma_direction_t        direction,
-+    struct ata_prd              *mem_prd,
-+    oxnas_dma_device_settings_t *device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+	oxnas_dma_sg_entry_t		 *sg_entries)
-+{
-+    struct ata_prd dev_prd;
-+    oxnas_dma_device_settings_t mem_settings;
-+
-+    if (unlikely(oxnas_dma_is_active(channel))) {
-+        printk(KERN_WARNING "oxnas_dma_device_set_prd() Trying to use channel %u while active\n", channel->channel_number_);
-+    }
-+
-+    // Assemble complete memory settings
-+    mem_settings = oxnas_ram_generic_dma_settings;
-+    mem_settings.address_ = 0;  // Not used for SG transfers
-+    mem_settings.address_mode_ = mem_mode;
-+
-+    // Device has only a single SG entry whose length will be assigned once
-+	// all the memory transfer lengths have been accumulated
-+    dev_prd.addr = device_settings->address_;
-+    dev_prd.flags_len = ATA_PRD_EOT;
-+
-+    return oxnas_dma_set_prd_common(
-+        channel,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? mem_prd       : &dev_prd,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? mem_prd       : &dev_prd,
-+        (direction == OXNAS_DMA_TO_DEVICE)   ? &mem_settings : device_settings,
-+        (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+		sg_entries);
-+}
-+
-+void oxnas_dma_set_callback(oxnas_dma_channel_t* channel, oxnas_dma_callback_t callback, oxnas_callback_arg_t arg)
-+{
-+#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)    
-+printk("Registering callback 0x%08x for channel %u\n", (unsigned)callback, channel->channel_number_);
-+#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)    
-+    channel->notification_callback_ = callback;
-+    channel->notification_arg_ = arg;
-+}
-+
-+static void default_callback(
-+    oxnas_dma_channel_t*        channel,
-+    oxnas_callback_arg_t        arg,
-+    oxnas_dma_callback_status_t status,
-+    u16                         checksum,
-+    int                         interrupt_count)
-+{
-+    up(&channel->default_semaphore_);
-+}
-+
-+void oxnas_dma_abort(
-+	oxnas_dma_channel_t *channel,
-+	int                  in_atomic)
-+{
-+    u32 ctrl_status;
-+    unsigned channel_number = channel->channel_number_;
-+    int must_wait = 0;
-+    int callback_registered = 0;
-+
-+    // Assert reset for the channel
-+    spin_lock(&dma_controller.spinlock_);
-+    ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+    ctrl_status |= DMA_CTRL_STATUS_RESET;
-+    writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+    spin_unlock(&dma_controller.spinlock_);
-+
-+    // Wait for the channel to become idle - should be quick as should finish
-+    // after the next AHB single or burst transfer
-+    while (readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS);
-+
-+    // Deassert reset for the channel
-+    spin_lock(&dma_controller.spinlock_);
-+    ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+    ctrl_status &= ~DMA_CTRL_STATUS_RESET;
-+    writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+    spin_unlock(&dma_controller.spinlock_);
-+
-+    // If no user callback is registered, we need to wait here for the DMA
-+    // channel to become inactive, i.e. for the ISR to be called and the
-+    // channel software returned to the idle state
-+    if (channel->notification_callback_ == OXNAS_DMA_CALLBACK_NUL) {
-+        must_wait = 1;
-+        if (!in_atomic) {
-+            // If the callers is not calling us from atomic context we can
-+            // register our own callback and sleep until it is invoked
-+            oxnas_dma_set_callback(channel, default_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+            callback_registered = 1;
-+        }
-+    }
-+
-+    // Fake an interrupt to cause the channel to be cleaned up by running the
-+    // DMA bottom half tasklet
-+    fake_interrupt(channel_number);
-+
-+    if (must_wait) {
-+        if (callback_registered) {
-+            // Sleep until the channel becomes inactive
-+            down_interruptible(&channel->default_semaphore_);
-+
-+            // Deregister the callback
-+            oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+        } else {
-+            // If we reach here we are in an atomic context and thus must not do
-+            // anything that might cause us to sleep
-+            // NB. Possible problem here if we're atomic because someone has
-+            // called spin_lock_bh(); I'm concerned that calling do_softirq()
-+            // under these circumstances might cause issues, althought the net-
-+            // working code calls do_softirq() and doesn't appear to worry
-+            if (local_softirq_pending()) {
-+                // If an interrupt has not arrived and caused the tasklet to
-+                // have been run already, cause it to run now.
-+                do_softirq();
-+            }
-+
-+            // The tasklet should have run by this point and cleaned up the channel
-+            BUG_ON(oxnas_dma_is_active(channel));
-+        }
-+    }
-+}
-+
-+void oxnas_dma_start(oxnas_dma_channel_t* channel)
-+{
-+    // Are there SG lists setup for this channel?
-+    if (channel->v_sg_info_->v_srcEntries_) {
-+#ifdef OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+        // Print the desciptor contents for debugging
-+        oxnas_dma_sg_entry_t* d = channel->v_sg_info_->v_srcEntries_;
-+        printk("qualifer_ = 0x%08lx, control_ = 0x%lx\n", channel->v_sg_info_->qualifer_, channel->v_sg_info_->control_);
-+        printk("Source Descriptors:\n");
-+        while (d) {
-+            printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
-+            d = d->v_next_;
-+        }
-+        printk("Destination Descriptors:\n");
-+        d = channel->v_sg_info_->v_dstEntries_;
-+        while (d) {
-+            printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
-+            d = d->v_next_;
-+        }
-+#endif // OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+
-+		// Write to the SG-DMA channel's reset register to reset the control
-+		// in case the previous SG-DMA transfer failed in some way, thus
-+		// leaving the SG-DMA controller hung up part way through processing
-+		// its SG list. The reset bits are self-clearing
-+		writel(1UL << DMA_SG_RESETS_CONTROL_BIT, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_RESETS));
-+
-+        // Write the pointer to the SG info struct into the Request Pointer reg.
-+        writel(channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+printk("p_sg_info_ = 0x%08x written to 0x%08x\n", (u32)channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
-+printk("*(DMA_SG_CONTROL) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL)));
-+printk("*(DMA_SG_STATUS)  = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS)));
-+printk("*(DMA_SG_REQ_PTR) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR)));
-+#endif // OXNAS_DMA_SG_TEST
-+
-+        // Start the transfer
-+        writel((1UL << DMA_SG_CONTROL_START_BIT) |
-+               (1UL << DMA_SG_CONTROL_QUEUING_ENABLE_BIT) |
-+               (1UL << DMA_SG_CONTROL_HBURST_ENABLE_BIT),
-+               DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL));
-+    } else {
-+        // Single transfer mode, so unpause the DMA controller channel
-+        spin_lock(&dma_controller.spinlock_);
-+        writel(encode_start(readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS))),
-+               DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+        spin_unlock(&dma_controller.spinlock_);
-+    }
-+}
-+
-+void oxnas_dma_dump_registers()
-+{
-+    unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(0, 0);
-+    unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
-+    int i;
-+
-+    printk("oxnas_dma_dump_registers(), adr= 0x%08lx, end=0x%08lx\n", (unsigned long)adr, (unsigned long)(adr + (DMA_REGS_PER_CHANNEL * dma_controller.numberOfChannels_)));
-+
-+    for (i=0; i < dma_controller.numberOfChannels_; i++) {
-+        for (; adr < end; adr++) {
-+            printk("0x%08lx\n", *adr);
-+        }
-+	printk("SG-Debug: 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(i, DMA_SG_RESETS)));
-+        printk("-----------------------\n");
-+        end += DMA_REGS_PER_CHANNEL;
-+    }
-+    printk("oxnas_dma_dump_registers() - end\n");
-+}
-+
-+void oxnas_dma_dump_registers_single(int channel_number)
-+{
-+    unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(channel_number, 0);
-+    unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
-+
-+    printk("DMA channel %d regs:\n", channel_number);
-+    for (; adr < end; adr++) {
-+        printk("0x%08lx\n", *adr);
-+    }
-+}
-+
-+#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0);   // Binary semaphore for testing
-+
-+static void dma_callback(
-+    oxnas_dma_channel_t         *channel,
-+    oxnas_callback_arg_t         arg,
-+    oxnas_dma_callback_status_t  error_code,
-+    u16                          checksum,
-+    int                          interrupt_count)
-+{
-+    printk("dma_callback() for channel %u, arg = 0x%lx, status = 0x%04x, checksum = 0x%04hx, interrupt_count = %d\n", channel->channel_number_, (unsigned long)arg, error_code, checksum, interrupt_count);
-+    up(&callback_semaphore);
-+}
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/slab.h>
-+
-+#ifdef OXNAS_DMA_TEST
-+static void dma_test(unsigned long length)
-+{
-+    void* memory1;
-+    void* memory2;
-+    unsigned long* ptr;
-+    unsigned long quads;
-+    int i;
-+    unsigned long* end;
-+    dma_addr_t dma_address1;
-+    dma_addr_t dma_address2;
-+    oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+
-+    printk("*************************************************************\n");
-+    printk("                                                               \n");
-+    printk("Simple DMA Test, length = %lu, number of channel = %u\n", length, MAX_OXNAS_DMA_CHANNELS);
-+    printk("                                                               \n");
-+    printk("*************************************************************\n");
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        channels[i] = oxnas_dma_request(0);
-+        if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+            printk("No DMA channels[%d] obtained\n", i);
-+        } else {
-+            printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+        }
-+    }
-+
-+    // Allocate some DMA coherent memory
-+    printk("Calling kmalloc()\n");
-+    memory1 = kmalloc(length, GFP_KERNEL | GFP_DMA);
-+    memory2 = kmalloc(length, GFP_KERNEL | GFP_DMA);
-+
-+    // Test each available DMA channel
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        int j;
-+
-+        // Fill each memory area with a different pattern
-+        ptr = (unsigned long*)memory1;
-+        quads = length/sizeof(unsigned long);
-+        for (j=0; j < quads; j++) {
-+            *ptr++ = 0xdeadbeef;
-+        }
-+        ptr = (unsigned long*)memory2;
-+        for (j=0; j < quads; j++) {
-+            *ptr++ = 0xc001babe;
-+        }
-+    
-+        printk("Before:\n");
-+        ptr = (unsigned long*)memory1;
-+        end = (unsigned long*)(memory1 + length);
-+        while (ptr < end) {
-+            for (j=0; j < 8; j++) {
-+                printk("0x%08lx ", *ptr++);
-+            }
-+            printk("\n");
-+        }
-+        printk("---------------------------------------------------------\n");
-+        ptr = (unsigned long*)memory2;
-+        end = (unsigned long*)(memory2 + length);
-+        while (ptr < end) {
-+            for (j=0; j < 8; j++) {
-+                printk("0x%08lx ", *ptr++);
-+            }
-+            printk("\n");
-+        }
-+    
-+        // Get a consistent DMA mapping for the memory to be DMAed from - causing a
-+        // flush from the CPU's cache to the memory
-+        dma_address1 = dma_map_single(0, memory1, length, DMA_TO_DEVICE);
-+        if (dma_mapping_error(dma_address1)) {
-+            printk("Consistent DMA mapping 1 failed\n");
-+        }
-+    
-+        // Get a consistent DMA mapping for the memory to be DMAed to - causing a
-+        // flush and invalidation of any entries in the CPU's cache covering the
-+        // memory region
-+        dma_address2 = dma_map_single(0, memory2, length, DMA_BIDIRECTIONAL);
-+        if (dma_mapping_error(dma_address2)) {
-+            printk("Consistent DMA mapping 2 failed\n");
-+        }
-+    
-+        // Setup up DMA from first half to second half on memory, using physical addresses
-+        printk("Calling oxnas_dma_set(), memory1 = 0x%08lx, memory2 = 0x%08lx\n", (unsigned long)memory1, (unsigned long)memory2);
-+        oxnas_dma_set(
-+            channels[i],
-+            (unsigned char*)dma_address1,
-+            length,
-+            (unsigned char*)dma_address2,
-+            OXNAS_DMA_MODE_INC,
-+            OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+            1,  // Calculate checksum over source data
-+#else // CONFIG_OXNAS_VERSION_0X800
-+			0,
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+            1); // Paused
-+    
-+        // Using notification callback
-+        oxnas_dma_set_callback(channels[i], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+//printk("Before starting status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
-+        // Start the transfer
-+        printk("oxnas_dma_start() for channel %u\n", channels[i]->channel_number_);
-+        oxnas_dma_start(channels[i]);
-+    
-+// Poll for transfer completion
-+//while (oxnas_dma_raw_isactive(channels[i])) {
-+//    printk(".");
-+//}
-+//printk("Found channel inactive, status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
-+    
-+        printk("Waiting for channel to be inactive\n");
-+    
-+        // Sleep until transfer completed
-+        while (down_interruptible(&callback_semaphore));
-+        oxnas_dma_set_callback(channels[i], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+        // Release the consistent DMA mappings
-+        dma_unmap_single(0, dma_address1, length, DMA_TO_DEVICE);
-+        dma_unmap_single(0, dma_address2, length, DMA_BIDIRECTIONAL);
-+    
-+        printk("After:\n");
-+        ptr = (unsigned long*)memory1;
-+        end = (unsigned long*)(memory1 + length);
-+        while (ptr < end) {
-+            for (j=0; j < 8; j++) {
-+                printk("0x%08lx ", *ptr++);
-+            }
-+            printk("\n");
-+        }
-+        printk("---------------------------------------------------------\n");
-+        ptr = (unsigned long*)memory2;
-+        end = (unsigned long*)(memory2 + length);
-+        while (ptr < end) {
-+            for (j=0; j < 8; j++) {
-+                printk("0x%08lx ", *ptr++);
-+            }
-+            printk("\n");
-+        }
-+    }
-+
-+    // Deallocate the memory
-+    printk("Calling kfree()\n");
-+    kfree(memory1);
-+    kfree(memory2);
-+    printk("Returned from kfree()\n");
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        oxnas_dma_free(channels[i]);
-+    }
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        channels[i] = oxnas_dma_request(0);
-+        if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+            printk("No DMA channels[%d] obtained\n", i);
-+        } else {
-+            printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+        }
-+    }
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        oxnas_dma_free(channels[i]);
-+    }
-+}
-+#endif // OXNAS_DMA_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+static void dma_sg_test(void)
-+{
-+    int i;
-+    struct scatterlist* src_scatterlist = 0;
-+    struct scatterlist* dst_scatterlist = 0;
-+    const int num_src_buffers = 8;
-+    const int num_dst_buffers = 3;
-+    unsigned long src_fill_value = 0;
-+    unsigned long total_src_len = 0;
-+    int channel_number;
-+    oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+
-+    printk("*************************************************************\n");
-+    printk("                                                               \n");
-+    printk("Scatter-Gather DMA Test\n");
-+    printk("                                                               \n");
-+    printk("*************************************************************\n");
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        channels[i] = oxnas_dma_request(0);
-+        if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+            printk("No DMA channels[%d] obtained\n", i);
-+        } else {
-+            printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+        }
-+    }
-+
-+    for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
-+        if (num_src_buffers) {
-+            printk("Allocating source SG list and entry buffers\n");
-+            // Allocate scatterlist and memory for source buffers - store virtual buffer
-+            // addresses in scatterlist.offset for convenience. Include some contiguous
-+            // entries to test coalescing
-+            src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_src_buffers, GFP_KERNEL);
-+            src_scatterlist[0].offset = (unsigned int)kmalloc(8*1024,  GFP_KERNEL | GFP_DMA);
-+            src_scatterlist[0].__address = (char*)(8*1024);    // Real allocation length
-+            src_scatterlist[0].length = 8*1024;
-+            src_scatterlist[0].page = (struct page*)0xdeadbeef; // Fill value
-+            src_scatterlist[1].offset = (unsigned int)kmalloc(8,     GFP_KERNEL | GFP_DMA);
-+            src_scatterlist[1].__address = (char*)8;       // Real allocation length
-+            src_scatterlist[1].length = 8;
-+            src_scatterlist[1].page = (struct page*)0xc001babe; // Fill value
-+            src_scatterlist[2].offset = (unsigned int)kmalloc(48*1024, GFP_KERNEL | GFP_DMA);
-+            src_scatterlist[2].__address = (char*)(48*1024);   // Real allocation length
-+            src_scatterlist[2].length = 16*1024;
-+            src_scatterlist[2].page = (struct page*)0x22222222; // Fill value
-+            src_scatterlist[3].offset = src_scatterlist[2].offset + src_scatterlist[2].length;
-+            src_scatterlist[3].__address = (char*)0;         // No allocation
-+            src_scatterlist[3].length = 16*1024;
-+            src_scatterlist[3].page = (struct page*)0x33333333; // Fill value
-+            src_scatterlist[4].offset = src_scatterlist[3].offset + src_scatterlist[3].length;
-+            src_scatterlist[4].__address = (char*)0;         // No allocation
-+            src_scatterlist[4].length = 16*1024;
-+            src_scatterlist[4].page = (struct page*)0x44444444; // Fill value
-+            src_scatterlist[5].offset = (unsigned int)kmalloc(64,      GFP_KERNEL | GFP_DMA);
-+            src_scatterlist[5].__address = (char*)64;        // Real allocation length
-+            src_scatterlist[5].length = 64;
-+            src_scatterlist[5].page = (struct page*)0x55555555; // Fill value
-+            src_scatterlist[6].offset = (unsigned int)kmalloc(256,     GFP_KERNEL | GFP_DMA);
-+            src_scatterlist[6].__address = (char*)256;       // Real allocation length
-+            src_scatterlist[6].length = 128;
-+            src_scatterlist[6].page = (struct page*)0x66666666; // Fill value
-+            src_scatterlist[7].offset = src_scatterlist[6].offset + src_scatterlist[6].length;
-+            src_scatterlist[7].__address = (char*)0;         // No allocation
-+            src_scatterlist[7].length = 128;
-+            src_scatterlist[7].page = (struct page*)0x77777777; // Fill value
-+        }
-+    
-+        // Fill source memory buffers with stuff
-+        for (i=0; i < num_src_buffers; i++) {
-+            unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+            int quads = src_scatterlist[i].length/sizeof(unsigned long);
-+            int j=0;
-+            printk("Filling source buffer %u\n", i);
-+            src_fill_value = (unsigned long)(src_scatterlist[i].page);
-+            for (; j < quads; j++) {
-+                *ptr++ = src_fill_value;
-+            }
-+        }
-+    
-+    #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+        // Print before contents of source buffers
-+        printk("Source Before:\n");
-+        for (i=0; i < num_src_buffers; i++) {
-+            unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+            unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
-+            printk("Buffer %d\n", i);
-+            while (ptr < end) {
-+                int j=0;
-+                for (; j < 8; j++) {
-+                    printk("0x%08lx ", *ptr++);
-+                }
-+                printk("\n");
-+            }
-+        }
-+    #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+    
-+        // Get a consistent DMA mapping for the memory to be DMAed from - causing a
-+        // flush from the CPU's cache to the memory
-+        for (i=0; i < num_src_buffers; i++) {
-+            printk("Creating DMA mappings for source entry buffer %u\n", i);
-+            src_scatterlist[i].dma_address = dma_map_single(0, (void*)src_scatterlist[i].offset, src_scatterlist[i].length, DMA_TO_DEVICE);
-+            if (dma_mapping_error(src_scatterlist[i].dma_address)) {
-+                printk("Consistent source DMA mapping %d failed\n", i);
-+            }
-+    
-+            // Set the checksum enabling high order address bit
-+            src_scatterlist[i].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+        }
-+    
-+        // Allocate scatterlist and memory for destination buffers - store virtual
-+        // buffer addresses in scatterlist.offset for convenience
-+        if (num_dst_buffers) {
-+            unsigned long dst_length;
-+            unsigned long offset;
-+            
-+            printk("Allocating destination SG list and entry buffers\n");
-+            total_src_len = 0;
-+            for (i=0; i < num_src_buffers; i++) {
-+                total_src_len += src_scatterlist[i].length;
-+            }
-+    
-+            // Following will only work if no remainder due to divide
-+            dst_length = total_src_len / num_dst_buffers;
-+            dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
-+    
-+            // First destination segment owns the buffer
-+            dst_scatterlist[0].offset = (unsigned int)kmalloc(total_src_len,  GFP_KERNEL | GFP_DMA);
-+            dst_scatterlist[0].__address = (char*)total_src_len; // Real allocation length
-+            dst_scatterlist[0].length = dst_length;
-+    
-+            offset = dst_length;
-+            for (i=1; i < num_dst_buffers; i++) {
-+                dst_scatterlist[i].offset = dst_scatterlist[0].offset + offset;
-+                dst_scatterlist[i].__address = 0; // No allocation
-+                dst_scatterlist[i].length = dst_length;
-+    
-+                offset += dst_length;
-+            }
-+        }
-+    
-+        // Fill destination memory buffers with zero    
-+        for (i=0; i < num_dst_buffers; i++) {
-+            unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+            int quads = dst_scatterlist[i].length/sizeof(unsigned long);
-+            int j=0;
-+            printk("Filling destination buffer %u\n", i);
-+            for (; j < quads; j++) {
-+                *ptr++ = 0x000000;
-+            }
-+        }
-+    
-+    //#ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+    //    // Print before contents of destination buffers
-+    //    printk("Destination Before:\n");
-+    //    for (i=0; i < num_dst_buffers; i++) {
-+    //        unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+    //        unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
-+    //        printk("Buffer %d\n", i);
-+    //        while (ptr < end) {
-+    //            int j=0;
-+    //            for (; j < 8; j++) {
-+    //                printk("0x%08lx ", *ptr++);
-+    //            }
-+    //            printk("\n");
-+    //        }
-+    //    }
-+    //#endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+    
-+        // Get a consistent DMA mapping for the memory to be DMAed to - causing an
-+        // invalidate to the CPU's cache
-+        for (i=0; i < num_dst_buffers; i++) {
-+            printk("Creating DMA mappings for destination entry buffer %u\n", i);
-+            dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+            if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
-+                printk("Consistent destination DMA mapping %d failed\n", i);
-+            }
-+        }
-+    
-+        // Setup up SG DMA transfer
-+        printk("Setting up transfer\n");
-+        oxnas_dma_set_sg(
-+            channels[channel_number],
-+            src_scatterlist,
-+            num_src_buffers,
-+            dst_scatterlist,
-+            num_dst_buffers,
-+            OXNAS_DMA_MODE_INC,
-+            OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+            1); // Compute checksum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+            0);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+        // Using second DMA channel requested
-+        oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+        // Start the transfer
-+        printk("Starting the transfer\n");
-+        oxnas_dma_start(channels[channel_number]);
-+    
-+        // Sleep until transfer completed
-+        printk("Waiting for transfer to complete...\n");
-+    
-+        while (down_interruptible(&callback_semaphore));
-+        oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+        // Release the consistent DMA mappings for the source buffers
-+        for (i=0; i < num_src_buffers; i++) {
-+            printk("Releasing DMA mappings for source entry buffer %u\n", i);
-+            // Ensure the checksum enabling high order address bit is not set, as
-+            // this would confuse the DMA mapping release function
-+            src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+            dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
-+        }
-+    
-+        // Release the consistent DMA mappings for the destination buffers
-+        for (i=0; i < num_dst_buffers; i++) {
-+            printk("Releasing DMA mappings for destination entry buffer %u\n", i);
-+            dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+        }
-+    
-+    {
-+    u32 sw_csum = 0;
-+    for (i=0; i < num_src_buffers; i++) {
-+        sw_csum = csum_partial((u8*)src_scatterlist[i].offset, src_scatterlist[i].length, sw_csum);
-+    }
-+    printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
-+    
-+    sw_csum = 0;
-+    for (i=0; i < num_dst_buffers; i++) {
-+        sw_csum = csum_partial((u8*)dst_scatterlist[i].offset, dst_scatterlist[i].length, sw_csum);
-+    }
-+    printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
-+    }
-+    
-+    #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+    //    // Print after contents of source buffers
-+    //    printk("Source After:\n");
-+    //    for (i=0; i < num_src_buffers; i++) {
-+    //        unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+    //        unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
-+    //        printk("Buffer %d\n", i);
-+    //        while (ptr < end) {
-+    //            int j=0;
-+    //            for (; j < 8; j++) {
-+    //                printk("0x%08lx ", *ptr++);
-+    //            }
-+    //            printk("\n");
-+    //        }
-+    //    }
-+    
-+        // Print after contents of destination buffers
-+        printk("Destination After:\n");
-+        for (i=0; i < num_dst_buffers; i++) {
-+            unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+            unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
-+            printk("Buffer %d\n", i);
-+            while (ptr < end) {
-+                int j=0;
-+                for (; j < 8; j++) {
-+                    printk("0x%08lx ", *ptr++);
-+                }
-+                printk("\n");
-+            }
-+        }
-+    #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+    
-+        // Free the memory for the source buffers
-+        for (i=0; i < num_src_buffers; i++) {
-+            // Check that unique allocation made for this entry
-+            if (src_scatterlist[i].__address) {
-+                printk("Freeing source SG entry buffer, adr = 0x%08x, len = 0x%08x\n", src_scatterlist[i].offset, (u32)src_scatterlist[i].__address);            
-+                kfree((void*)src_scatterlist[i].offset);
-+            }
-+        }
-+    
-+        // Free the memory for the source scatterlist
-+        if (src_scatterlist) {
-+            printk("Freeing source SG scatter list structure\n");
-+            kfree(src_scatterlist);
-+        }
-+    
-+        // Free the memory for the destination buffers
-+        for (i=0; i < num_dst_buffers; i++) {
-+            if (dst_scatterlist[i].__address) {
-+                printk("Freeing destination SG entry, adr = 0x%08x, len = 0x%08x\n", dst_scatterlist[i].offset, (u32)dst_scatterlist[i].__address);            
-+                kfree((void*)dst_scatterlist[i].offset);
-+            }
-+        }
-+    
-+        // Free the memory for the destination scatterlist
-+        if (dst_scatterlist) {
-+            printk("Freeing source SG scatter list structure\n");
-+            kfree(dst_scatterlist);
-+        }
-+    }
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        oxnas_dma_free(channels[i]);
-+    }
-+}
-+#endif // OXNAS_DMA_SG_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST_2
-+static void dma_sg_test2()
-+{
-+    /** Include initial 2 bytes of pad that real network buffers would contain
-+        in order to ensure that IP header and TCP/UDP header are quad aligned */
-+    static const unsigned char bad_src_data0[] = {
-+        0xff, 0xff, 0x00, 0xa0, 0xd2, 0x05, 0x06, 0xec, 0x00, 0xcf, 0x52, 0x49, 0xc3, 0x03, 0x08, 0x00,
-+        0x45, 0x00, 0x05, 0xb4, 0x99, 0x45, 0x40, 0x00, 0x40, 0x06, 0x42, 0xf5, 0xac, 0x1f, 0x00, 0x65,
-+        0xac, 0x1f, 0x00, 0x66
-+    };
-+
-+    static const unsigned char bad_src_data1[] = {
-+        0x04, 0x00, 0x13, 0x89, 0x02, 0x8a, 0x5c, 0x83, 0x52, 0xde, 0xc7, 0x0c, 0x80, 0x19, 0x0b, 0x68,
-+        0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xff, 0xff, 0xb3, 0x9d, 0x3f, 0x82, 0xf0, 0xff,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+        0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+        0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31
-+    };
-+    
-+    /** Include initial 2 bytes of pad that real network buffers would contain
-+        in order to ensure that IP header and TCP/UDP header are quad aligned */
-+    static const unsigned char good_src_data0[] = {
-+        0xff, 0xff, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5
-+    };
-+
-+    static const unsigned char good_src_data1[] = {
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+        0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
-+    };
-+
-+    static const int src_offset = 2;    // To jump IP quad align padding
-+    static const int dst_buffer_size = 512;
-+
-+    const unsigned char *src_data0 = bad_src_data0;
-+    const unsigned char *src_data1 = bad_src_data1;
-+    unsigned long src_data0_len = sizeof(bad_src_data0);
-+    unsigned long src_data1_len = sizeof(bad_src_data1);
-+    int channel_number;
-+    oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+    int i;
-+
-+//    const unsigned char *src_data0 = good_src_data0;
-+//    const unsigned char *src_data1 = good_src_data1;
-+//    unsigned long src_data0_len = sizeof(good_src_data0);
-+//    unsigned long src_data1_len = sizeof(good_src_data1);
-+
-+    printk("*************************************************************\n");
-+    printk("                                                               \n");
-+    printk("Scatter-Gather DMA Test 2\n");
-+    printk("                                                               \n");
-+    printk("*************************************************************\n");
-+
-+    printk("seg0 0x%08x, %lu\n", (u32)src_data0, src_data0_len);
-+    printk("seg1 0x%08x, %lu\n", (u32)src_data1, src_data1_len);
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        channels[i] = oxnas_dma_request(0);
-+        if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+            printk("No DMA channels[%d] obtained\n", i);
-+        } else {
-+            printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+        }
-+    }
-+
-+    // Test each available DMA channel
-+    for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
-+    
-+        struct scatterlist* src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL);
-+    
-+        unsigned long total_src_length = src_data0_len + src_data1_len;
-+        src_scatterlist[0].offset = (unsigned int)kmalloc(total_src_length,  GFP_KERNEL | GFP_DMA) + src_offset;
-+        src_scatterlist[0].length = src_data0_len - src_offset;
-+        memcpy((u8*)src_scatterlist[0].offset, src_data0, src_scatterlist[0].length);
-+    
-+        src_scatterlist[1].offset = src_scatterlist[0].offset + src_scatterlist[0].length;
-+        src_scatterlist[1].length = src_data1_len;
-+        memcpy((u8*)src_scatterlist[1].offset, src_data1, src_scatterlist[1].length);
-+    
-+        unsigned long total_dst_length = total_src_length - src_offset;  // Excludes initial IP quad alignment pad
-+        unsigned num_dst_buffers = total_dst_length / dst_buffer_size;
-+        if ((num_dst_buffers * dst_buffer_size) < total_dst_length) {
-+            ++num_dst_buffers;
-+        }
-+        printk("total_src_length = %lu, src_offset = %u, total_dst_length = %lu, dst_buffer_size = %u, num_dst_buffers = %u\n", total_src_length, src_offset, total_dst_length, dst_buffer_size, num_dst_buffers);
-+        struct scatterlist* dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
-+    
-+        int i;
-+        unsigned long remainder = total_dst_length;
-+        for (i=0; i < num_dst_buffers; ++i) {
-+            dst_scatterlist[i].offset = (unsigned int)kmalloc(dst_buffer_size,  GFP_KERNEL | GFP_DMA);
-+            dst_scatterlist[i].length = (remainder < dst_buffer_size) ? remainder : dst_buffer_size;
-+            remainder -= dst_scatterlist[i].length;
-+        }
-+    
-+        int j;
-+        for (j=0; j < OXNAS_DMA_SG_TEST2_ITERATIONS; ++j) {
-+            src_scatterlist[0].dma_address = dma_map_single(0, (void*)src_scatterlist[0].offset, src_scatterlist[0].length, DMA_TO_DEVICE);
-+            if (dma_mapping_error(src_scatterlist[0].dma_address)) {
-+                printk("Consistent source DMA mapping 0 failed\n");
-+            }
-+    // Set the checksum enabling high order address bit
-+    //src_scatterlist[0].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+    
-+            src_scatterlist[1].dma_address = dma_map_single(0, (void*)src_scatterlist[1].offset, src_scatterlist[1].length, DMA_TO_DEVICE);
-+            if (dma_mapping_error(src_scatterlist[1].dma_address)) {
-+                printk("Consistent source DMA mapping 1 failed\n");
-+            }
-+            // Set the checksum enabling high order address bit
-+            src_scatterlist[1].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+    
-+            printk("num_dst_buffers = %u\n", num_dst_buffers);
-+            for (i=0; i < num_dst_buffers; i++) {
-+                memset((void*)dst_scatterlist[i].offset, 0, dst_scatterlist[i].length);
-+    
-+                dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+                if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
-+                    printk("Consistent destination DMA mapping %d failed\n", i);
-+                }
-+            }
-+    
-+            // Setup up SG DMA transfer
-+            printk("Setting up transfer\n");
-+            oxnas_dma_set_sg(
-+                channels[channel_number],
-+                src_scatterlist,
-+                2,
-+                dst_scatterlist,
-+                num_dst_buffers,
-+                OXNAS_DMA_MODE_INC,
-+                OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+                1); // Compute checksum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+                0);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+            // Using second DMA channel requested
-+            oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+            // Start the transfer
-+            printk("Starting the transfer\n");
-+            oxnas_dma_start(channels[channel_number]);
-+    
-+            // Sleep until transfer completed
-+            printk("Waiting for transfer to complete...\n");
-+            while (down_interruptible(&callback_semaphore));
-+            oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+            printk("Error code = %u\n", channels[channel_number]->error_code_);
-+    
-+            // Release the consistent DMA mappings for the source buffers
-+            for (i=0; i < 2; i++) {
-+                // Ensure the checksum enabling high order address bit is not set, as
-+                // this would confuse the DMA mapping release function
-+                src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+                dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
-+            }
-+    
-+            // Release the consistent DMA mappings for the destination buffers
-+            for (i=0; i < num_dst_buffers; i++) {
-+                printk("Releasing DMA mappings for destination entry buffer %u\n", i);
-+                dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+            }
-+    
-+            u32 sw_csum = 0;
-+    //sw_csum = csum_partial((u8*)src_scatterlist[0].offset, src_scatterlist[0].length, 0);
-+            sw_csum = csum_partial((u8*)src_scatterlist[1].offset, src_scatterlist[1].length, sw_csum);
-+            printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
-+    
-+            sw_csum = 0;
-+            unsigned offset = src_scatterlist[0].length;
-+    //unsigned offset = 0;
-+            for (i=0; i < num_dst_buffers; i++) {
-+                sw_csum = csum_partial((u8*)dst_scatterlist[i].offset + offset, dst_scatterlist[i].length - offset, sw_csum);
-+                offset = 0;
-+            }
-+            printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
-+        }
-+    
-+        for (i=0; i < num_dst_buffers; ++i) {
-+            kfree((void*)dst_scatterlist[i].offset);
-+        }
-+        kfree(dst_scatterlist);
-+    
-+        kfree((void*)(src_scatterlist[0].offset - src_offset));
-+        kfree(src_scatterlist);
-+    }
-+
-+    for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+        oxnas_dma_free(channels[i]);
-+    }
-+}
-+#endif // OXNAS_DMA_SG_TEST_2
-+#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+
-+EXPORT_SYMBOL(oxnas_dma_request);
-+EXPORT_SYMBOL(oxnas_dma_free);
-+EXPORT_SYMBOL(oxnas_dma_set_callback);
-+EXPORT_SYMBOL(oxnas_dma_set_common);
-+EXPORT_SYMBOL(oxnas_dma_is_active);
-+EXPORT_SYMBOL(oxnas_dma_raw_isactive);
-+EXPORT_SYMBOL(oxnas_dma_set);
-+EXPORT_SYMBOL(oxnas_dma_device_set);
-+EXPORT_SYMBOL(oxnas_dma_abort);
-+EXPORT_SYMBOL(oxnas_dma_dump_registers);
-+EXPORT_SYMBOL(oxnas_dma_dump_registers_single);
-+EXPORT_SYMBOL(oxnas_dma_start);
-+
-+EXPORT_SYMBOL(oxnas_pata_dma_settings);
-+EXPORT_SYMBOL(oxnas_sata_dma_settings);
-+EXPORT_SYMBOL(oxnas_dpe_rx_dma_settings);
-+EXPORT_SYMBOL(oxnas_dpe_tx_dma_settings);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c
---- linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3051 @@
-+/*
-+ * /arch/=arm/mach-oxnas/dpe-test.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+ 
-+/** 
-+ * Test driver for the cipher core
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/fs.h>
-+#include <asm/arch/cipher.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/dma-mapping.h>
-+#include <asm/arch/dma.h>
-+
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+#define DRIVER_AUTHOR "Oxford Semiconductor Inc."
-+#define DRIVER_DESC   "Cipher block testing"
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+// uses /dev/dv940led
-+#define DEVICE_NAME "ox800dpetst"
-+MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
-+
-+#define FAILED(reason) {printk(KERN_ERR"%s failed %s\n",__FUNCTION__,reason);++failed;}
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+#if 0
-+static u32 READL(int a) {u32 v = readl(a);printk("0x%08x <- [0x%08x]\n",v,a);return v;}
-+static void WRITEL(int v,int a){printk("0x%08x -> [0x%08x]\n",v,a);writel(v,a);}
-+#else
-+static u32 READL(int a) {u32 v = readl(a);return v;}
-+static void WRITEL(int v,int a){writel(v,a);}
-+#endif
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef int (ox800dpe_test_t)(void) ;
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox800dpe"
-+**************************************************************************/
-+
-+/*************************************************************************/
-+static int test1(void) {
-+    int failed = 0;
-+    u32 reg;
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // 1st data set 
-+    WRITEL(be32_to_cpu( 0x00112233), OX800DPE_DATA_IN0 );
-+
-+    /* in fifo no longer empty */
-+    reg = READL( OX800DPE_STATUS );
-+    if ( (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo still empty after data input")
-+    
-+    WRITEL(be32_to_cpu( 0x44556677), OX800DPE_DATA_IN1 );
-+    WRITEL(be32_to_cpu( 0x8899aabb), OX800DPE_DATA_IN2 );
-+
-+    // shouldn't be busy as not enough data
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("core lept into action before putting in all the data");
-+    
-+    WRITEL(be32_to_cpu( 0xccddeeff), OX800DPE_DATA_IN3 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be full */
-+    if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still empty after encrypting data ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    /* check output */
-+    {
-+        u32 data[4];
-+
-+        data[0] = READL( OX800DPE_DATA_OUT0 );
-+        data[1] = READL( OX800DPE_DATA_OUT1 );
-+        data[2] = READL( OX800DPE_DATA_OUT2 );
-+        data[3] = READL( OX800DPE_DATA_OUT3 );
-+
-+        if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
-+            (data[1] != cpu_to_be32(0x6a7b0430)) ||
-+            (data[2] != cpu_to_be32(0xd8cdb780)) ||
-+            (data[3] != cpu_to_be32(0x70b4c55a)))
-+        {
-+            FAILED("encryption output incorrect");
-+            printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+        }
-+    }
-+        
-+    /* output should be empty again */
-+    reg = READL( OX800DPE_STATUS );
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after data read");
-+    
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test2(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x00112233);
-+    data_in[1] = be32_to_cpu( 0x44556677);
-+    data_in[2] = be32_to_cpu( 0x8899aabb);
-+    data_in[3] = be32_to_cpu( 0xccddeeff);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
-+        (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
-+        (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
-+        (data_out[3] != cpu_to_be32(0x70b4c55a)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test3(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+    data_in[1] = be32_to_cpu( 0x6a7b0430);
-+    data_in[2] = be32_to_cpu( 0xd8cdb780);
-+    data_in[3] = be32_to_cpu( 0x70b4c55a);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg =  OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+        (data_out[1] != cpu_to_be32(0x44556677)) ||
-+        (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+        (data_out[3] != cpu_to_be32(0xccddeeff)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+    
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test4(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t out_address;
-+    
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with non expected output
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_PRIMARY_IS_KEY3 | OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    
-+    // 1st data set 
-+    WRITEL(be32_to_cpu( 0x69c4e0d8), OX800DPE_DATA_IN0 );
-+    WRITEL(be32_to_cpu( 0x6a7b0430), OX800DPE_DATA_IN1 );
-+    WRITEL(be32_to_cpu( 0xd8cdb780), OX800DPE_DATA_IN2 );
-+    WRITEL(be32_to_cpu( 0x70b4c55a), OX800DPE_DATA_IN3 );
-+
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+        (data_out[1] != cpu_to_be32(0x44556677)) ||
-+        (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+        (data_out[3] != cpu_to_be32(0xccddeeff)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_out ); 
-+    kfree(data_out);
-+    
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test5(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    dma_addr_t in_address;
-+    
-+    u32* data_in;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x00112233);
-+    data_in[1] = be32_to_cpu( 0x44556677);
-+    data_in[2] = be32_to_cpu( 0x8899aabb);
-+    data_in[3] = be32_to_cpu( 0xccddeeff);
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_ECB_AES  |
-+          OX800DPE_CTL_PRIMARY_IS_KEY3 ;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_in ) );
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be full */
-+    if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still empty after encrypting data ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+
-+    /* check output */
-+    {
-+        u32 data[4];
-+
-+        data[0] = READL( OX800DPE_DATA_OUT0 );
-+        data[1] = READL( OX800DPE_DATA_OUT1 );
-+        data[2] = READL( OX800DPE_DATA_OUT2 );
-+        data[3] = READL( OX800DPE_DATA_OUT3 );
-+
-+        if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
-+            (data[1] != cpu_to_be32(0x6a7b0430)) ||
-+            (data[2] != cpu_to_be32(0xd8cdb780)) ||
-+            (data[3] != cpu_to_be32(0x70b4c55a)))
-+        {
-+            FAILED("encryption output incorrect");
-+            printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+        }
-+    }
-+        
-+    /* output should be empty again */
-+    reg = READL( OX800DPE_STATUS );
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after data read");
-+    
-+    // free dmas
-+    kfree(data_in);
-+
-+    oxnas_dma_free( dma_in ); 
-+    
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test6(void) {
-+    int failed = 0;
-+    u32 reg;
-+
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for key encryption
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_ENCRYPT_KEY |
-+          OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+
-+    // data to be encrypted to form a key    
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    /* output should be empty */
-+    reg = READL( OX800DPE_STATUS );
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    {
-+        u32 data[4];
-+
-+        data[0] = READL( OX800DPE_KEY00 );
-+        data[1] = READL( OX800DPE_KEY01 );
-+        data[2] = READL( OX800DPE_KEY02 );
-+        data[3] = READL( OX800DPE_KEY03 );
-+        
-+        if ((data[0] != cpu_to_be32(0x4791b833)) ||
-+            (data[1] != cpu_to_be32(0x7e2d8a69)) ||
-+            (data[2] != cpu_to_be32(0x290233f1)) ||
-+            (data[3] != cpu_to_be32(0xf3dff5a9)))
-+        {
-+            FAILED("encrypted key incorrect");
-+            printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+        }
-+    }
-+        
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test7(void) {
-+    int failed = 0;
-+    u32 reg;
-+
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // setup for key encryption
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_ENCRYPT_KEY |
-+          OX800DPE_CTL_MODE_ECB_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+
-+    // data to be encrypted to form a key    
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    /* output should be empty */
-+    reg = READL( OX800DPE_STATUS );
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    {
-+        u32 data[4];
-+
-+        data[0] = READL( OX800DPE_KEY00 );
-+        data[1] = READL( OX800DPE_KEY01 );
-+        data[2] = READL( OX800DPE_KEY02 );
-+        data[3] = READL( OX800DPE_KEY03 );
-+        
-+        if ((data[0] != cpu_to_be32(0x4791b833)) ||
-+            (data[1] != cpu_to_be32(0x7e2d8a69)) ||
-+            (data[2] != cpu_to_be32(0x290233f1)) ||
-+            (data[3] != cpu_to_be32(0xf3dff5a9)))
-+        {
-+            FAILED("encrypted key incorrect");
-+            printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+        }
-+    }
-+        
-+    return failed;
-+
-+}
-+
-+
-+
-+/**********************************************************************/
-+/* CBC tests                                                          */
-+/**********************************************************************/
-+
-+static int test8(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x00112233);
-+    data_in[1] = be32_to_cpu( 0x44556677);
-+    data_in[2] = be32_to_cpu( 0x8899aabb);
-+    data_in[3] = be32_to_cpu( 0xccddeeff);
-+    data_in[4] = be32_to_cpu( 0x00112233);
-+    data_in[5] = be32_to_cpu( 0x44556677);
-+    data_in[6] = be32_to_cpu( 0x8899aabb);
-+    data_in[7] = be32_to_cpu( 0xccddeeff);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    data_out[4] = ~0;
-+    data_out[5] = ~0;
-+    data_out[6] = ~0;
-+    data_out[7] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        8 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        8 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
-+        (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
-+        (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
-+        (data_out[3] != cpu_to_be32(0x70b4c55a)) ||
-+
-+        (data_out[4] != cpu_to_be32(0x7d7786be)) ||
-+        (data_out[5] != cpu_to_be32(0x32d059a6)) ||
-+        (data_out[6] != cpu_to_be32(0x0ca8021a)) ||
-+        (data_out[7] != cpu_to_be32(0x65dd9f09)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+        printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test9(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+    data_in[1] = be32_to_cpu( 0x6a7b0430);
-+    data_in[2] = be32_to_cpu( 0xd8cdb780);
-+    data_in[3] = be32_to_cpu( 0x70b4c55a);                              
-+    data_in[4] = be32_to_cpu( 0x7d7786be);
-+    data_in[5] = be32_to_cpu( 0x32d059a6);
-+    data_in[6] = be32_to_cpu( 0x0ca8021a);
-+    data_in[7] = be32_to_cpu( 0x65dd9f09);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    data_out[4] = ~0;
-+    data_out[5] = ~0;
-+    data_out[6] = ~0;
-+    data_out[7] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        8 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        8 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+        (data_out[1] != cpu_to_be32(0x44556677)) ||
-+        (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+        (data_out[3] != cpu_to_be32(0xccddeeff)) ||
-+        (data_out[4] != cpu_to_be32(0x00112233)) ||
-+        (data_out[5] != cpu_to_be32(0x44556677)) ||
-+        (data_out[6] != cpu_to_be32(0x8899aabb)) ||
-+        (data_out[7] != cpu_to_be32(0xccddeeff)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+        printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test10(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x00112233);
-+    data_in[1] = be32_to_cpu( 0x44556677);
-+    data_in[2] = be32_to_cpu( 0x8899aabb);
-+    data_in[3] = be32_to_cpu( 0xccddeeff);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x0bde5b88)) ||
-+        (data_out[1] != cpu_to_be32(0x114ac430)) ||
-+        (data_out[2] != cpu_to_be32(0x134e99ee)) ||
-+        (data_out[3] != cpu_to_be32(0xd3557046)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test11(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+    data_in[1] = be32_to_cpu( 0x6a7b0430);
-+    data_in[2] = be32_to_cpu( 0xd8cdb780);
-+    data_in[3] = be32_to_cpu( 0x70b4c55a);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+        (data_out[1] != cpu_to_be32(0x44556677)) ||
-+        (data_out[2] != cpu_to_be32(0x8899aab4)) ||
-+        (data_out[3] != cpu_to_be32(0x33221100)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test12(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x00112233);
-+    data_in[1] = be32_to_cpu( 0x44556677);
-+    data_in[2] = be32_to_cpu( 0x8899aabb);
-+    data_in[3] = be32_to_cpu( 0xccddeeff);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    
-+    
-+    
-+    
-+    /* check output */
-+    if ((data_out[0] != 0x850d2506) ||
-+        (data_out[1] != 0xd71056c7) ||
-+        (data_out[2] != 0xe62c220f) ||
-+        (data_out[3] != 0xc3dedaf9))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test13(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = 0x850d2506;
-+    data_in[1] = 0xd71056c7;
-+    data_in[2] = 0xe62c220f;
-+    data_in[3] = 0xc3dedaf9;
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_CBC_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    reg = READL( OX800DPE_STATUS );
-+    // shouldn't be busy
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle even with incomplete data");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx not empty before data input ");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx fifo filling without data");
-+    
-+    
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // setup initialisation vector
-+    WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
-+    WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+        (data_out[1] != cpu_to_be32(0x44556677)) ||
-+        (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+        (data_out[3] != cpu_to_be32(0xccddeeff)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/**********************************************************************/
-+/* LRW tests                                                          */
-+/**********************************************************************/
-+
-+static int test14(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x30313233);
-+    data_in[1] = be32_to_cpu( 0x34353637);
-+    data_in[2] = be32_to_cpu( 0x38394142);
-+    data_in[3] = be32_to_cpu( 0x43444546);
-+    data_in[4] = be32_to_cpu( 0x30313233);
-+    data_in[5] = be32_to_cpu( 0x34353637);
-+    data_in[6] = be32_to_cpu( 0x38394142);
-+    data_in[7] = be32_to_cpu( 0x43444546);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    data_out[4] = ~0;
-+    data_out[5] = ~0;
-+    data_out[6] = ~0;
-+    data_out[7] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        8 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        8 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_LRW_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+
-+    // setup index
-+    WRITEL(0, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /*
-+    check output.
-+    note: first 4 quads contain unwanted data used to set
-+    tweek location to 1, they are not checked.
-+    */
-+    if ((data_out[4] != cpu_to_be32(0xf1b273cd)) ||
-+        (data_out[5] != cpu_to_be32(0x65a3df5f)) ||
-+        (data_out[6] != cpu_to_be32(0xe95d4892)) ||
-+        (data_out[7] != cpu_to_be32(0x54634eb8)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+        printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test15(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0xf1b273cd);
-+    data_in[1] = be32_to_cpu( 0x65a3df5f);
-+    data_in[2] = be32_to_cpu( 0xe95d4892);
-+    data_in[3] = be32_to_cpu( 0x54634eb8);                              
-+    data_in[4] = be32_to_cpu( 0xf1b273cd);
-+    data_in[5] = be32_to_cpu( 0x65a3df5f);
-+    data_in[6] = be32_to_cpu( 0xe95d4892);
-+    data_in[7] = be32_to_cpu( 0x54634eb8);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    data_out[4] = ~0;
-+    data_out[5] = ~0;
-+    data_out[6] = ~0;
-+    data_out[7] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        8 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        8 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        8 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_LRW_AES |
-+          OX800DPE_CTL_PRIMARY_IS_KEY3;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY20 );
-+    WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY21 );
-+    WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY22 );
-+    WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY23 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+    
-+    // setup index
-+    WRITEL(0, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[4] != cpu_to_be32(0x30313233)) ||
-+        (data_out[5] != cpu_to_be32(0x34353637)) ||
-+        (data_out[6] != cpu_to_be32(0x38394142)) ||
-+        (data_out[7] != cpu_to_be32(0x43444546)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+        printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test16(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[8 ] = be32_to_cpu( 0x30313233);
-+    data_in[9 ] = be32_to_cpu( 0x34353637);
-+    data_in[10] = be32_to_cpu( 0x38394142);
-+    data_in[11] = be32_to_cpu( 0x43444546);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    data_out[4] = ~0;
-+    data_out[5] = ~0;
-+    data_out[6] = ~0;
-+    data_out[7] = ~0;
-+    data_out[8] = ~0;
-+    data_out[9] = ~0;
-+    data_out[10] = ~0;
-+    data_out[11] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        12 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        12 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        12 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        12 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_PRIMARY_IS_KEY3 |
-+          OX800DPE_CTL_MODE_LRW_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY20 );
-+    WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY21 );
-+    WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY22 );
-+    WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY23 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
-+
-+    // setup index
-+    WRITEL(0, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /*
-+    check output.
-+    note: first 4 quads contain unwanted data used to set
-+    tweek location to 1, they are not checked.
-+    */
-+    if ((data_out[ 8] != cpu_to_be32(0x00c82bae)) ||
-+        (data_out[ 9] != cpu_to_be32(0x95bbcde5)) ||
-+        (data_out[10] != cpu_to_be32(0x274f0769)) ||
-+        (data_out[11] != cpu_to_be32(0xb260e136)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test17(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[ 8] = be32_to_cpu( 0x00c82bae);
-+    data_in[ 9] = be32_to_cpu( 0x95bbcde5);
-+    data_in[10] = be32_to_cpu( 0x274f0769);
-+    data_in[11] = be32_to_cpu( 0xb260e136);
-+    data_out[ 0] = ~0;
-+    data_out[ 1] = ~0;
-+    data_out[ 2] = ~0;
-+    data_out[ 3] = ~0;
-+    data_out[ 4] = ~0;
-+    data_out[ 5] = ~0;
-+    data_out[ 6] = ~0;
-+    data_out[ 7] = ~0;
-+    data_out[ 8] = ~0;
-+    data_out[ 9] = ~0;
-+    data_out[10] = ~0;
-+    data_out[11] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        12 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        12 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        12 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        12 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_LRW_AES ;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY03 );
-+                        
-+    // key no 2         
-+    WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
-+    
-+    // setup index
-+    WRITEL(0, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[ 8] != cpu_to_be32(0x30313233)) ||
-+        (data_out[ 9] != cpu_to_be32(0x34353637)) ||
-+        (data_out[10] != cpu_to_be32(0x38394142)) ||
-+        (data_out[11] != cpu_to_be32(0x43444546)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test18(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x30313233);
-+    data_in[1] = be32_to_cpu( 0x34353637);
-+    data_in[2] = be32_to_cpu( 0x38394142);
-+    data_in[3] = be32_to_cpu( 0x43444546);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_LRW_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+
-+    // setup index
-+    WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /*
-+    check output.
-+    */
-+    if ((data_out[0] != cpu_to_be32(0x76322183)) ||
-+        (data_out[1] != cpu_to_be32(0xed8ff182)) ||
-+        (data_out[2] != cpu_to_be32(0xf9596203)) ||
-+        (data_out[3] != cpu_to_be32(0x690e5e01)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test19(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x76322183);
-+    data_in[1] = be32_to_cpu( 0xed8ff182);
-+    data_in[2] = be32_to_cpu( 0xf9596203);
-+    data_in[3] = be32_to_cpu( 0x690e5e01);                              
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_MODE_LRW_AES |
-+          OX800DPE_CTL_PRIMARY_IS_KEY3;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY20 );
-+    WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY21 );
-+    WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY22 );
-+    WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY23 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+    
-+    // setup index
-+    WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
-+    WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[0] != cpu_to_be32(0x30313233)) ||
-+        (data_out[1] != cpu_to_be32(0x34353637)) ||
-+        (data_out[2] != cpu_to_be32(0x38394142)) ||
-+        (data_out[3] != cpu_to_be32(0x43444546)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test20(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory
-+    data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[0] = be32_to_cpu( 0x30313233);
-+    data_in[1] = be32_to_cpu( 0x34353637);
-+    data_in[2] = be32_to_cpu( 0x38394142);
-+    data_in[3] = be32_to_cpu( 0x43444546);
-+    data_out[0] = ~0;
-+    data_out[1] = ~0;
-+    data_out[2] = ~0;
-+    data_out[3] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        4 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        4 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        4 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // don't authenticate
-+    WRITEL(0 ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for encryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_LRW_AES;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+
-+    // setup index
-+    WRITEL(0x00000000, OX800DPE_DATA_LRW0 );
-+    WRITEL(0x00000008, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until dma done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /*
-+    check output.
-+    */
-+    if ((data_out[0] == 0xc0a37fda) )
-+    {
-+        FAILED("encryption output indicates most significant bit is ignored.");
-+        printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test21(void) {
-+    int failed = 0;
-+    u32 reg;
-+    oxnas_dma_channel_t* dma_in;
-+    oxnas_dma_channel_t* dma_out;
-+    dma_addr_t in_address;
-+    dma_addr_t out_address;
-+    
-+    u32* data_in;
-+    u32* data_out;
-+    
-+    // setup dmas
-+    dma_in = oxnas_dma_request(1);
-+    dma_out = oxnas_dma_request(1);
-+    
-+    // get some dma accessable memory (512B + 16B
-+    data_in = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    data_out = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+    
-+    // fill with input and non expected output
-+    data_in[128] = be32_to_cpu( 0x30313233);
-+    data_in[129] = be32_to_cpu( 0x34353637);
-+    data_in[130] = be32_to_cpu( 0x38394142);
-+    data_in[131] = be32_to_cpu( 0x43444546);                              
-+    data_out[128] = ~0;
-+    data_out[129] = ~0;
-+    data_out[130] = ~0;
-+    data_out[131] = ~0;
-+    
-+    // map the dma regons
-+    in_address = dma_map_single(
-+        0,
-+        data_in,
-+        132 * sizeof(u32),
-+        DMA_TO_DEVICE);
-+        
-+    // map the dma regons
-+    out_address = dma_map_single(
-+        0,
-+        data_out,
-+        132 * sizeof(u32),
-+        DMA_FROM_DEVICE);
-+        
-+    // setup the transfers
-+    oxnas_dma_device_set(
-+        dma_in,
-+        OXNAS_DMA_TO_DEVICE,
-+        (char*)in_address,
-+        132 * sizeof(u32),
-+        &oxnas_dpe_rx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+        
-+    oxnas_dma_device_set(
-+        dma_out,
-+        OXNAS_DMA_FROM_DEVICE,
-+        (char*)out_address,
-+        132 * sizeof(u32),
-+        &oxnas_dpe_tx_dma_settings,
-+        OXNAS_DMA_MODE_INC, 1);
-+
-+    // authenticate
-+    WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+    
-+    // toggle cleardown bit to start
-+    WRITEL(OX800DPE_CTL_ABORT  ,OX800DPE_CONTROL);
-+    WRITEL(0                   ,OX800DPE_CONTROL);
-+    
-+    // shouldn't be busy or full
-+    reg = READL( OX800DPE_STATUS );
-+    if (! (reg & OX800DPE_STAT_IDLE) )
-+        FAILED("not idle after abort toggle");
-+    if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+        FAILED("tx fifo not empty after abort toggle");
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx not empty after abort toggle");
-+    
-+    // setup for decryption 
-+    reg = OX800DPE_CTL_DIRECTION_ENC |
-+          OX800DPE_CTL_MODE_LRW_AES ;
-+    WRITEL(reg  ,OX800DPE_CONTROL);
-+
-+    // key no 1
-+    WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
-+    WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
-+    WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
-+    WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
-+    
-+    // key no 2
-+    WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+    WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+    WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+    WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+
-+    // setup index
-+    WRITEL(0x0fffffff, OX800DPE_DATA_LRW0 );
-+    WRITEL(0x00000000, OX800DPE_DATA_LRW1 );
-+
-+    /* wait until done */
-+    while(  !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+    
-+    // start dma transfers
-+    oxnas_dma_start(dma_out);
-+    oxnas_dma_start(dma_in);
-+    
-+    /* wait until done */
-+    while(  oxnas_dma_is_active( dma_out ) );
-+    
-+    reg = READL( OX800DPE_STATUS );
-+
-+    /* output should be empty */
-+    if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+        FAILED("tx still full after fetching ");
-+
-+    /* in empty */
-+    if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+        FAILED("rx still full after encrypting data ");
-+    
-+    dma_unmap_single(0, in_address, 132 * sizeof(u32), DMA_TO_DEVICE);
-+    dma_unmap_single(0, out_address, 132 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+    /* check output */
-+    if ((data_out[128] != cpu_to_be32(0x76322183)) ||
-+        (data_out[129] != cpu_to_be32(0xed8ff182)) ||
-+        (data_out[130] != cpu_to_be32(0xf9596203)) ||
-+        (data_out[131] != cpu_to_be32(0x690e5e01)))
-+    {
-+        FAILED("encryption output incorrect");
-+        printk("%08x%08x%08x%08x\n",data_out[128],data_out[129],data_out[130],data_out[131]);
-+    }
-+        
-+    // free dmas
-+    oxnas_dma_free( dma_in ); 
-+    oxnas_dma_free( dma_out ); 
-+    
-+    kfree(data_in);
-+    kfree(data_out);
-+
-+    return failed;
-+
-+}
-+
-+
-+/*****************************************************************************/
-+#define NOCIPHERTESTS 21
-+static ox800dpe_test_t*  tests[NOCIPHERTESTS] = {
-+    /* ordinary AES tests */
-+    test1,
-+    test2,
-+    test3,
-+    test4,
-+    test5,
-+    test6,
-+    test7,
-+    
-+    /* CBC AES tests */
-+    test8,
-+    test9,
-+    test10,
-+    test11,
-+    test12,
-+    test13,
-+    
-+    /* LRW AES tests */
-+    test14,
-+    test15,
-+    test16,
-+    test17,
-+    test18,
-+    test19,
-+    test20,
-+    test21
-+    
-+} ;
-+
-+ 
-+static int __init ox800dpe_init(void)
-+{
-+    int i;
-+    int result;
-+    printk("*******************************************************************\n");
-+    printk("* CIPHER CORE TESTING START                                       *\n");
-+    printk("*******************************************************************\n");
-+    
-+        /* Enable the clock to the DPE block */
-+        writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+    
-+        /* Bring out of reset */
-+        writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+        
-+    
-+    
-+    
-+    for (i = 0; i < NOCIPHERTESTS; ++i)
-+    {
-+        printk("\nTest %d start\n",i+1);
-+        result = (tests[i])();
-+        if (result)
-+            printk("Test %d failed with %d faults.\n",i+1,result);
-+        else
-+            printk("Test %d passed\n",i+1);
-+            
-+    }
-+    
-+    printk("*******************************************************************\n");
-+    printk("* CIPHER CORE TESTING END                                         *\n");
-+    printk("*******************************************************************\n");
-+
-+	return 0;
-+}
-+
-+
-+
-+/***************************************************************************/
-+module_init(ox800dpe_init);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3637 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/crc32.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/delay.h>
-+#include <linux/in.h>
-+#include <net/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/udp.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/irqs.h>
-+
-+#ifdef CONFIG_LEON_COPRO
-+#include <asm/arch/leon-program.h>
-+#endif // CONFIG_LEON_COPRO
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_ethtool.h"
-+#include "gmac_phy.h"
-+#include "gmac_desc.h"
-+#include "gmac_reg.h"
-+
-+//#define DUMP_REGS_ON_GMAC_UP
-+
-+#define MAX_GMAC_UNITS 1
-+
-+#define ALLOW_AUTONEG
-+
-+//#define ALLOW_OX800_1000M
-+
-+//#define SUPPORT_IPV6
-+
-+#ifdef CONFIG_LEON_COPRO
-+//#define TEST_COPRO
-+#define COPRO_RX_MITIGATION 0   /* No Rx mitigation in CoPro */
-+#define COPRO_RX_MITIGATION_FRAMES 5
-+#define COPRO_RX_MITIGATION_USECS 500
-+
-+#define COPRO_TX_QUEUE_NUM_ENTRIES  4
-+#define COPRO_CMD_QUEUE_NUM_ENTRIES 6
-+#define COPRO_MAX_QUEUED_TX_SKBS    16
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_OFFLOAD_TX
-+#define NUM_RX_DMA_DESCRIPTORS  NUM_GMAC_DMA_DESCRIPTORS
-+#define NUM_TX_DMA_DESCRIPTORS  0
-+#else
-+#define NUM_RX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS / 2)
-+#define NUM_TX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS - NUM_RX_DMA_DESCRIPTORS)
-+#endif // CONFIG_LEON_OFFLOAD_TX
-+
-+#if (((NUM_RX_DMA_DESCRIPTORS) + (NUM_TX_DMA_DESCRIPTORS)) > (NUM_GMAC_DMA_DESCRIPTORS))
-+#error "GMAC TX+RX descriptors exceed allocation"
-+#endif
-+
-+#define DESC_SINCE_REFILL_LIMIT ((NUM_RX_DMA_DESCRIPTORS) / 4)
-+
-+static const u32 MAC_BASE_OFFSET = 0x0000;
-+static const u32 DMA_BASE_OFFSET = 0x1000;
-+
-+static const int MIN_PACKET_SIZE = 68;
-+static const int NORMAL_PACKET_SIZE = 1500;
-+static const int MAX_JUMBO = 9000;
-+
-+#define RX_BUFFER_SIZE 796	// Must be multiple of 4, If not defined will size buffer to hold a single MTU-sized packet
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+static const int EXTRA_RX_SKB_SPACE = 24;	// Has extra 2 bytes of Rx payload csum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+static const int EXTRA_RX_SKB_SPACE = 22;	// Ethernet header 14, VLAN 4, CRC 4
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+// The amount of header to copy from a receive packet into the skb buffer
-+static const int GMAC_HLEN = 66;
-+
-+#define GMAC_ALLOC_ORDER 0
-+static const int GMAC_ALLOC_SIZE = ((1 << GMAC_ALLOC_ORDER) * PAGE_SIZE);
-+
-+static const u32 AUTO_NEGOTIATION_WAIT_TIMEOUT_MS = 5000;
-+
-+static const u32 NAPI_POLL_WEIGHT = 64;
-+static const u32 NAPI_OOM_POLL_INTERVAL_MS = 50;
-+
-+static const int WATCHDOG_TIMER_INTERVAL = 500*HZ/1000;
-+
-+#define AUTO_NEG_MS_WAIT 500
-+static const int AUTO_NEG_INTERVAL = (AUTO_NEG_MS_WAIT)*HZ/1000;
-+static const int START_RESET_INTERVAL = 50*HZ/1000;
-+static const int RESET_INTERVAL = 10*HZ/1000;
-+
-+static const int GMAC_RESET_TIMEOUT_MS = 10000;
-+
-+static int debug = 0;
-+
-+MODULE_AUTHOR("Brian Clarke (Oxford Semiconductor Ltd)");
-+MODULE_DESCRIPTION("GMAC Network Driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION("v2.0");
-+
-+/* Ethernet MAC adr to assign to interface */
-+static int mac_adr[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0x00 };
-+module_param_array(mac_adr, int, NULL, S_IRUGO);
-+
-+/* PHY type kernel cmdline options */
-+static int phy_is_rgmii = 0;
-+module_param(phy_is_rgmii, int, S_IRUGO);
-+
-+/* Parse netdev kernel cmdline options */
-+static int __init do_setup(char *str)
-+{
-+    int i;
-+    int ints[5];    // Hold arg count and four args
-+	u32 mac_hi = 0;
-+	u32 mac_lo = 0;
-+
-+	/* Get the netdev bootargs parameters */
-+    get_options(str, sizeof(ints)/sizeof(int), ints);
-+    for (i=1; i<=ints[0]; i++) {
-+        switch (i) {
-+            case 3:
-+                mac_hi = ints[i];
-+                break;
-+            case 4:
-+                mac_lo = ints[i];
-+                break;
-+        }
-+    }
-+
-+	/* Break down the mac adr into its components */
-+	for (i=0; i < sizeof(mac_adr)/sizeof(int); i++) {
-+		if (i < sizeof(u32)) {
-+			mac_adr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
-+		} else {
-+			mac_adr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
-+		}
-+	}
-+
-+	return 0;
-+}
-+__setup("netdev=",do_setup);
-+
-+#ifdef DUMP_REGS_ON_GMAC_UP
-+static void dump_mac_regs(u32 macBase, u32 dmaBase)
-+{
-+    int n = 0;
-+
-+    for (n=0; n<0x60; n+=4) {
-+        printk(KERN_INFO "MAC Register %08x (%08x) = %08x\n", n, macBase+n, readl(macBase+n));
-+    }
-+
-+    for (n=0; n<0x60; n+=4) {
-+        printk(KERN_INFO "DMA Register %08x (%08x) = %08x\n", n, dmaBase+n, readl(dmaBase+n));
-+    }
-+}
-+#endif // DUMP_REGS_ON_GMAC_UP
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_update_semaphore;
-+
-+static void copro_update_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    up(&copro_update_semaphore);
-+}
-+
-+static struct semaphore copro_start_semaphore;
-+
-+static void copro_start_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    up(&copro_start_semaphore);
-+}
-+
-+static struct semaphore copro_rx_enable_semaphore;
-+
-+static void copro_rx_enable_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    up(&copro_rx_enable_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_int_en_set(
-+    gmac_priv_t *priv,
-+    u32          mask)
-+{
-+    unsigned long irq_flags = 0;
-+
-+#ifdef CONFIG_LEON_COPRO
-+    int cmd_queue_result = -1;
-+    while (cmd_queue_result) {
-+        if (in_irq())
-+            spin_lock(&priv->cmd_que_lock_);
-+        else
-+            spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_SET, mask, 0);
-+
-+        if (in_irq())
-+            spin_unlock(&priv->cmd_que_lock_);
-+        else
-+            spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else
-+    if (in_irq())
-+        spin_lock(&priv->cmd_que_lock_);
-+    else
-+        spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+    dma_reg_set_mask(priv, DMA_INT_ENABLE_REG, mask);
-+
-+    if (in_irq())
-+        spin_unlock(&priv->cmd_que_lock_);
-+    else
-+        spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_int_clr_semaphore;
-+static unsigned long    copro_int_clr_return;
-+
-+static void copro_int_clr_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    copro_int_clr_return = entry->operand_;
-+    up(&copro_int_clr_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_int_en_clr(
-+    gmac_priv_t *priv,
-+    u32          mask,
-+    u32         *new_value,
-+	int          in_atomic)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+    unsigned long irq_flags = 0;
-+
-+    int cmd_queue_result = -1;
-+    while (cmd_queue_result) {
-+        if (in_irq())
-+            spin_lock(&priv->cmd_que_lock_);
-+        else
-+            spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_CLR, mask, copro_int_clr_callback);
-+
-+        if (in_irq())
-+            spin_unlock(&priv->cmd_que_lock_);
-+        else
-+            spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+    if (new_value) {
-+        // Wait until the CoPro acknowledges that it has stopped
-+        if (in_atomic) {
-+            while (down_trylock(&copro_int_clr_semaphore)) {
-+                udelay(100);
-+            }
-+        } else {
-+            down_interruptible(&copro_int_clr_semaphore);
-+        }
-+        *new_value = copro_int_clr_return;
-+    }
-+#else
-+    unsigned long temp;
-+    unsigned long irq_flags = 0;
-+
-+    if (in_irq())
-+        spin_lock(&priv->cmd_que_lock_);
-+    else
-+        spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+    temp = dma_reg_clear_mask(priv, DMA_INT_ENABLE_REG, mask);
-+
-+    if (in_irq())
-+        spin_unlock(&priv->cmd_que_lock_);
-+    else
-+        spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+
-+    if (new_value) {
-+        *new_value = temp;
-+    }
-+#endif
-+}
-+
-+/**
-+ * May be invoked from either ISR or process context, so locking must be
-+ * invoked appropriate to the return from in_irq()
-+ */
-+static void change_rx_enable(
-+    gmac_priv_t *priv,
-+    u32          start,
-+    int          waitForAck,
-+	int          in_atomic)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+    unsigned long irq_flags = 0;
-+    int cmd_queue_result = -1;
-+
-+    while (cmd_queue_result) {
-+        if (in_irq())
-+            spin_lock(&priv->cmd_que_lock_);
-+        else
-+            spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+        // Request the CoPro to start/stop GMAC receiver
-+        cmd_queue_result =
-+            cmd_que_queue_cmd(&priv->cmd_queue_,
-+                              GMAC_CMD_CHANGE_RX_ENABLE,
-+                              start,
-+                              waitForAck ? copro_rx_enable_callback : 0);
-+
-+        if (in_irq())
-+            spin_unlock(&priv->cmd_que_lock_);
-+        else
-+            spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+    if (waitForAck) {
-+        // Wait until the CoPro acknowledges that the receiver has been stopped
-+        if (in_atomic) {
-+            while (down_trylock(&copro_rx_enable_semaphore)) {
-+                udelay(100);
-+            }
-+        } else {
-+            down_interruptible(&copro_rx_enable_semaphore);
-+        }
-+    }
-+#else // CONFIG_LEON_COPRO
-+    start ? dma_reg_set_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT) :
-+            dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT);
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+/**
-+ * Invoked from the watchdog timer action routine which runs as softirq, so
-+ * must disable interrupts when obtaining locks
-+ */
-+static void change_gig_mode(gmac_priv_t *priv)
-+{
-+	unsigned int is_gig = priv->mii.using_1000;
-+
-+#ifdef CONFIG_LEON_COPRO
-+    unsigned long irq_flags = 0;
-+    int cmd_queue_result = -1;
-+
-+    while (cmd_queue_result) {
-+        spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+        // Request the CoPro to change gigabit mode
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_GIG_MODE, is_gig, 0);
-+        spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else // CONFIG_LEON_COPRO
-+	static const int MAX_TRIES = 1000;
-+	int tries = 0;
-+
-+    // Mask to extract the transmit status field from the status register
-+    u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+
-+    // Must stop transmission in order to change store&forward mode
-+    dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+
-+    // Transmission only stops after current Tx frame has completed trans-
-+    // mission, so wait for the Tx state machine to enter the stopped state
-+    while ((dma_reg_read(priv, DMA_STATUS_REG) & ts_mask) != (DMA_STATUS_TS_STOPPED << DMA_STATUS_TS_BIT)) {
-+		mdelay(1);
-+		if (unlikely(++tries == MAX_TRIES)) {
-+			break;
-+		}
-+	}
-+
-+	if (unlikely(tries == MAX_TRIES)) {
-+		printk(KERN_WARNING "Timed out of wait for Tx to stop\n");
-+	}
-+
-+    if (is_gig) {
-+        mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        // In gigabit mode the OX800 cannot support the required data rate to
-+        // the GMAC, so must use store&forward and OX800 doesn't support Tx
-+		// checksumming in the GMAC
-+        dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+    } else {
-+        mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+        dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+    }
-+
-+    // Re-start transmission after store&forward change applied
-+    dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+/**
-+ * Invoked from the watchdog timer action routine which runs as softirq, so
-+ * must disable interrupts when obtaining locks
-+ */
-+static void change_pause_mode(gmac_priv_t *priv)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+	unsigned int enable_pause = priv->mii.using_pause;
-+    unsigned long irq_flags = 0;
-+    int cmd_queue_result = -1;
-+
-+    while (cmd_queue_result) {
-+        spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+        // Request the CoPro to change pause mode
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_PAUSE_MODE, enable_pause, 0);
-+        spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else // CONFIG_LEON_COPRO
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	unsigned int enable_pause = priv->mii.using_pause;
-+
-+    if (enable_pause) {
-+        mac_reg_set_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+    } else {
-+        mac_reg_clear_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+    }
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+static void refill_rx_ring(struct net_device *dev)
-+{
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+	int filled = 0;
-+
-+	if (unlikely(priv->rx_buffers_per_page)) {
-+		// Receive into pages
-+		struct page *page = 0;
-+		int offset = 0;
-+		dma_addr_t phys_adr = 0;
-+
-+		// While there are empty RX descriptor ring slots
-+		while (1) {
-+			int available;
-+			int desc;
-+			rx_frag_info_t frag_info;
-+
-+			// Have we run out of space in the current page?
-+			if (offset + NET_IP_ALIGN + priv->rx_buffer_size_ > GMAC_ALLOC_SIZE) {
-+				page = 0;
-+				offset = 0;
-+			}
-+
-+			if (!page) {
-+				// Start a new page
-+				available = available_for_write(&priv->rx_gmac_desc_list_info);
-+				if (available < priv->rx_buffers_per_page) {
-+					break;
-+				}
-+
-+				// Allocate a page to hold a received packet
-+				page = alloc_pages(GFP_ATOMIC, GMAC_ALLOC_ORDER);
-+				if (unlikely(page == NULL)) {
-+					printk(KERN_WARNING "refill_rx_ring() Could not alloc page\n");
-+					break;
-+				}
-+
-+				// Get a consistent DMA mapping for the entire page that will be
-+				// DMAed to - causing an invalidation of any entries in the CPU's
-+				// cache covering the memory region
-+				phys_adr = dma_map_page(0, page, 0, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
-+				BUG_ON(dma_mapping_error(phys_adr));
-+			} else {
-+				// Using the current page again
-+				get_page(page);
-+			}
-+
-+			// Ensure IP header is quad aligned
-+			offset += NET_IP_ALIGN;
-+			frag_info.page = page;
-+			frag_info.length = priv->rx_buffer_size_;
-+			frag_info.phys_adr = phys_adr + offset;
-+
-+			// Try to associate a descriptor with the fragment info
-+			desc = set_rx_descriptor(priv, &frag_info);
-+			if (desc >= 0) {
-+				filled = 1;
-+			} else {
-+				// Failed to associate the descriptor, so release the DMA mapping
-+				// for the socket buffer
-+				dma_unmap_page(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+				// No more RX descriptor ring entries to refill
-+				break;
-+			}
-+
-+			// Account for the space used in the current page
-+			offset += frag_info.length;
-+
-+			// Start next packet on a cacheline boundary
-+			offset = SKB_DATA_ALIGN(offset);
-+		}
-+	} else {
-+		// Preallocate MTU-sized SKBs
-+		while (1) {
-+			struct sk_buff *skb;
-+			rx_frag_info_t frag_info;
-+			int desc;
-+
-+			if (!available_for_write(&priv->rx_gmac_desc_list_info)) {
-+				break;
-+			}
-+
-+			// Allocate a new skb for the descriptor ring which is large enough
-+			// for any packet received from the link
-+			skb = dev_alloc_skb(priv->rx_buffer_size_ + NET_IP_ALIGN);
-+			if (!skb) {
-+				// Can't refill any more RX descriptor ring entries
-+				break;
-+			} else {
-+				// Despite what the comments in the original code from Synopsys
-+				// claimed, the GMAC DMA can cope with non-quad aligned buffers
-+				// - it will always perform quad transfers but zero/ignore the
-+				// unwanted bytes.
-+				skb_reserve(skb, NET_IP_ALIGN);
-+			}
-+
-+			// Get a consistent DMA mapping for the memory to be DMAed to
-+			// causing invalidation of any entries in the CPU's cache covering
-+			// the memory region
-+			frag_info.page = (struct page*)skb;
-+			frag_info.length = skb_tailroom(skb);
-+			frag_info.phys_adr = dma_map_single(0, skb->tail, frag_info.length, DMA_FROM_DEVICE);
-+			BUG_ON(dma_mapping_error(frag_info.phys_adr));
-+
-+			// Associate the skb with the descriptor
-+			desc = set_rx_descriptor(priv, &frag_info);
-+			if (desc >= 0) {
-+				filled = 1;
-+			} else {
-+				// No, so release the DMA mapping for the socket buffer
-+				dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+				// Free the socket buffer
-+				dev_kfree_skb(skb);
-+
-+				// No more RX descriptor ring entries to refill
-+				break;
-+			}
-+		}
-+	}
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	if (likely(filled)) {
-+		// Issue a RX poll demand to restart RX descriptor processing and DFF
-+		// mode does not automatically restart descriptor processing after a
-+		// descriptor unavailable event
-+		dma_reg_write(priv, DMA_RX_POLL_REG, 0);
-+	}
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+}
-+
-+static inline void set_phy_type_rgmii(void)
-+{
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	// Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
-+	u32 reg_contents = readl(SYS_CTRL_GMAC_CTRL);
-+	reg_contents |= (1UL << SYS_CTRL_GMAC_RGMII);
-+    writel(reg_contents, SYS_CTRL_RSTEN_SET_CTRL);
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+}
-+
-+static void initialise_phy(gmac_priv_t* priv)
-+{
-+	switch (priv->phy_type) {
-+		case PHY_TYPE_VITESSE_VSC8201XVZ:
-+			{
-+				// Allow s/w to override mode/duplex pin settings
-+				u32 acsr = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR);
-+
-+				printk(KERN_INFO "%s: PHY is Vitesse VSC8201XVZ\n", priv->netdev->name);
-+				acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
-+				priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR, acsr);
-+			}
-+			break;
-+		case PHY_TYPE_REALTEK_RTL8211BGR:
-+			printk(KERN_INFO "%s: PHY is Realtek RTL8211BGR\n", priv->netdev->name);
-+			set_phy_type_rgmii();
-+			break;
-+		case PHY_TYPE_LSI_ET1011C:
-+		case PHY_TYPE_LSI_ET1011C2:
-+			{
-+				u32 phy_reg;
-+
-+				printk(KERN_INFO "%s: PHY is LSI ET1011C\n", priv->netdev->name);
-+
-+				// Configure clocks
-+				phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG);
-+				phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
-+				phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
-+				phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
-+                              (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
-+							   (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
-+							   (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
-+				priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG, phy_reg);
-+
-+				// Enable Tx/Rx LED
-+				phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2);
-+				phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
-+				phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
-+				priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2, phy_reg);
-+			}
-+			break;
-+		case PHY_TYPE_ICPLUS_IP1001:
-+			printk(KERN_INFO "%s: PHY is ICPlus 1001\n", priv->netdev->name);
-+			break;
-+	}
-+}
-+
-+static struct kobj_type ktype_gmac_link_state = {
-+	.release = 0,
-+	.sysfs_ops = 0,
-+	.default_attrs = 0,
-+};
-+
-+static int gmac_link_state_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+	return get_ktype(kobj) == &ktype_gmac_link_state;
-+}
-+
-+static const char* gmac_link_state_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+	return "gmac_link_state";
-+}
-+
-+static struct kset_uevent_ops gmac_link_state_uevent_ops = {
-+	.filter = gmac_link_state_hotplug_filter,
-+	.name   = gmac_link_state_hotplug_name,
-+	.uevent = NULL,
-+};
-+
-+static int gmac_link_state_init_sysfs(gmac_priv_t* priv)
-+{
-+	int err = 0;
-+
-+	/* Prepare the sysfs interface for use */
-+	kobject_set_name(&priv->link_state_kset.kobj, "gmac_link_state");
-+	priv->link_state_kset.ktype = &ktype_gmac_link_state;
-+
-+	err = subsystem_register(&priv->link_state_kset);
-+	if (err)
-+		return err;
-+
-+	/* Setup hotplugging */
-+	priv->link_state_kset.uevent_ops = &gmac_link_state_uevent_ops;
-+
-+	/* Setup the heirarchy, the name will be set on detection */
-+	kobject_init(&priv->link_state_kobject);
-+	priv->link_state_kobject.kset = kset_get(&priv->link_state_kset);
-+	priv->link_state_kobject.parent = &priv->link_state_kset.kobj;
-+
-+	/* Build the sysfs entry */
-+	kobject_set_name(&priv->link_state_kobject, "gmac_link_state-1");
-+	return kobject_add(&priv->link_state_kobject);
-+}
-+
-+static void work_handler(struct work_struct *ws) {
-+	gmac_priv_t *priv = container_of(ws, gmac_priv_t, link_state_change_work);
-+
-+	kobject_uevent(&priv->link_state_kobject, priv->link_state ? KOBJ_ONLINE : KOBJ_OFFLINE);
-+}
-+
-+static void link_state_change_callback(
-+	int   link_state,
-+	void *arg)
-+{
-+	gmac_priv_t* priv = (gmac_priv_t*)arg;
-+
-+	priv->link_state = link_state;
-+	schedule_work(&priv->link_state_change_work);
-+}
-+
-+static void start_watchdog_timer(gmac_priv_t* priv)
-+{
-+    priv->watchdog_timer.expires = jiffies + WATCHDOG_TIMER_INTERVAL;
-+    priv->watchdog_timer_shutdown = 0;
-+    mod_timer(&priv->watchdog_timer, priv->watchdog_timer.expires);
-+}
-+
-+static void delete_watchdog_timer(gmac_priv_t* priv)
-+{
-+    // Ensure link/PHY state watchdog timer won't be invoked again
-+    priv->watchdog_timer_shutdown = 1;
-+    del_timer_sync(&priv->watchdog_timer);
-+}
-+
-+static inline int is_auto_negotiation_in_progress(gmac_priv_t* priv)
-+{
-+    return !(phy_read(priv->netdev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE);
-+}
-+
-+static void watchdog_timer_action(unsigned long arg)
-+{
-+    typedef enum watchdog_state {
-+        WDS_IDLE,
-+        WDS_RESETTING,
-+        WDS_NEGOTIATING
-+    } watchdog_state_t;
-+
-+    static int state = WDS_IDLE;
-+
-+    gmac_priv_t* priv = (gmac_priv_t*)arg;
-+    unsigned long new_timeout = jiffies + WATCHDOG_TIMER_INTERVAL;
-+#ifndef ARMULATING
-+    int ready;
-+    int duplex_changed;
-+    int gigabit_changed;
-+    int pause_changed;
-+
-+	// Interpret the PHY/link state.
-+	if (priv->phy_force_negotiation || (state == WDS_RESETTING)) {
-+		mii_check_link(&priv->mii);
-+		ready = 0;
-+	} else {
-+		duplex_changed = mii_check_media_ex(&priv->mii, 1, priv->mii_init_media, &gigabit_changed, &pause_changed, link_state_change_callback, priv);
-+		priv->mii_init_media = 0;
-+		ready = netif_carrier_ok(priv->netdev);
-+	}
-+
-+    if (!ready) {
-+        if (priv->phy_force_negotiation) {
-+            if (netif_carrier_ok(priv->netdev)) {
-+                state = WDS_RESETTING;
-+            } else {
-+                state = WDS_IDLE;
-+            }
-+
-+            priv->phy_force_negotiation = 0;
-+        }
-+
-+        // May be a good idea to restart everything here, in an attempt to clear
-+        // out any fault conditions
-+        if ((state == WDS_NEGOTIATING) && is_auto_negotiation_in_progress(priv)) {
-+            new_timeout = jiffies + AUTO_NEG_INTERVAL;
-+        } else {
-+            switch (state) {
-+                case WDS_IDLE:
-+                    // Reset the PHY to get it into a known state
-+                    start_phy_reset(priv);
-+                    new_timeout = jiffies + START_RESET_INTERVAL;
-+                    state = WDS_RESETTING;
-+                    break;
-+                case WDS_RESETTING:
-+                    if (!is_phy_reset_complete(priv)) {
-+                        new_timeout = jiffies + RESET_INTERVAL;
-+                    } else {
-+                        // Force or auto-negotiate PHY mode
-+                        set_phy_negotiate_mode(priv->netdev);
-+
-+                        // Set PHY specfic features
-+                        initialise_phy(priv);
-+
-+                        state = WDS_NEGOTIATING;
-+                        new_timeout = jiffies + AUTO_NEG_INTERVAL;
-+                    }
-+                    break;
-+                default:
-+                    DBG(1, KERN_ERR "watchdog_timer_action() %s: Unexpected state\n", priv->netdev->name);
-+                    state = WDS_IDLE;
-+                    break;
-+            }
-+        }
-+    } else {
-+        state = WDS_IDLE;
-+        if (duplex_changed) {
-+            priv->mii.full_duplex ? mac_reg_set_mask(priv,   MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT)) :
-+                                    mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT));
-+        }
-+
-+        if (gigabit_changed) {
-+            change_gig_mode(priv);
-+        }
-+
-+		if (pause_changed) {
-+			change_pause_mode(priv);
-+		}
-+    }
-+#endif // !ARMULATING
-+
-+    // Re-trigger the timer, unless some other thread has requested it be stopped
-+    if (!priv->watchdog_timer_shutdown) {
-+        // Restart the timer
-+        mod_timer(&priv->watchdog_timer, new_timeout);
-+    }
-+}
-+
-+static int inline is_ip_packet(unsigned short eth_protocol)
-+{
-+    return (eth_protocol == ETH_P_IP)
-+#ifdef SUPPORT_IPV6
-+		|| (eth_protocol == ETH_P_IPV6)
-+#endif // SUPPORT_IPV6
-+		;
-+}
-+
-+static int inline is_ipv4_packet(unsigned short eth_protocol)
-+{
-+    return eth_protocol == ETH_P_IP;
-+}
-+
-+#ifdef SUPPORT_IPV6
-+static int inline is_ipv6_packet(unsigned short eth_protocol)
-+{
-+    return eth_protocol == ETH_P_IPV6;
-+}
-+#endif // SUPPORT_IPV6
-+
-+static int inline is_hw_checksummable(unsigned short protocol)
-+{
-+    return (protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+           || (protocol == IPPROTO_ICMP)
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+           ;
-+}
-+
-+static u32 unmap_rx_page(
-+	gmac_priv_t *priv,
-+	dma_addr_t   phys_adr)
-+{
-+	u32 offset = phys_adr & ~PAGE_MASK;
-+	u32 next_offset = offset + priv->rx_buffer_size_;
-+	next_offset = SKB_DATA_ALIGN(next_offset);
-+	next_offset += NET_IP_ALIGN;
-+
-+	// If this is the last packet in a page
-+	if (next_offset > GMAC_ALLOC_SIZE) {
-+		// Release the DMA mapping for the page
-+		dma_unmap_page(0, phys_adr & PAGE_MASK, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
-+	}
-+
-+	return offset;
-+}
-+
-+#define FCS_LEN 4		// Ethernet CRC length
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define HW_CSUM_LEN 2	// The OX800 H/W appending partial csum length
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+static inline int get_desc_len(
-+	u32 desc_status,
-+	int last)
-+{
-+	int length = get_rx_length(desc_status);
-+
-+	if (last) {
-+		length -= FCS_LEN;
-+#if defined(CONFIG_OXNAS_VERSION_0X800) && defined(USE_RX_CSUM)
-+	    length -= HW_CSUM_LEN;
-+#endif // CONFIG_OXNAS_VERSION_0X800 && USE_RX_CSUM
-+	}
-+
-+	return length;
-+}
-+
-+static int process_rx_packet_skb(gmac_priv_t *priv)
-+{
-+	int             desc;
-+	int             last;
-+	u32             desc_status = 0;
-+	rx_frag_info_t  frag_info;
-+	int             packet_len;
-+	struct sk_buff *skb;
-+	int             valid;
-+	int             ip_summed;
-+
-+	desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info);
-+	if (desc < 0) {
-+		return 0;
-+	}
-+
-+	// Release the DMA mapping for the received data
-+    dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+	// Get the packet data length
-+	packet_len = get_desc_len(desc_status, last);
-+
-+	// Get pointer to the SKB
-+	skb = (struct sk_buff*)frag_info.page;
-+
-+	// Is the packet entirely contained within the descriptors and without errors?
-+	valid = !(desc_status & (1UL << RDES0_ES_BIT));
-+
-+	if (unlikely(!valid)) {
-+		goto not_valid_skb;
-+	}
-+
-+	ip_summed = CHECKSUM_NONE;
-+
-+#ifdef USE_RX_CSUM
-+	// Has the h/w flagged an IP header checksum failure?
-+	valid = !(desc_status & (1UL << RDES0_IPC_BIT));
-+
-+	if (likely(valid)) {
-+		// Determine whether Ethernet frame contains an IP packet -
-+		// only bother with Ethernet II frames, but do cope with
-+		// 802.1Q VLAN tag presence
-+		int vlan_offset = 0;
-+		unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
-+		int is_ip = is_ip_packet(eth_protocol);
-+
-+		if (!is_ip) {
-+			// Check for VLAN tag
-+			if (eth_protocol == ETH_P_8021Q) {
-+				// Extract the contained protocol type from after
-+				// the VLAN tag
-+				eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
-+				is_ip = is_ip_packet(eth_protocol);
-+
-+				// Adjustment required to skip the VLAN stuff and
-+				// get to the IP header
-+				vlan_offset = 4;
-+			}
-+		}
-+
-+		// Only offload checksum calculation for IP packets
-+		if (is_ip) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+			u16 payload_length = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+			struct iphdr* ipv4_header = 0;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+			if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
-+				valid = 0;
-+			} else
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+			if (is_ipv4_packet(eth_protocol)) {
-+				ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+				// H/W can only checksum non-fragmented IP packets
-+				if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+					switch (ipv4_header->protocol) {
-+						case IPPROTO_TCP:
-+							// Compute TCP pseudo-header checksum
-+							payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
-+							break;
-+						case IPPROTO_UDP:
-+							{
-+								struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
-+								payload_length = ntohs(udp_header->len);
-+							}
-+							break;
-+						default:
-+							// Not supporting any other than TCP/UDP
-+							break;
-+					}
-+#else // CONFIG_OXNAS_VERSION_0X800
-+				if (is_hw_checksummable(ipv4_header->protocol)) {
-+					ip_summed = CHECKSUM_UNNECESSARY;
-+				}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+				}
-+			}
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+			 else {
-+#ifdef SUPPORT_IPV6
-+				struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+				if (is_hw_checksummable(ipv6_header->nexthdr)) {
-+					ip_summed = CHECKSUM_UNNECESSARY;
-+				}
-+#endif // SUPPORT_IPV6
-+			}
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+			if (payload_length) {
-+				// Get the hardware generated payload checksum from
-+				// the end of the received packet, reverse the 1's
-+				// complement operation that the h/w applies and add
-+				// to the pseudo-header checksum, in network order
-+				u16 hw_csum = ~(*(u16*)(skb->data + packet_len + FCS_LEN));
-+
-+				// Calculate checksum of pseudo header and payload
-+				if (csum_tcpudp_magic(
-+						ipv4_header->saddr,
-+						ipv4_header->daddr,
-+						payload_length,
-+						ipv4_header->protocol,
-+						hw_csum)) {
-+					// Bad checksum, so indicate in descriptor status
-+					desc_status |= (1UL << RDES0_IPC_BIT);
-+					valid = 0;
-+				} else {
-+					ip_summed = CHECKSUM_UNNECESSARY;
-+				}
-+			}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+		}
-+	}
-+
-+	if (unlikely(!valid)) {
-+		goto not_valid_skb;
-+	}
-+#endif // USE_RX_CSUM
-+
-+	// Increase the skb's data pointer to account for the RX packet that has
-+	// been DMAed into it
-+	skb_put(skb, packet_len);
-+
-+	// Set the device for the skb
-+	skb->dev = priv->netdev;
-+
-+	// Set packet protocol
-+	skb->protocol = eth_type_trans(skb, priv->netdev);
-+
-+	// Record whether h/w checksumed the packet
-+	skb->ip_summed = ip_summed;
-+
-+	// Send the packet up the network stack
-+	netif_receive_skb(skb);
-+
-+	// Update receive statistics
-+	priv->netdev->last_rx = jiffies;
-+	++priv->stats.rx_packets;
-+	priv->stats.rx_bytes += packet_len;
-+
-+	return 1;
-+
-+not_valid_skb:
-+	dev_kfree_skb(skb);
-+
-+	DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
-+
-+	// Update receive statistics from the descriptor status
-+	if (is_rx_collision_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.collisions;
-+	}
-+	if (is_rx_crc_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_crc_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_frame_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_frame_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_length_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_length_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_csum_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_frame_errors;
-+		++priv->stats.rx_errors;
-+	}
-+
-+	return 0;
-+}
-+
-+static int process_rx_packet(gmac_priv_t *priv)
-+{
-+	struct sk_buff *skb = NULL;
-+	int             last;
-+	u32             desc_status;
-+	rx_frag_info_t  frag_info;
-+	int             desc;
-+	u32             offset;
-+	int             desc_len;
-+	unsigned char  *packet;
-+	int             valid;
-+	int             desc_used = 0;
-+	int             hlen = 0;
-+	int             partial_len = 0;
-+	int             first = 1;
-+
-+	// Check that there is at least one Rx descriptor available. Cache the
-+	// descriptor information so we don't have to touch the uncached/unbuffered
-+	// descriptor memory more than necessary when we come to use that descriptor
-+	if (!rx_available_for_read(&priv->rx_gmac_desc_list_info, &desc_status)) {
-+		return 0;
-+	}
-+
-+	// Attempt to allocate an skb before we change anything on the Rx descriptor ring
-+	skb = dev_alloc_skb(GMAC_HLEN + NET_IP_ALIGN);
-+	if (unlikely(skb == NULL)) {
-+		return 0;
-+	}
-+
-+	// Align IP header start in header storage
-+	skb_reserve(skb, NET_IP_ALIGN);
-+
-+	// Process all descriptors associated with the packet
-+	while (1) {
-+		int prev_len;
-+
-+		// First call to get_rx_descriptor() will use the status read from the
-+		// first descriptor by the call to rx_available_for_read() above
-+		while ((desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info)) < 0) {
-+			// We are part way through processing a multi-descriptor packet
-+			// and the GMAC hasn't finished with the next descriptor for the
-+			// packet yet, so have to poll until it becomes available
-+			desc_status = 0;
-+			udelay(1);
-+		}
-+
-+		// We've consumed a descriptor
-+		++desc_used;
-+
-+		if (!frag_info.page) {
-+			panic("process_rx_packet() %s: Found RX descriptor without attached page\n", priv->netdev->name);
-+		}
-+
-+		// If this is the last packet in the page, release the DMA mapping
-+		offset = unmap_rx_page(priv, frag_info.phys_adr);
-+		if (!first) {
-+			// The buffer adr of descriptors associate with middle or last
-+			// parts of a packet have ls 2 bits of buffer adr ignored by GMAC DMA
-+			offset &= ~0x3;
-+		}
-+
-+		// Get the length of the packet excluding CRC, h/w csum etc.
-+		prev_len = partial_len;
-+		partial_len = get_desc_len(desc_status, last);
-+		desc_len = partial_len - prev_len;
-+
-+		// Get a pointer to the start of the packet data received into page
-+		packet = page_address(frag_info.page) + offset;
-+
-+		// Is the packet entirely contained within the desciptors and without errors?
-+		valid = !(desc_status & (1UL << RDES0_ES_BIT));
-+
-+		if (unlikely(!valid)) {
-+			goto not_valid;
-+		}
-+
-+		if (first) {
-+			// Store headers in skb buffer
-+			hlen = min(GMAC_HLEN, desc_len);
-+
-+			// Copy header into skb buffer
-+			memcpy(skb->data, packet, hlen);
-+			skb->tail += hlen;
-+
-+			if (desc_len > hlen) {
-+				// Point skb frags array at remaining packet data in pages
-+				skb_shinfo(skb)->nr_frags = 1;
-+				skb_shinfo(skb)->frags[0].page = frag_info.page;
-+				skb_shinfo(skb)->frags[0].page_offset = offset + hlen;
-+				skb_shinfo(skb)->frags[0].size = desc_len - hlen;
-+			} else {
-+				// Entire packet now in skb buffer so don't require page anymore
-+				put_page(frag_info.page);
-+			}
-+
-+			first = 0;
-+		} else {
-+			// Store intermediate descriptor data into packet
-+			int frag_index = skb_shinfo(skb)->nr_frags;
-+			skb_shinfo(skb)->frags[frag_index].page = frag_info.page;
-+			skb_shinfo(skb)->frags[frag_index].page_offset = offset;
-+			skb_shinfo(skb)->frags[frag_index].size = desc_len;
-+			++skb_shinfo(skb)->nr_frags;
-+		}
-+
-+		if (last) {
-+			int ip_summed = CHECKSUM_NONE;
-+
-+			// Update total packet length skb metadata
-+			skb->len = partial_len;
-+			skb->data_len = skb->len - hlen;
-+			skb->truesize = skb->len + sizeof(struct sk_buff);
-+
-+#ifdef USE_RX_CSUM
-+			// Has the h/w flagged an IP header checksum failure?
-+			valid = !(desc_status & (1UL << RDES0_IPC_BIT));
-+
-+			// Are we offloading RX checksuming?
-+			if (likely(valid)) {
-+				// Determine whether Ethernet frame contains an IP packet -
-+				// only bother with Ethernet II frames, but do cope with
-+				// 802.1Q VLAN tag presence
-+				int vlan_offset = 0;
-+				unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
-+				int is_ip = is_ip_packet(eth_protocol);
-+
-+				if (!is_ip) {
-+					// Check for VLAN tag
-+					if (eth_protocol == ETH_P_8021Q) {
-+						// Extract the contained protocol type from after
-+						// the VLAN tag
-+						eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
-+						is_ip = is_ip_packet(eth_protocol);
-+
-+						// Adjustment required to skip the VLAN stuff and
-+						// get to the IP header
-+						vlan_offset = 4;
-+					}
-+				}
-+
-+				// Only offload checksum calculation for IP packets
-+				if (is_ip) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+					u16 payload_length = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+					struct iphdr* ipv4_header = 0;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+					if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
-+						valid = 0;
-+					} else
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+					if (is_ipv4_packet(eth_protocol)) {
-+						ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+						// H/W can only checksum non-fragmented IP packets
-+						if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+							switch (ipv4_header->protocol) {
-+								case IPPROTO_TCP:
-+									// Compute TCP pseudo-header checksum
-+									payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
-+									break;
-+								case IPPROTO_UDP:
-+									{
-+										struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
-+										payload_length = ntohs(udp_header->len);
-+									}
-+									break;
-+								default:
-+									// Not supporting any other than TCP/UDP
-+									break;
-+							}
-+#else // CONFIG_OXNAS_VERSION_0X800
-+						if (is_hw_checksummable(ipv4_header->protocol)) {
-+							ip_summed = CHECKSUM_UNNECESSARY;
-+						}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+						}
-+					}
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+					 else {
-+#ifdef SUPPORT_IPV6
-+						struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+						if (is_hw_checksummable(ipv6_header->nexthdr)) {
-+							ip_summed = CHECKSUM_UNNECESSARY;
-+						}
-+#endif // SUPPORT_IPV6
-+					}
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+					if (payload_length) {
-+						// Get the hardware generated payload checksum from
-+						// the end of the received packet, reverse the 1's
-+						// complement operation that the h/w applies and add
-+						// to the pseudo-header checksum, in network order
-+						u16 hw_csum = ~(*(u16*)(packet + desc_len + FCS_LEN));
-+
-+						// Calculate checksum of pseudo header and payload
-+						if (csum_tcpudp_magic(
-+								ipv4_header->saddr,
-+								ipv4_header->daddr,
-+								payload_length,
-+								ipv4_header->protocol,
-+								hw_csum)) {
-+							// Bad checksum, so indicate in descriptor status
-+							desc_status |= (1UL << RDES0_IPC_BIT);
-+							valid = 0;
-+						} else {
-+							ip_summed = CHECKSUM_UNNECESSARY;
-+						}
-+					}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+				}
-+			}
-+
-+			if (unlikely(!valid)) {
-+				goto not_valid;
-+			}
-+#endif // USE_RX_CSUM
-+
-+			// Initialise other required skb header fields
-+			skb->dev = priv->netdev;
-+			skb->protocol = eth_type_trans(skb, priv->netdev);
-+
-+			// Record whether h/w checksumed the packet
-+			skb->ip_summed = ip_summed;
-+
-+			// Send the skb up the network stack
-+			netif_receive_skb(skb);
-+
-+			// Update receive statistics
-+			priv->netdev->last_rx = jiffies;
-+			++priv->stats.rx_packets;
-+			priv->stats.rx_bytes += partial_len;
-+
-+			break;
-+		}
-+
-+		// Want next call to get_rx_descriptor() to read status from descriptor
-+		desc_status = 0;
-+	}
-+    return desc_used;
-+
-+not_valid:
-+	if (!skb_shinfo(skb)->nr_frags) {
-+		// Free the page as it wasn't attached to the skb
-+		put_page(frag_info.page);
-+	}
-+
-+	dev_kfree_skb(skb);
-+
-+	DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
-+
-+	// Update receive statistics from the descriptor status
-+	if (is_rx_collision_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.collisions;
-+	}
-+	if (is_rx_crc_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_crc_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_frame_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_frame_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_length_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_length_errors;
-+		++priv->stats.rx_errors;
-+	}
-+	if (is_rx_csum_error(desc_status)) {
-+		DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+		++priv->stats.rx_frame_errors;
-+		++priv->stats.rx_errors;
-+	}
-+
-+	return desc_used;
-+}
-+
-+/*
-+ * NAPI receive polling method
-+ */
-+static int poll(
-+	struct napi_struct *napi,
-+	int                 budget)
-+{
-+	gmac_priv_t *priv = container_of(napi, gmac_priv_t, napi_struct);
-+	struct net_device *dev = priv->netdev;
-+    int rx_work_limit = budget;
-+    int work_done = 0;
-+    int continue_polling;
-+    int finished;
-+    int available;
-+	int desc_since_refill = 0;
-+
-+    finished = 0;
-+    do {
-+        u32 status;
-+
-+        // While there are receive polling jobs to be done
-+        while (rx_work_limit) {
-+			int desc_used;
-+
-+			if (unlikely(priv->rx_buffers_per_page)) {
-+				desc_used = process_rx_packet(priv);
-+			} else {
-+				desc_used = process_rx_packet_skb(priv);
-+			}
-+
-+			if (!desc_used) {
-+				break;
-+			}
-+
-+            // Increment count of processed packets
-+            ++work_done;
-+
-+            // Decrement our remaining budget
-+            if (rx_work_limit > 0) {
-+                --rx_work_limit;
-+            }
-+
-+            // Rx overflows seem to upset the GMAC, so try to ensure we never see them
-+			desc_since_refill += desc_used;
-+            if (desc_since_refill >= DESC_SINCE_REFILL_LIMIT) {
-+                desc_since_refill = 0;
-+                refill_rx_ring(dev);
-+            }
-+        }
-+
-+        if (rx_work_limit) {
-+            // We have unused budget remaining, but apparently no Rx packets to
-+            // process
-+            available = 0;
-+
-+            // Clear any RI status so we don't immediately get reinterrupted
-+            // when we leave polling, due to either a new RI event, or a left
-+            // over interrupt from one of the RX descriptors we've already
-+            // processed
-+            status = dma_reg_read(priv, DMA_STATUS_REG);
-+            if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+                // Ack the RI, including the normal summary sticky bit
-+                dma_reg_write(priv, DMA_STATUS_REG, ((1UL << DMA_STATUS_RI_BIT)  |
-+                                                     (1UL << DMA_STATUS_NIS_BIT)));
-+
-+                // Must check again for available RX descriptors, in case the RI
-+                // status came from a new RX descriptor
-+                available = rx_available_for_read(&priv->rx_gmac_desc_list_info, 0);
-+            }
-+
-+            if (!available) {
-+                // We have budget left but no Rx packets to process so stop
-+                // polling
-+                continue_polling = 0;
-+                finished = 1;
-+            }
-+        } else {
-+            // If we have consumed all our budget, don't cancel the
-+            // poll, the NAPI instructure assumes we won't
-+            continue_polling = 1;
-+
-+            // Must leave poll() routine as no budget left
-+            finished = 1;
-+        }
-+    } while (!finished);
-+
-+    // Attempt to fill any empty slots in the RX ring
-+    refill_rx_ring(dev);
-+
-+    // Decrement the budget even if we didn't process any packets
-+    if (!work_done) {
-+        work_done = 1;
-+    }
-+
-+    if (!continue_polling) {
-+        // No more received packets to process so return to interrupt mode
-+        netif_rx_complete(dev, napi);
-+
-+        // Enable interrupts caused by received packets that may have been
-+		// disabled in the ISR before entering polled mode
-+        gmac_int_en_set(priv, (1UL << DMA_INT_ENABLE_RI_BIT) |
-+                              (1UL << DMA_INT_ENABLE_RU_BIT) |
-+							   (1UL << DMA_INT_ENABLE_OV_BIT));
-+    }
-+
-+    return work_done;
-+}
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
-+static void copro_fill_tx_job(
-+    volatile gmac_tx_que_ent_t *job,
-+    struct sk_buff             *skb)
-+{
-+    int i;
-+    int nr_frags = skb_shinfo(skb)->nr_frags;
-+    unsigned short flags = 0;
-+    dma_addr_t hdr_dma_address;
-+
-+    // if too many fragments call sbk_linearize()
-+    // and take the CPU memory copies hit 
-+    if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
-+        int err;
-+        printk(KERN_WARNING "Fill: linearizing socket buffer as required %d frags and have only %d\n", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
-+        err = skb_linearize(skb);
-+        if (err) {
-+            panic("Fill: No free memory");
-+        }
-+
-+        // update nr_frags
-+        nr_frags = skb_shinfo(skb)->nr_frags;
-+    }
-+
-+    // Get a DMA mapping of the packet's data
-+    hdr_dma_address = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
-+    BUG_ON(dma_mapping_error(hdr_dma_address));
-+
-+    // Allocate storage for remainder of fragments and create DMA mappings
-+    // Get a DMA mapping for as many fragments as will fit into the first level
-+    // fragment info. storage within the job structure
-+    for (i=0; i < nr_frags; ++i) {
-+        struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
-+        job->frag_ptr_[i] = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
-+        job->frag_len_[i] = frag->size;
-+    }
-+
-+    // Is h/w checksumming and possibly TSO required
-+    if (likely((skb->ip_summed == CHECKSUM_PARTIAL) &&
-+               (ntohs(skb->protocol) == ETH_P_IP))) {
-+        flags |= (1UL << TX_JOB_FLAGS_ACCELERATE_BIT);
-+    }
-+
-+    // Fill the job description with information about the packet
-+    job->skb_         = (u32)skb;
-+    job->len_         = skb->len;
-+    job->data_len_    = skb->data_len;
-+    job->ethhdr_      = hdr_dma_address;
-+    job->iphdr_       = hdr_dma_address + (skb_network_header(skb) - skb->data);
-+    job->iphdr_csum_  = ((struct iphdr*)skb_network_header(skb))->check;
-+    job->tso_segs_    = skb_shinfo(skb)->gso_segs;
-+    job->tso_size_    = skb_shinfo(skb)->gso_size;
-+    job->flags_       = flags;
-+    job->statistics_  = 0;
-+}
-+
-+static void copro_free_tx_resources(volatile gmac_tx_que_ent_t* job)
-+{
-+    int i;
-+    struct sk_buff* skb = (struct sk_buff*)job->skb_;
-+    int nr_frags = skb_shinfo(skb)->nr_frags;
-+
-+    // This should never happen, since we check space when we filled
-+    // the job in copro_fill_tx_job
-+    if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
-+        panic("Free: Insufficient fragment storage, required %d, have only %d", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
-+    }
-+
-+    // Release the DMA mapping for the data directly referenced by the SKB
-+    dma_unmap_single(0, job->ethhdr_, skb_headlen(skb), DMA_TO_DEVICE);
-+
-+    // Release the DMA mapping for any fragments in the first level fragment
-+    // info. storage within the job structure
-+    for (i=0; (i < nr_frags) && (i < COPRO_NUM_TX_FRAGS_DIRECT); ++i) {
-+        dma_unmap_page(0, job->frag_ptr_[i], job->frag_len_[i], DMA_TO_DEVICE);
-+    }
-+
-+    // Inform the network stack that we've finished with the packet
-+    dev_kfree_skb_irq(skb);
-+}
-+
-+static void copro_process_pending_tx_skbs(
-+    struct net_device          *dev,
-+    volatile gmac_tx_que_ent_t *job)
-+{
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    // Process pending SKBs, oldest first
-+    do {
-+        // Get the oldest pending SKB
-+        struct sk_buff *skb;
-+        struct list_head *entry = priv->copro_tx_skb_list_.next;
-+        BUG_ON(!entry);
-+        list_del(entry);
-+
-+        skb = list_entry(entry, struct sk_buff, cb);
-+        BUG_ON(!skb);
-+
-+        // Keep track of how many entries are in the pending SKB list
-+        --priv->copro_tx_skb_list_count_;
-+
-+        // Fill the Tx offload job with the network packet's details
-+        copro_fill_tx_job(job, skb);
-+
-+        // Enqueue the new Tx offload job with the CoPro
-+        tx_que_new_job(dev, job);
-+
-+        if (list_empty(&priv->copro_tx_skb_list_)) {
-+            // No more pending SKBs
-+            break;
-+        }
-+    } while ((job = tx_que_get_idle_job(dev)));
-+}
-+
-+static void finish_xmit(struct net_device *dev)
-+{
-+    gmac_priv_t                *priv = (gmac_priv_t*)netdev_priv(dev);
-+    volatile gmac_tx_que_ent_t *job;
-+
-+    // Process all available completed jobs
-+    while ((job = tx_que_get_finished_job(dev))) {
-+        int aborted;
-+        int carrier;
-+        int collisions;
-+        u32 statistics = job->statistics_;
-+
-+        copro_free_tx_resources(job);
-+
-+        // Accumulate TX statistics returned by CoPro in the job structure
-+        priv->stats.tx_bytes   += (statistics & TX_JOB_STATS_BYTES_MASK)   >> TX_JOB_STATS_BYTES_BIT;
-+        priv->stats.tx_packets += (statistics & TX_JOB_STATS_PACKETS_MASK) >> TX_JOB_STATS_PACKETS_BIT;
-+        aborted    = (statistics & TX_JOB_STATS_ABORT_MASK)     >> TX_JOB_STATS_ABORT_BIT;
-+        carrier    = (statistics & TX_JOB_STATS_CARRIER_MASK)   >> TX_JOB_STATS_CARRIER_BIT;
-+        collisions = (statistics & TX_JOB_STATS_COLLISION_MASK) >> TX_JOB_STATS_COLLISION_BIT;
-+        priv->stats.tx_aborted_errors += aborted;
-+        priv->stats.tx_carrier_errors += carrier;
-+        priv->stats.collisions        += collisions;
-+        priv->stats.tx_errors += (aborted + carrier);
-+    }
-+
-+    // Process any queued pending SKBs for which resources are available
-+    if (priv->copro_tx_skb_list_count_ && (job = tx_que_get_idle_job(dev))) {
-+        copro_process_pending_tx_skbs(dev, job);
-+
-+        // Record start of transmission, so timeouts will work once they're
-+        // implemented
-+        dev->trans_start = jiffies;
-+
-+        // Interrupt the CoPro to cause it to examine the Tx offload queue
-+        wmb();
-+        writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
-+    }
-+
-+    // If the network stack's Tx queue was stopped and we now have resources
-+    // to process more Tx offload jobs
-+    if (netif_queue_stopped(dev) &&
-+        !tx_que_is_full(&priv->tx_queue_) &&
-+        !priv->copro_tx_skb_list_count_) {
-+        // Restart the network stack's TX queue
-+        netif_wake_queue(dev);
-+    }
-+}
-+#else
-+static void finish_xmit(struct net_device *dev)
-+{
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned     descriptors_freed = 0;
-+    u32          desc_status = 0;
-+
-+    // Handle transmit descriptors for the completed packet transmission
-+    while (1) {
-+        struct sk_buff *skb;
-+        tx_frag_info_t  fragment;
-+        int             buffer_owned;
-+		int				 desc_index;
-+
-+        // Get tx descriptor content, accumulating status for all buffers
-+        // contributing to each packet
-+		desc_index = get_tx_descriptor(priv, &skb, &desc_status, &fragment, &buffer_owned);
-+
-+		if (desc_index < 0) {
-+			// No more completed Tx packets
-+			break;
-+		}
-+
-+        // Only unmap DMA buffer if descriptor owned the buffer
-+        if (buffer_owned) {
-+            // Release the DMA mapping for the buffer
-+            dma_unmap_single(0, fragment.phys_adr, fragment.length, DMA_TO_DEVICE);
-+        }
-+
-+        // When all buffers contributing to a packet have been processed
-+        if (skb) {
-+            // Check the status of the transmission
-+            if (likely(is_tx_valid(desc_status))) {
-+                priv->stats.tx_bytes += skb->len;
-+                priv->stats.tx_packets++;
-+            } else {
-+                priv->stats.tx_errors++;
-+                if (is_tx_aborted(desc_status)) {
-+                    ++priv->stats.tx_aborted_errors;
-+                }
-+                if (is_tx_carrier_error(desc_status)) {
-+                    ++priv->stats.tx_carrier_errors;
-+                }
-+            }
-+
-+            if (unlikely(is_tx_collision_error(desc_status))) {
-+                ++priv->stats.collisions;
-+            }
-+
-+            // Inform the network stack that packet transmission has finished
-+            dev_kfree_skb_irq(skb);
-+
-+            // Start accumulating status for the next packet
-+            desc_status = 0;
-+        }
-+
-+        // Track how many descriptors we make available, so we know
-+        // if we need to re-start of network stack's TX queue processing
-+        ++descriptors_freed;
-+    }
-+
-+    // If the TX queue is stopped, there may be a pending TX packet waiting to
-+    // be transmitted
-+    if (unlikely(netif_queue_stopped(dev))) {
-+		// No locking with hard_start_xmit() required, as queue is already
-+		// stopped so hard_start_xmit() won't touch the h/w
-+
-+        // If any TX descriptors have been freed and there is an outstanding TX
-+        // packet waiting to be queued due to there not having been a TX
-+        // descriptor available when hard_start_xmit() was presented with an skb
-+        // by the network stack
-+        if (priv->tx_pending_skb) {
-+            // Construct the GMAC specific DMA descriptor
-+            if (set_tx_descriptor(priv,
-+                                  priv->tx_pending_skb,
-+                                  priv->tx_pending_fragments,
-+                                  priv->tx_pending_fragment_count,
-+                                  priv->tx_pending_skb->ip_summed == CHECKSUM_PARTIAL) >= 0) {
-+                // No TX packets now outstanding
-+                priv->tx_pending_skb = 0;
-+                priv->tx_pending_fragment_count = 0;
-+
-+                // We have used one of the TX descriptors freed by transmission
-+                // completion processing having occured above
-+                --descriptors_freed;
-+
-+                // Issue a TX poll demand to restart TX descriptor processing, as we
-+                // have just added one, in case it had found there were no more
-+                // pending transmission
-+                dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+            }
-+        }
-+
-+        // If there are TX descriptors available we should restart the TX queue
-+        if (descriptors_freed) {
-+            // The TX queue had been stopped by hard_start_xmit() due to lack of
-+            // TX descriptors, so restart it now that we've freed at least one
-+            netif_wake_queue(dev);
-+        }
-+    }
-+}
-+#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
-+
-+#ifndef CONFIG_LEON_COPRO
-+static void process_non_dma_ints(u32 raw_status)
-+{
-+    printk(KERN_ERR "Found GPI/GMI/GLI interrupt\n");
-+}
-+#endif // !CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+static void copro_fwd_intrs_handler(
-+    void *dev_id,
-+    u32   status)
-+{
-+    struct net_device *dev = (struct net_device *)dev_id;
-+    gmac_priv_t       *priv = (gmac_priv_t*)netdev_priv(dev);
-+    int                restart_watchdog = 0;
-+    int                restart_tx = 0;
-+    int                poll_tx = 0;
-+
-+    // Test for normal receive interrupt
-+    if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+        if (netif_rx_schedule_prep(dev, &priv->napi_struct)) {
-+            // Tell system we have work to be done
-+            __netif_rx_schedule(dev, &priv->napi_struct);
-+        } else {
-+            printk(KERN_ERR "copro_fwd_intrs_handler() %s: RX interrupt while in poll\n", dev->name);
-+        }
-+    }
-+
-+    // Test for unavailable RX buffers - CoPro should have disabled
-+    if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
-+        DBG(30, KERN_INFO "int_handler() %s: RX buffer unavailable\n", dev->name);
-+        // Accumulate receive statistics
-+        ++priv->stats.rx_over_errors;
-+        ++priv->stats.rx_errors;
-+    }
-+
-+    // Test for Rx overflow - CoPro should have disabled
-+	if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
-+		DBG(30, KERN_INFO "int_handler() %s: Rx overflow\n", dev->name);
-+		// Accumulate receive statistics
-+		++priv->stats.rx_fifo_errors;
-+		++priv->stats.rx_errors;
-+	}
-+
-+    // Test for normal TX interrupt
-+    if (status & ((1UL << DMA_STATUS_TI_BIT) |
-+                  (1UL << DMA_STATUS_ETI_BIT))) {
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+        // Finish packet transmision started by start_xmit
-+        finish_xmit(dev);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+    }
-+
-+    // Test for abnormal transmitter interrupt where there may be completed
-+    // packets waiting to be processed
-+    if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
-+                           (1UL << DMA_STATUS_UNF_BIT)))) {
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+        // Complete processing of any TX packets closed by the DMA
-+        finish_xmit(dev);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+        if (status & (1UL << DMA_STATUS_TJT_BIT)) {
-+            // A transmit jabber timeout causes the transmitter to enter the
-+            // stopped state
-+            DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
-+            restart_tx = 1;
-+        } else {
-+            DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
-+        }
-+
-+        // Issue a TX poll demand in an attempt to restart TX descriptor
-+        // processing
-+        poll_tx = 1;
-+    }
-+
-+    // Test for any of the error states which we deal with directly within
-+    // this interrupt service routine.
-+    if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
-+                           (1UL << DMA_STATUS_RWT_BIT) |
-+                           (1UL << DMA_STATUS_RPS_BIT) |
-+                           (1UL << DMA_STATUS_TPS_BIT) |
-+                           (1UL << DMA_STATUS_FBE_BIT)))) {
-+        // Test for early RX interrupt
-+        if (status & (1UL << DMA_STATUS_ERI_BIT)) {
-+            // Don't expect to see this, as never enable it
-+            DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
-+        }
-+
-+        if (status & (1UL << DMA_STATUS_RWT_BIT)) {
-+            DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
-+            // Accumulate receive statistics
-+            ++priv->stats.rx_frame_errors;
-+            ++priv->stats.rx_errors;
-+            restart_watchdog = 1;
-+        }
-+
-+        if (status & (1UL << DMA_STATUS_RPS_BIT)) {
-+            // Mask to extract the receive status field from the status register
-+//            u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
-+//            u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
-+//            printk("int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
-+            ++priv->stats.rx_errors;
-+            restart_watchdog = 1;
-+
-+            // Restart the receiver
-+            DBG(35, KERN_INFO "int_handler() %s: Restarting receiver\n", dev->name);
-+            change_rx_enable(priv, 1, 0, 1);
-+        }
-+
-+        if (status & (1UL << DMA_STATUS_TPS_BIT)) {
-+            // Mask to extract the transmit status field from the status register
-+//            u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+//            u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
-+//            printk("int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
-+            ++priv->stats.tx_errors;
-+            restart_watchdog = 1;
-+            restart_tx = 1;
-+        }
-+
-+        // Test for pure error interrupts
-+        if (status & (1UL << DMA_STATUS_FBE_BIT)) {
-+            // Mask to extract the bus error status field from the status register
-+//            u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
-+//            u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
-+//            printk("int_handler() %s: Bus error 0x%x\n", dev->name, eb);
-+            restart_watchdog = 1;
-+        }
-+
-+        if (restart_watchdog) {
-+            // Restart the link/PHY state watchdog immediately, which will
-+            // attempt to restart the system
-+            mod_timer(&priv->watchdog_timer, jiffies);
-+            restart_watchdog = 0;
-+        }
-+    }
-+
-+    if (unlikely(restart_tx)) {
-+        // Restart the transmitter, causes am implicit Tx descriptor list poll
-+        DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+        dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+        poll_tx = 0;
-+    }
-+
-+    if (unlikely(poll_tx)) {
-+        // Issue a TX poll demand in an attempt to restart TX descriptor
-+        // processing
-+        DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+        dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+    }
-+}
-+#else // CONFIG_LEON_COPRO 
-+static irqreturn_t int_handler(int int_num, void* dev_id)
-+{
-+    struct net_device *dev = (struct net_device *)dev_id;
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    u32 int_enable;
-+    int rx_polling;
-+    u32 raw_status;
-+    u32 status;
-+
-+    /** Read the interrupt enable register to determine if we're in rx poll mode
-+     *  Id like to get rid of this read, if a more efficient way of determining
-+     *  whether we are polling is available */
-+    spin_lock(&priv->cmd_que_lock_);
-+    int_enable = dma_reg_read(priv, DMA_INT_ENABLE_REG);
-+    spin_unlock(&priv->cmd_que_lock_);
-+
-+    rx_polling = !(int_enable & (1UL << DMA_INT_ENABLE_RI_BIT));
-+
-+    // Get interrupt status
-+    raw_status = dma_reg_read(priv, DMA_STATUS_REG);
-+
-+    // MMC, PMT and GLI interrupts are not masked by the interrupt enable
-+    // register, so must deal with them on the raw status
-+    if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
-+                      (1UL << DMA_STATUS_GMI_BIT) |
-+                      (1UL << DMA_STATUS_GLI_BIT)))) {
-+        process_non_dma_ints(raw_status);
-+    }
-+
-+    // Get status of enabled interrupt sources
-+    status = raw_status & int_enable;
-+
-+    while (status) {
-+        // Whether the link/PHY watchdog timer should be restarted
-+        int restart_watchdog = 0;
-+        int restart_tx       = 0;
-+        int poll_tx          = 0;
-+        u32 int_disable_mask = 0;
-+
-+        // Test for RX interrupt resulting from sucessful reception of a packet-
-+        // must do this before ack'ing, else otherwise can get into trouble with
-+        // the sticky summary bits when we try to disable further RI interrupts
-+        if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+//printk("RI ");
-+            // Disable interrupts caused by received packets as henceforth
-+            // we shall poll for packet reception
-+            int_disable_mask |= (1UL << DMA_INT_ENABLE_RI_BIT);
-+
-+            // Do NAPI compatible receive processing for RI interrupts
-+            if (likely(netif_rx_schedule_prep(dev, &priv->napi_struct))) {
-+                // Remember that we are polling, so we ignore RX events for the
-+                // remainder of the ISR
-+                rx_polling = 1;
-+
-+                // Tell system we have work to be done
-+                __netif_rx_schedule(dev, &priv->napi_struct);
-+            } else {
-+                printk(KERN_ERR "int_handler() %s: RX interrupt while in poll\n", dev->name);
-+            }
-+        }
-+
-+        // Test for unavailable RX buffers - must do this before ack'ing, else
-+        // otherwise can get into trouble with the sticky summary bits
-+        if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
-+            printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX buffer unavailable\n", dev->name);
-+            // Accumulate receive statistics
-+            ++priv->stats.rx_over_errors;
-+            ++priv->stats.rx_errors;
-+
-+            // Disable RX buffer unavailable reporting, so we don't get swamped
-+            int_disable_mask |= (1UL << DMA_INT_ENABLE_RU_BIT);
-+        }
-+
-+		if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
-+			printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX overflow\n", dev->name);
-+			// Accumulate receive statistics
-+			++priv->stats.rx_fifo_errors;
-+			++priv->stats.rx_errors;
-+
-+            // Disable RX overflow reporting, so we don't get swamped
-+            int_disable_mask |= (1UL << DMA_INT_ENABLE_OV_BIT);
-+		}
-+
-+        // Do any interrupt disabling with a single register write
-+        if (int_disable_mask) {
-+            gmac_int_en_clr(priv, int_disable_mask, 0);
-+
-+            // Update our record of the current interrupt enable status
-+            int_enable &= ~int_disable_mask;
-+        }
-+
-+        // The broken GMAC interrupt mechanism with its sticky summary bits
-+        // means that we have to ack all asserted interrupts here; we can't not
-+        // ack the RI interrupt source as we might like to (in order that the
-+        // poll() routine could examine the status) because if it was asserted
-+        // prior to being masked above, then the summary bit(s) would remain
-+        // asserted and cause an immediate re-interrupt.
-+        dma_reg_write(priv, DMA_STATUS_REG, status | ((1UL << DMA_STATUS_NIS_BIT) |
-+                                                      (1UL << DMA_STATUS_AIS_BIT)));
-+
-+        // Test for normal TX interrupt
-+        if (status & ((1UL << DMA_STATUS_TI_BIT) |
-+                      (1UL << DMA_STATUS_ETI_BIT))) {
-+            // Finish packet transmision started by start_xmit
-+            finish_xmit(dev);
-+        }
-+
-+        // Test for abnormal transmitter interrupt where there may be completed
-+        // packets waiting to be processed
-+        if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
-+                               (1UL << DMA_STATUS_UNF_BIT)))) {
-+            // Complete processing of any TX packets closed by the DMA
-+            finish_xmit(dev);
-+
-+            if (status & (1UL << DMA_STATUS_TJT_BIT)) {
-+                // A transmit jabber timeout causes the transmitter to enter the
-+                // stopped state
-+                DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
-+                restart_tx = 1;
-+            } else {
-+                DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
-+            }
-+
-+            // Issue a TX poll demand in an attempt to restart TX descriptor
-+            // processing
-+            poll_tx = 1;
-+        }
-+
-+        // Test for any of the error states which we deal with directly within
-+        // this interrupt service routine.
-+        if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
-+                               (1UL << DMA_STATUS_RWT_BIT) |
-+                               (1UL << DMA_STATUS_RPS_BIT) |
-+                               (1UL << DMA_STATUS_TPS_BIT) |
-+                               (1UL << DMA_STATUS_FBE_BIT)))) {
-+            // Test for early RX interrupt
-+            if (status & (1UL << DMA_STATUS_ERI_BIT)) {
-+                // Don't expect to see this, as never enable it
-+                DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
-+            }
-+
-+            if (status & (1UL << DMA_STATUS_RWT_BIT)) {
-+                DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
-+                // Accumulate receive statistics
-+                ++priv->stats.rx_frame_errors;
-+                ++priv->stats.rx_errors;
-+                restart_watchdog = 1;
-+            }
-+
-+            if (status & (1UL << DMA_STATUS_RPS_BIT)) {
-+				// Mask to extract the receive status field from the status register
-+				u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
-+				u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
-+				printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
-+				++priv->stats.rx_errors;
-+				restart_watchdog = 1;
-+
-+                // Restart the receiver
-+                printk(/*DBG(35, KERN_INFO */"int_handler() %s: Restarting receiver\n", dev->name);
-+                dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SR_BIT));
-+            }
-+
-+            if (status & (1UL << DMA_STATUS_TPS_BIT)) {
-+				// Mask to extract the transmit status field from the status register
-+//				u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+//				u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
-+//				DBG(30, KERN_INFO "int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
-+                ++priv->stats.tx_errors;
-+                restart_watchdog = 1;
-+                restart_tx = 1;
-+            }
-+
-+            // Test for pure error interrupts
-+            if (status & (1UL << DMA_STATUS_FBE_BIT)) {
-+				// Mask to extract the bus error status field from the status register
-+//				u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
-+//				u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
-+//				DBG(30, KERN_INFO "int_handler() %s: Bus error 0x%x\n", dev->name, eb);
-+                restart_watchdog = 1;
-+            }
-+
-+            if (restart_watchdog) {
-+                // Restart the link/PHY state watchdog immediately, which will
-+                // attempt to restart the system
-+                mod_timer(&priv->watchdog_timer, jiffies);
-+                restart_watchdog = 0;
-+            }
-+        }
-+
-+        if (unlikely(restart_tx)) {
-+            // Restart the transmitter
-+            DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
-+            dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+        }
-+
-+        if (unlikely(poll_tx)) {
-+            // Issue a TX poll demand in an attempt to restart TX descriptor
-+            // processing
-+            DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
-+            dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+        }
-+
-+        // Read the record of current interrupt requests again, in case some
-+        // more arrived while we were processing
-+        raw_status = dma_reg_read(priv, DMA_STATUS_REG);
-+
-+        // MMC, PMT and GLI interrupts are not masked by the interrupt enable
-+        // register, so must deal with them on the raw status
-+        if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
-+                                   (1UL << DMA_STATUS_GMI_BIT) |
-+                                   (1UL << DMA_STATUS_GLI_BIT))))  {
-+            process_non_dma_ints(raw_status);
-+        }
-+
-+        // Get status of enabled interrupt sources.
-+        status = raw_status & int_enable;
-+    }
-+
-+    return IRQ_HANDLED;
-+}
-+#endif // CONFIG_LEON_COPRO 
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_stop_semaphore;
-+
-+static void copro_stop_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    up(&copro_stop_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_down(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    int desc;
-+    u32 int_enable;
-+#ifdef CONFIG_LEON_COPRO
-+    tx_que_t *tx_queue = &priv->tx_queue_;
-+    int cmd_queue_result;
-+#endif // CONFIG_LEON_COPRO
-+
-+	// Stop NAPI
-+	napi_disable(&priv->napi_struct);
-+
-+    // Stop further TX packets being delivered to hard_start_xmit();
-+    netif_stop_queue(dev);
-+    netif_carrier_off(dev);
-+
-+    // Disable all GMAC interrupts and wait for change to be acknowledged
-+    gmac_int_en_clr(priv, ~0UL, &int_enable, 0);
-+
-+#ifdef CONFIG_LEON_COPRO
-+    // Tell the CoPro to stop network offload operations
-+    cmd_queue_result = -1;
-+    while (cmd_queue_result) {
-+        spin_lock(&priv->cmd_que_lock_);
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, copro_stop_callback);
-+        spin_unlock(&priv->cmd_que_lock_);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+    // Wait until the CoPro acknowledges the STOP command
-+    down_interruptible(&copro_stop_semaphore);
-+
-+    // Wait until the CoPro acknowledges that it has completed stopping
-+    down_interruptible(&priv->copro_stop_complete_semaphore_);
-+
-+    // Clear out the Tx offload job queue, deallocating associated resources
-+    while (tx_que_not_empty(tx_queue)) {
-+        // Free any dynamic fragment ptr/len storage
-+        /** @todo */
-+        tx_que_inc_r_ptr(tx_queue);
-+    }
-+
-+    // Reinitialise the Tx offload queue metadata
-+    tx_que_init(
-+        &priv->tx_queue_,
-+        (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
-+        priv->copro_tx_que_num_entries_);
-+
-+    // Empty the pending SKB queue
-+    while (!list_empty(&priv->copro_tx_skb_list_)) {
-+        struct sk_buff *skb;
-+
-+        // Remove the first entry on the list
-+        struct list_head *entry = priv->copro_tx_skb_list_.next;
-+        BUG_ON(!entry);
-+        list_del(entry);
-+
-+        // Get pointer to SKB from it's list_head member
-+        skb = list_entry(entry, struct sk_buff, cb);
-+        BUG_ON(!skb);
-+
-+        // Inform the network stack that we've finished with the packet
-+        dev_kfree_skb(skb);
-+    }
-+    priv->copro_tx_skb_list_count_ =  0;
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+    // Stop transmitter, take ownership of all tx descriptors
-+    dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_ST_BIT);
-+    if (priv->desc_vaddr) {
-+        tx_take_ownership(&priv->tx_gmac_desc_list_info);
-+    }
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+    // Stop receiver, waiting until it's really stopped and then take ownership
-+    // of all rx descriptors
-+    change_rx_enable(priv, 0, 1, 0);
-+
-+    if (priv->desc_vaddr) {
-+        rx_take_ownership(&priv->rx_gmac_desc_list_info);
-+    }
-+
-+    // Stop all timers
-+    delete_watchdog_timer(priv);
-+
-+    if (priv->desc_vaddr) {
-+        // Free receive descriptors
-+        do {
-+            int first_last = 0;
-+            rx_frag_info_t frag_info;
-+
-+            desc = get_rx_descriptor(priv, &first_last, 0, &frag_info);
-+            if (desc >= 0) {
-+				if (unlikely(priv->rx_buffers_per_page)) {
-+					// If this is the last packet in the page, release the DMA mapping
-+					unmap_rx_page(priv, frag_info.phys_adr);
-+					put_page(frag_info.page);
-+				} else {
-+                    // Release the DMA mapping for the packet buffer
-+                    dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+                    // Free the skb
-+                    dev_kfree_skb((struct sk_buff *)frag_info.page);
-+				}
-+            }
-+        } while (desc >= 0);
-+
-+        // Free transmit descriptors
-+        do {
-+            struct sk_buff *skb;
-+            tx_frag_info_t  frag_info;
-+            int             buffer_owned;
-+
-+            desc = get_tx_descriptor(priv, &skb, 0, &frag_info, &buffer_owned);
-+            if (desc >= 0) {
-+                if (buffer_owned) {
-+                    // Release the DMA mapping for the packet buffer
-+                    dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+                }
-+
-+                if (skb) {
-+                    // Free the skb
-+                    dev_kfree_skb(skb);
-+                }
-+            }
-+        } while (desc >= 0);
-+
-+        // Free any resources associated with the buffers of a pending packet
-+        if (priv->tx_pending_fragment_count) {
-+            tx_frag_info_t *frag_info = priv->tx_pending_fragments;
-+
-+            while (priv->tx_pending_fragment_count--) {
-+                dma_unmap_single(0, frag_info->phys_adr, frag_info->length, DMA_FROM_DEVICE);
-+                ++frag_info;
-+            }
-+        }
-+
-+        // Free the socket buffer of a pending packet
-+        if (priv->tx_pending_skb) {
-+            dev_kfree_skb(priv->tx_pending_skb);
-+            priv->tx_pending_skb = 0;
-+        }
-+    }
-+
-+    // Power down the PHY
-+    phy_powerdown(dev);
-+}
-+
-+static int stop(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    gmac_down(dev);
-+
-+#ifdef CONFIG_LEON_COPRO
-+    shutdown_copro();
-+
-+    if (priv->shared_copro_params_) {
-+        // Free the DMA coherent parameter space
-+        dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
-+        priv->shared_copro_params_ = 0;
-+    }
-+
-+    // Disable semaphore register from causing ARM interrupts
-+    *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = 0;
-+    *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = 0;
-+
-+    // Release interrupts lines used by semaphore register interrupts
-+    if (priv->copro_a_irq_alloced_) {
-+        free_irq(priv->copro_a_irq_, dev);
-+        priv->copro_a_irq_alloced_ = 0;
-+    }
-+    if (priv->copro_b_irq_alloced_) {
-+        free_irq(priv->copro_b_irq_, dev);
-+        priv->copro_b_irq_alloced_ = 0;
-+    }
-+#endif // CONFIG_LEON_COPRO 
-+
-+	// Free the shadow descriptor memory
-+	kfree(priv->tx_desc_shadow_);
-+	priv->tx_desc_shadow_ = 0;
-+
-+	kfree(priv->rx_desc_shadow_);
-+	priv->rx_desc_shadow_ = 0;
-+
-+    // Release the IRQ
-+    if (priv->have_irq) {
-+        free_irq(dev->irq, dev);
-+        priv->have_irq = 0;
-+    }
-+
-+    // Disable the clock to the MAC block
-+    writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+	// Free the sysfs resources
-+	kobject_del(&priv->link_state_kobject);
-+	subsystem_unregister(&priv->link_state_kset);
-+
-+    return 0;
-+}
-+
-+static void hw_set_mac_address(struct net_device *dev, unsigned char* addr)
-+{
-+    u32 mac_lo;
-+    u32 mac_hi;
-+
-+    mac_lo  =  (u32)addr[0];
-+    mac_lo |= ((u32)addr[1] << 8);
-+    mac_lo |= ((u32)addr[2] << 16);
-+    mac_lo |= ((u32)addr[3] << 24);
-+
-+    mac_hi  =  (u32)addr[4];
-+    mac_hi |= ((u32)addr[5] << 8);
-+
-+    mac_reg_write(netdev_priv(dev), MAC_ADR0_LOW_REG, mac_lo);
-+    mac_reg_write(netdev_priv(dev), MAC_ADR0_HIGH_REG, mac_hi);
-+}
-+
-+static int set_mac_address(struct net_device *dev, void *p)
-+{
-+    struct sockaddr *addr = p;
-+
-+    if (!is_valid_ether_addr(addr->sa_data)) {
-+        return -EADDRNOTAVAIL;
-+    }
-+
-+    memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+    hw_set_mac_address(dev, addr->sa_data);
-+
-+    return 0;
-+}
-+
-+static void multicast_hash(struct dev_mc_list *dmi, u32 *hash_lo, u32 *hash_hi)
-+{
-+    u32 crc = ether_crc_le(dmi->dmi_addrlen, dmi->dmi_addr);
-+    u32 mask = 1 << ((crc >> 26) & 0x1F);
-+
-+    if (crc >> 31) {
-+        *hash_hi |= mask;
-+    } else {
-+        *hash_lo |= mask;
-+    }
-+}
-+
-+static void set_multicast_list(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = netdev_priv(dev);
-+    u32 hash_lo=0;
-+    u32 hash_hi=0;
-+    u32 mode = 0;
-+    int i;
-+
-+    // Disable promiscuous mode and uni/multi-cast matching
-+    mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
-+
-+    // Disable all perfect match registers
-+    for (i=0; i < NUM_PERFECT_MATCH_REGISTERS; ++i) {
-+        mac_adrhi_reg_write(priv, i, 0);
-+    }
-+
-+    // Promiscuous mode overrides all-multi which overrides other filtering
-+    if (dev->flags & IFF_PROMISC) {
-+        mode |= (1 << MAC_FRAME_FILTER_PR_BIT);
-+    } else if (dev->flags & IFF_ALLMULTI) {
-+        mode |= (1 << MAC_FRAME_FILTER_PM_BIT);
-+    } else {
-+        struct dev_mc_list *dmi;
-+
-+        if (dev->mc_count <= NUM_PERFECT_MATCH_REGISTERS) {
-+            // Use perfect matching registers
-+            for (i=0, dmi = dev->mc_list; dmi; dmi = dmi->next, ++i) {
-+                u32 addr;
-+
-+                addr  =      dmi->dmi_addr[0];
-+                addr |= (u32)dmi->dmi_addr[1] << 8;
-+                addr |= (u32)dmi->dmi_addr[2] << 16;
-+                addr |= (u32)dmi->dmi_addr[3] << 24;
-+                mac_adrlo_reg_write(priv, i, addr);
-+
-+                addr  =      dmi->dmi_addr[4];
-+                addr |= (u32)dmi->dmi_addr[5] << 8;
-+                addr |= (1 << MAC_ADR1_HIGH_AE_BIT);
-+                mac_adrhi_reg_write(priv, i, addr);
-+            }
-+        } else {
-+            // Use hashing
-+            mode |= (1 << MAC_FRAME_FILTER_HUC_BIT);
-+            mode |= (1 << MAC_FRAME_FILTER_HMC_BIT);
-+
-+            for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
-+                multicast_hash(dmi, &hash_lo, &hash_hi);
-+            }
-+        }
-+    }
-+
-+    // Update the filtering rules
-+    mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
-+
-+    // Update the filtering hash table
-+    mac_reg_write(priv, MAC_HASH_LOW_REG,  hash_lo);
-+    mac_reg_write(priv, MAC_HASH_HIGH_REG, hash_hi);
-+}
-+
-+static int gmac_up(struct net_device *dev)
-+{
-+    int status = 0;
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+    u32 reg_contents;
-+#ifdef CONFIG_LEON_COPRO
-+    int cmd_queue_result;
-+#endif // CONFIG_LEON_COPRO
-+
-+    // Reset the entire GMAC
-+    dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
-+
-+    // Ensure reset is performed before testing for completion
-+    wmb();
-+
-+    // Wait for the reset operation to complete
-+    status = -EIO;
-+	printk(KERN_INFO "Resetting GMAC\n");
-+    for (;;) {
-+        if (!(dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT))) {
-+            status = 0;
-+            break;
-+        }
-+    }
-+
-+    // Did the GMAC reset operation fail?
-+    if (status) {
-+        printk(KERN_ERR "open() %s: GMAC reset failed\n", dev->name);
-+        goto gmac_up_err_out;
-+    }
-+	printk(KERN_INFO "GMAC reset complete\n");
-+
-+	/* Initialise MAC config register contents
-+	 */
-+    reg_contents = 0;
-+    if (!priv->mii.using_1000) {
-+        DBG(1, KERN_INFO "open() %s: PHY in 10/100Mb mode\n", dev->name);
-+        reg_contents |= (1UL << MAC_CONFIG_PS_BIT);
-+    } else {
-+        DBG(1, KERN_INFO "open() %s: PHY in 1000Mb mode\n", dev->name);
-+    }
-+    if (priv->mii.full_duplex) {
-+        reg_contents |= (1UL << MAC_CONFIG_DM_BIT);
-+    }
-+
-+#ifdef USE_RX_CSUM
-+	reg_contents |= (1UL << MAC_CONFIG_IPC_BIT);
-+#endif // USE_RX_CSUM
-+
-+    if (priv->jumbo_) {
-+		// Allow passage of jumbo frames through both transmitter and receiver
-+		reg_contents |=	((1UL << MAC_CONFIG_JE_BIT) |
-+                        (1UL << MAC_CONFIG_JD_BIT) |
-+						 (1UL << MAC_CONFIG_WD_BIT));
-+	}
-+
-+	// Enable transmitter and receiver
-+    reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
-+                     (1UL << MAC_CONFIG_RE_BIT));
-+
-+	// Select the minimum IFG - I found that 80 bit times caused very poor
-+	// IOZone performance, so stcik with the 96 bit times default
-+	reg_contents |= (0UL << MAC_CONFIG_IFG_BIT);
-+
-+    // Write MAC config setup to the GMAC
-+    mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
-+
-+	/* Initialise MAC VLAN register contents
-+	 */
-+    reg_contents = 0;
-+    mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
-+
-+    // Initialise the hardware's record of our primary MAC address
-+    hw_set_mac_address(dev, dev->dev_addr);
-+
-+    // Initialise multicast and promiscuous modes
-+    set_multicast_list(dev);
-+
-+    // Disable all MMC interrupt sources
-+    mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
-+    mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
-+
-+    // Remember how large the unified descriptor array is to be
-+    priv->total_num_descriptors = NUM_TX_DMA_DESCRIPTORS + NUM_RX_DMA_DESCRIPTORS;
-+
-+    // Initialise the structures managing the TX descriptor list
-+    init_tx_desc_list(&priv->tx_gmac_desc_list_info,
-+                      priv->desc_vaddr,
-+                      priv->tx_desc_shadow_,
-+                      NUM_TX_DMA_DESCRIPTORS);
-+
-+    // Initialise the structures managing the RX descriptor list
-+    init_rx_desc_list(&priv->rx_gmac_desc_list_info,
-+                      priv->desc_vaddr + NUM_TX_DMA_DESCRIPTORS,
-+                      priv->rx_desc_shadow_,
-+                      NUM_RX_DMA_DESCRIPTORS,
-+                      priv->rx_buffer_size_);
-+
-+    // Reset record of pending Tx packet
-+    priv->tx_pending_skb = 0;
-+    priv->tx_pending_fragment_count = 0;
-+
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+    // Write the physical DMA consistent address of the start of the tx descriptor array
-+    dma_reg_write(priv, DMA_TX_DESC_ADR_REG, priv->desc_dma_addr);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+    // Write the physical DMA consistent address of the start of the rx descriptor array
-+    dma_reg_write(priv, DMA_RX_DESC_ADR_REG, priv->desc_dma_addr +
-+                        (priv->tx_gmac_desc_list_info.num_descriptors * sizeof(gmac_dma_desc_t)));
-+
-+    // Initialise the GMAC DMA bus mode register
-+    dma_reg_write(priv, DMA_BUS_MODE_REG, ((1UL << DMA_BUS_MODE_FB_BIT)   |	// Force bursts
-+                                           (8UL << DMA_BUS_MODE_PBL_BIT)  |	// AHB burst size
-+                                           (1UL << DMA_BUS_MODE_DA_BIT)));	// Round robin Rx/Tx
-+
-+    // Prepare receive descriptors
-+    refill_rx_ring(dev);
-+
-+    // Clear any pending interrupt requests
-+    dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
-+
-+	/* Initialise flow control register contents
-+	 */
-+	// Enable Rx flow control
-+    reg_contents = (1UL << MAC_FLOW_CNTL_RFE_BIT);
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	if (priv->mii.using_pause) {
-+		// Enable Tx flow control
-+		reg_contents |= (1UL << MAC_FLOW_CNTL_TFE_BIT);
-+	}
-+
-+    // Set the duration of the pause frames generated by the transmitter when
-+	// the Rx fifo fill threshold is exceeded
-+	reg_contents |= ((0x100UL << MAC_FLOW_CNTL_PT_BIT) |	// Pause for 256 slots
-+					  (0x1UL << MAC_FLOW_CNTL_PLT_BIT));
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+	// Write flow control setup to the GMAC
-+    mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
-+
-+	/* Initialise operation mode register contents
-+	 */
-+    // Initialise the GMAC DMA operation mode register. Set Tx/Rx FIFO thresholds
-+    // to make best use of our limited SDRAM bandwidth when operating in gigabit
-+	reg_contents = ((DMA_OP_MODE_TTC_256 << DMA_OP_MODE_TTC_BIT) |    // Tx threshold
-+                    (1UL << DMA_OP_MODE_FUF_BIT) |    					// Forward Undersized good Frames
-+                    (DMA_OP_MODE_RTC_128 << DMA_OP_MODE_RTC_BIT) |	// Rx threshold 128 bytes
-+                    (1UL << DMA_OP_MODE_OSF_BIT));						// Operate on 2nd frame
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	// Enable hardware flow control
-+	reg_contents |= (1UL << DMA_OP_MODE_EFC_BIT);
-+
-+	// Set threshold for enabling hardware flow control at (full-4KB) to give
-+	// space for upto two in-flight std MTU packets to arrive after pause frame
-+	// has been sent.
-+	reg_contents |= ((0UL << DMA_OP_MODE_RFA2_BIT) |
-+					  (3UL << DMA_OP_MODE_RFA_BIT));
-+
-+	// Set threshold for disabling hardware flow control (-7KB)
-+	reg_contents |= ((1UL << DMA_OP_MODE_RFD2_BIT) |
-+					  (2UL << DMA_OP_MODE_RFD_BIT));
-+
-+    // Don't flush Rx frames from FIFO just because there's no descriptor available
-+	reg_contents |= (1UL << DMA_OP_MODE_DFF_BIT);
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+	// Write settings to operation mode register
-+    dma_reg_write(priv, DMA_OP_MODE_REG, reg_contents);
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    // Use store&forward when operating in gigabit mode, as OX800 does not have
-+    // sufficient SDRAM bandwidth to support gigabit Tx without it and OX800
-+	// does not support Tx checksumming in the GMAC
-+    if (priv->mii.using_1000) {
-+        dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+    } else {
-+        dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+    }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+    // GMAC requires store&forward in order to compute Tx checksums
-+    dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+    // Ensure setup is complete, before enabling TX and RX
-+    wmb();
-+
-+#ifdef CONFIG_LEON_COPRO
-+    // Update the CoPro's parameters with the current MTU
-+    priv->copro_params_.mtu_ = dev->mtu;
-+
-+    // Only attempt to write to uncached/unbuffered shared parameter storage if
-+    // CoPro is started and thus storage has been allocated
-+    if (priv->shared_copro_params_) {
-+        // Fill the CoPro parameter block
-+        memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+    }
-+
-+    // Make sure the CoPro parameter block updates have made it to memory (which
-+    // is uncached/unbuffered, so just compiler issues to overcome)
-+    wmb();
-+
-+    // Tell the CoPro to re-read parameters
-+    cmd_queue_result = -1;
-+    while (cmd_queue_result) {
-+        spin_lock(&priv->cmd_que_lock_);
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, copro_update_callback);
-+        spin_unlock(&priv->cmd_que_lock_);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+    // Wait until the CoPro acknowledges that the update of parameters is complete
-+    down_interruptible(&copro_update_semaphore);
-+
-+    // Tell the CoPro to begin network offload operations
-+    cmd_queue_result = -1;
-+    while (cmd_queue_result) {
-+        spin_lock(&priv->cmd_que_lock_);
-+        cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, copro_start_callback);
-+        spin_unlock(&priv->cmd_que_lock_);
-+    }
-+
-+    // Interrupt the CoPro so it sees the new command
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+    // Wait until the CoPro acknowledges that it has started
-+    down_interruptible(&copro_start_semaphore);
-+#endif // CONFIG_LEON_COPRO
-+
-+	// Start NAPI
-+	napi_enable(&priv->napi_struct);
-+
-+    // Start the transmitter and receiver
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+    dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // !LEON_OFFLOAD_TX
-+    change_rx_enable(priv, 1, 0, 0);
-+
-+    // Enable interesting GMAC interrupts
-+    gmac_int_en_set(priv, ((1UL << DMA_INT_ENABLE_NI_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_AI_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_FBE_BIT) |
-+                           (1UL << DMA_INT_ENABLE_RI_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_RU_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_OV_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_RW_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_RS_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_TI_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_UN_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_TJ_BIT)  |
-+                           (1UL << DMA_INT_ENABLE_TS_BIT)));
-+
-+    // (Re)start the link/PHY state monitoring timer
-+    start_watchdog_timer(priv);
-+
-+    // Allow the network stack to call hard_start_xmit()
-+    netif_start_queue(dev);
-+
-+#ifdef DUMP_REGS_ON_GMAC_UP
-+    dump_mac_regs(priv->macBase, priv->dmaBase);
-+#endif // DUMP_REGS_ON_GMAC_UP
-+
-+    return status;
-+
-+gmac_up_err_out:
-+    stop(dev);
-+
-+    return status;
-+}
-+
-+static void set_rx_packet_info(struct net_device *dev)
-+{
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+	int max_packet_buffer_size = dev->mtu + EXTRA_RX_SKB_SPACE;
-+
-+	if (max_packet_buffer_size > max_descriptor_length()) {
-+#ifndef RX_BUFFER_SIZE
-+		priv->rx_buffer_size_ = max_packet_buffer_size;
-+#else // !RX_BUFFER_SIZE
-+		priv->rx_buffer_size_ = RX_BUFFER_SIZE;
-+#endif // ! RX_BUFFER_SIZE
-+		priv->rx_buffers_per_page = GMAC_ALLOC_SIZE / (priv->rx_buffer_size_ + NET_IP_ALIGN);
-+	} else {
-+		priv->rx_buffer_size_ = max_packet_buffer_size;
-+		priv->rx_buffers_per_page = 0;
-+	}
-+}
-+
-+static int change_mtu(struct net_device *dev, int new_mtu)
-+{
-+    int status = 0;
-+    gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+    int original_mtu = dev->mtu;
-+
-+    // Check that new MTU is within supported range
-+    if ((new_mtu < MIN_PACKET_SIZE) || (new_mtu > MAX_JUMBO)) {
-+        DBG(1, KERN_WARNING "change_mtu() %s: Invalid MTU %d\n", dev->name, new_mtu);
-+        status = -EINVAL;
-+    } else {
-+        // Put MAC/PHY into quiesent state, causing all current buffers to be
-+        // deallocated and the PHY to powerdown
-+        gmac_down(dev);
-+
-+        // Record the new MTU, so bringing the MAC back up will allocate
-+        // resources to suit the new MTU
-+        dev->mtu = new_mtu;
-+
-+		// Set length etc. of rx packets
-+		set_rx_packet_info(dev);
-+
-+        // Reset the PHY to get it into a known state and ensure we have TX/RX
-+        // clocks to allow the GMAC reset to complete
-+        if (phy_reset(priv->netdev)) {
-+            DBG(1, KERN_ERR "change_mtu() %s: Failed to reset PHY\n", dev->name);
-+            status = -EIO;
-+        } else {
-+			// Set PHY specfic features
-+			initialise_phy(priv);
-+
-+            // Record whether jumbo frames should be enabled
-+            priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
-+
-+            // Force or auto-negotiate PHY mode
-+            priv->phy_force_negotiation = 1;
-+
-+            // Reallocate buffers with new MTU
-+            gmac_up(dev);
-+        }
-+    }
-+
-+    // If there was a failure
-+    if (status) {
-+        // Return the MTU to its original value
-+        DBG(1, KERN_INFO "change_mtu() Failed, returning MTU to original value\n");
-+        dev->mtu = original_mtu;
-+    }
-+
-+    return status;
-+}
-+
-+#ifdef TEST_COPRO
-+DECLARE_MUTEX_LOCKED(start_sem);
-+DECLARE_MUTEX_LOCKED(heartbeat_sem);
-+
-+void start_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    printk("START callback, operand = 0x%08x\n", entry->operand_);
-+    up(&start_sem);
-+}
-+
-+void heartbeat_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+    printk("Heartbeat callback, operand = 0x%08x\n", entry->operand_);
-+    up(&heartbeat_sem);
-+}
-+
-+static void test_copro(gmac_priv_t* priv)
-+{
-+    unsigned long irq_flags;
-+
-+    spin_lock(&priv->cmd_que_lock_);
-+    cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, 0);
-+    spin_unlock(&priv->cmd_que_lock_);
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+    mdelay(500);
-+
-+    spin_lock(&priv->cmd_que_lock_);
-+    cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, start_callback);
-+    spin_unlock(&priv->cmd_que_lock_);
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+    mdelay(500);
-+
-+    spin_lock(&priv->cmd_que_lock_);
-+    cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_HEARTBEAT, 0, heartbeat_callback);
-+    spin_unlock(&priv->cmd_que_lock_);
-+    writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+    mdelay(500);
-+
-+    printk("Waiting for start ack...\n");
-+    down_interruptible(&start_sem);
-+    printk("Start ack received\n");
-+
-+    printk("Waiting for heartbeat ack...\n");
-+    down_interruptible(&heartbeat_sem);
-+    printk("Heartbeat ack received\n");
-+}
-+#endif // TEST_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO 
-+#define SEM_INT_FWD      8
-+#define SEM_INT_ACK      16
-+#define SEM_INT_TX       17
-+#define SEM_INT_STOP_ACK 18
-+
-+#define SEM_INTA_MASK  (1UL << SEM_INT_FWD)
-+#define SEM_INTB_MASK ((1UL << SEM_INT_ACK) | (1UL << SEM_INT_TX) | (1UL << SEM_INT_STOP_ACK))
-+
-+static irqreturn_t copro_sema_intr(int irq, void *dev_id)
-+{
-+    struct net_device *dev = (struct net_device *)dev_id;
-+    gmac_priv_t       *priv = (gmac_priv_t*)netdev_priv(dev);
-+    u32                asserted;
-+    u32                fwd_intrs_status = 0;
-+    int                is_fwd_intr;
-+
-+    // Read the contents of semaphore A register
-+    asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
-+
-+    while (asserted) {
-+        // Extract any forwarded interrupts info
-+        is_fwd_intr = asserted & (1UL << SEM_INT_FWD);
-+        if (is_fwd_intr) {
-+            fwd_intrs_status = ((volatile gmac_fwd_intrs_t*)descriptors_phys_to_virt(priv->copro_params_.fwd_intrs_mailbox_))->status_;
-+        }
-+
-+        // Clear any interrupts directed at the ARM
-+        *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
-+
-+        if (is_fwd_intr) {
-+            // Process any forwarded GMAC interrupts
-+            copro_fwd_intrs_handler(dev_id, fwd_intrs_status);
-+        }
-+
-+        // Stay in interrupt routine if interrupt has been re-asserted
-+        asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
-+    }
-+
-+    return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t copro_semb_intr(int irq, void *dev_id)
-+{
-+    struct net_device *dev = (struct net_device *)dev_id;
-+    gmac_priv_t       *priv = (gmac_priv_t*)netdev_priv(dev);
-+    u32                asserted;
-+
-+    // Read the contents of semaphore B register
-+    asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
-+
-+    while (asserted) {
-+        // Clear any interrupts directed at the ARM
-+        *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
-+
-+        // Process any outstanding command acknowledgements
-+        if (asserted & (1UL << SEM_INT_ACK)) {
-+            while (!cmd_que_dequeue_ack(&priv->cmd_queue_));
-+        }
-+
-+        // Process STOP completion signal
-+        if (asserted & (1UL << SEM_INT_STOP_ACK)) {
-+            up(&priv->copro_stop_complete_semaphore_);
-+        }
-+
-+#ifdef CONFIG_LEON_OFFLOAD_TX
-+        // Process any completed TX offload jobs
-+        if (asserted & (1UL << SEM_INT_TX)) {
-+            finish_xmit(dev);
-+        }
-+#endif // CONFIG_LEON_OFFLOAD_TX
-+
-+        // Stay in interrupt routine if interrupt has been re-asserted
-+        asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
-+    }
-+
-+    return IRQ_HANDLED;
-+}
-+#endif // CONFIG_LEON_COPRO 
-+
-+static int open(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    int status;
-+
-+    // Ensure the MAC block is properly reset
-+    writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Enable the clock to the MAC block
-+    writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Ensure reset and clock operations are complete
-+    wmb();
-+
-+    // Reset the PHY to get it into a known state and ensure we have TX/RX clocks
-+    // to allow the GMAC reset to complete
-+    if (phy_reset(priv->netdev)) {
-+        DBG(1, KERN_ERR "open() %s: Failed to reset PHY\n", dev->name);
-+        status = -EIO;
-+        goto open_err_out;
-+    }
-+
-+	// Set PHY specfic features
-+	initialise_phy(priv);
-+
-+    // Check that the MAC address is valid.  If it's not, refuse to bring the
-+    // device up
-+    if (!is_valid_ether_addr(dev->dev_addr)) {
-+        DBG(1, KERN_ERR "open() %s: MAC address invalid\n", dev->name);
-+        status = -EINVAL;
-+        goto open_err_out;
-+    }
-+
-+#ifdef CONFIG_LEON_COPRO 
-+    // Register ISRs for the semaphore register interrupt sources, which will
-+    // originate from the CoPro
-+    if (request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", dev)) {
-+        panic("open: Failed to allocate semaphore A %u\n", priv->copro_a_irq_);
-+        status = -ENODEV;
-+        goto open_err_out;
-+    }
-+    priv->copro_a_irq_alloced_ = 1;
-+
-+    if (request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", dev)) {
-+        panic("open: Failed to allocate semaphore B %u\n", priv->copro_b_irq_);
-+        status = -ENODEV;
-+        goto open_err_out;
-+    }
-+    priv->copro_b_irq_alloced_ = 1;
-+#else // CONFIG_LEON_COPRO 
-+    // Allocate the IRQ
-+    if (request_irq(dev->irq, &int_handler, 0, dev->name, dev)) {
-+        DBG(1, KERN_ERR "open() %s: Failed to allocate irq %d\n", dev->name, dev->irq);
-+        status = -ENODEV;
-+        goto open_err_out;
-+    }
-+    priv->have_irq = 1;
-+#endif // CONFIG_LEON_COPRO 
-+
-+    // Need a consistent DMA mapping covering all the memory occupied by DMA
-+    // unified descriptor array, as both CPU and DMA engine will be reading and
-+    // writing descriptor fields.
-+    priv->desc_vaddr    = (gmac_dma_desc_t*)GMAC_DESC_ALLOC_START;
-+    priv->desc_dma_addr = GMAC_DESC_ALLOC_START_PA;
-+
-+    if (!priv->desc_vaddr) {
-+        DBG(1, KERN_ERR "open() %s: Failed to allocate consistent memory for DMA descriptors\n", dev->name);
-+        status = -ENOMEM;
-+        goto open_err_out;
-+    }
-+
-+	// Allocate memory to hold shadow of GMAC descriptors
-+	if (!(priv->tx_desc_shadow_ = kmalloc(NUM_TX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
-+        DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Tx descriptor shadows\n", dev->name);
-+        status = -ENOMEM;
-+        goto open_err_out;
-+	}
-+	if (!(priv->rx_desc_shadow_ = kmalloc(NUM_RX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
-+        DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Rx descriptor shadows\n", dev->name);
-+        status = -ENOMEM;
-+        goto open_err_out;
-+	}
-+
-+	// Record whether jumbo frames should be enabled
-+    priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
-+
-+	set_rx_packet_info(dev);
-+
-+#ifdef CONFIG_LEON_COPRO 
-+    // Allocate SRAM for the command queue entries
-+    priv->copro_params_.cmd_que_head_ = DESCRIPTORS_BASE_PA + DESCRIPTORS_SIZE;
-+
-+    priv->copro_params_.cmd_que_tail_ =
-+        (u32)((gmac_cmd_que_ent_t*)(priv->copro_params_.cmd_que_head_) + priv->copro_cmd_que_num_entries_);
-+    priv->copro_params_.fwd_intrs_mailbox_ = priv->copro_params_.cmd_que_tail_;
-+    priv->copro_params_.tx_que_head_ = priv->copro_params_.fwd_intrs_mailbox_ + sizeof(gmac_fwd_intrs_t);
-+    priv->copro_params_.tx_que_tail_ =
-+        (u32)((gmac_tx_que_ent_t*)(priv->copro_params_.tx_que_head_) + priv->copro_tx_que_num_entries_);
-+    priv->copro_params_.free_start_ = priv->copro_params_.tx_que_tail_;
-+
-+    // Set RX interrupt mitigation behaviour
-+    priv->copro_params_.rx_mitigation_        = COPRO_RX_MITIGATION;
-+    priv->copro_params_.rx_mitigation_frames_ = COPRO_RX_MITIGATION_FRAMES;
-+    priv->copro_params_.rx_mitigation_usec_   = COPRO_RX_MITIGATION_USECS;
-+
-+    // Initialise command queue metadata
-+    cmd_que_init(
-+        &priv->cmd_queue_,
-+        (gmac_cmd_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.cmd_que_head_),
-+        priv->copro_cmd_que_num_entries_);
-+
-+    // Initialise tx offload queue metadata
-+    tx_que_init(
-+        &priv->tx_queue_,
-+        (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
-+        priv->copro_tx_que_num_entries_);
-+
-+    // Allocate DMA coherent space for the parameter block shared with the CoPro
-+    priv->shared_copro_params_ = dma_alloc_coherent(0, sizeof(copro_params_t), &priv->shared_copro_params_pa_, GFP_KERNEL);
-+    if (!priv->shared_copro_params_) {
-+        DBG(1, KERN_ERR "open() %s: Failed to allocate DMA coherent space for parameters\n");
-+        status = -ENOMEM;
-+        goto open_err_out;
-+    }
-+
-+    // Update the CoPro's parameters with the current MTU
-+    priv->copro_params_.mtu_ = dev->mtu;
-+
-+    // Fill the shared CoPro parameter block from the ARM's local copy
-+    memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+
-+    // Load CoPro program and start it running
-+    init_copro(leon_srec, priv->shared_copro_params_pa_);
-+
-+    // Enable selected semaphore register bits to cause ARM interrupts
-+    *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = SEM_INTA_MASK;
-+    *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = SEM_INTB_MASK;
-+
-+#ifdef TEST_COPRO
-+    // Send test commands to the CoPro
-+    test_copro(priv);
-+#endif // TEST_COPRO
-+#endif // CONFIG_LEON_COPRO 
-+
-+    // Do startup operations that are in common with gmac_down()/_up() processing
-+    priv->mii_init_media = 1;
-+    priv->phy_force_negotiation = 1;
-+    status = gmac_up(dev);
-+    if (status) {
-+        goto open_err_out;
-+    }
-+
-+    return 0;
-+
-+open_err_out:
-+    stop(dev);
-+
-+    return status;
-+}
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
-+static int hard_start_xmit(
-+    struct sk_buff *skb,
-+    struct net_device *dev)
-+{
-+    gmac_priv_t                *priv = (gmac_priv_t*)netdev_priv(dev);
-+    volatile gmac_tx_que_ent_t *job;
-+    unsigned long               irq_flags;
-+
-+    if (skb_shinfo(skb)->frag_list) {
-+        panic("Frag list - can't handle this!\n");
-+    }
-+
-+    // Protection against concurrent operations in ISR and hard_start_xmit()
-+    if (!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags)) {
-+        return NETDEV_TX_LOCKED;
-+    }
-+
-+    // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
-+    // be called when the queue has been stopped (although I think only in SMP)
-+    // so do a check here to make sure we should proceed
-+    if (netif_queue_stopped(dev)) {
-+        spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+        return NETDEV_TX_BUSY;
-+    }
-+
-+    job = tx_que_get_idle_job(dev);
-+    if (!job) {
-+        // Tx offload queue is full, so add skb to pending skb list
-+        list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
-+
-+        // Keep track of how many entries are in the pending SKB list
-+        ++priv->copro_tx_skb_list_count_;
-+
-+        // Have we queued the max allowed number of SKBs?
-+        if (priv->copro_tx_skb_list_count_ >= COPRO_MAX_QUEUED_TX_SKBS) {
-+            // Stop further calls to hard_start_xmit() until some descriptors
-+            // are freed up by already queued TX packets being completed
-+            netif_stop_queue(dev);
-+        }
-+    } else {
-+        if (priv->copro_tx_skb_list_count_) {
-+            // Have queued pending SKBs, so add new SKB to tail of pending list
-+            list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
-+
-+            // Keep track of how many entries are in the pending SKB list
-+            ++priv->copro_tx_skb_list_count_;
-+
-+            // Process pending SKBs, oldest first
-+            copro_process_pending_tx_skbs(dev, job);
-+        } else {
-+            // Fill the Tx offload job with the network packet's details
-+            copro_fill_tx_job(job, skb);
-+
-+            // Enqueue the new Tx offload job with the CoPro
-+            tx_que_new_job(dev, job);
-+        }
-+
-+        // Record start of transmission, so timeouts will work once they're
-+        // implemented
-+        dev->trans_start = jiffies;
-+
-+        // Interrupt the CoPro to cause it to examine the Tx offload queue
-+        wmb();
-+        writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
-+
-+        // If the network stack's Tx queue was stopped and we now have resources
-+        // to process more Tx offload jobs
-+        if (netif_queue_stopped(dev) &&
-+            !tx_que_is_full(&priv->tx_queue_) &&
-+            !priv->copro_tx_skb_list_count_) {
-+            // Restart the network stack's TX queue
-+            netif_wake_queue(dev);
-+        }
-+    }
-+
-+    spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+
-+    return NETDEV_TX_OK;
-+}
-+#else
-+static inline void unmap_fragments(
-+    tx_frag_info_t *frags,
-+    int             count)
-+{
-+    while (count--) {
-+        dma_unmap_single(0, frags->phys_adr, frags->length, DMA_TO_DEVICE);
-+        ++frags;
-+    }
-+}
-+
-+static int hard_start_xmit(
-+    struct sk_buff    *skb,
-+    struct net_device *dev)
-+{
-+    gmac_priv_t            *priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long           irq_flags;
-+    struct skb_shared_info *shinfo = skb_shinfo(skb);
-+    int                     fragment_count = shinfo->nr_frags + 1;
-+    tx_frag_info_t          fragments[fragment_count];
-+    int                     frag_index;
-+
-+    // Get consistent DMA mappings for the SDRAM to be DMAed from by the GMAC,
-+    // causing a flush from the CPU's cache to the memory.
-+
-+    // Do the DMA mappings before acquiring the tx lock, even though it complicates
-+    // the later code, as this can be a long operation involving cache flushing
-+
-+    // Map the main buffer
-+    fragments[0].length = skb_headlen(skb);
-+    fragments[0].phys_adr = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
-+    BUG_ON(dma_mapping_error(fragments[0].phys_adr));
-+
-+    // Map any SG fragments
-+    for (frag_index = 0; frag_index < shinfo->nr_frags; ++frag_index) {
-+        skb_frag_t *frag = &shinfo->frags[frag_index];
-+
-+        fragments[frag_index + 1].length = frag->size;
-+        fragments[frag_index + 1].phys_adr = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
-+        BUG_ON(dma_mapping_error(fragments[frag_index + 1].phys_adr));
-+    }
-+
-+    // Protection against concurrent operations in ISR and hard_start_xmit()
-+    if (unlikely(!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags))) {
-+        unmap_fragments(fragments, fragment_count);
-+        return NETDEV_TX_LOCKED;
-+    }
-+
-+    // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
-+    // be called when the queue has been stopped (although I think only in SMP)
-+    // so do a check here to make sure we should proceed
-+    if (unlikely(netif_queue_stopped(dev))) {
-+        unmap_fragments(fragments, fragment_count);
-+        spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+        return NETDEV_TX_BUSY;
-+    }
-+
-+    // Construct the GMAC DMA descriptor
-+    if (unlikely(set_tx_descriptor(priv,
-+                          skb,
-+                          fragments,
-+                          fragment_count,
-+                          skb->ip_summed == CHECKSUM_PARTIAL) < 0)) {
-+        // Shouldn't see a full ring without the queue having already been
-+        // stopped, and the queue should already have been stopped if we have
-+        // already queued a single pending packet
-+        if (priv->tx_pending_skb) {
-+            printk(KERN_WARNING "hard_start_xmit() Ring full and pending packet already queued\n");
-+            unmap_fragments(fragments, fragment_count);
-+            spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+            return NETDEV_TX_BUSY;
-+        }
-+
-+        // Should keep a record of the skb that we haven't been able to queue
-+        // for transmission and queue it as soon as a descriptor becomes free
-+        priv->tx_pending_skb = skb;
-+        priv->tx_pending_fragment_count = fragment_count;
-+
-+        // Copy the fragment info to the allocated storage
-+        memcpy(priv->tx_pending_fragments, fragments, sizeof(tx_frag_info_t) * fragment_count);
-+
-+        // Stop further calls to hard_start_xmit() until some descriptors are
-+        // freed up by already queued TX packets being completed
-+        netif_stop_queue(dev);
-+    } else {
-+        // Record start of transmission, so timeouts will work once they're
-+        // implemented
-+        dev->trans_start = jiffies;
-+
-+        // Poke the transmitter to look for available TX descriptors, as we have
-+        // just added one, in case it had previously found there were no more
-+        // pending transmission
-+        dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+    }
-+
-+    spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+
-+    return NETDEV_TX_OK;
-+}
-+#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
-+
-+static struct net_device_stats *get_stats(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    return &priv->stats;
-+}
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+/**
-+ * Polling 'interrupt' - used by things like netconsole to send skbs without
-+ * having to re-enable interrupts. It's not called while the interrupt routine
-+ * is executing.
-+ */
-+static void netpoll(struct net_device *netdev)
-+{
-+    disable_irq(netdev->irq);
-+    int_handler(netdev->irq, netdev, NULL);
-+    enable_irq(netdev->irq);
-+}
-+#endif // CONFIG_NET_POLL_CONTROLLER
-+
-+static int probe(
-+    struct net_device *netdev,
-+    u32                vaddr,
-+    u32                irq,
-+    int                copro_a_irq,
-+    int                copro_b_irq)
-+{
-+    int err = 0;
-+    u32 version;
-+    int i;
-+    unsigned synopsis_version;
-+    unsigned vendor_version;
-+    gmac_priv_t* priv = netdev_priv(netdev);
-+	u32 reg_contents;
-+
-+    // Ensure the MAC block is properly reset
-+    writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Enable the clock to the MAC block
-+    writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Ensure reset and clock operations are complete
-+    wmb();
-+
-+    // Ensure all of the device private data are zero, so we can clean up in
-+    // the event of a later failure to initialise all fields
-+    priv = (gmac_priv_t*)netdev_priv(netdev);
-+    memset(priv, 0, sizeof(gmac_priv_t));
-+
-+    // No debug messages allowed
-+    priv->msg_level = 0UL;
-+
-+    // Initialise the ISR/hard_start_xmit() lock
-+    spin_lock_init(&priv->tx_spinlock_);
-+    
-+    // Initialise the PHY access lock
-+    spin_lock_init(&priv->phy_lock);
-+
-+    // Set hardware device base addresses
-+    priv->macBase = vaddr + MAC_BASE_OFFSET;
-+    priv->dmaBase = vaddr + DMA_BASE_OFFSET;
-+
-+    // Initialise IRQ ownership to not owned
-+    priv->have_irq = 0;
-+
-+    // Lock protecting access to CoPro command queue functions or direct access
-+    // to the GMAC interrupt enable register if CoPro is not in use
-+    spin_lock_init(&priv->cmd_que_lock_);
-+
-+#ifdef CONFIG_LEON_COPRO
-+    sema_init(&copro_stop_semaphore, 0);
-+    sema_init(&copro_start_semaphore, 0);
-+    sema_init(&copro_int_clr_semaphore, 0);
-+    sema_init(&copro_update_semaphore, 0);
-+    sema_init(&copro_rx_enable_semaphore, 0);
-+    priv->copro_a_irq_alloced_ = 0;
-+    priv->copro_b_irq_alloced_ = 0;
-+    sema_init(&priv->copro_stop_complete_semaphore_, 0);
-+    INIT_LIST_HEAD(&priv->copro_tx_skb_list_);
-+    priv->copro_tx_skb_list_count_ = 0;
-+#endif // CONFIG_LEON_COPRO
-+
-+    init_timer(&priv->watchdog_timer);
-+    priv->watchdog_timer.function = &watchdog_timer_action;
-+    priv->watchdog_timer.data = (unsigned long)priv;
-+
-+    // Set pointer to device in private data
-+    priv->netdev = netdev;
-+
-+    /** Do something here to detect the present or otherwise of the MAC
-+     *  Read the version register as a first test */
-+    version = mac_reg_read(priv, MAC_VERSION_REG);
-+    synopsis_version = version & 0xff;
-+    vendor_version   = (version >> 8) & 0xff;
-+
-+    /** Assume device is at the adr and irq specified until have probing working */
-+    netdev->base_addr  = vaddr;
-+    netdev->irq        = irq;
-+#ifdef CONFIG_LEON_COPRO
-+    priv->copro_a_irq_ = copro_a_irq;
-+    priv->copro_b_irq_ = copro_b_irq;
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+    // Allocate the CoPro A IRQ
-+    err = request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", netdev);
-+    if (err) {
-+        DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq A (%d)\n", netdev->name, priv->copro_a_irq_);
-+        goto probe_err_out;
-+    }
-+    // Release the CoPro A IRQ again, as open()/stop() should manage IRQ ownership
-+    free_irq(priv->copro_a_irq_, netdev);
-+
-+    // Allocate the CoPro B IRQ
-+    err = request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", netdev);
-+    if (err) {
-+        DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq B (%d)\n", netdev->name, priv->copro_b_irq_);
-+        goto probe_err_out;
-+    }
-+    // Release the CoPro B IRQ again, as open()/stop() should manage IRQ ownership
-+    free_irq(priv->copro_b_irq_, netdev);
-+#else // CONFIG_LEON_COPRO
-+    // Allocate the IRQ
-+    err = request_irq(netdev->irq, &int_handler, 0, netdev->name, netdev);
-+    if (err) {
-+        DBG(1, KERN_ERR "probe() %s: Failed to allocate irq %d\n", netdev->name, netdev->irq);
-+        goto probe_err_out;
-+    }
-+
-+    // Release the IRQ again, as open()/stop() should manage IRQ ownership
-+    free_irq(netdev->irq, netdev);
-+#endif // CONFIG_LEON_COPRO
-+
-+    // Initialise the ethernet device with std. contents
-+    ether_setup(netdev);
-+
-+    // Tell the kernel of our MAC address
-+	for (i = 0; i < netdev->addr_len; i++) {
-+		netdev->dev_addr[i] = (unsigned char)mac_adr[i];
-+	}
-+
-+    // Setup operations pointers
-+    netdev->open               = &open;
-+    netdev->hard_start_xmit    = &hard_start_xmit;
-+    netdev->stop               = &stop;
-+    netdev->get_stats          = &get_stats;
-+    netdev->change_mtu         = &change_mtu;
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+    netdev->poll_controller    = &netpoll;
-+#endif // CONFIG_NET_POLL_CONTROLLER
-+    netdev->set_mac_address    = &set_mac_address;
-+    netdev->set_multicast_list = &set_multicast_list;
-+
-+	// Initialise NAPI support
-+	netif_napi_add(netdev, &priv->napi_struct, &poll, NAPI_POLL_WEIGHT);
-+
-+    set_ethtool_ops(netdev);
-+
-+    if (debug) {
-+      netdev->flags |= IFF_DEBUG;
-+    }
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TSO)
-+    // Do TX H/W checksum and SG list processing
-+    netdev->features |= NETIF_F_HW_CSUM;
-+    netdev->features |= NETIF_F_SG;
-+
-+    // Do hardware TCP/IP Segmentation Offload
-+    netdev->features |= NETIF_F_TSO;
-+#elif !defined(CONFIG_LEON_COPRO) && !defined(CONFIG_OXNAS_VERSION_0X800)
-+    // Do TX H/W checksum and SG list processing
-+    netdev->features |= NETIF_F_HW_CSUM;
-+    netdev->features |= NETIF_F_SG;
-+#endif // USE_TX_CSUM
-+
-+    // We take care of our own TX locking
-+    netdev->features |= NETIF_F_LLTX;
-+
-+    // Initialise PHY support
-+    priv->mii.phy_id_mask   = 0x1f;
-+    priv->mii.reg_num_mask  = 0x1f;
-+    priv->mii.force_media   = 0;
-+    priv->mii.full_duplex   = 1;
-+    priv->mii.using_100     = 0;
-+    priv->mii.using_1000    = 1;
-+	priv->mii.using_pause   = 1;
-+    priv->mii.dev           = netdev;
-+    priv->mii.mdio_read     = phy_read;
-+    priv->mii.mdio_write    = phy_write;
-+
-+    priv->gmii_csr_clk_range = 5;   // Slowest for now
-+
-+    // Use simple mux for 25/125 Mhz clock switching and
-+    // enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
-+	reg_contents = readl(SYS_CTRL_GMAC_CTRL);
-+	reg_contents |= ((1UL << SYS_CTRL_GMAC_SIMPLE_MAX) |
-+					  (1UL << SYS_CTRL_GMAC_CKEN_GTX));
-+    writel(reg_contents, SYS_CTRL_GMAC_CTRL);
-+
-+    // Remember whether auto-negotiation is allowed
-+#ifdef ALLOW_AUTONEG
-+    priv->ethtool_cmd.autoneg = 1;
-+	priv->ethtool_pauseparam.autoneg = 1;
-+#else // ALLOW_AUTONEG
-+    priv->ethtool_cmd.autoneg = 0;
-+	priv->ethtool_pauseparam.autoneg = 0;
-+#endif // ALLOW_AUTONEG
-+
-+    // Set up PHY mode for when auto-negotiation is not allowed
-+    priv->ethtool_cmd.speed = SPEED_1000;
-+    priv->ethtool_cmd.duplex = DUPLEX_FULL;
-+    priv->ethtool_cmd.port = PORT_MII;
-+    priv->ethtool_cmd.transceiver = XCVR_INTERNAL;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+	// We can support both reception and generation of pause frames
-+	priv->ethtool_pauseparam.rx_pause = 1;
-+	priv->ethtool_pauseparam.tx_pause = 1;
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+    // Initialise the set of features we would like to advertise as being
-+	// available for negotiation
-+    priv->ethtool_cmd.advertising = (ADVERTISED_10baseT_Half |
-+                                     ADVERTISED_10baseT_Full |
-+                                     ADVERTISED_100baseT_Half |
-+                                     ADVERTISED_100baseT_Full |
-+#if !defined(CONFIG_OXNAS_VERSION_0X800) || defined(ALLOW_OX800_1000M)
-+                                     ADVERTISED_1000baseT_Half |
-+                                     ADVERTISED_1000baseT_Full |
-+									  ADVERTISED_Pause |
-+									  ADVERTISED_Asym_Pause |
-+#endif
-+                                     ADVERTISED_Autoneg |
-+                                     ADVERTISED_MII);
-+
-+    // Attempt to locate the PHY
-+    phy_detect(netdev);
-+    priv->ethtool_cmd.phy_address = priv->mii.phy_id;
-+
-+    // Did we find a PHY?
-+	if (priv->phy_type == PHY_TYPE_NONE) {
-+		printk(KERN_WARNING "%s: No PHY found\n", netdev->name);
-+		err = ENXIO;
-+		goto probe_err_out;
-+    }
-+
-+	// Setup the PHY
-+	initialise_phy(priv);
-+
-+	// Find out what modes the PHY supports
-+	priv->ethtool_cmd.supported = get_phy_capabilies(priv);
-+#if defined(CONFIG_OXNAS_VERSION_0X800) && !defined(ALLOW_OX800_1000M)
-+	// OX800 has broken 1000M support in the MAC
-+	priv->ethtool_cmd.supported &= ~(SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half);
-+#endif
-+
-+    // Register the device with the network intrastructure
-+    err = register_netdev(netdev);
-+    if (err) {
-+        DBG(1, KERN_ERR "probe() %s: Failed to register device\n", netdev->name);
-+        goto probe_err_out;
-+    }
-+
-+    // Record details about the hardware we found
-+    printk(KERN_NOTICE "%s: GMAC ver = %u, vendor ver = %u at 0x%lx, IRQ %d\n", netdev->name, synopsis_version, vendor_version, netdev->base_addr, netdev->irq);
-+#ifndef ARMULATING
-+    printk(KERN_NOTICE "%s: Found PHY at address %u, type 0x%08x -> %s\n", priv->netdev->name, priv->phy_addr, priv->phy_type, (priv->ethtool_cmd.supported & SUPPORTED_1000baseT_Full) ? "10/100/1000" : "10/100");
-+#endif // !ARMULATING
-+    printk(KERN_NOTICE "%s: Ethernet addr: ", priv->netdev->name);
-+    for (i = 0; i < 5; i++) {
-+        printk("%02x:", netdev->dev_addr[i]);
-+    }
-+    printk("%02x\n", netdev->dev_addr[5]);
-+
-+#ifdef CONFIG_LEON_COPRO
-+    // Define sizes of queues for communicating with the CoPro
-+    priv->copro_cmd_que_num_entries_ = COPRO_CMD_QUEUE_NUM_ENTRIES;
-+    priv->copro_tx_que_num_entries_ = COPRO_TX_QUEUE_NUM_ENTRIES;
-+#endif // CONFIG_LEON_COPRO 
-+
-+	// Initialise sysfs for link state reporting
-+	err = gmac_link_state_init_sysfs(priv);
-+	if (err) {
-+        DBG(1, KERN_ERR "probe() %s: Failed to initialise sysfs support\n", netdev->name);
-+        goto probe_err_out;
-+	}
-+
-+	// Initialise the work queue entry to be used to issue hotplug events to userspace
-+	INIT_WORK(&priv->link_state_change_work, work_handler);
-+
-+    return 0;
-+
-+probe_err_out:
-+#ifdef CONFIG_LEON_COPRO 
-+    shutdown_copro();
-+
-+    if (priv->shared_copro_params_) {
-+        // Free the DMA coherent parameter space
-+        dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
-+        priv->shared_copro_params_ = 0;
-+    }
-+#endif // CONFIG_LEON_COPRO 
-+
-+    // Disable the clock to the MAC block
-+    writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+    return err;
-+}
-+
-+static int gmac_found_count = 0;
-+static struct net_device* gmac_netdev[MAX_GMAC_UNITS];
-+
-+/**
-+ * External entry point to the driver, called from Space.c to detect a card
-+ */
-+struct net_device* __init synopsys_gmac_probe(int unit)
-+{
-+    int err = 0;
-+    struct net_device *netdev = alloc_etherdev(sizeof(gmac_priv_t));
-+
-+    printk(KERN_NOTICE "Probing for Synopsis GMAC, unit %d\n", unit);
-+
-+    // Will allocate private data later, as may want descriptors etc in special memory
-+    if (!netdev) {
-+        printk(KERN_WARNING "synopsys_gmac_probe() failed to alloc device\n");
-+        err = -ENODEV;
-+    } else {
-+        if (unit >= 0) {
-+            sprintf(netdev->name, "eth%d", unit);
-+
-+            netdev_boot_setup_check(netdev);
-+
-+            if (gmac_found_count >= MAX_GMAC_UNITS) {
-+                err = -ENODEV;
-+            } else {
-+                err = probe(netdev, MAC_BASE, MAC_INTERRUPT, SEM_A_INTERRUPT, SEM_B_INTERRUPT);
-+                if (err) {
-+                    printk(KERN_WARNING "synopsys_gmac_probe() Probing failed for %s\n", netdev->name);
-+                } else {
-+                    ++gmac_found_count;
-+                }
-+            }
-+        }
-+
-+        if (err) {
-+            netdev->reg_state = NETREG_UNREGISTERED;
-+            free_netdev(netdev);
-+        } else {
-+			gmac_netdev[unit] = netdev;
-+		}
-+    }
-+
-+    return ERR_PTR(err);
-+}
-+
-+static int __init gmac_module_init(void)
-+{
-+	return (int)synopsys_gmac_probe(0);
-+}
-+module_init(gmac_module_init);
-+
-+static void __exit gmac_module_cleanup(void)
-+{
-+	int i;
-+	for (i=0; i < gmac_found_count; i++) {
-+		stop(gmac_netdev[i]);
-+		gmac_netdev[i]->reg_state = NETREG_UNREGISTERED;
-+		free_netdev(gmac_netdev[i]);
-+	}
-+}
-+module_exit(gmac_module_cleanup);
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,194 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#if !defined(__GMAC_H__)
-+#define __GMAC_H__
-+
-+#include <asm/semaphore.h>
-+#include <asm/types.h>
-+#include <linux/mii.h>
-+#include <linux/netdevice.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/list.h>
-+#include <linux/ethtool.h>
-+#include <linux/kobject.h>
-+#include <asm/arch/desc_alloc.h>
-+#include <asm/arch/dma.h>
-+#ifdef CONFIG_LEON_COPRO
-+#include <asm/arch/leon.h>
-+#include "gmac_offload.h"
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef GMAC_DEBUG
-+#define DBG(n, args...)\
-+    do {\
-+        if ((n) <= priv->msg_level)\
-+            printk(args);\
-+    } while (0)
-+#else
-+#define DBG(n, args...)   do { } while(0)
-+#endif
-+
-+#define MS_TO_JIFFIES(x) (((x) < (1000/(HZ))) ? 1 : (x) * (HZ) / 1000)
-+
-+#define USE_RX_CSUM
-+//#define ARMULATING
-+
-+typedef struct gmac_desc_list_info {
-+    volatile gmac_dma_desc_t *base_ptr;
-+    gmac_dma_desc_t          *shadow_ptr;
-+    int                       num_descriptors;
-+    int                       empty_count;
-+    int                       full_count;
-+    int                       r_index;
-+    int                       w_index;
-+} gmac_desc_list_info_t;
-+
-+#ifdef CONFIG_LEON_COPRO
-+typedef struct copro_params {
-+    u32 cmd_que_head_;
-+    u32 cmd_que_tail_;
-+    u32 fwd_intrs_mailbox_;
-+    u32 tx_que_head_;
-+    u32 tx_que_tail_;
-+    u32 free_start_;
-+    u32 mtu_;
-+    u32 rx_mitigation_;
-+    u32 rx_mitigation_frames_;
-+    u32 rx_mitigation_usec_;
-+} __attribute ((aligned(4),packed)) copro_params_t;
-+#endif // CONFIG_LEON_COPRO
-+
-+typedef struct tx_frag_info {
-+    dma_addr_t  phys_adr;
-+    u16         length;
-+} tx_frag_info_t;
-+
-+// Private data structure for the GMAC driver
-+typedef struct gmac_priv {
-+    /** Base address of GMAC MAC registers */
-+    u32                       macBase;
-+    /** Base address of GMAC DMA registers */
-+    u32                       dmaBase;
-+
-+    struct net_device*        netdev;
-+
-+    struct net_device_stats   stats;
-+
-+    u32                       msg_level;
-+    
-+    /** Whether we own an IRQ */
-+    int                       have_irq;
-+
-+    /** Pointer to outstanding tx packet that has not yet been queued due to
-+     *  lack of descriptors */
-+    struct sk_buff           *tx_pending_skb;
-+    tx_frag_info_t            tx_pending_fragments[18];
-+    int                       tx_pending_fragment_count;
-+
-+    /** DMA consistent physical address of outstanding tx packet */
-+    dma_addr_t                tx_pending_dma_addr;
-+    unsigned long             tx_pending_length;
-+
-+    /** To synchronise ISR and thread TX activities' access to private data */
-+    spinlock_t                tx_spinlock_;
-+
-+    /** To synchronise access to the PHY */
-+    spinlock_t                phy_lock;
-+
-+    /** The timer for NAPI polling when out of memory when trying to fill RX
-+     *  descriptor ring */
-+
-+    /** PHY related info */
-+    struct mii_if_info        mii;
-+    struct ethtool_cmd        ethtool_cmd;
-+	struct ethtool_pauseparam ethtool_pauseparam;
-+    u32                       phy_addr;
-+    u32                       phy_type;
-+    int                       gmii_csr_clk_range;
-+
-+    /** Periodic timer to check link status etc */
-+    struct timer_list         watchdog_timer;
-+    volatile int              watchdog_timer_shutdown;
-+
-+    /** The number of descriptors in the gmac_dma_desc_t array holding both the TX and
-+     *  RX descriptors. The TX descriptors reside at the start of the array */
-+    unsigned                  total_num_descriptors;
-+    /** The CPU accessible virtual address of the start of the descriptor array */
-+    gmac_dma_desc_t*          desc_vaddr;
-+    /** The hardware accessible physical address of the start of the descriptor array */
-+    dma_addr_t                desc_dma_addr;
-+
-+    /** Descriptor list management */
-+    gmac_desc_list_info_t     tx_gmac_desc_list_info;
-+    gmac_desc_list_info_t     rx_gmac_desc_list_info;
-+    
-+    /** Record of disabling RX overflow interrupts */
-+    unsigned                  rx_overflow_ints_disabled;
-+
-+    /** The result of the last H/W DMA generated checksum operation */
-+    u16                       tx_csum_result_;
-+
-+    /** Whether we deal in jumbo frames */
-+    int                       jumbo_;
-+
-+    volatile int              mii_init_media;
-+    volatile int              phy_force_negotiation;
-+
-+#ifdef CONFIG_LEON_COPRO
-+    /** DMA coherent memory for CoPro's parameter storage */
-+    copro_params_t  *shared_copro_params_;
-+    dma_addr_t       shared_copro_params_pa_;
-+
-+    /** ARM's local CoPro parameter storage */
-+    copro_params_t   copro_params_;
-+
-+    /** Queue for commands/acks to/from CoPro */
-+    int              copro_a_irq_;
-+    int              copro_a_irq_alloced_;
-+    int              copro_b_irq_;
-+    int              copro_b_irq_alloced_;
-+    cmd_que_t        cmd_queue_;
-+    tx_que_t         tx_queue_;
-+    int              copro_cmd_que_num_entries_;
-+    int              copro_tx_que_num_entries_;
-+	struct semaphore copro_stop_complete_semaphore_;
-+	struct list_head copro_tx_skb_list_;
-+	int				 copro_tx_skb_list_count_;
-+#endif // CONFIG_LEON_COPRO
-+
-+    spinlock_t       cmd_que_lock_;
-+	u32				  rx_buffer_size_;
-+	int				  rx_buffers_per_page;
-+
-+	gmac_dma_desc_t *tx_desc_shadow_;
-+	gmac_dma_desc_t *rx_desc_shadow_;
-+
-+	struct napi_struct napi_struct;
-+
-+	/** sysfs dir tree root for recovery button driver */
-+	struct kset        link_state_kset;
-+	struct kobject     link_state_kobject;
-+	struct work_struct link_state_change_work;
-+	int                link_state;
-+} gmac_priv_t;
-+
-+#endif        //  #if !defined(__GMAC_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,452 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_desc.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/delay.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_desc.h"
-+
-+void init_rx_desc_list(
-+    gmac_desc_list_info_t    *desc_list,
-+    volatile gmac_dma_desc_t *base_ptr,
-+	gmac_dma_desc_t          *shadow_ptr,
-+    int                       num_descriptors,
-+	u16                       rx_buffer_length)
-+{
-+    int i;
-+
-+    desc_list->base_ptr = base_ptr;
-+    desc_list->shadow_ptr = shadow_ptr;
-+    desc_list->num_descriptors = num_descriptors;
-+    desc_list->empty_count = num_descriptors;
-+    desc_list->full_count = 0;
-+    desc_list->r_index = 0;
-+    desc_list->w_index = 0;
-+
-+	for (i=0; i < num_descriptors; ++i) {
-+		gmac_dma_desc_t          *shadow = shadow_ptr + i;
-+		volatile gmac_dma_desc_t *desc   = base_ptr + i;
-+
-+		// Initialise the shadow descriptor
-+		shadow->status = 0;
-+		shadow->length = (rx_buffer_length << RDES1_RBS1_BIT);
-+		if (i == (num_descriptors - 1)) {
-+			shadow->length |= (1UL << RDES1_RER_BIT);
-+		}
-+		shadow->buffer1 = 0;
-+		shadow->buffer2 = 0;
-+
-+		// Copy the shadow descriptor into the real descriptor
-+		desc->status  = shadow->status;
-+		desc->length  = shadow->length;
-+		desc->buffer1 = shadow->buffer1;
-+		desc->buffer2 = shadow->buffer2;
-+	}
-+}
-+
-+void init_tx_desc_list(
-+    gmac_desc_list_info_t    *desc_list,
-+    volatile gmac_dma_desc_t *base_ptr,
-+	gmac_dma_desc_t          *shadow_ptr,
-+    int                       num_descriptors)
-+{
-+    int i;
-+
-+    desc_list->base_ptr = base_ptr;
-+    desc_list->shadow_ptr = shadow_ptr;
-+    desc_list->num_descriptors = num_descriptors;
-+    desc_list->empty_count = num_descriptors;
-+    desc_list->full_count = 0;
-+    desc_list->r_index = 0;
-+    desc_list->w_index = 0;
-+
-+	for (i=0; i < num_descriptors; ++i) {
-+		gmac_dma_desc_t          *shadow = shadow_ptr + i;
-+		volatile gmac_dma_desc_t *desc   = base_ptr + i;
-+
-+		// Initialise the shadow descriptor
-+		shadow->status = 0;
-+		shadow->length = (1UL << TDES1_IC_BIT);
-+		if (i == (num_descriptors - 1)) {
-+			shadow->length |= (1UL << TDES1_TER_BIT);
-+		}
-+		shadow->buffer1 = 0;
-+		shadow->buffer2 = 0;
-+
-+		// Copy the shadow descriptor into the real descriptor
-+		desc->status  = shadow->status;
-+		desc->length  = shadow->length;
-+		desc->buffer1 = shadow->buffer1;
-+		desc->buffer2 = shadow->buffer2;
-+	}
-+}
-+
-+void rx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+    int i;
-+    for (i=0; i < desc_list->num_descriptors; ++i) {
-+        (desc_list->base_ptr + i)->status &= ~(1UL << RDES0_OWN_BIT);
-+    }
-+
-+    // Ensure all write to the descriptor shared with MAC have completed
-+    wmb();
-+}
-+
-+void tx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+    int i;
-+    for (i=0; i < desc_list->num_descriptors; ++i) {
-+        (desc_list->base_ptr + i)->status &= ~(1UL << TDES0_OWN_BIT);
-+    }
-+
-+    // Ensure all write to the descriptor shared with MAC have completed
-+    wmb();
-+}
-+
-+int set_rx_descriptor(
-+    gmac_priv_t    *priv,
-+    rx_frag_info_t *frag_info)
-+{
-+    int index = -1;
-+
-+    // Is there a Rx descriptor available for writing by the CPU?
-+    if (available_for_write(&priv->rx_gmac_desc_list_info)) {
-+        // Setup the descriptor required to describe the RX packet
-+        volatile gmac_dma_desc_t *descriptor;
-+        gmac_dma_desc_t          *shadow;
-+
-+        // Get the index of the next RX descriptor available for writing by the CPU
-+        index = priv->rx_gmac_desc_list_info.w_index;
-+
-+        // Get a pointer to the next RX descriptor available for writing by the CPU
-+        descriptor = priv->rx_gmac_desc_list_info.base_ptr   + index;
-+        shadow     = priv->rx_gmac_desc_list_info.shadow_ptr + index;
-+
-+        // Set first buffer pointer to buffer from skb
-+        descriptor->buffer1 = shadow->buffer1 = frag_info->phys_adr;
-+
-+        // Remember the skb associated with the buffer
-+        shadow->buffer2 = (u32)frag_info->page;
-+
-+        // Ensure all prior writes to the descriptor shared with MAC have
-+        // completed before setting the descriptor ownership flag to transfer
-+        // ownership to the GMAC
-+        wmb();
-+
-+        // Set RX descriptor status to transfer ownership to the GMAC
-+        descriptor->status = (1UL << RDES0_OWN_BIT);
-+
-+        // Update the index of the next descriptor available for writing by the CPU
-+        priv->rx_gmac_desc_list_info.w_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
-+
-+        // Account for the descriptor used to hold the new packet
-+        --priv->rx_gmac_desc_list_info.empty_count;
-+        ++priv->rx_gmac_desc_list_info.full_count;
-+    }
-+
-+    return index;
-+}
-+
-+int get_rx_descriptor(
-+    gmac_priv_t    *priv,
-+    int            *last,
-+    u32            *status,
-+    rx_frag_info_t *frag_info)
-+{
-+	int                       index;
-+	volatile gmac_dma_desc_t *descriptor;
-+	gmac_dma_desc_t          *shadow;
-+	u32                       desc_status;
-+
-+	if (!priv->rx_gmac_desc_list_info.full_count) {
-+		return -2;
-+	}
-+
-+	// Get the index of the descriptor released the longest time ago by the GMAC DMA 
-+    index       = priv->rx_gmac_desc_list_info.r_index;
-+	descriptor  = priv->rx_gmac_desc_list_info.base_ptr   + index;
-+	shadow      = priv->rx_gmac_desc_list_info.shadow_ptr + index;
-+
-+	if (status && *status) {
-+		desc_status = *status;
-+	} else {
-+		desc_status = descriptor->status;
-+	}
-+
-+    if (desc_status & (1UL << RDES0_OWN_BIT)) {
-+		return -1;
-+	}
-+
-+	// Update the index of the next descriptor with which the GMAC DMA may have finished
-+	priv->rx_gmac_desc_list_info.r_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
-+
-+	// Account for the descriptor which is now no longer waiting to be processed by the CPU
-+	++priv->rx_gmac_desc_list_info.empty_count;
-+	--priv->rx_gmac_desc_list_info.full_count;
-+
-+	// Get packet details from the descriptor
-+	frag_info->page = (struct page*)(shadow->buffer2);
-+	frag_info->phys_adr = shadow->buffer1;
-+	frag_info->length = get_rx_length(desc_status);
-+
-+	// Is this descriptor the last contributing to a packet
-+	*last = desc_status & (1UL << RDES0_LS_BIT);
-+
-+	// Accumulate the status
-+	if (status && !*status) {
-+		*status = desc_status;
-+	}
-+
-+    return index;
-+}
-+
-+static inline int num_descriptors_needed(u16 length)
-+{
-+	static const int GMAC_MAX_DESC_ORDER = 11;
-+	static const u16 GMAC_MAX_DESC_MASK = ((1 << (GMAC_MAX_DESC_ORDER)) - 1);
-+
-+	int count = length >> GMAC_MAX_DESC_ORDER;
-+	if (length & GMAC_MAX_DESC_MASK) {
-+		++count;
-+	}
-+	if ((count * max_descriptor_length()) < length) {
-+		++count;
-+	}
-+
-+	return count;
-+}
-+
-+int set_tx_descriptor(
-+    gmac_priv_t    *priv,
-+    struct sk_buff *skb,
-+    tx_frag_info_t *frag_info,
-+    int             frag_count,
-+    int             use_hw_csum)
-+{
-+	int first_descriptor_index = -1;
-+	int num_descriptors = frag_count;
-+    int frag_index = 0;
-+	int check_oversized_frags = priv->netdev->mtu >= (max_descriptor_length() - ETH_HLEN);
-+
-+	if (unlikely(check_oversized_frags)) {
-+		// Calculate the number of extra descriptors required due to fragments
-+		// being longer than the maximum buffer size that can be described by a
-+		// single descriptor
-+		num_descriptors = 0;
-+		do {
-+			// How many descriptors are required to describe the fragment?
-+			num_descriptors += num_descriptors_needed(frag_info[frag_index].length);
-+		} while (++frag_index < frag_count);
-+	}
-+
-+    // Are sufficicent descriptors available for writing by the CPU?
-+    if (available_for_write(&priv->tx_gmac_desc_list_info) < num_descriptors) {
-+        return -1;
-+    }
-+
-+	{
-+		volatile gmac_dma_desc_t *previous_descriptor = 0;
-+		gmac_dma_desc_t          *previous_shadow = 0;
-+		volatile gmac_dma_desc_t *descriptors[num_descriptors];
-+		int desc_index = 0;
-+
-+		frag_index = 0;
-+		do {
-+			int        last_frag   = (frag_index == (frag_count - 1));
-+			u16        part_length = frag_info[frag_index].length;
-+			dma_addr_t phys_adr    = frag_info[frag_index].phys_adr;
-+			int        part        = 0;
-+			int        parts       = 1;
-+
-+			if (unlikely(check_oversized_frags)) {
-+				// How many descriptors are required to describe the fragment?
-+				parts = num_descriptors_needed(part_length);
-+			}
-+
-+			// Setup a descriptor for each part of the fragment that can be
-+			// described by a single descriptor
-+			do {
-+				int                       last_part  = (part == (parts - 1));
-+				int                       index      = priv->tx_gmac_desc_list_info.w_index;
-+				volatile gmac_dma_desc_t *descriptor = priv->tx_gmac_desc_list_info.base_ptr + index;
-+				gmac_dma_desc_t          *shadow     = priv->tx_gmac_desc_list_info.shadow_ptr + index;
-+				u32                       length     = shadow->length;
-+				u32                       buffer2    = 0;
-+
-+				// Remember descriptor pointer for final passing of ownership to GMAC
-+				descriptors[desc_index++] = descriptor;
-+
-+				// May have a second chained descriptor, but never a second buffer,
-+				// so clear the flag indicating whether there is a chained descriptor
-+				length &= ~(1UL << TDES1_TCH_BIT);
-+
-+				// Clear the first/last descriptor flags
-+				length &= ~((1UL << TDES1_LS_BIT) | (1UL << TDES1_FS_BIT));
-+
-+				// Set the Tx checksum mode
-+				length &= ~(((1UL << TDES1_CIC_NUM_BITS) - 1) << TDES1_CIC_BIT);
-+				if (use_hw_csum) {
-+					// Don't want full mode as network stack will have already
-+					// computed the TCP/UCP pseudo header and placed in into the
-+					// TCP/UCP checksum field
-+					length |= (TDES1_CIC_PAYLOAD << TDES1_CIC_BIT);
-+				}
-+				// Set fragment buffer length
-+				length &= ~(((1UL << TDES1_TBS1_NUM_BITS) - 1) << TDES1_TBS1_BIT);
-+				length |= ((part_length > max_descriptor_length() ? max_descriptor_length() : part_length) << TDES1_TBS1_BIT);
-+
-+				// Set fragment buffer address
-+				descriptor->buffer1 = shadow->buffer1 = phys_adr;
-+
-+				if (previous_shadow) {
-+					// Make the previous descriptor chain to the current one
-+					previous_shadow->length |= (1UL << TDES1_TCH_BIT);
-+					previous_descriptor->length = previous_shadow->length;
-+
-+					previous_shadow->buffer2 |= descriptors_virt_to_phys((u32)descriptor);
-+					previous_descriptor->buffer2 = previous_shadow->buffer2;
-+				}
-+
-+				// Is this the first desciptor for the packet?
-+				if (!frag_index && !part) {
-+					// Need to return index of first descriptor used for packet
-+					first_descriptor_index = index;
-+
-+					// Set flag indicating is first descriptor for packet
-+					length |= (1UL << TDES1_FS_BIT);
-+				}
-+
-+				// Is this the last descriptor for the packet?
-+				if (last_frag && last_part) {
-+					// Store the skb pointer with the last descriptor for packet, in
-+					// which the second buffer address will be unused as we do not use
-+					// second buffers and only intermedate buffers may use the chained
-+					// descriptor address
-+					buffer2 = (u32)skb;
-+
-+					// Set flag indicating is last descriptor for packet
-+					length |= (1UL << TDES1_LS_BIT);
-+				} else {
-+					// For descriptor chaining need to remember previous descriptor
-+					previous_descriptor = descriptor;
-+					previous_shadow = shadow;
-+
-+					// Is this descriptor not the last describing a single fragment
-+					// buffer?
-+					if (!last_part) {
-+						// This descriptor does not own the fragment buffer, so use
-+						// the (h/w ignored) lsb of buffer2 to encode this info.
-+						buffer2 = 1;
-+
-+						// Update the fragment buffer part details
-+						part_length -= max_descriptor_length();
-+						phys_adr    += max_descriptor_length();
-+					}
-+				}
-+
-+				// Write the assembled length descriptor entry to the descriptor
-+				descriptor->length = shadow->length = length;
-+
-+				// Write the assembled buffer2 descriptor entry to the descriptor
-+				shadow->buffer2 = buffer2;
-+
-+				// Update the index of the next descriptor available for writing by the CPU
-+				priv->tx_gmac_desc_list_info.w_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
-+			} while (++part < parts);
-+		} while (++frag_index < frag_count);
-+
-+		// Ensure all prior writes to the descriptors shared with MAC have
-+		// completed before setting the descriptor ownership flags to transfer
-+		// ownership to the GMAC
-+		wmb();
-+
-+		// Transfer descriptors to GMAC's ownership in reverse order, so when
-+		// GMAC begins processing the first descriptor all others are already
-+		// owned by the GMAC
-+		for (desc_index = (num_descriptors - 1); desc_index >= 0; --desc_index) {
-+			descriptors[desc_index]->status = (1UL << TDES0_OWN_BIT);
-+		}
-+	}
-+
-+    // Account for the number of descriptors used to hold the new packet
-+    priv->tx_gmac_desc_list_info.empty_count -= (num_descriptors);
-+    priv->tx_gmac_desc_list_info.full_count  += (num_descriptors);
-+
-+    return first_descriptor_index;
-+}
-+
-+int get_tx_descriptor(
-+    gmac_priv_t     *priv,
-+    struct sk_buff **skb,
-+    u32             *status,
-+    tx_frag_info_t  *frag_info,
-+    int             *buffer_owned)
-+{
-+    int index = -1;
-+	u32 local_status;
-+
-+    // Find the first available Tx descriptor
-+    if (tx_available_for_read(&priv->tx_gmac_desc_list_info, &local_status)) {
-+        gmac_dma_desc_t *shadow;
-+        u32 length;
-+        u32 buffer2;
-+
-+        // Get the descriptor released the longest time ago by the GMAC DMA
-+        index = priv->tx_gmac_desc_list_info.r_index;
-+        shadow = priv->tx_gmac_desc_list_info.shadow_ptr + index;
-+
-+        // Get the length of the buffer
-+        length = shadow->length;
-+        frag_info->length = ((length >> TDES1_TBS1_BIT) & ((1UL << TDES1_TBS1_NUM_BITS) - 1));
-+
-+        // Get a pointer to the buffer
-+        frag_info->phys_adr = shadow->buffer1;
-+
-+		// Get buffer ownership or skb info
-+        buffer2 = shadow->buffer2;
-+
-+        // Check that chained buffer not is use before setting skb from buffer2
-+        if (!(length & (1UL << TDES1_TCH_BIT))) {
-+            *skb = (struct sk_buff*)buffer2;
-+			*buffer_owned = 1;
-+        } else {
-+            // The lsb (h/w ignored) is used to encode buffer ownership
-+            *buffer_owned = !(buffer2 & 1);
-+			*skb = 0;
-+        }
-+
-+        // Accumulate status
-+        if (status) {
-+            *status |= local_status;
-+        }
-+
-+        // Update the index of the next descriptor with which the GMAC DMA may have finished
-+        priv->tx_gmac_desc_list_info.r_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
-+
-+        // Account for the descriptor which is now no longer waiting to be processed by the CPU
-+        ++priv->tx_gmac_desc_list_info.empty_count;
-+        --priv->tx_gmac_desc_list_info.full_count;
-+    }
-+
-+    return index;
-+}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,315 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_desc.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#if !defined(__GMAC_DESC_H__)
-+#define __GMAC_DESC_H__
-+
-+#include <asm/types.h>
-+#include "gmac.h"
-+
-+typedef enum rdes0 {
-+    RDES0_OWN_BIT  = 31,
-+    RDES0_AFM_BIT  = 30,
-+    RDES0_FL_BIT   = 16,
-+    RDES0_ES_BIT   = 15,
-+    RDES0_DE_BIT   = 14,
-+    RDES0_SAF_BIT  = 13,
-+    RDES0_LE_BIT   = 12,
-+    RDES0_OE_BIT   = 11,
-+    RDES0_IPC_BIT  = 10,
-+    RDES0_FS_BIT   = 9,
-+    RDES0_LS_BIT   = 8,
-+    RDES0_VLAN_BIT = 7,
-+    RDES0_LC_BIT   = 6,
-+    RDES0_FT_BIT   = 5,
-+    RDES0_RWT_BIT  = 4,
-+    RDES0_RE_BIT   = 3,
-+    RDES0_DRE_BIT  = 2,
-+    RDES0_CE_BIT   = 1,
-+    RDES0_PCE_BIT  = 0
-+} rdes0_t;
-+
-+#define RX_DESC_STATUS_FL_NUM_BITS 14
-+
-+typedef enum rdes1 {
-+    RDES1_DIC_BIT  = 31,
-+    RDES1_RER_BIT  = 25,
-+    RDES1_RCH_BIT  = 24,
-+    RDES1_RBS2_BIT = 11,
-+    RDES1_RBS1_BIT = 0,
-+} rdes1_t;
-+
-+#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
-+#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
-+
-+typedef enum tdes0 {
-+    TDES0_OWN_BIT = 31,
-+    TDES0_IHE_BIT = 16,
-+    TDES0_ES_BIT  = 15,
-+    TDES0_JT_BIT  = 14,
-+    TDES0_FF_BIT  = 13,
-+    TDES0_PCE_BIT = 12,
-+    TDES0_LOC_BIT = 11,
-+    TDES0_NC_BIT  = 10,
-+    TDES0_LC_BIT  = 9,
-+    TDES0_EC_BIT  = 8,
-+    TDES0_VF_BIT  = 7,
-+    TDES0_CC_BIT  = 3,
-+    TDES0_ED_BIT  = 2,
-+    TDES0_UF_BIT  = 1,
-+    TDES0_DB_BIT  = 0
-+} tdes0_t;
-+
-+#define TDES0_CC_NUM_BITS 4
-+
-+typedef enum tdes1 {
-+    TDES1_IC_BIT   = 31,
-+    TDES1_LS_BIT   = 30,
-+    TDES1_FS_BIT   = 29,
-+    TDES1_CIC_BIT  = 27,
-+    TDES1_DC_BIT   = 26,
-+    TDES1_TER_BIT  = 25,
-+    TDES1_TCH_BIT  = 24,
-+    TDES1_DP_BIT   = 23,
-+    TDES1_TBS2_BIT = 11,
-+    TDES1_TBS1_BIT = 0
-+} tdes1_t;
-+
-+#define TDES1_CIC_NUM_BITS  2
-+#define TDES1_TBS2_NUM_BITS 11
-+#define TDES1_TBS1_NUM_BITS 11
-+
-+#define TDES1_CIC_NONE    0
-+#define TDES1_CIC_HDR     1
-+#define TDES1_CIC_PAYLOAD 2
-+#define TDES1_CIC_FULL    3
-+
-+extern void init_rx_desc_list(
-+    gmac_desc_list_info_t    *desc_list,
-+    volatile gmac_dma_desc_t *base_ptr,
-+	gmac_dma_desc_t          *shadow_ptr,
-+    int                       num_descriptors,
-+	u16                       rx_buffer_length);
-+
-+extern void init_tx_desc_list(
-+    gmac_desc_list_info_t    *desc_list,
-+    volatile gmac_dma_desc_t *base_ptr,
-+	gmac_dma_desc_t          *shadow_ptr,
-+    int                       num_descriptors);
-+
-+/** Force ownership of all descriptors in the specified list to being owned by
-+ *  the CPU
-+ */
-+extern void rx_take_ownership(gmac_desc_list_info_t* desc_list);
-+
-+/** Force ownership of all descriptors in the specified list to being owned by
-+ *  the CPU
-+ */
-+extern void tx_take_ownership(gmac_desc_list_info_t* desc_list);
-+
-+/** Return the number of descriptors available for the CPU to fill with new
-+ *  packet info */
-+static inline int available_for_write(gmac_desc_list_info_t* desc_list)
-+{
-+    return desc_list->empty_count;
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ *  the GMAC DMA has finished */
-+static inline int tx_available_for_read(
-+	volatile gmac_desc_list_info_t *desc_list,
-+	u32                            *status)
-+{
-+	if (!desc_list->full_count) {
-+		return 0;
-+	}
-+
-+	*status = (desc_list->base_ptr + desc_list->r_index)->status;
-+
-+	if (*status & (1UL << TDES0_OWN_BIT)) {
-+		return 0;
-+	}
-+
-+	return 1;
-+}
-+
-+/**
-+ * Return non-zero if there is a descriptor available with a packet with which
-+ * the GMAC DMA has finished.
-+ */
-+static inline int rx_available_for_read(
-+	volatile gmac_desc_list_info_t *desc_list,
-+	u32                            *status)
-+{
-+	u32 local_status;
-+
-+	if (!desc_list->full_count) {
-+		return 0;
-+	}
-+
-+	local_status = (desc_list->base_ptr + desc_list->r_index)->status;
-+
-+    if (local_status & (1UL << RDES0_OWN_BIT)) {
-+		return 0;
-+	}
-+
-+	if (status) {
-+		*status = local_status;
-+	}
-+
-+    return 1;
-+}
-+
-+typedef struct rx_frag_info {
-+	struct page *page;
-+    dma_addr_t      phys_adr;
-+    u16             length;
-+} rx_frag_info_t;
-+
-+/**
-+ * Fill a RX descriptor and pass ownership to DMA engine
-+ */
-+extern int set_rx_descriptor(
-+    gmac_priv_t    *priv,
-+    rx_frag_info_t *frag_info);
-+
-+/**
-+ * Extract data from the next available descriptor with which the GMAC DMA
-+ * controller has finished.
-+ * The caller indicates via the 'first_last' argument whether the first
-+ * descriptor contributing to a packet is expected. The 'first_last' argument
-+ * will be returned set to indicate whether the descriptor was the last
-+ * contributing to a packet.
-+ * If the 'status' argument is non-null it will have the status from the
-+ * descriptor or'ed into it, thus enabling the compound status for all
-+ * descriptors contributing to a packet to be built up
-+ */
-+extern int get_rx_descriptor(
-+    gmac_priv_t    *priv,
-+    int            *last,
-+    u32            *status,
-+    rx_frag_info_t *frag_info);
-+
-+/**
-+ * Fill in descriptors describing all fragments in a single Tx packet and pass
-+ * ownership to the GMAC. The 'frag_info' argument points to an array describing
-+ * each buffer that is to contribute to the transmitted packet. The 'frag_count'
-+ * argument gives the number of elements in that array
-+ */
-+extern int set_tx_descriptor(
-+    gmac_priv_t    *priv,
-+    struct sk_buff *skb,
-+    tx_frag_info_t *frag_info,
-+    int             frag_count,
-+    int             use_hw_csum);
-+
-+/**
-+ * Extract information about the TX packet transmitted the longest time ago.
-+ * If the 'status' argument is non-null it will have the status from the
-+ * descriptor or'ed into it.
-+ */
-+extern int get_tx_descriptor(
-+    gmac_priv_t     *priv,
-+    struct sk_buff **skb,
-+    u32             *status,
-+    tx_frag_info_t  *frag_info,
-+    int             *buffer_owned); 
-+
-+/**
-+ * @param A u32 containing the status from a received frame's DMA descriptor
-+ * @return An int which is non-zero if a valid received frame has no error
-+ *         condititions flagged
-+ */
-+static inline int is_rx_valid(u32 status)
-+{
-+    return !(status & (1UL << RDES0_ES_BIT)) &&
-+           !(status & (1UL << RDES0_IPC_BIT));
-+}
-+
-+static inline int is_rx_dribbling(u32 status)
-+{
-+    return status & (1UL << RDES0_DRE_BIT);
-+}
-+
-+static inline u32 get_rx_length(u32 status)
-+{
-+    return (status >> RDES0_FL_BIT) & ((1UL << RX_DESC_STATUS_FL_NUM_BITS) - 1);
-+}
-+
-+static inline int is_rx_collision_error(u32 status)
-+{
-+    return status & ((1UL << RDES0_OE_BIT) | (1UL << RDES0_LC_BIT));
-+}
-+
-+static inline int is_rx_crc_error(u32 status)
-+{
-+    return status & (1UL << RDES0_CE_BIT);
-+}
-+
-+static inline int is_rx_frame_error(u32 status)
-+{
-+    return status & (1UL << RDES0_DE_BIT);
-+}
-+
-+static inline int is_rx_length_error(u32 status)
-+{
-+    return status & (1UL << RDES0_LE_BIT);
-+}
-+
-+static inline int is_rx_csum_error(u32 status)
-+{
-+    return (status & (1UL << RDES0_IPC_BIT))
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+           || (status & (1UL << RDES0_PCE_BIT))
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+           ;
-+}
-+
-+static inline int is_rx_long_frame(u32 status)
-+{
-+    return status & (1UL << RDES0_VLAN_BIT);
-+}
-+
-+static inline int is_tx_valid(u32 status)
-+{
-+    return !(status & (1UL << TDES0_ES_BIT));
-+}
-+
-+static inline int is_tx_collision_error(u32 status)
-+{
-+    return (status & (((1UL << TDES0_CC_NUM_BITS) - 1) << TDES0_CC_BIT)) >> TDES0_CC_BIT;
-+}
-+
-+static inline int is_tx_aborted(u32 status)
-+{
-+    return status & ((1UL << TDES0_LC_BIT) | (1UL << TDES0_EC_BIT));
-+}
-+
-+static inline int is_tx_carrier_error(u32 status)
-+{
-+    return status & ((1UL << TDES0_LOC_BIT) | (1UL << TDES0_NC_BIT));
-+}
-+
-+static inline u16 max_descriptor_length(void) {
-+	static const int GMAC_MAX_DESC_LEN = 2047;
-+
-+	return GMAC_MAX_DESC_LEN;
-+}
-+#endif  //  #if !defined(__GMAC_DESC_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,275 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_ethtool.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+ 
-+#include <asm/types.h>
-+#include <linux/errno.h>
-+#include <linux/ethtool.h>
-+#include <linux/netdevice.h>
-+#include <asm/io.h>
-+#include <asm/arch/leon.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_desc.h"
-+
-+static int get_settings(struct net_device* dev, struct ethtool_cmd* cmd)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long irq_flags;
-+    int status;
-+
-+    spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+    status = mii_ethtool_gset(&priv->mii, cmd);
-+    spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+    return status;
-+}
-+
-+static int set_settings(struct net_device* dev, struct ethtool_cmd* cmd)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long irq_flags;
-+    int status;
-+
-+    spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+    status = mii_ethtool_sset(&priv->mii, cmd);
-+    spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+    return status;
-+}
-+
-+static void get_drvinfo(struct net_device* dev, struct ethtool_drvinfo* drvinfo)
-+{
-+    strncpy(drvinfo->driver,     "GMAC", 32);
-+    strncpy(drvinfo->version,    "1.0", 32);
-+    strncpy(drvinfo->fw_version, "1.0", 32);    // Version of CoPro s/w
-+    strncpy(drvinfo->bus_info,   "AMBA", 32);
-+}
-+
-+static int nway_reset(struct net_device* dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long irq_flags;
-+    int status;
-+
-+    spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+    status = mii_nway_restart(&priv->mii);
-+    spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+    return status;
-+}
-+
-+static u32 get_msglevel(struct net_device* dev)
-+{
-+    return ((gmac_priv_t*)netdev_priv(dev))->msg_level;
-+}
-+
-+static void set_msglevel(struct net_device* dev, u32 data)
-+{
-+    ((gmac_priv_t*)netdev_priv(dev))->msg_level = data;
-+}
-+
-+static u32 get_rx_csum(struct net_device* dev)
-+{
-+#ifdef USE_RX_CSUM
-+	return 1;
-+#else
-+	return 0;
-+#endif
-+}
-+
-+static int set_rx_csum(struct net_device* dev, u32 data)
-+{
-+    return 0;
-+}
-+
-+static int get_regs_len(struct net_device* dev)
-+{
-+    return 0;
-+}
-+
-+static void get_regs(struct net_device* dev, struct ethtool_regs* regs, void *p)
-+{
-+    gmac_priv_t   *priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long  irq_state;
-+	u32            status;
-+
-+    printk("RX ring info:\n");
-+    printk("  num_descriptors     = %d\n", priv->rx_gmac_desc_list_info.num_descriptors);
-+    printk("  empty_count         = %d\n", priv->rx_gmac_desc_list_info.empty_count);
-+    printk("  full_count          = %d\n", priv->rx_gmac_desc_list_info.full_count);
-+    printk("  r_index             = %d\n", priv->rx_gmac_desc_list_info.r_index);
-+    printk("  w_index             = %d\n", priv->rx_gmac_desc_list_info.w_index);
-+    printk("  available_for_write = %d\n", available_for_write(&priv->rx_gmac_desc_list_info));
-+    printk("  available_for_read    %s\n", rx_available_for_read(&priv->rx_gmac_desc_list_info, 0) ? "yes" :"no");
-+
-+    spin_lock_irqsave(&priv->tx_spinlock_, irq_state);
-+    printk("TX ring info:\n");
-+    printk("  num_descriptors     = %d\n", priv->tx_gmac_desc_list_info.num_descriptors);
-+    printk("  empty_count         = %d\n", priv->tx_gmac_desc_list_info.empty_count);
-+    printk("  full_count          = %d\n", priv->tx_gmac_desc_list_info.full_count);
-+    printk("  r_index             = %d\n", priv->tx_gmac_desc_list_info.r_index);
-+    printk("  w_index             = %d\n", priv->tx_gmac_desc_list_info.w_index);
-+    printk("  available_for_write = %d\n", available_for_write(&priv->tx_gmac_desc_list_info));
-+    printk("  available_for_read    %s\n", tx_available_for_read(&priv->tx_gmac_desc_list_info, &status) ? "yes" : "no");
-+    spin_unlock_irqrestore(&priv->tx_spinlock_, irq_state);
-+}
-+
-+static void get_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
-+{
-+}
-+
-+static int set_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
-+{
-+    return -EINVAL;
-+}
-+
-+static int get_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    if (priv->copro_params_.rx_mitigation_) {
-+        ethtool_coalesce->rx_max_coalesced_frames = priv->copro_params_.rx_mitigation_frames_;
-+        ethtool_coalesce->rx_coalesce_usecs       = priv->copro_params_.rx_mitigation_usec_;
-+printk("get_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
-+    }
-+#endif // CONFIG_LEON_COPRO
-+   return 0;
-+}
-+
-+static int set_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    if (priv->copro_params_.rx_mitigation_) {
-+printk("set_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
-+        priv->copro_params_.rx_mitigation_frames_ = ethtool_coalesce->rx_max_coalesced_frames;
-+        priv->copro_params_.rx_mitigation_usec_   = ethtool_coalesce->rx_coalesce_usecs;
-+
-+        // Only attempt to write to uncached/unbuffered shared parameter storage
-+        // if CoPro is started and thus storage has been allocated
-+        if (priv->shared_copro_params_) {
-+            // Fill the CoPro parameter block
-+            memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+        }
-+
-+        // Make sure the CoPro parameter block updates have made it to memory (which
-+        // is uncached/unbuffered, so just compiler issues to overcome)
-+        wmb();
-+
-+        spin_lock(&priv->cmd_que_lock_);
-+        cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, 0);
-+        spin_unlock(&priv->cmd_que_lock_);
-+
-+        // Interrupt the CoPro so it sees the new command
-+        writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+    }
-+#endif // CONFIG_LEON_COPRO
-+
-+    return 0;
-+}
-+
-+static void get_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
-+{
-+}
-+
-+static int set_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
-+{
-+    return -EINVAL;
-+}
-+
-+static void get_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
-+{
-+}
-+
-+static int set_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
-+{
-+    return -EINVAL;
-+}
-+
-+static int self_test_count(struct net_device* dev)
-+{
-+    return -EINVAL;
-+}
-+
-+static void self_test(struct net_device* dev, struct ethtool_test* ethtool_test, u64 *data)
-+{
-+}
-+
-+static void get_strings(struct net_device* dev, u32 stringset, u8 *data)
-+{
-+}
-+
-+static int phys_id(struct net_device* dev, u32 data)
-+{
-+    return -EINVAL;
-+}
-+
-+static int get_stats_count(struct net_device* dev)
-+{
-+    return -EINVAL;
-+}
-+
-+static void get_ethtool_stats(struct net_device* dev, struct ethtool_stats* ethtool_stats, u64 *data)
-+{
-+}
-+
-+static struct ethtool_ops ethtool_ops = {
-+    .get_settings      = get_settings,
-+    .set_settings      = set_settings,
-+    .get_drvinfo       = get_drvinfo,
-+    .get_regs_len      = get_regs_len,
-+    .get_regs          = get_regs,
-+    .get_wol           = get_wol,
-+    .set_wol           = set_wol,
-+    .get_msglevel      = get_msglevel,
-+    .set_msglevel      = set_msglevel,
-+    .nway_reset        = nway_reset,
-+    .get_link          = ethtool_op_get_link,
-+    .get_coalesce      = get_coalesce,
-+    .set_coalesce      = set_coalesce,
-+    .get_ringparam     = get_ringparam,
-+    .set_ringparam     = set_ringparam,
-+    .get_pauseparam    = get_pauseparam,
-+    .set_pauseparam    = set_pauseparam,
-+    .get_rx_csum       = get_rx_csum,
-+    .set_rx_csum       = set_rx_csum,
-+    .get_tx_csum       = ethtool_op_get_tx_csum,
-+    .set_tx_csum       = ethtool_op_set_tx_csum,
-+    .get_sg            = ethtool_op_get_sg,
-+    .set_sg            = ethtool_op_set_sg,
-+    .get_tso           = ethtool_op_get_tso,
-+    .set_tso           = ethtool_op_set_tso,
-+    .self_test_count   = self_test_count,
-+    .self_test         = self_test,
-+    .get_strings       = get_strings,
-+    .phys_id           = phys_id,
-+    .get_stats_count   = get_stats_count,
-+    .get_ethtool_stats = get_ethtool_stats
-+};
-+
-+void set_ethtool_ops(struct net_device *netdev)
-+{
-+    SET_ETHTOOL_OPS(netdev, &ethtool_ops);
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,26 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_ethtool.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#if !defined(__GMAC_ETHTOOL_H__)
-+#define __GMAC_ETHTOOL_H__
-+
-+extern void set_ethtool_ops(struct net_device *netdev);
-+
-+#endif        //  #if !defined(__GMAC_ETHTOOL_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,223 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac-offload.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifdef CONFIG_LEON_COPRO
-+
-+#include <linux/slab.h>
-+#include "gmac.h"
-+
-+void cmd_que_init(
-+    cmd_que_t          *queue,
-+    gmac_cmd_que_ent_t *start,
-+    int                 num_entries)
-+{
-+    // Initialise queue management metadata
-+    INIT_LIST_HEAD(&queue->ack_list_);
-+    queue->head_ = start;
-+    queue->tail_ = start + num_entries;
-+    queue->w_ptr_ = queue->head_;
-+
-+    // Zeroise all entries in the queue
-+    memset(start, 0, num_entries * sizeof(gmac_cmd_que_ent_t));
-+}
-+
-+int cmd_que_dequeue_ack(cmd_que_t *queue)
-+{
-+    struct list_head *list_entry;
-+    cmd_que_ack_t    *ack;
-+
-+    if (list_empty(&queue->ack_list_)) {
-+        return -1;
-+    }
-+
-+    // Remove the first entry on the acknowledgement list
-+    list_entry = queue->ack_list_.next;
-+    BUG_ON(!list_entry);
-+
-+    // Get pointer to ack entry from it's list_head member        
-+    ack = list_entry(list_entry, cmd_que_ack_t, list_);
-+    BUG_ON(!ack);
-+    BUG_ON(!ack->entry_);
-+    BUG_ON(!ack->callback_);
-+
-+    // Has the CoPro acknowledged the command yet?
-+    if (!(ack->entry_->opcode_ & (1UL << GMAC_CMD_QUE_SKP_BIT))) {
-+        // No, so no further acknowledgements can be pending as CoPro executes
-+        // commands/acks in order
-+        return -1;
-+    }
-+
-+    // Going to process the acknowledgement, so remove it from the pending list
-+    list_del(list_entry);
-+
-+//printk("ak=0x%08x:0x%08x\n", ack->entry_->opcode_, ack->entry_->operand_);
-+    // Invoke the acknowledgement handler routine
-+    ack->callback_(ack->entry_);
-+
-+    // Reset ACK flag in command queue entry
-+    ack->entry_->opcode_ &= ~(1UL << GMAC_CMD_QUE_ACK_BIT);
-+
-+    kfree(ack);
-+    return 0;
-+}
-+
-+#define OPCODE_FLAGS_MASK ((1UL << (GMAC_CMD_QUE_OWN_BIT)) |\
-+                           (1UL << (GMAC_CMD_QUE_ACK_BIT)) |\
-+                           (1UL << (GMAC_CMD_QUE_SKP_BIT)))
-+
-+int cmd_que_queue_cmd(
-+    cmd_que_t            *queue,
-+    u32                   opcode,
-+    u32                   operand,
-+    cmd_que_ack_callback  callback)
-+{
-+    int result = -1;
-+
-+    do {
-+        volatile gmac_cmd_que_ent_t* entry = queue->w_ptr_;
-+        u32 old_opcode = entry->opcode_;
-+
-+        if (old_opcode & (1UL << GMAC_CMD_QUE_OWN_BIT)) {
-+            // Queue is full as we've run into an entry still owned by the CoPro
-+            break;
-+        }
-+
-+        if (!(old_opcode & (1UL << GMAC_CMD_QUE_ACK_BIT))) {
-+            // We've found an entry we own that isn't waiting for the contained
-+            // ack to be processed, so we can use it for the new command
-+            opcode &= ~(OPCODE_FLAGS_MASK);
-+            opcode |= (1UL << GMAC_CMD_QUE_OWN_BIT);
-+
-+            if (callback) {
-+                // Register ack. handler before releasing entry to CoPro
-+                cmd_que_ack_t *ack = kmalloc(sizeof(cmd_que_ack_t), GFP_ATOMIC);
-+                BUG_ON(!ack);
-+
-+                ack->entry_ = queue->w_ptr_;
-+                ack->callback_ = callback;
-+                INIT_LIST_HEAD(&ack->list_);
-+                list_add_tail(&ack->list_, &queue->ack_list_);
-+
-+                // Mark the entry as requiring an ack.
-+                opcode |= (1UL << GMAC_CMD_QUE_ACK_BIT);
-+            }
-+
-+            // Copy the command into the queue entry and pass ownership to the
-+            // CoPro, being sure to set the OWN flag last
-+//printk("op=0x%08x:0x%08x\n", opcode, operand);
-+            queue->w_ptr_->operand_ = operand;
-+            wmb();
-+            queue->w_ptr_->opcode_  = opcode;
-+            // Ensure the OWN flag gets to memory before any following interrupt
-+            // to the CoPro is issued
-+            wmb();
-+
-+            result = 0;
-+        }
-+
-+        // Make the write pointer point to the next potentially available entry
-+        if (++queue->w_ptr_ == queue->tail_) {
-+            queue->w_ptr_ = queue->head_;
-+        }
-+    } while (result);
-+
-+    return result;
-+}
-+
-+void tx_que_init(
-+    tx_que_t          *queue,
-+    gmac_tx_que_ent_t *start,
-+    int                num_entries)
-+{
-+    // Initialise queue management metadata
-+    queue->head_ = start;
-+    queue->tail_ = start + num_entries;
-+    queue->w_ptr_ = queue->head_;
-+    queue->r_ptr_ = queue->head_;
-+    queue->full_ = 0;
-+
-+    // Zeroise all entries in the queue
-+    memset(start, 0, num_entries * sizeof(gmac_tx_que_ent_t));
-+}
-+
-+static inline void tx_que_inc_w_ptr(tx_que_t *queue)
-+{
-+    if (++queue->w_ptr_ == queue->tail_) {
-+        queue->w_ptr_ = queue->head_;
-+    }
-+    queue->full_ = (queue->w_ptr_ == queue->r_ptr_);
-+}
-+
-+volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    tx_que_t *queue = &priv->tx_queue_;
-+    volatile gmac_tx_que_ent_t *entry = 0;
-+
-+    if (tx_que_not_empty(queue)) {
-+        entry = queue->r_ptr_;
-+        if (entry->flags_ & (1UL << TX_JOB_FLAGS_OWN_BIT)) {
-+            entry = (volatile gmac_tx_que_ent_t*)0;
-+        } else {
-+            tx_que_inc_r_ptr(queue);
-+        }
-+    }
-+
-+    return entry;
-+}
-+
-+/**
-+ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
-+ * before any subsequent call to tx_que_get_idle_job()
-+ */
-+volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    tx_que_t *queue = &priv->tx_queue_;
-+    volatile gmac_tx_que_ent_t *entry = 0;
-+
-+    // Must not reuse completed Tx packets returned by CoPro until the queue
-+    // reader has had a chance to process them
-+    if (!tx_que_is_full(queue)) {
-+        entry = queue->w_ptr_;
-+    }
-+
-+    return entry;
-+}
-+
-+/**
-+ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
-+ * before any subsequent call to tx_que_get_idle_job()
-+ */
-+void tx_que_new_job(
-+    struct net_device *dev,
-+    volatile gmac_tx_que_ent_t *entry)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    // Make sure any modifications to Tx job structures make it to memory before
-+    // setting the OWN flag to pass ownership to the CoPro
-+    wmb();
-+
-+    entry->flags_ |= (1UL << TX_JOB_FLAGS_OWN_BIT);
-+
-+    tx_que_inc_w_ptr(&priv->tx_queue_);
-+}
-+#endif // #ifdef CONFIG_LEON_COPRO
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,163 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac-offload.h
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifdef CONFIG_LEON_COPRO
-+
-+#if !defined(__GMAC_OFFLOAD_H__)
-+#define __GMAC_OFFLOAD_H__
-+
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+
-+#define GMAC_CMD_QUE_OWN_BIT 31 // 0-Owned by ARM, 1-Owned by CoPro
-+#define GMAC_CMD_QUE_ACK_BIT 30
-+#define GMAC_CMD_QUE_SKP_BIT 29
-+
-+typedef struct gmac_cmd_que_ent {
-+    u32 opcode_;
-+    u32 operand_;
-+} __attribute ((aligned(4),packed)) gmac_cmd_que_ent_t;
-+
-+#define GMAC_CMD_STOP               0
-+#define GMAC_CMD_START              1
-+#define GMAC_CMD_INT_EN_SET         2
-+#define GMAC_CMD_INT_EN_CLR         3
-+#define GMAC_CMD_HEARTBEAT          4
-+#define GMAC_CMD_UPDATE_PARAMS      5
-+#define GMAC_CMD_CHANGE_GIG_MODE    6
-+#define GMAC_CMD_CHANGE_RX_ENABLE   7
-+#define GMAC_CMD_CLEAR_RX_INTS      8
-+#define GMAC_CMD_CHANGE_PAUSE_MODE  9
-+
-+typedef void (*cmd_que_ack_callback)(volatile gmac_cmd_que_ent_t* entry);
-+
-+typedef struct cmd_que_ack {
-+    struct list_head             list_;
-+    volatile gmac_cmd_que_ent_t *entry_;
-+    cmd_que_ack_callback         callback_;
-+} cmd_que_ack_t;
-+
-+typedef struct cmd_que {
-+    gmac_cmd_que_ent_t          *head_;
-+    gmac_cmd_que_ent_t          *tail_;
-+    volatile gmac_cmd_que_ent_t *w_ptr_;
-+    struct list_head             ack_list_;
-+} cmd_que_t;
-+
-+extern void cmd_que_init(
-+    cmd_que_t          *queue,
-+    gmac_cmd_que_ent_t *start,
-+    int                 num_entries);
-+
-+extern int cmd_que_dequeue_ack(cmd_que_t *queue);
-+
-+extern int cmd_que_queue_cmd(
-+    cmd_que_t            *queue,
-+    u32                   opcode,
-+    u32                   operand,
-+    cmd_que_ack_callback  callback);    // non-zero if ack. required
-+
-+#define COPRO_SEM_INT_CMD 0
-+#define COPRO_SEM_INT_TX  1
-+
-+typedef struct gmac_fwd_intrs {
-+    u32 status_;
-+} __attribute ((aligned(4),packed)) gmac_fwd_intrs_t;
-+
-+#define TX_JOB_FLAGS_OWN_BIT              0
-+#define TX_JOB_FLAGS_COPRO_RESERVED_1_BIT 1
-+#define TX_JOB_FLAGS_ACCELERATE_BIT       2
-+
-+#define TX_JOB_STATS_BYTES_BIT 0
-+#define TX_JOB_STATS_BYTES_NUM_BITS 16
-+#define TX_JOB_STATS_BYTES_MASK (((1UL << TX_JOB_STATS_BYTES_NUM_BITS) - 1) << TX_JOB_STATS_BYTES_BIT)
-+#define TX_JOB_STATS_PACKETS_BIT 16
-+#define TX_JOB_STATS_PACKETS_NUM_BITS 6
-+#define TX_JOB_STATS_PACKETS_MASK (((1UL << TX_JOB_STATS_PACKETS_NUM_BITS) - 1) << TX_JOB_STATS_PACKETS_BIT)
-+#define TX_JOB_STATS_ABORT_BIT 22
-+#define TX_JOB_STATS_ABORT_NUM_BITS 3
-+#define TX_JOB_STATS_ABORT_MASK (((1UL << TX_JOB_STATS_ABORT_NUM_BITS) - 1) << TX_JOB_STATS_ABORT_BIT)
-+#define TX_JOB_STATS_CARRIER_BIT 25
-+#define TX_JOB_STATS_CARRIER_NUM_BITS 3
-+#define TX_JOB_STATS_CARRIER_MASK (((1UL << TX_JOB_STATS_CARRIER_NUM_BITS) - 1) << TX_JOB_STATS_CARRIER_BIT)
-+#define TX_JOB_STATS_COLLISION_BIT 28
-+#define TX_JOB_STATS_COLLISION_NUM_BITS 4
-+#define TX_JOB_STATS_COLLISION_MASK (((1UL << TX_JOB_STATS_COLLISION_NUM_BITS) - 1) << TX_JOB_STATS_COLLISION_BIT)
-+
-+/* Make even number else gmac_tx_que_ent_t struct below alignment will be wrong */
-+#define COPRO_NUM_TX_FRAGS_DIRECT 18
-+
-+typedef struct gmac_tx_que_ent {
-+    u32 skb_;
-+    u32 len_;
-+    u32 data_len_;
-+    u32 ethhdr_;
-+    u32 iphdr_;
-+    u16 iphdr_csum_;
-+    u16 tso_segs_;
-+    u16 tso_size_;
-+    u16 flags_;
-+    u32 frag_ptr_[COPRO_NUM_TX_FRAGS_DIRECT];
-+    u16 frag_len_[COPRO_NUM_TX_FRAGS_DIRECT];
-+    u32 statistics_;
-+} __attribute ((aligned(4),packed)) gmac_tx_que_ent_t;
-+
-+typedef struct tx_que {
-+    gmac_tx_que_ent_t          *head_;
-+    gmac_tx_que_ent_t          *tail_;
-+    volatile gmac_tx_que_ent_t *w_ptr_;
-+    volatile gmac_tx_que_ent_t *r_ptr_;
-+    int                         full_;
-+} tx_que_t;
-+
-+extern void tx_que_init(
-+    tx_que_t          *queue,
-+    gmac_tx_que_ent_t *start,
-+    int                num_entries);
-+
-+static inline int tx_que_not_empty(tx_que_t *queue)
-+{
-+    return (queue->r_ptr_ != queue->w_ptr_) || queue->full_;
-+}
-+
-+static inline int tx_que_is_full(tx_que_t *queue)
-+{
-+    return queue->full_;
-+}
-+
-+static inline void tx_que_inc_r_ptr(tx_que_t *queue)
-+{
-+    if (++queue->r_ptr_ == queue->tail_) {
-+        queue->r_ptr_ = queue->head_;
-+    }
-+    if (queue->full_) {
-+        queue->full_ = 0;
-+    }
-+}
-+
-+extern volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev);
-+
-+extern volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev);
-+
-+extern void tx_que_new_job(
-+    struct net_device *dev,
-+    volatile gmac_tx_que_ent_t *entry);
-+
-+#endif        //  #if !defined(__GMAC_OFFLOAD_H__)
-+#endif // CONFIG_LEON_COPRO
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,318 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_phy.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/delay.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_phy.h"
-+#include "gmac_reg.h"
-+
-+static const int PHY_TRANSFER_TIMEOUT_MS = 100;
-+
-+/*
-+ * Reads a register from the MII Management serial interface
-+ */
-+int phy_read(struct net_device *dev, int phyaddr, int phyreg)
-+{
-+    int data = 0;
-+#ifndef ARMULATING
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long end;
-+
-+    u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+               (phyreg << MAC_GMII_ADR_GR_BIT) |
-+               (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
-+               (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+    mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+    end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+    while (time_before(jiffies, end)) {
-+        if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+            // Successfully read from PHY
-+            data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
-+            break;
-+        }
-+    }
-+
-+    DBG(1, KERN_INFO "phy_read() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, data);
-+#endif // ARMULATING
-+
-+    return data;
-+}
-+
-+/*
-+ * Writes a register to the MII Management serial interface
-+ */
-+void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata)
-+{
-+#ifndef ARMULATING
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    unsigned long end;
-+
-+    u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+               (phyreg << MAC_GMII_ADR_GR_BIT) |
-+               (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
-+               (1UL << MAC_GMII_ADR_GW_BIT) |
-+               (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+    mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
-+    mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+    end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+    while (time_before(jiffies, end)) {
-+        if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+            break;
-+        }
-+    }
-+
-+    DBG(1, KERN_INFO "phy_write() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, phydata);
-+#endif // ARMULATING
-+}
-+
-+/*
-+ * Finds and reports the PHY address
-+ */
-+void phy_detect(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+#ifdef ARMULATING
-+    priv->mii.phy_id = 0;
-+    priv->phy_type = 0x22 << 16 | 0x1619;
-+    priv->phy_addr = 0;
-+#else // ARMULATING
-+    int phyaddr;
-+
-+    DBG(2, KERN_INFO "phy_detect() %s: Entered\n", priv->netdev->name);
-+
-+    // Scan all 32 PHY addresses if necessary
-+    priv->phy_type = 0;
-+    for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
-+        unsigned int id1, id2;
-+
-+        // Read the PHY identifiers
-+        id1 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID1);
-+        id2 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID2);
-+
-+        DBG(2, KERN_INFO "phy_detect() %s: PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", priv->netdev->name, phyaddr, id1, id2);
-+
-+        // Make sure it is a valid identifier
-+        if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-+            id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
-+            DBG(2, KERN_NOTICE "phy_detect() %s: Found PHY at address = %u\n", priv->netdev->name, phyaddr);
-+            priv->mii.phy_id = phyaddr & 31;
-+            priv->phy_type = id1 << 16 | id2;
-+            priv->phy_addr = phyaddr;
-+            break;
-+        }
-+    }
-+#endif // ARMULATING
-+}
-+
-+void start_phy_reset(gmac_priv_t* priv)
-+{
-+    // Ask the PHY to reset
-+    phy_write(priv->netdev, priv->phy_addr, MII_BMCR, BMCR_RESET);
-+}
-+
-+int is_phy_reset_complete(gmac_priv_t* priv)
-+{
-+#ifdef ARMULATING
-+    return 1;
-+#else // ARMULATING
-+    int complete = 0;
-+    int bmcr;
-+
-+    // Read back the status until it indicates reset, or we timeout
-+    bmcr = phy_read(priv->netdev, priv->phy_addr, MII_BMCR);
-+    if (!(bmcr & BMCR_RESET)) {
-+        complete = 1;
-+    }
-+
-+    return complete;
-+#endif // ARMULATING
-+}
-+
-+int phy_reset(struct net_device *dev)
-+{
-+#ifdef ARMULATING
-+    return 0;
-+#else // ARMULATING
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+    int complete = 0;
-+    unsigned long end;
-+
-+    // Start the reset operation
-+    start_phy_reset(priv);
-+
-+    // Total time to wait for reset to complete
-+    end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+
-+    // Should apparently wait at least 50mS before reading back from PHY; this
-+    // could just be a nasty feature of the SMC91x MAC/PHY and not apply to us
-+    msleep(50);
-+
-+    // Read back the status until it indicates reset, or we timeout
-+    while (!(complete = is_phy_reset_complete(priv)) && time_before(jiffies, end)) {
-+        msleep(1);
-+    }
-+
-+    return !complete;
-+#endif // ARMULATING
-+}
-+
-+void phy_powerdown(struct net_device *dev)
-+{
-+    gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+    unsigned int bmcr = phy_read(dev, priv->phy_addr, MII_BMCR);
-+    phy_write(dev, priv->phy_addr, MII_BMCR, bmcr | BMCR_PDOWN);
-+}
-+
-+void set_phy_negotiate_mode(struct net_device *dev)
-+{
-+    gmac_priv_t        *priv = (gmac_priv_t*)netdev_priv(dev);
-+    struct mii_if_info *mii = &priv->mii;
-+    struct ethtool_cmd *ecmd = &priv->ethtool_cmd;
-+    u32                 bmcr;
-+
-+	bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
-+
-+    if (ecmd->autoneg == AUTONEG_ENABLE) {
-+        u32 advert, tmp;
-+        u32 advert2 = 0, tmp2 = 0;
-+
-+//printk("set_phy_negotiate_mode() Auto negotiating link mode\n");
-+        // Advertise only what has been requested
-+        advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
-+        tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4 |
-+		                 ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-+
-+        if (ecmd->supported & (SUPPORTED_1000baseT_Full | ADVERTISE_1000HALF)) {
-+            advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-+            tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
-+        }
-+
-+        if (ecmd->advertising & ADVERTISED_10baseT_Half) {
-+            tmp |= ADVERTISE_10HALF;
-+        }
-+        if (ecmd->advertising & ADVERTISED_10baseT_Full) {
-+            tmp |= ADVERTISE_10FULL;
-+        }
-+        if (ecmd->advertising & ADVERTISED_100baseT_Half) {
-+            tmp |= ADVERTISE_100HALF;
-+        }
-+        if (ecmd->advertising & ADVERTISED_100baseT_Full) {
-+            tmp |= ADVERTISE_100FULL;
-+        }
-+        if ((ecmd->supported & SUPPORTED_1000baseT_Half) &&
-+            (ecmd->advertising & ADVERTISED_1000baseT_Half)) {
-+                tmp2 |= ADVERTISE_1000HALF;
-+        }
-+        if ((ecmd->supported & SUPPORTED_1000baseT_Full) &&
-+            (ecmd->advertising & ADVERTISED_1000baseT_Full)) {
-+                tmp2 |= ADVERTISE_1000FULL;
-+        }
-+
-+        if (ecmd->advertising & ADVERTISED_Pause) {
-+            tmp |= ADVERTISE_PAUSE_CAP;
-+        }
-+        if (ecmd->advertising & ADVERTISED_Asym_Pause) {
-+            tmp |= ADVERTISE_PAUSE_ASYM;
-+        }
-+
-+        if (advert != tmp) {
-+//printk("set_phy_negotiate_mode() Setting MII_ADVERTISE to 0x%08x\n", tmp);
-+            mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
-+            mii->advertising = tmp;
-+        }
-+        if (advert2 != tmp2) {
-+//printk("set_phy_negotiate_mode() Setting MII_CTRL1000 to 0x%08x\n", tmp2);
-+            mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
-+        }
-+
-+        // Auto-negotiate the link state
-+        bmcr |= (BMCR_ANRESTART | BMCR_ANENABLE);
-+        mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr);
-+    } else {
-+        u32 tmp;
-+//printk("set_phy_negotiate_mode() Unilaterally setting link mode\n");
-+
-+        // Turn off auto negotiation, set speed and duplicitly unilaterally
-+        tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_FULLDPLX);
-+        if (ecmd->speed == SPEED_1000) {
-+            tmp |= BMCR_SPEED1000;
-+        } else if (ecmd->speed == SPEED_100) {
-+            tmp |= BMCR_SPEED100;
-+        }
-+
-+        if (ecmd->duplex == DUPLEX_FULL) {
-+            tmp |= BMCR_FULLDPLX;
-+            mii->full_duplex = 1;
-+        } else {
-+            mii->full_duplex = 0;
-+        }
-+
-+        if (bmcr != tmp) {
-+            mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp);
-+        }
-+    }
-+}
-+
-+u32 get_phy_capabilies(gmac_priv_t* priv)
-+{
-+    struct mii_if_info *mii = &priv->mii;
-+
-+	// Ask the PHY for it's capabilities
-+	u32 reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_BMSR);
-+
-+	// Assume PHY has MII interface
-+	u32 features = SUPPORTED_MII;
-+
-+	if (reg & BMSR_ANEGCAPABLE) {
-+		features |= SUPPORTED_Autoneg;
-+	}
-+	if (reg & BMSR_100FULL) {
-+		features |= SUPPORTED_100baseT_Full;
-+	}
-+	if (reg & BMSR_100HALF) {
-+		features |= SUPPORTED_100baseT_Half;
-+	}
-+	if (reg & BMSR_10FULL) {
-+		features |= SUPPORTED_10baseT_Full;
-+	}
-+	if (reg & BMSR_10HALF) {
-+		features |= SUPPORTED_10baseT_Half;
-+	}
-+
-+	// Does the PHY have the extended status register?
-+	if (reg & BMSR_ESTATEN) {
-+		reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_ESTATUS);
-+
-+		if (reg & ESTATUS_1000_TFULL)
-+			features |= SUPPORTED_1000baseT_Full;
-+		if (reg & ESTATUS_1000_THALF)
-+			features |= SUPPORTED_1000baseT_Half;
-+	}
-+
-+	return features;
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_phy.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#if !defined(__GMAC_PHY_H__)
-+#define __GMAC_PHY_H__
-+
-+#include <asm/types.h>
-+#include <linux/netdevice.h>
-+#include <linux/mii.h>
-+#include "gmac.h"
-+
-+#define PHY_TYPE_NONE					0
-+#define PHY_TYPE_MICREL_KS8721BL		0x00221619
-+#define PHY_TYPE_VITESSE_VSC8201XVZ	0x000fc413
-+#define PHY_TYPE_REALTEK_RTL8211BGR	0x001cc912
-+#define PHY_TYPE_LSI_ET1011C			0x0282f013
-+#define PHY_TYPE_LSI_ET1011C2			0x0282f014
-+#define PHY_TYPE_ICPLUS_IP1001			0x02430d90
-+
-+#define VSC8201_MII_ACSR			0x1c	// Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
-+#define VSC8201_MII_ACSR_MDPPS_BIT	2		// Mode/Duplex Pin Priority Select
-+
-+#define ET1011C_MII_CONFIG	0x16
-+#define ET1011C_MII_CONFIG_IFMODESEL	0
-+#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS	3
-+#define ET1011C_MII_CONFIG_SYSCLKEN	4
-+#define ET1011C_MII_CONFIG_TXCLKEN		5
-+#define ET1011C_MII_CONFIG_TBI_RATESEL	8
-+#define ET1011C_MII_CONFIG_CRS_TX_EN	15
-+
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII		0
-+#define ET1011C_MII_CONFIG_IFMODESEL_TBI			1
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX	2
-+
-+#define ET1011C_MII_LED2 0x1c
-+#define ET1011C_MII_LED2_LED_TXRX		12
-+#define ET1011C_MII_LED2_LED_NUM_BITS	4
-+
-+#define ET1011C_MII_LED2_LED_TXRX_ON		0xe
-+#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY	0x7
-+
-+extern int phy_read(struct net_device *dev, int phyaddr, int phyreg);
-+
-+extern void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata);
-+
-+extern void phy_detect(struct net_device *dev);
-+
-+extern int phy_reset(struct net_device *dev);
-+
-+extern void phy_powerdown(struct net_device *dev);
-+
-+extern void start_phy_reset(gmac_priv_t* priv);
-+
-+extern int is_phy_reset_complete(gmac_priv_t* priv);
-+
-+extern void set_phy_negotiate_mode(struct net_device *dev);
-+
-+extern u32 get_phy_capabilies(gmac_priv_t* priv);
-+
-+extern u32 get_phy_capabilies(gmac_priv_t* priv);
-+#endif        //  #if !defined(__GMAC_PHY_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,508 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_reg.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#if !defined(__GMAC_REG_H__)
-+#define __GMAC_REG_H__
-+
-+#include <asm/io.h>
-+#include "gmac.h"
-+
-+/**
-+ * MAC register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+//printk("$WReading MAC register %u at byte adr 0x%08x\n", reg_num, priv->macBase + (reg_num << 2));
-+    return readl(priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+//printk("$WWriting MAC register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->macBase + (reg_num << 2), value);
-+    writel(value, priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ *  clear. A set bit in this parameter will cause the matching bit in the
-+ *  register to be cleared
-+ */
-+static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+    mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ *  set. A set bit in this parameter will cause the matching bit in the register
-+ *  to be set
-+ */
-+static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+    mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
-+}
-+
-+/**
-+ * DMA register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+//printk("$WReading DMA register %u at byte adr 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2));
-+    return readl(priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+//printk("$WWriting DMA register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2), value);
-+    writel(value, priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ *  clear. A set bit in this parameter will cause the matching bit in the
-+ *  register to be cleared
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+    u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
-+    dma_reg_write(priv, reg_num, new_value);
-+    return new_value;
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ *  set. A set bit in this parameter will cause the matching bit in the register
-+ *  to be set
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+    u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
-+    dma_reg_write(priv, reg_num, new_value);
-+    return new_value;
-+}
-+
-+#define NUM_PERFECT_MATCH_REGISTERS 15
-+
-+/**
-+ * MAC register indices
-+ */
-+typedef enum gmac_mac_regs {
-+    MAC_CONFIG_REG       = 0,
-+    MAC_FRAME_FILTER_REG = 1,
-+    MAC_HASH_HIGH_REG    = 2,
-+    MAC_HASH_LOW_REG     = 3,
-+    MAC_GMII_ADR_REG     = 4,
-+    MAC_GMII_DATA_REG    = 5,
-+    MAC_FLOW_CNTL_REG    = 6,
-+    MAC_VLAN_TAG_REG     = 7,
-+    MAC_VERSION_REG      = 8,
-+    MAC_ADR0_HIGH_REG    = 16,
-+    MAC_ADR0_LOW_REG     = 17,
-+    MAC_ADR1_HIGH_REG    = 18,
-+    MAC_ADR1_LOW_REG     = 19,
-+    MAC_ADR2_HIGH_REG    = 20,
-+    MAC_ADR2_LOW_REG     = 21,
-+    MAC_ADR3_HIGH_REG    = 22,
-+    MAC_ADR3_LOW_REG     = 23,
-+    MAC_ADR4_HIGH_REG    = 24,
-+    MAC_ADR4_LOW_REG     = 25,
-+    MAC_ADR5_HIGH_REG    = 26,
-+    MAC_ADR5_LOW_REG     = 27,
-+    MAC_ADR6_HIGH_REG    = 28,
-+    MAC_ADR6_LOW_REG     = 29,
-+    MAC_ADR7_HIGH_REG    = 30,
-+    MAC_ADR7_LOW_REG     = 31,
-+    MAC_ADR8_HIGH_REG    = 32,
-+    MAC_ADR8_LOW_REG     = 33,
-+    MAC_ADR9_HIGH_REG    = 34,
-+    MAC_ADR9_LOW_REG     = 35,
-+    MAC_ADR10_HIGH_REG   = 36,
-+    MAC_ADR10_LOW_REG    = 37,
-+    MAC_ADR11_HIGH_REG   = 38,
-+    MAC_ADR11_LOW_REG    = 39,
-+    MAC_ADR12_HIGH_REG   = 40,
-+    MAC_ADR12_LOW_REG    = 41,
-+    MAC_ADR13_HIGH_REG   = 42,
-+    MAC_ADR13_LOW_REG    = 43,
-+    MAC_ADR14_HIGH_REG   = 44,
-+    MAC_ADR14_LOW_REG    = 45,
-+    MAC_ADR15_HIGH_REG   = 46,
-+    MAC_ADR15_LOW_REG    = 47
-+} gmac_mac_regs_t;
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the perfect matching low register
-+ * @param value A u32 specifying the value to write to the register
-+ */
-+static inline void mac_adrlo_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+    mac_reg_write(priv, MAC_ADR1_LOW_REG + (2*reg_num), value);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the perfect matching high register
-+ * @param value A u32 specifying the value to write to the register
-+ */
-+static inline void mac_adrhi_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+    mac_reg_write(priv, MAC_ADR1_HIGH_REG + (2*reg_num), value);
-+}
-+
-+/**
-+ * MAC register field definitions
-+ */
-+typedef enum gmac_config_reg {
-+    MAC_CONFIG_WD_BIT  = 23,
-+    MAC_CONFIG_JD_BIT  = 22,
-+    MAC_CONFIG_BE_BIT  = 21,
-+    MAC_CONFIG_JE_BIT  = 20,
-+    MAC_CONFIG_IFG_BIT = 17,
-+    MAC_CONFIG_PS_BIT  = 15,
-+    MAC_CONFIG_DO_BIT  = 13,
-+    MAC_CONFIG_LM_BIT  = 12,
-+    MAC_CONFIG_DM_BIT  = 11,
-+    MAC_CONFIG_IPC_BIT = 10,
-+    MAC_CONFIG_DR_BIT  = 9,
-+    MAC_CONFIG_ACS_BIT = 7,
-+    MAC_CONFIG_BL_BIT  = 5,
-+    MAC_CONFIG_DC_BIT  = 4,
-+    MAC_CONFIG_TE_BIT  = 3,
-+    MAC_CONFIG_RE_BIT  = 2
-+} gmac_config_reg_t;
-+
-+#define MAC_CONFIG_IFG_NUM_BITS 3
-+#define MAC_CONFIG_BL_NUM_BITS 2
-+
-+typedef enum gmac_frame_filter_reg {
-+    MAC_FRAME_FILTER_RA_BIT   = 31,
-+    MAC_FRAME_FILTER_SAF_BIT  = 9,
-+    MAC_FRAME_FILTER_SAIF_BIT = 8,
-+    MAC_FRAME_FILTER_PCF_BIT  = 6,
-+    MAC_FRAME_FILTER_DBF_BIT  = 5,
-+    MAC_FRAME_FILTER_PM_BIT   = 4,
-+    MAC_FRAME_FILTER_DAIF_BIT = 3,
-+    MAC_FRAME_FILTER_HMC_BIT  = 2,
-+    MAC_FRAME_FILTER_HUC_BIT  = 1,
-+    MAC_FRAME_FILTER_PR_BIT   = 0
-+} gmac_frame_filter_reg_t;
-+
-+#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
-+
-+typedef enum gmac_hash_table_high_reg {
-+    MAC_HASH_HIGH_HTH_BIT = 0
-+} gmac_hash_table_high_reg_t;
-+
-+typedef enum gmac_hash_table_low_reg {
-+    MAC_HASH_LOW_HTL_BIT = 0
-+} gmac_hash_table_low_reg_t;
-+
-+typedef enum gmac_gmii_address_reg {
-+    MAC_GMII_ADR_PA_BIT = 11,
-+    MAC_GMII_ADR_GR_BIT = 6,
-+    MAC_GMII_ADR_CR_BIT = 2,
-+    MAC_GMII_ADR_GW_BIT = 1,
-+    MAC_GMII_ADR_GB_BIT = 0
-+} gmac_gmii_address_reg_t;
-+
-+#define MAC_GMII_ADR_PA_NUM_BITS 5
-+#define MAC_GMII_ADR_GR_NUM_BITS 5
-+#define MAC_GMII_ADR_CR_NUM_BITS 3
-+
-+typedef enum gmac_gmii_data_reg {
-+    MAC_GMII_DATA_GD_BIT = 0
-+} gmac_gmii_data_reg_t;
-+
-+#define MAC_GMII_DATA_GD_NUM_BITS 16
-+
-+typedef enum gmac_flow_control_reg {
-+    MAC_FLOW_CNTL_PT_BIT      = 16,
-+    MAC_FLOW_CNTL_PLT_BIT     = 4,
-+    MAC_FLOW_CNTL_UP_BIT      = 3,
-+    MAC_FLOW_CNTL_RFE_BIT     = 2,
-+    MAC_FLOW_CNTL_TFE_BIT     = 1,
-+    MAC_FLOW_CNTL_FCB_BPA_BIT = 0
-+} gmac_flow_control_reg_t;
-+
-+#define MAC_FLOW_CNTL_PT_NUM_BITS 16
-+#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
-+
-+typedef enum gmac_vlan_tag_reg {
-+    MAC_VLAN_TAG_LV_BIT = 0
-+} gmac_vlan_tag_reg_t;
-+
-+#define MAC_VLAN_TAG_LV_NUM_BITS 16
-+
-+typedef enum gmac_version_reg {
-+    MAC_VERSION_UD_BIT = 8,
-+    MAC_VERSION_SD_BIT = 0
-+} gmac_version_reg_t;
-+
-+#define MAC_VERSION_UD_NUM_BITS 8
-+#define MAC_VERSION_SD_NUM_BITS 8
-+
-+typedef enum gmac_mac_adr_0_high_reg {
-+    MAC_ADR0_HIGH_MO_BIT = 31,
-+    MAC_ADR0_HIGH_A_BIT  = 0
-+} gmac_mac_adr_0_high_reg_t;
-+
-+#define MAC_ADR0_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_0_low_reg {
-+    MAC_ADR0_LOW_A_BIT = 0
-+} gmac_mac_adr_0_low_reg_t;
-+
-+typedef enum gmac_mac_adr_1_high_reg {
-+    MAC_ADR1_HIGH_AE_BIT  = 31,
-+    MAC_ADR1_HIGH_SA_BIT  = 30,
-+    MAC_ADR1_HIGH_MBC_BIT = 24,
-+    MAC_ADR1_HIGH_A_BIT   = 0
-+} gmac_mac_adr_1_high_reg_t;
-+
-+#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
-+#define MAC_ADR1_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_1_low_reg {
-+    MAC_ADR1_LOW_A_BIT = 0
-+} gmac_mac_adr_1_low_reg_t;
-+
-+
-+/**
-+ * MMC register indices - registers accessed via the MAC accessor functions
-+ */
-+typedef enum gmac_mmc_regs {
-+    MMC_CONTROL_REG = 64,
-+    MMC_RX_INT_REG  = 65,
-+    MMC_TX_INT_REG  = 66,
-+    MMC_RX_MASK_REG = 67,
-+    MMC_TX_MASK_REG = 68
-+} gmac_mmc_regs_t;
-+
-+
-+/**
-+ * DMA register indices
-+ */
-+typedef enum gmac_dma_regs {
-+    DMA_BUS_MODE_REG        = 0,
-+    DMA_TX_POLL_REG         = 1,
-+    DMA_RX_POLL_REG         = 2,
-+    DMA_RX_DESC_ADR_REG     = 3,
-+    DMA_TX_DESC_ADR_REG     = 4,
-+    DMA_STATUS_REG          = 5,
-+    DMA_OP_MODE_REG         = 6,
-+    DMA_INT_ENABLE_REG      = 7,
-+    DMA_MISSED_OVERFLOW_REG = 8,
-+    DMA_CUR_TX_DESC_REG     = 18,
-+    DMA_CUR_RX_DESC_REG     = 19,
-+    DMA_CUR_TX_ADR_REG      = 20,
-+    DMA_CUR_RX_ADR_REG      = 21
-+} gmac_dma_regs_t;
-+
-+
-+/**
-+ * DMA register field definitions
-+ */
-+
-+typedef enum gmac_dma_bus_mode_reg {
-+    DMA_BUS_MODE_FB_BIT  = 16,
-+    DMA_BUS_MODE_PR_BIT  = 14,
-+    DMA_BUS_MODE_PBL_BIT = 8,
-+    DMA_BUS_MODE_DSL_BIT = 2,
-+    DMA_BUS_MODE_DA_BIT  = 1,
-+    DMA_BUS_MODE_SWR_BIT = 0
-+} gmac_dma_bus_mode_reg_t;
-+
-+#define DMA_BUS_MODE_PR_NUM_BITS 2
-+#define DMA_BUS_MODE_PBL_NUM_BITS 6
-+#define DMA_BUS_MODE_DSL_NUM_BITS 5
-+
-+typedef enum gmac_dma_tx_poll_demand_reg {
-+    DMA_TX_POLL_TPD_BIT = 0
-+} gmac_dma_tx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_poll_demand_reg {
-+    DMA_RX_POLL_RPD_BIT = 0
-+} gmac_dma_rx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_desc_list_adr_reg {
-+    DMA_RX_DESC_ADR_SRL_BIT = 0
-+} gmac_dma_rx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_tx_desc_list_adr_reg {
-+    DMA_TX_DESC_ADR_STL_BIT = 0
-+} gmac_dma_tx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_status_reg {
-+    DMA_STATUS_GPI_BIT = 28,
-+    DMA_STATUS_GMI_BIT = 27,
-+    DMA_STATUS_GLI_BIT = 26,
-+    DMA_STATUS_EB_BIT  = 23,
-+    DMA_STATUS_TS_BIT  = 20,
-+    DMA_STATUS_RS_BIT  = 17,
-+    DMA_STATUS_NIS_BIT = 16,
-+    DMA_STATUS_AIS_BIT = 15,
-+    DMA_STATUS_ERI_BIT = 14,
-+    DMA_STATUS_FBE_BIT = 13,
-+    DMA_STATUS_ETI_BIT = 10,
-+    DMA_STATUS_RWT_BIT = 9,
-+    DMA_STATUS_RPS_BIT = 8,
-+    DMA_STATUS_RU_BIT  = 7,
-+    DMA_STATUS_RI_BIT  = 6,
-+    DMA_STATUS_UNF_BIT = 5,
-+    DMA_STATUS_OVF_BIT = 4,
-+    DMA_STATUS_TJT_BIT = 3,
-+    DMA_STATUS_TU_BIT  = 2,
-+    DMA_STATUS_TPS_BIT = 1,
-+    DMA_STATUS_TI_BIT  = 0
-+} gmac_dma_status_reg_t;
-+
-+#define DMA_STATUS_EB_NUM_BITS 3
-+#define DMA_STATUS_TS_NUM_BITS 3
-+#define DMA_STATUS_RS_NUM_BITS 3
-+
-+typedef enum gmac_dma_status_ts_val {
-+    DMA_STATUS_TS_CLOSING   = 7,
-+    DMA_STATUS_TS_SUSPENDED = 6,
-+    DMA_STATUS_TS_RESERVED  = 5,
-+    DMA_STATUS_TS_FLUSHING  = 4,
-+    DMA_STATUS_TS_READING   = 3,
-+    DMA_STATUS_TS_WAITING   = 2,
-+    DMA_STATUS_TS_FETCHING  = 1,
-+    DMA_STATUS_TS_STOPPED   = 0
-+} gmac_dma_status_ts_val_t;
-+
-+typedef enum gmac_dma_op_mode_reg {
-+    DMA_OP_MODE_DT_BIT   = 26,
-+    DMA_OP_MODE_RSF_BIT  = 25,
-+    DMA_OP_MODE_DFF_BIT  = 24,
-+    DMA_OP_MODE_RFA2_BIT = 23,
-+    DMA_OP_MODE_RFD2_BIT = 22,
-+    DMA_OP_MODE_SF_BIT   = 21,
-+    DMA_OP_MODE_FTF_BIT  = 20,
-+    DMA_OP_MODE_TTC_BIT  = 14,
-+    DMA_OP_MODE_ST_BIT   = 13,
-+    DMA_OP_MODE_RFD_BIT  = 11,
-+    DMA_OP_MODE_RFA_BIT  = 9,
-+    DMA_OP_MODE_EFC_BIT  = 8,
-+    DMA_OP_MODE_FEF_BIT  = 7,
-+    DMA_OP_MODE_FUF_BIT  = 6,
-+    DMA_OP_MODE_RTC_BIT  = 3,
-+    DMA_OP_MODE_OSF_BIT  = 2,
-+    DMA_OP_MODE_SR_BIT   = 1
-+} gmac_dma_op_mode_reg_t;
-+
-+#define DMA_OP_MODE_TTC_NUM_BITS 3
-+
-+typedef enum gmac_dma_op_mode_ttc_val {
-+    DMA_OP_MODE_TTC_16  = 7,
-+    DMA_OP_MODE_TTC_24  = 6,
-+    DMA_OP_MODE_TTC_32  = 5,
-+    DMA_OP_MODE_TTC_40  = 4,
-+    DMA_OP_MODE_TTC_256 = 3,
-+    DMA_OP_MODE_TTC_192 = 2,
-+    DMA_OP_MODE_TTC_128 = 1,
-+    DMA_OP_MODE_TTC_64  = 0 
-+} gmac_dma_op_mode_ttc_val_t;
-+
-+#define DMA_OP_MODE_RFD_NUM_BITS 2
-+#define DMA_OP_MODE_RFA_NUM_BITS 2
-+#define DMA_OP_MODE_RTC_NUM_BITS 2
-+
-+typedef enum gmac_dma_op_mode_rtc_val {
-+    DMA_OP_MODE_RTC_128 = 3,
-+    DMA_OP_MODE_RTC_96  = 2,
-+    DMA_OP_MODE_RTC_32  = 1,
-+    DMA_OP_MODE_RTC_64  = 0 
-+} gmac_dma_op_mode_rtc_val_t;
-+
-+typedef enum gmac_dma_intr_enable_reg {
-+    DMA_INT_ENABLE_NI_BIT  = 16,
-+    DMA_INT_ENABLE_AI_BIT  = 15,
-+    DMA_INT_ENABLE_ERE_BIT = 14,
-+    DMA_INT_ENABLE_FBE_BIT = 13,
-+    DMA_INT_ENABLE_ETE_BIT = 10,
-+    DMA_INT_ENABLE_RW_BIT  = 9,
-+    DMA_INT_ENABLE_RS_BIT  = 8,
-+    DMA_INT_ENABLE_RU_BIT  = 7,
-+    DMA_INT_ENABLE_RI_BIT  = 6,
-+    DMA_INT_ENABLE_UN_BIT  = 5,
-+    DMA_INT_ENABLE_OV_BIT  = 4,
-+    DMA_INT_ENABLE_TJ_BIT  = 3,
-+    DMA_INT_ENABLE_TU_BIT  = 2,
-+    DMA_INT_ENABLE_TS_BIT  = 1,
-+    DMA_INT_ENABLE_TI_BIT  = 0
-+} gmac_dma_intr_enable_reg_t;
-+
-+typedef enum gmac_dma_missed_overflow_reg {
-+    DMA_MISSED_OVERFLOW_OFOC_BIT  = 28,    // Overflow bit for FIFO Overflow Counter
-+    DMA_MISSED_OVERFLOW_AMFC_BIT  = 17,    // Application Missed Frames Count
-+    DMA_MISSED_OVERFLOW_OAMFO_BIT = 16,    // Overflow bit for Application Missed Frames Count
-+    DMA_MISSED_OVERFLOW_CMFC_BIT  = 0      // Controller Missed Frames Count
-+} gmac_dma_missed_overflow_reg_t;
-+
-+#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
-+#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
-+
-+typedef enum gmac_dma_current_tx_desc_reg {
-+    DMA_CUR_TX_DESC_A_BIT = 0
-+} gmac_dma_current_tx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_rx_desc_reg {
-+    DMA_CUR_RX_DESC_A_BIT = 0
-+} gmac_dma_current_rx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_tx_adr_reg {
-+    DMA_CUR_TX_ADR_A_BIT = 0
-+} gmac_dma_current_tx_adr_reg_t;
-+
-+typedef enum gmac_dma_current_rx_adr_reg {
-+    DMA_CUR_RX_ADR_A_BIT = 0
-+} gmac_dma_current_rx_adr_reg_t;
-+
-+#endif        //  #if !defined(__GMAC_REG_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c
---- linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,657 @@
-+#include <asm/io.h>
-+#include <asm/bitops.h>
-+#include <asm/uaccess.h>         // copy_to_user and copy_from_user
-+#include <linux/init.h>          // modules
-+#include <linux/module.h>        // module
-+#include <linux/types.h>         // dev_t type
-+#include <linux/fs.h>            // chrdev allocation
-+#include <linux/slab.h>          // kmalloc and kfree
-+#include <linux/cdev.h>          // struct cdev
-+#include <linux/errno.h>         // error codes
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/arch/hardware.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+MODULE_AUTHOR("C Ford");
-+MODULE_DESCRIPTION("gpioTest first version");
-+
-+struct gpioTest_dev {
-+  struct semaphore sem;    // Mutual exclusion semaphore
-+  struct cdev      cdev;        // Char device structure
-+  int	           found;
-+};
-+
-+struct gpioTest_dev * gpioTest_device;  // Contains the gpioTest devices
-+
-+dev_t dev;                         // Contains major and first minor number
-+static wait_queue_head_t ir_block;
-+
-+////////////////////////////
-+// LINKED LIST OPERATIONS //
-+////////////////////////////
-+
-+
-+///////////////
-+// CALLBACKS //
-+///////////////
-+
-+#define GPIO_TEST_SCL (1UL << CONFIG_OXNAS_I2C_SCL)
-+#define GPIO_TEST_SDA (1UL << CONFIG_OXNAS_I2C_SDA)
-+
-+void DumpGPIO( void )
-+{
-+	printk( KERN_INFO "================= GPIO Dump\n"
-+	  "     GPIO_A_DATA                            0x%08x\n"
-+	  "     GPIO_A_OUTPUT_ENABLE                   0x%08x\n"
-+	  "     GPIO_A_INTERRUPT_ENABLE                0x%08x\n"
-+	  "     GPIO_A_INTERRUPT_EVENT                 0x%08x\n"
-+	  "     GPIO_A_OUTPUT_VALUE                    0x%08x\n"
-+	  "     GPIO_A_OUTPUT_SET                      0x%08x\n"
-+	  "     GPIO_A_OUTPUT_CLEAR                    0x%08x\n"
-+	  "     GPIO_A_OUTPUT_ENABLE_SET               0x%08x\n"
-+	  "     GPIO_A_OUTPUT_ENABLE_CLEAR             0x%08x\n"
-+	  "     GPIO_A_INPUT_DEBOUNCE_ENABLE           0x%08x\n"
-+	  "     GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE  0x%08x\n"
-+	  "     GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE  0x%08x\n"
-+	  "     GPIO_A_RISING_EDGE_DETECT              0x%08x\n"
-+	  "     GPIO_A_FALLING_EDGE_DETECT             0x%08x\n"
-+	  "     GPIO_A_LEVEL_INTERRUPT_ENABLE          0x%08x\n"
-+	  "     GPIO_A_INTERRUPT_STATUS_REGISTER       0x%08x\n",
-+        readl( GPIO_A_DATA                           ),
-+        readl( GPIO_A_OUTPUT_ENABLE                  ),
-+        readl( GPIO_A_INTERRUPT_ENABLE               ),
-+        readl( GPIO_A_INTERRUPT_EVENT                ),
-+        readl( GPIO_A_OUTPUT_VALUE                   ),
-+        readl( GPIO_A_OUTPUT_SET                     ),
-+        readl( GPIO_A_OUTPUT_CLEAR                          ),
-+        readl( GPIO_A_OUTPUT_ENABLE_SET              ),
-+        readl( GPIO_A_OUTPUT_ENABLE_CLEAR            ),
-+        readl( GPIO_A_INPUT_DEBOUNCE_ENABLE          ),
-+        readl( GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ),
-+        readl( GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ),
-+        readl( GPIO_A_RISING_EDGE_DETECT             ),
-+        readl( GPIO_A_FALLING_EDGE_DETECT            ),
-+        readl( GPIO_A_LEVEL_INTERRUPT_ENABLE         ),
-+        readl( GPIO_A_INTERRUPT_STATUS_REGISTER      ) );	
-+	
-+}
-+
-+irqreturn_t irqHandler( int irq, void* dev_id)
-+{
-+	// is this interrupt fors us??
-+	struct gpioTest_dev* pGPIO = (struct gpioTest_dev*) dev_id;
-+	unsigned int temp = readl( (volatile unsigned long *) GPIO_A_INTERRUPT_STATUS_REGISTER );
-+	
-+	if ( !(temp & (GPIO_TEST_SCL | GPIO_TEST_SDA) ) )
-+	{
-+		printk("Not for us...\n");
-+		return IRQ_NONE;
-+	}	
-+
-+	// apparantly it is, for simplicity, we will stop the intterupting pin, 
-+	// and clear its source, then signal the bottmo half to continue
-+	if ( test_bit( CONFIG_OXNAS_I2C_SCL, (volatile unsigned long *) &temp ) )
-+	{
-+		printk("Int Found CONFIG_OXNAS_I2C_SCL\n");
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SCL);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SCL);
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SCL);
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SCL);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SCL);
-+		pGPIO->found |= GPIO_TEST_SCL;
-+	}
-+	
-+	if ( test_bit( CONFIG_OXNAS_I2C_SDA, (volatile unsigned long *) &temp ) )
-+	{
-+		printk("Int Found CONFIG_OXNAS_I2C_SDA\n");
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SDA);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SDA);
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SDA);
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SDA);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL <<  CONFIG_OXNAS_I2C_SDA);
-+		pGPIO->found |= GPIO_TEST_SDA;
-+	}
-+	
-+	if ( pGPIO->found )
-+	{
-+		printk("Int cleared\n");
-+		wake_up_interruptible(&ir_block);
-+	}
-+	
-+	return IRQ_HANDLED;
-+}
-+
-+int gpioTest_go(void)
-+{
-+	unsigned long flags;
-+	unsigned int  temp;
-+	unsigned int  i;
-+	
-+	//assert( CONFIG_OXNAS_I2C_SDA < CONFIG_OXNAS_I2C_SCL );
-+
-+	printk( KERN_ERR "****************************************************************\n");
-+	printk( KERN_ERR "**************************************************  gpioTest_go:\n");
-+	printk( KERN_ERR "Please connect I2c SDA to I2C SCLK, and optionally attach scope:\n\n");
-+	
-+	printk( KERN_ERR "Test 1: setup all inputs (and check for pull up res)\n");
-+
-+	// Setting lines to GPIO
-+	*( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL <<  (CONFIG_OXNAS_I2C_SDA  & 0x0000001F) );
-+	*( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL <<  (CONFIG_OXNAS_I2C_SCL  & 0x0000001F) );
-+	                                                                     
-+	*( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL <<  (CONFIG_OXNAS_I2C_SDA  & 0x0000001F) );	
-+	*( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL <<  (CONFIG_OXNAS_I2C_SCL  & 0x0000001F) );	
-+  
-+// Setting lines to Input 
-+/*
-+temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+temp |= (GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
-+writel( temp, GPIO_A_OUTPUT_ENABLE );
-+for (i=0; i<65000; ++i)
-+{
-+	temp = (i & 0x00000007) << CONFIG_OXNAS_I2C_SCL;
-+	flags = readl( GPIO_A_OUTPUT_VALUE );
-+	flags &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
-+	flags |= temp;
-+	writel( flags, GPIO_A_OUTPUT_VALUE );
-+	printk( "reads 0x%08x  ",readl( GPIO_A_DATA ) );
-+	udelay(100);
-+	printk( " 0x%08x\n",readl( GPIO_A_DATA ) );
-+	
-+}
-+*/
-+DumpGPIO();	
-+	// Setting lines to Input
-+	temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+	temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+	writel( temp, GPIO_A_OUTPUT_ENABLE );
-+	udelay(1);
-+	if ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ||
-+	     *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL))
-+	{
-+		printk( KERN_ERR "Test 1: Failed to clear GPIO Output Enable register)\n");
-+		return -1;
-+	}
-+	
-+	udelay(1);
-+	// read the input value: it should be one due to the pull up
-+	if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+	     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
-+	{
-+		printk( KERN_ERR "Test 1: Failed to read 1 on the input(check for pull up res.))\n");
-+		return -1;
-+	}
-+	
-+	printk( KERN_ERR "===== Passed Test 1 =======   Created GPIO inputs, and read correct values\n");
-+	
-+	// Test 2: set output using direct setting, first set the output latches to zero on all lines
-+	printk( KERN_ERR "Test 2: output testing and OE testing\n");
-+	*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR   ) |= (1UL <<  (CONFIG_OXNAS_I2C_SDA  & 0x0000001F) );	
-+	*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR   ) |= (1UL <<  (CONFIG_OXNAS_I2C_SCL  & 0x0000001F) );	
-+	for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
-+	{
-+		// from all input, set output using direct write. Assume all input at start.
-+		temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+		temp |= ((0x00000001) << i);
-+		writel( temp, GPIO_A_OUTPUT_ENABLE );
-+	
-+		udelay(1);
-+		if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
-+		{
-+			printk( KERN_ERR "Test 2: Failed to read 0 on the %d input (output enabled with direct write.))\n", i);
-+			return -1;
-+		}
-+		
-+		// Setting lines to Input
-+		temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+		temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+		writel( temp, GPIO_A_OUTPUT_ENABLE );
-+			
-+		udelay(1);
-+		if ( ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
-+		     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) )         ||
-+		     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+		{
-+			printk( KERN_ERR "Test 2: Failed to reset to clean state 1)\n");
-+			return -1;
-+		}
-+			
-+		// from all inputs, set an output enable usign output enable set
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL <<  i);		
-+		
-+		udelay(1);
-+		if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+		{
-+			printk( KERN_ERR "Test 2: Failed to read 0 on the input %d (output enabled with direct write.))\n", i);
-+			return -1;
-+		}
-+		
-+		// now exercise the setting and clearing of the output value
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL <<  i);		
-+		
-+		udelay(1);
-+		if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) )    )
-+		{
-+			printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
-+			return -1;
-+		}
-+		
-+		// now exercise the setting and clearing of the output value
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL <<  i);		
-+		
-+		udelay(1);
-+		if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+		{
-+			printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
-+			return -1;
-+		}
-+		
-+		// from i as output, set all inputs , set an output enable usign output enable set
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR ) |= (1UL <<  i);		
-+		
-+		udelay(1);
-+		if ( temp != readl( GPIO_A_OUTPUT_ENABLE )        ||
-+		     ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+		     ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
-+		     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) )         ||
-+		     !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) )           )
-+		{
-+			printk( KERN_ERR "Test 2: Failed to reset to clean state 2)\n");
-+			return -1;
-+		}
-+	}
-+	
-+	printk( KERN_ERR "===== Passed Test 2 =======   Used all Set and clear methods for both OE and OV\n");
-+	
-+	// Test 3, now exercise the interrupt.
-+	printk( KERN_ERR "Test 3: Interrupt testing\n");
-+	init_waitqueue_head(&ir_block);
-+
-+	request_irq( 
-+		(int) GPIO_1_INTERRUPT,  	// unsigned int 	irq, 
-+		&irqHandler,             	// irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+		IRQF_SHARED,                	// unsigned long 	irq_flags,
-+		"GPIO Test Module",      	// const char * 	devname,
-+		(void*) gpioTest_device  );   	// void * dev_id)
-+	
-+	
-+	// set int condiiton....
-+	for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
-+	{
-+		int tmo;
-+		int drv = i+1 > CONFIG_OXNAS_I2C_SDA ? CONFIG_OXNAS_I2C_SCL : i+1;	// BHC - This is rubbish, there's no contract saying SDA has to be on a higher numbered GPIO than SCL
-+		
-+		
-+		// ================================================= level detect
-+		// set an interrupt on i being high-level
-+		printk( KERN_INFO "Test %d level int High against OP %d\n", i, drv);
-+		local_irq_save(flags);
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL <<  i);		
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE )         |= (1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL <<  i);
-+		gpioTest_device->found = 0;
-+		local_irq_restore(flags);
-+
-+ 		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo1 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
-+		if ( !(gpioTest_device->found & ((0x00000001 << i))) )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
-+					  "While waiting for level high int....\n");
-+			return -1;
-+		}
-+
-+		// Next try setting the lines low, and ensure that the devices times out
-+		local_irq_save(flags);
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR 			      ) |= (1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET		      ) |= (1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL <<  i);		
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT 		      ) |= (1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE         ) |= (1UL <<  i);	
-+		gpioTest_device->found = 0;
-+
-+		local_irq_restore(flags);
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo2 == 0x%08x\n", tmo );
-+		if ( gpioTest_device->found )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 did not timed out "
-+					  "While waiting for level high int with 0 input....\n");
-+			return -1;
-+		}
-+
-+		// set the int acive low level now.
-+		printk( KERN_INFO "Test %d level int Low against OP %d\n", i, drv);
-+		local_irq_save(flags);
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE         ) |= (1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT                ) |= (1UL <<  i);
-+		gpioTest_device->found = 0;
-+		
-+		local_irq_restore(flags);
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo3 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
-+		if ( !(gpioTest_device->found & ((0x00000001 << i))) )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
-+					  "While waiting for level low int....\n");
-+			return -1;
-+		}
-+		
-+		// Next try setting the lines high, and ensure that the devices times out
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR            ) |= ~(1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE         ) |= (1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT                ) |= (1UL <<  i);
-+		gpioTest_device->found = 0;
-+
-+		local_irq_restore(flags);
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo4 == 0x%08x\n", tmo );
-+		if ( gpioTest_device->found )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 did not timed out "
-+					  "While waiting for level low int with 1 input....\n");
-+			return -1;
-+		}
-+		
-+		// Setting lines to Input --------------------------------------
-+		temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+		temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+		writel( temp, GPIO_A_OUTPUT_ENABLE );
-+		// ================================================= Edge detect
-+		
-+		// set an interrupt on i being high-level
-+		local_irq_save(flags);
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |=  (1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL <<  i);		
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE         ) &= ~(1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT                ) |=  (1UL <<  i);
-+		gpioTest_device->found = 0;
-+		
-+		printk( KERN_INFO "Test %d rising edge int High against falling edge on OP %d\n", i, drv);
-+		local_irq_restore(flags);
-+		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |=  (1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR             ) |=  (1UL <<  drv);
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+		if ( gpioTest_device->found || tmo )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
-+			return -1;
-+		}
-+		
-+		// now do th rising edge...
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |=  (1UL <<  drv);
-+		
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+		if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
-+			return -1;
-+		}
-+
-+		// set the int acive low level now.
-+		local_irq_save(flags);
-+		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |=  (1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR             ) |=  (1UL <<  drv);
-+		
-+		*( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL <<  i);
-+		*( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |=  (1UL <<  i);		
-+		*( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE         ) &= ~(1UL <<  i);	
-+		*( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT                ) |=  (1UL <<  i);
-+		gpioTest_device->found = 0;
-+		
-+		printk( KERN_INFO "Test %d falling edge int against rising edge on OP %d\n", i, drv);
-+		local_irq_restore(flags);
-+		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |=  (1UL <<  drv);		
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_SET        ) |=  (1UL <<  drv);
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+		if ( gpioTest_device->found || tmo )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
-+			return -1;
-+		}
-+		
-+		// now do th rising edge...
-+		*( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR) |=  (1UL <<  drv);
-+		
-+		tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+		if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
-+		{
-+			
-+			printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
-+			return -1;
-+		}
-+
-+		
-+		
-+		// Setting lines to Input --------------------------------------
-+		temp  = readl( GPIO_A_OUTPUT_ENABLE );
-+		temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+		writel( temp, GPIO_A_OUTPUT_ENABLE );
-+	}
-+	
-+	
-+	printk("$G All gpiuo tests passed.\n");
-+	
-+	return 0;
-+}
-+
-+
-+/*
-+Read callback:
-+-> filp,  contains the device in its private data
-+-> buf,   the buffer in userspace
-+-> count, amount of that to be read
-+-> f_pos, the starting point of the data
-+-> return:number of bytes read
-+*/
-+ssize_t gpioTest_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos){
-+// dev was stored in filp during the open call.
-+// struct gpioTest_dev *dev = filp->private_data;
-+  
-+  printk( KERN_ERR "gpioTest_read:\n");
-+
-+// Copy this quantum (from the offset, to the end of this quantum)
-+// to userspace
-+// if(copy_to_user(buf, dptr->data[s_pos] + q_pos, count)){
-+//   retval = -EFAULT;
-+//   goto out;
-+// }
-+
-+// Update the file offset
-+// *f_pos += count;
-+// retval = count;
-+// out:
-+// up(&dev->sem);
-+  return 0;
-+}
-+
-+/*
-+Write callback
-+-> filp,  contains the device in its private data
-+-> buf,   the buffer in userspace
-+-> count, amount of that to be written
-+-> f_pos, the starting point of the data
-+-> return:number of bytes written
-+*/
-+ssize_t gpioTest_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){
-+
-+//  struct gpioTest_dev *dev = filp->private_data;
-+  
-+  printk( KERN_ERR "gpioTest_write:\n");
-+
-+ 
-+  // Copy the data to be written from userspace
-+  // if(copy_from_user(dptr->data[s_pos]+q_pos, buf, count)){
-+  //   retval = -EFAULT;
-+  // }
-+  // 
-+  // *f_pos+=count;
-+  // retval = count;
-+
-+  // Update the size
-+  // if(dev->size < *f_pos){
-+  //   dev->size = *f_pos;
-+  // }
-+
-+// out:
-+  // up(&dev->sem);
-+  return 0;
-+}
-+
-+
-+
-+/*
-+Release callback
-+*/
-+int gpioTest_release(struct inode *inode, struct file *filp)
-+{
-+  printk( KERN_ERR "gpioTest_release:\n");
-+  return 0;
-+}
-+
-+/*
-+Open callback
-+*/
-+int gpioTest_open(struct inode *inode, struct file *filp){
-+//  struct gpioTest_dev *dev;
-+
-+  printk( KERN_ERR "gpioTest_open:\n");
-+  // This macro takes a pointer to a field of type 'container_field', within
-+  // a strcture of type 'container_type' and returns a pointer to the containing
-+  // structure.
-+  // dev = container_of(inode->i_cdev, struct gpioTest_dev, cdev);
-+  // Store the pointer for future access
-+  // filp->private_data = dev;
-+
-+  return 0;
-+}
-+
-+
-+
-+
-+//////////////////
-+// MODULE STUFF //
-+//////////////////
-+
-+// File operations for this charater device
-+struct file_operations gpioTest_fops = {
-+    .owner =    THIS_MODULE,
-+    //.llseek =   gpioTest_llseek,
-+    .read =     gpioTest_read,
-+    .write =    gpioTest_write,
-+    //    .ioctl =    gpioTest_ioctl,
-+    .open =     gpioTest_open,
-+    .release =  gpioTest_release,
-+};
-+
-+
-+/*
-+ Module loading
-+*/
-+static int gpioTest_init(void){
-+	
-+	// alloc_chrdev_region return 0 on success
-+	int res = alloc_chrdev_region(
-+		&dev,
-+		0,
-+		1, 
-+		"GPIOTest");
-+
-+	printk( KERN_ERR "gpioTest_init:\n");
-+	
-+	if(res){
-+		printk(KERN_WARNING "gpioTest: could not allocate device\n");
-+		return res;
-+	}else{
-+		printk(KERN_WARNING "gpioTest: registered with major number:%i\n", MAJOR(dev));
-+	}
-+	
-+	
-+	// Allocate memory for gpioTest_COUNT gpioTest_devices
-+	gpioTest_device = kmalloc(sizeof(struct gpioTest_dev), GFP_KERNEL);
-+	if(gpioTest_device == NULL){
-+		res = -ENOMEM;
-+		goto fail;
-+	}
-+	
-+	// Fill the gpioTest_devices region with zeros
-+	memset(gpioTest_device, 0, sizeof(struct gpioTest_dev));
-+	
-+	// Initialise the devices
-+   
-+	// Register the cdev, gpioTest_fops contains all the defined callbacks
-+	cdev_init(&gpioTest_device->cdev,&gpioTest_fops);
-+	gpioTest_device->cdev.owner 	= THIS_MODULE;
-+	gpioTest_device->cdev.ops 	= &gpioTest_fops;
-+	res 				= cdev_add(&gpioTest_device->cdev,MKDEV(MAJOR(dev), MINOR(dev)) ,1);
-+	if(res){
-+		printk(KERN_NOTICE "Error %d adding gpioTest\n", res);
-+	}else{
-+		printk(KERN_NOTICE "gpioTest added\n");
-+	}
-+	
-+	// perform a test
-+	res  = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+		res &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+		writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+	if ( gpioTest_go() )
-+	{
-+		DumpGPIO();
-+	}
-+	
-+	// perform a test again with debounce.
-+	res  = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+		res |= (GPIO_TEST_SCL | GPIO_TEST_SDA);
-+		writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+	if ( gpioTest_go() )
-+	{
-+		DumpGPIO();
-+	}
-+	
-+
-+
-+  return 0;
-+
-+fail:
-+  // do cleanup;
-+  return res;
-+}
-+
-+
-+/*
-+ Module unloading
-+*/
-+static void gpioTest_exit(void){
-+	// Free the devices
-+	printk( KERN_ERR "gpioTest_exit:\n");
-+	cdev_del(&gpioTest_device->cdev);
-+	kfree(gpioTest_device);
-+	gpioTest_device = NULL;
-+	unregister_chrdev_region(dev,1);
-+}
-+
-+module_init(gpioTest_init);
-+module_exit(gpioTest_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/i2s.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c
---- linux-2.6.24/arch/arm/mach-oxnas/i2s.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,352 @@
-+/* 
-+ *  procfs3.c -  create a "file" in /proc, use the file_operation way
-+ *  		to manage the file.
-+ */
-+ 
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>	/* We're doing kernel work */
-+#include <linux/module.h>	/* Specifically, a module */
-+#include <linux/proc_fs.h>	/* Necessary because we use proc fs */
-+#include <asm/uaccess.h>		/* for copy_*_user */
-+#include "asm/arch-oxnas/i2s.h"
-+#include "asm/io.h"
-+
-+#define DRV_NAME		"i2s"
-+#define DRV_VERSION	"0.1"
-+#define PROC_ENTRY_FILENAME 	"i2s"
-+#define PROCFS_MAX_SIZE 	2048
-+
-+
-+
-+MODULE_AUTHOR("Chris Ford");
-+MODULE_DESCRIPTION("I2S Test module");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+/**
-+ * The buffer (2k) for this module
-+ *
-+ */
-+static char procfs_buffer[PROCFS_MAX_SIZE];
-+
-+/**
-+ * The size of the data hold in the buffer
-+ *
-+ */
-+static unsigned long procfs_buffer_size = 0;
-+
-+/**
-+ * The structure keeping information about the /proc file
-+ *
-+ */
-+static struct proc_dir_entry *Our_Proc_File;
-+
-+
-+void RefreshI2SRegisters(void)
-+{
-+	int iLen = sprintf( procfs_buffer,  
-+		"DumpI2SRegisters----------------------------------\n"
-+		"                                                  \n"
-+		"     TX_CONTROL                = 0x%08x\n"
-+		"     TX_SETUP                  = 0x%08x\n"
-+		"     TX_SETUP1                 = 0x%08x\n"
-+		"     TX_STATUS                 = 0x%08x\n"
-+		"     RX_CONTROL                = 0x%08x\n"
-+		"     RX_SETUP                  = 0x%08x\n"
-+		"     RX_SETUP1                 = 0x%08x\n"
-+		"     RX_STATUS                 = 0x%08x\n"
-+		"     TX_DEBUG                  = 0x%08x\n"
-+		"     TX_DEBUG2                 = 0x%08x\n"
-+		"     TX_DEBUG3                 = 0x%08x\n"
-+		"     RX_DEBUG_                 = 0x%08x\n"
-+		"     RX_DEBUG2                 = 0x%08x\n"
-+		"     RX_DEBUG3                 = 0x%08x\n"
-+		"     TX_BUFFER_LEVEL           = 0x%08x\n"
-+		"     TX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
-+		"     RX_BUFFER_LEVEL           = 0x%08x\n"
-+		"     RX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
-+		"     RX_SPDIF_DEBUG            = 0x%08x\n"
-+		"     RX_SPDIF_DEBUG2           = 0x%08x\n",
-+		(u32) __raw_readl( TX_CONTROL                 ),
-+		(u32) __raw_readl( TX_SETUP                   ),
-+		(u32) __raw_readl( TX_SETUP1                  ),
-+		(u32) __raw_readl( TX_STATUS                  ),
-+		(u32) __raw_readl( RX_CONTROL                 ),
-+		(u32) __raw_readl( RX_SETUP                   ),
-+		(u32) __raw_readl( RX_SETUP1                  ),
-+		(u32) __raw_readl( RX_STATUS                  ),
-+		(u32) __raw_readl( TX_DEBUG                   ),
-+		(u32) __raw_readl( TX_DEBUG2                  ),
-+		(u32) __raw_readl( TX_DEBUG3                  ),
-+		(u32) __raw_readl( RX_DEBUG_                  ),
-+		(u32) __raw_readl( RX_DEBUG2                  ),
-+		(u32) __raw_readl( RX_DEBUG3                  ),
-+		(u32) __raw_readl( TX_BUFFER_LEVEL            ),
-+		(u32) __raw_readl( TX_BUFFER_INTERRUPT_LEVEL  ),
-+		(u32) __raw_readl( RX_BUFFER_LEVEL            ),
-+		(u32) __raw_readl( RX_BUFFER_INTERRUPT_LEVEL  ),
-+		(u32) __raw_readl( RX_SPDIF_DEBUG             ),
-+		(u32) __raw_readl( RX_SPDIF_DEBUG2            ) );
-+	
-+	procfs_buffer_size = iLen + sprintf( procfs_buffer + iLen, 
-+		"     INTERRUPT_CONTROL_STATUS  = 0x%08x\n"
-+		"     INTERRUPT_MASK            = 0x%08x\n"
-+		"     VERSION                   = 0x%08x\n"
-+		"     TX_DATA_IN_FORMAT         = 0x%08x\n"
-+		"     TX_CHANNELS_ENABLE        = 0x%08x\n"
-+		"     TX_WRITES_TO              = 0x%08x\n"
-+		"     RX_DATA_OUT_FORMAT        = 0x%08x\n"
-+		"     RX_CHANNELS_ENABLE        = 0x%08x\n"
-+		"     RX_READS_FROM             = 0x%08x\n"
-+		"     TX_CPU_DATA_WRITES_ALT    = 0x%08x\n"
-+		"     RX_CPU_DATA_READS_ALT     = 0x%08x\n"
-+		"     TX_CPU_DATA_WRITES        = 0x%08x\n"
-+		"     RX_CPU_DATA_READS         = 0x%08x\n"
-+		"\n"
-+		"--------------------------------------------------\n",
-+		(u32) __raw_readl( INTERRUPT_CONTROL_STATUS   ),
-+		(u32) __raw_readl( INTERRUPT_MASK             ),
-+		(u32) __raw_readl( VERSION                    ),
-+		(u32) __raw_readl( TX_DATA_IN_FORMAT          ),
-+		(u32) __raw_readl( TX_CHANNELS_ENABLE         ),
-+		(u32) __raw_readl( TX_WRITES_TO               ),
-+		(u32) __raw_readl( RX_DATA_OUT_FORMAT         ),
-+		(u32) __raw_readl( RX_CHANNELS_ENABLE         ),
-+		(u32) __raw_readl( RX_READS_FROM              ),
-+		(u32) __raw_readl( TX_CPU_DATA_WRITES_ALT     ),
-+		(u32) __raw_readl( RX_CPU_DATA_READS_ALT      ),
-+		(u32) __raw_readl( TX_CPU_DATA_WRITES         ),
-+		(u32) __raw_readl( RX_CPU_DATA_READS          ) );
-+}
-+
-+
-+void DumpI2SRegisters(void)
-+{
-+	RefreshI2SRegisters();
-+	printk( KERN_INFO "%s", procfs_buffer );  
-+	return;
-+}
-+
-+
-+/**
-+ * This funtion is called when the /proc file is read
-+ *
-+ */
-+static ssize_t procfs_read(
-+	struct file *filp,	/* see include/linux/fs.h   */
-+	char *buffer,		/* buffer to fill with data */
-+	size_t length,		/* length of the buffer     */
-+	loff_t * offset)
-+{
-+	static int finished = 0;
-+
-+	/* 
-+	 * We return 0 to indicate end of file, that we have
-+	 * no more information. Otherwise, processes will
-+	 * continue to read from us in an endless loop. 
-+	 */
-+	if ( finished ) {
-+		printk(KERN_INFO "procfs_read: END\n");
-+		finished = 0;
-+		return 0;
-+	}
-+	
-+	finished = 1;
-+		
-+	/* 
-+	 * We use put_to_user to copy the string from the kernel's
-+	 * memory segment to the memory segment of the process
-+	 * that called us. get_from_user, BTW, is
-+	 * used for the reverse. 
-+	 */
-+	if ( copy_to_user(buffer, procfs_buffer, procfs_buffer_size) ) {
-+		return -EFAULT;
-+	}
-+
-+	printk(KERN_INFO "procfs_read: read %lu bytes\n", procfs_buffer_size);
-+
-+	return procfs_buffer_size;	/* Return the number of bytes "read" */
-+}
-+
-+/*
-+ * This function is called when /proc is written
-+ */
-+static ssize_t
-+procfs_write(struct file *file, const char *buffer, size_t len, loff_t * off)
-+{
-+	if ( len > PROCFS_MAX_SIZE )	{
-+		procfs_buffer_size = PROCFS_MAX_SIZE;
-+	}
-+	else	{
-+		procfs_buffer_size = len;
-+	}
-+	
-+	if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
-+		return -EFAULT;
-+	}
-+
-+	printk(KERN_INFO "procfs_write: write %s\n",buffer);
-+	printk(KERN_INFO "procfs_write: write %lu bytes\n", procfs_buffer_size);
-+	
-+	return procfs_buffer_size;
-+}
-+
-+/* 
-+ * This function decides whether to allow an operation
-+ * (return zero) or not allow it (return a non-zero
-+ * which indicates why it is not allowed).
-+ *
-+ * The operation can be one of the following values:
-+ * 0 - Execute (run the "file" - meaningless in our case)
-+ * 2 - Write (input to the kernel module)
-+ * 4 - Read (output from the kernel module)
-+ *
-+ * This is the real function that checks file
-+ * permissions. The permissions returned by ls -l are
-+ * for referece only, and can be overridden here.
-+ */
-+
-+static int module_permission(struct inode *inode, int op, struct nameidata *foo)
-+{
-+	/* 
-+	 * We allow everybody to read from our module, but
-+	 * only root (uid 0) may write to it 
-+	 */
-+	 if (op == 4 || (op == 2 && current->euid == 0)) {
-+		 printk( KERN_INFO "Insufficient permissions\n");
-+		return 0;
-+	 }
-+
-+	/* 
-+	 * If it's anything else, access is denied 
-+	 */
-+	return -EACCES;
-+}
-+
-+/* 
-+ * The file is opened - we don't really care about
-+ * that, but it does mean we need to increment the
-+ * module's reference count. 
-+ */
-+int procfs_open(struct inode *inode, struct file *file)
-+{
-+	u32 temp = 0;
-+	
-+	/* Open an entry on the proc filesystem */
-+	printk(KERN_INFO "I2S::procfs_open\n");
-+	try_module_get(THIS_MODULE);
-+	
-+	// printk(KERN_INFO "I2S::pre-reg set..\n");
-+	// RefreshI2SRegisters();
-+
-+	/* Setup the I2S TX Core... */
-+	temp  = 1                 << TX_CONTROL_ENABLE        |
-+		1                 << TX_CONTROL_FLUSH         |
-+		0                 << TX_CONTROL_MUTE          |
-+		0                 << TX_CONTROL_TRICK         |
-+		0                 << TX_CONTROL_SPEED         |
-+		1                 << TX_CONTROL_ABORT_DMA     |
-+		0                 << TX_CONTROL_AHB_ENABLE    |
-+		1                 << TX_CONTROL_QUAD_BURSTS;
-+	__raw_writel( temp, TX_CONTROL );
-+	
-+	temp  = TRUE_I2S          << TX_SETUP_FORMAT          |
-+		I2S_SLAVE         << TX_SETUP_MODE            |
-+		0                 << TX_SETUP_FLOW_INVERT     |
-+		0                 << TX_SETUP_POS_EDGE        |
-+		0                 << TX_SETUP_CLOCK_STOP      |
-+		0                 << TX_SETUP_SPLIT_QUAD      |
-+		0                 << TX_SETUP_SPDIF_EN;
-+	__raw_writel( temp, TX_SETUP );
-+	
-+	temp  = TWOS_COMPLIMENT   << TX_SETUP1_INPUT          |
-+		0		  << TX_SETUP1_REVERSE        |
-+		0         	  << TX_SETUP1_INVERT         |
-+		0                 << TX_SETUP1_BIG_ENDIAN     |
-+		0                 << TX_SETUP1_QUAD_ENDIAN    |
-+		0                 << TX_SETUP1_QUAD_SAMPLES   |
-+		0                 << TX_SETUP1_FLOW_CONTROL;
-+	__raw_writel( temp, TX_SETUP1 );
-+	
-+	/* Setup the I2S RX Core... */
-+	
-+	printk(KERN_INFO "\n\nI2S::post-reg set..\n");
-+	RefreshI2SRegisters();
-+	return 0;
-+}
-+
-+/* 
-+ * The file is closed - again, interesting only because
-+ * of the reference count. 
-+ */
-+int procfs_close(struct inode *inode, struct file *file)
-+{
-+	printk(KERN_INFO "I2S::procfs_close\n");
-+	module_put(THIS_MODULE);
-+	return 0;		/* success */
-+}
-+
-+static struct file_operations File_Ops_4_Our_Proc_File = {
-+	.read 	 = procfs_read,
-+	.write 	 = procfs_write,
-+	.open 	 = procfs_open,
-+	.release = procfs_close,
-+};
-+
-+/* 
-+ * Inode operations for our proc file. We need it so
-+ * we'll have some place to specify the file operations
-+ * structure we want to use, and the function we use for
-+ * permissions. It's also possible to specify functions
-+ * to be called for anything else which could be done to
-+ * an inode (although we don't bother, we just put
-+ * NULL). 
-+ */
-+
-+static struct inode_operations Inode_Ops_4_Our_Proc_File = {
-+	.permission = module_permission,	/* check for permissions */
-+};
-+
-+/* 
-+ * Module initialization and cleanup 
-+ */
-+static int __init oxnas_i2s_init_module(void)
-+{
-+	printk(KERN_INFO "I2S::init_module\n");
-+
-+	/* create the /proc file */
-+	Our_Proc_File = create_proc_entry(PROC_ENTRY_FILENAME, 0644, NULL);
-+	
-+	/* check if the /proc file was created successfuly */
-+	if (Our_Proc_File == NULL){
-+		printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
-+		       PROC_ENTRY_FILENAME);
-+		return -ENOMEM;
-+	}
-+	
-+	Our_Proc_File->owner 	  = THIS_MODULE;
-+	Our_Proc_File->proc_iops  = &Inode_Ops_4_Our_Proc_File;
-+	Our_Proc_File->proc_fops  = &File_Ops_4_Our_Proc_File;
-+	Our_Proc_File->mode 	  = S_IFREG | S_IRUGO | S_IWUSR;
-+	Our_Proc_File->uid 	  = 0;
-+	Our_Proc_File->gid 	  = 0;
-+	Our_Proc_File->size	  = 80;
-+
-+	printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME);
-+
-+	return 0;	/* success */
-+}
-+
-+static void __exit oxnas_i2s_cleanup_module(void)
-+{
-+	printk(KERN_INFO "I2S::cleanup_module\n");
-+	remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
-+	printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME);
-+}
-+
-+module_init(oxnas_i2s_init_module);
-+module_exit(oxnas_i2s_cleanup_module);
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/irq.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c
---- linux-2.6.24/arch/arm/mach-oxnas/irq.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ *  linux/arch/arm/mach-oxnas/irq.c
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/list.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach/irq.h>
-+
-+static void OXNAS_mask_irq(unsigned int irq)
-+{
-+    *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = (1UL << irq);
-+}
-+
-+static void OXNAS_unmask_irq(unsigned int irq)
-+{
-+    *((volatile unsigned long*)RPS_IRQ_ENABLE) = (1UL << irq);
-+}
-+
-+static struct irq_chip OXNAS_chip = {
-+	.name	= "OXNAS",
-+    .ack	= OXNAS_mask_irq,
-+    .mask	= OXNAS_mask_irq,
-+    .unmask = OXNAS_unmask_irq,
-+};
-+
-+void __init oxnas_init_irq(void)
-+{
-+    unsigned irq;
-+
-+    // Disable all IRQs
-+    *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = ~0UL;
-+
-+    // Disable FIQ
-+    *((volatile unsigned long*)(RPS_FIQ_DISABLE)) = ~0UL;
-+
-+    // Initialise IRQ tracking structures
-+    for (irq=0; irq < NR_IRQS; irq++)
-+    {
-+        set_irq_chip(irq, &OXNAS_chip);
-+        set_irq_handler(irq, handle_level_irq);
-+        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-+    }
-+}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/leds.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leds.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#define DEBUG
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+
-+#include <linux/platform_device.h>
-+
-+
-+#include <linux/leds.h>
-+ 
-+#include <asm/hardware.h>
-+
-+#define DEBUG_PRINT(A) printk(KERN_NOTICE A)
-+
-+#define writel(data,address) (*(volatile u32 *) address = data)
-+#define readl(address)       (*(volatile u32 *) address)
-+
-+/* run pwm refresh at approximately 100Hz to avoid flicker */
-+/* resolution is 8bits, sys clock 200MHz divider is therefore 7812 less 1 cycle */
-+#define PWM_PERIOD  (7811)
-+
-+#define MAX_PWMS     16
-+
-+static void ramp_power_on_leds(unsigned long data);
-+
-+DEFINE_TIMER (power_ramp_timer, ramp_power_on_leds, 0, 0);
-+
-+enum { POWER_ON,
-+	NUMBER_LEDS};
-+	
-+static struct platform_device *oxnas_leds;	
-+static u16 offset[NUMBER_LEDS] = {25};
-+
-+static u16 led [NUMBER_LEDS];
-+
-+#define MAX_BRIGHTNESS   255
-+
-+static void set_led(u16 led, u16 value)
-+{
-+	u16 led_index = offset[led] % MAX_PWMS;
-+	
-+	writel(value, (PWM_DATA_REGISTER_BASE+4*led_index));
-+	
-+}
-+
-+static void ramp_power_on_leds(unsigned long data)
-+{
-+	if (led[POWER_ON] < MAX_BRIGHTNESS) {
-+		 set_led(POWER_ON, ++led[POWER_ON]);
-+		 mod_timer(&power_ramp_timer, (power_ramp_timer.expires + msecs_to_jiffies(64)) );
-+	}
-+	else del_timer(&power_ramp_timer);
-+}
-+
-+static void oxnasled_power_on_set(struct led_classdev *led_cdev, enum led_brightness value)
-+{
-+	if (value == 0) {
-+		current_bright = 0;
-+		led[POWER_ON]=0;
-+	    set_led(POWER_ON, 0);
-+		
-+	}
-+	else
-+	{
-+		power_ramp_timer.expires = jiffies + msecs_to_jiffies(64);
-+		add_timer(&power_ramp_timer);
-+	}
-+}
-+
-+static struct led_classdev oxnas_power_on_led = {
-+	.name			= "oxnas:power_on",
-+	.brightness_set		= oxnasled_power_on_set,
-+};
-+
-+
-+#ifdef CONFIG_PM
-+
-+// TODO implement led suspend operation on NAS
-+static int oxnasled_suspend(struct platform_device *dev, pm_message_t state)
-+{
-+#ifdef CONFIG_LEDS_TRIGGERS
-+	if (oxnas_amber_led.trigger && strcmp(oxnas_amber_led.trigger->name, "sharpsl-charge"))
-+#endif
-+		led_classdev_suspend(&oxnas_amber_led);
-+	led_classdev_suspend(&oxnas_green_led);
-+	return 0;
-+}
-+// TODO implement led resume operation on NAS
-+static int oxnasled_resume(struct platform_device *dev)
-+{
-+	led_classdev_resume(&oxnas_amber_led);
-+	led_classdev_resume(&oxnas_green_led);
-+	return 0;
-+}
-+#endif
-+
-+static int oxnasled_probe(struct platform_device *pdev)
-+{
-+	int ret;
-+	int i;
-+
-+	writel(PWM_PERIOD, PWM_CLOCK_REGISTER);
-+
-+	
-+	/* enable PWM drives outputs */
-+	for (i=0; i < NUMBER_LEDS ; ++i)
-+	{
-+		if (offset[i] < 32) {
-+			writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) | (1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0); 
-+		}
-+		else {
-+			writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) | (1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+		}
-+	}
-+
-+	ret = led_classdev_register(&pdev->dev, &oxnas_power_on_led);
-+	
-+	if (ret < 0) goto error_1;
-+	
-+	return ret;
-+	
-+error_1:		
-+	return ret;
-+}
-+
-+static int oxnasled_remove(struct platform_device *pdev)
-+{
-+	int i;
-+	
-+	led_classdev_unregister(&oxnas_power_on_led);
-+
-+	/* disable PWM drives outputs */
-+	for (i=0; i < NUMBER_LEDS ; ++i)
-+	{
-+		if (offset[i] < 32) {
-+			writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) & ~((u32)1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0); 
-+		}
-+		else {
-+			writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) & ~((u32)1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+		}
-+	}
-+	
-+	writel(PWM_CLOCK_REGISTER, 0);
-+	
-+	return 0;
-+}
-+
-+
-+static struct platform_driver oxnasled_driver = {
-+	.probe		= oxnasled_probe,
-+	.remove		= oxnasled_remove,
-+#ifdef CONFIG_PM
-+	.suspend	= oxnasled_suspend,
-+	.resume		= oxnasled_resume,
-+#endif
-+	.driver		= {
-+		.name		= "oxnas-leds",
-+		.owner      = THIS_MODULE,
-+	},
-+};
-+
-+static int __init oxnasled_init(void)
-+{
-+	int ret;
-+
-+	ret = platform_driver_register(&oxnasled_driver);
-+	
-+	
-+	
-+	/* now register the devices on the bus so they can be associated with the driver */
-+	if (!ret) 
-+			oxnas_leds=platform_device_register_simple("oxnas-leds", -1, NULL, 0);
-+	return ret;
-+}
-+
-+static void __exit oxnasled_exit(void)
-+{
-+	if (oxnas_leds) {
-+		platform_device_unregister(oxnas_leds);
-+	}
-+
-+ 	platform_driver_unregister(&oxnasled_driver);
-+}
-+
-+module_init(oxnasled_init);
-+module_exit(oxnasled_exit);
-+
-+MODULE_AUTHOR("John Larkworthy <john.larkworthy at oxsem.com");
-+MODULE_DESCRIPTION("OXNAS front panel LED driver");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c
---- linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leds.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/leds.h>
-+
-+static void ledtrig_ide_timerfunc(unsigned long data);
-+
-+DEFINE_LED_TRIGGER(ledtrig_ide);
-+static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
-+static int ide_activity;
-+static int ide_lastactivity;
-+
-+void ledtrig_sata_activity(void)
-+{
-+	ide_activity++;
-+	if (!timer_pending(&ledtrig_ide_timer))
-+		mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
-+}
-+EXPORT_SYMBOL(ledtrig_sata_activity);
-+
-+static void ledtrig_ide_timerfunc(unsigned long data)
-+{
-+	if (ide_lastactivity != ide_activity) {
-+		ide_lastactivity = ide_activity;
-+		led_trigger_event(ledtrig_ide, LED_FULL);
-+	    	mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
-+	} else {
-+		led_trigger_event(ledtrig_ide, LED_OFF);
-+	}
-+}
-+
-+static int __init ledtrig_ide_init(void)
-+{
-+	led_trigger_register_simple("sata-disk", &ledtrig_ide);
-+	return 0;
-+}
-+
-+static void __exit ledtrig_ide_exit(void)
-+{
-+	led_trigger_unregister_simple(ledtrig_ide);
-+}
-+
-+module_init(ledtrig_ide_init);
-+module_exit(ledtrig_ide_exit);
-+
-+MODULE_AUTHOR("John Larkworthy <john.larkworthy at oxnas.com>");
-+MODULE_DESCRIPTION("LED SATA Disk Activity Trigger");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c
---- linux-2.6.24/arch/arm/mach-oxnas/leon.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,244 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leon.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifdef CONFIG_SUPPORT_LEON
-+
-+#include <asm/io.h>
-+#include <asm/types.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/ctype.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <asm/arch/leon.h>
-+
-+static u8 asciihex_to_decimal(u8 ascii)
-+{
-+    return isdigit(ascii) ? (ascii - '0') : (isalpha(ascii) ? ((toupper(ascii) - 'A') + 10)  : 0);
-+}
-+
-+static u8 srec_read_u8(const s8** srec)
-+{
-+    u8 first_ascii  = **srec;
-+    u8 second_ascii = *++*srec;
-+    ++*srec;
-+    return ((asciihex_to_decimal(first_ascii) << 4) | asciihex_to_decimal(second_ascii));
-+}
-+
-+static u32 srec_read_u32(const s8** srec)
-+{
-+    u32 word  = ((u32)srec_read_u8(srec) << 24);
-+    word     |= ((u32)srec_read_u8(srec) << 16);
-+    word     |= ((u16)srec_read_u8(srec) << 8);
-+    word     |= srec_read_u8(srec);
-+    return word;
-+}
-+
-+static void skip_to_next_record(const s8** srec)
-+{
-+    while (*++*srec != '\n');
-+    ++*srec;
-+}
-+
-+/**
-+ * @param  srec An const s8** pointing to the position in the input s-record
-+ *         array at which to begin parsing
-+ * @param  buf An u8* into which any extracted record in to be placed
-+ * @param  adr An u8** into which either the extracted record's load address is
-+ *         to be written, or the execution start address
-+ * @param  len An u8* into which the length in bytes of the extracted record is
-+ *         to be written
-+ * @return An int which is zero if another record is available, else if non-zero
-+ *         indicated that the execution start address is available in the
-+ *         adr argument
-+ */
-+static void read_record(u8 len, const s8** srec, u8* buf)
-+{
-+    int quads = len/sizeof(u32);
-+    int spare = len - (quads*sizeof(u32));
-+
-+    int i=0;
-+    while (i < quads) {
-+        ((u32*)buf)[i++] = srec_read_u32(srec);
-+    }
-+    i = len-spare;
-+    while (i < len) {
-+        buf[i++] = srec_read_u8(srec);
-+    }
-+}
-+
-+static int get_next_record(const s8** srec, u8* buf, u8** adr, u8* len)
-+{
-+    int again;
-+    int last = 1;
-+
-+    *adr = 0;
-+    do {
-+        again = 0;
-+        if (**srec == 'S') {
-+            switch (*++*srec) {
-+                case '0':
-+                    skip_to_next_record(srec);
-+                    again = 1;
-+                    break;
-+                case '3':
-+                    ++*srec;
-+                    *len = srec_read_u8(srec) - sizeof(u32) - 1;
-+                    *adr = (u8*)srec_read_u32(srec);
-+                    read_record(*len, srec, buf);
-+                    skip_to_next_record(srec);
-+                    last = 0;
-+                    break;
-+                case '7':
-+                    ++*srec;
-+                    *len = srec_read_u8(srec) - 1;
-+                    if (*len >= sizeof(u32)) {
-+                        *adr = (u8*)srec_read_u32(srec);
-+                    }
-+                    break;
-+                default:
-+                    break;
-+            }
-+        }
-+    } while (again);
-+
-+    return last;
-+}
-+
-+static const u32 ENDIAN_LITTLE_READ_BIT = 30;
-+static const u32 ENDIAN_BIG_WRITE_BIT   = 31;
-+
-+static u8* convert_adr_to_virt(u8* adr)
-+{
-+	static const u32 ARM_HIGH_ORDER_ADR_BIT = 30;
-+
-+    u32 virt = (u32)adr;
-+
-+	// Zero the Leon endian control bits
-+	virt &= ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT));
-+
-+	// Convert to an ARM physical address
-+	virt |= (1UL << ARM_HIGH_ORDER_ADR_BIT);
-+
-+    // Is address sane?
-+    if (virt < LEON_IMAGE_BASE_PA) {
-+        panic("CoPro SRAM load address 0x%08x below mapped region beginning at 0x%08lx\n", (u32)adr, LEON_IMAGE_BASE_PA);
-+    } else {
-+        virt -= LEON_IMAGE_BASE_PA;
-+        virt += LEON_IMAGE_BASE;
-+    }
-+
-+    return (u8*)virt;
-+}
-+
-+static void leon_load_image(const s8 *srec)
-+{
-+    u8       *buf;
-+    u8       *adr;
-+    u8        len;
-+    u32       code_base;
-+
-+    // Copy each record to the specified address
-+    // Convert the LEON physical address to an ARM virtual address before
-+	// attempting to get the ARM to access it
-+    // NB must endian-swap any trailing non-quad multiple bytes, as LEON will
-+    // expect its instruction data in big endian format, whereas the ARM is
-+    // little endian
-+    buf  = kmalloc(512, GFP_KERNEL);
-+    while (!get_next_record(&srec, buf, &adr, &len)) {
-+        int i=0;
-+        int quads = len/sizeof(u32);
-+        int spare = len - (quads*sizeof(u32));
-+        int padded_len = len+(sizeof(u32)-spare);
-+        u32* quad_ptr;
-+
-+        adr = convert_adr_to_virt(adr);
-+
-+        quad_ptr = (u32*)adr;
-+        while (i < quads) {
-+            *quad_ptr++ = ((u32*)buf)[i++];
-+        }
-+        adr = (u8*)quad_ptr;
-+        for (i=len; i < padded_len; i++) {
-+            buf[i] = 0;
-+        }
-+        i = padded_len-1;
-+        while (i >= (len-spare)) {
-+            *adr++ = buf[i--];
-+        }
-+    }
-+    kfree(buf);
-+
-+    // Start LEON execution at the address specified by the S-records, with
-+    // correct endianess. Use the address unchanged, as the LEON required
-+    // physical addresses and may make use of alternative upper nibble values
-+    code_base = (((u32)adr & ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT))) | (1UL << ENDIAN_BIG_WRITE_BIT));
-+
-+    // Set the LEON's start address
-+    printk(KERN_NOTICE "CoPro: Programming start address as 0x%08x (basic adr = 0x%08x)\n", code_base, (u32)adr);
-+    writel(code_base, SYS_CTRL_COPRO_CTRL);
-+
-+    // Ensure start address has been loaded before release the LEON from reset
-+    wmb();
-+}
-+
-+void init_copro(const s8 *srec, unsigned long arg)
-+{
-+    // Ensure the LEON is in reset
-+    writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+    // Enable the clock to the LEON
-+    writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Ensure reset and clock operations are complete
-+    wmb();
-+
-+    // Place LEON context argument in top quad of SRAM
-+	*((u32*)(LEON_IMAGE_BASE+LEON_IMAGE_SIZE-sizeof(u32))) = arg;
-+
-+    // Load LEON's program and data and execution start address
-+    leon_load_image(srec);
-+
-+    // Release the LEON from reset so it begins execution of the loaded code
-+    writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Give the LEON a chance to stabilise before giving it any commands
-+    mdelay(100);
-+    return;
-+}
-+EXPORT_SYMBOL_GPL(init_copro);
-+
-+void shutdown_copro(void)
-+{
-+    // Ensure the LEON is in reset
-+    writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+    // Disable the clock to the LEON
-+    writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+    // Ensure reset and clock operations are complete
-+    wmb();
-+}
-+EXPORT_SYMBOL_GPL(shutdown_copro);
-+
-+#endif // CONFIG_SUPPORT_LEON
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,374 @@
-+/*
-+ *  arch/arm/mach-oxnas/oxnas-ahb-monitor.c
-+ *
-+ *  Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include <asm/hardware.h>
-+
-+
-+/* usb test masks and offsets */
-+#define TEST_MASK    0xF
-+#define TEST_OFFSET  16
-+
-+#define MODULE_VERS "0.1"
-+#define MODULE_NAME "oxnas-test"
-+MODULE_AUTHOR(		"John Larkworthy"					);
-+MODULE_DESCRIPTION(	"Driver to access the test hardware in oxnas units"	);
-+MODULE_LICENSE(		"GPL"							);
-+
-+
-+static struct proc_dir_entry *proc_dir_usb_test_read, *oxnas_test_dir;
-+
-+
-+static struct {
-+	void * address;
-+	char * name;
-+	long unsigned low_add;
-+	long unsigned high_add;
-+	unsigned burst;
-+	unsigned burst_mask;
-+	unsigned hprot;
-+	unsigned hprot_mask;
-+	unsigned mode;
-+} monitor[] =
-+{
-+	{ (void *) 0x00000, "ARM_Data", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x10000, "Arm_Inst", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x20000, "DMA_A", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x30000, "DMA_B", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x40000, "CoPro", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x50000, "USBHS", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x60000, "GMAC", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+	{ (void *) 0x70000, "PCI", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 }
-+};		
-+#define NO_MONITORS (sizeof(monitor)/sizeof(monitor[0]))
-+
-+/* create proc filing system entries to accept configuration data */
-+static int usb_test_write_entries(const char *name, write_proc_t *w, read_proc_t *r, int data)
-+{
-+	struct proc_dir_entry * entry = create_proc_entry(name, 0222, oxnas_test_dir);
-+	if (entry) {
-+		entry->write_proc = w;
-+		entry->read_proc =r;
-+		entry->data = (void *)data;
-+		entry->owner = THIS_MODULE;
-+		return 0;
-+	}
-+	else
-+	{
-+		return -ENOMEM;
-+	}
-+}
-+
-+static int
-+oxnas_test_read(char *buf, char **start, off_t offset,
-+		  int count, int *eof, void *unused)
-+{
-+	
-+	int i;
-+	int len = 0;
-+	long unsigned *rd_monitor;
-+	
-+	
-+	for (i=0; i < NO_MONITORS; i++)
-+	{
-+	rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
-+		len += sprintf(buf+len, "%s	CL:%ld EV:%ld hld:%ld slw:%lx tm:%ld\n", 
-+			monitor[i].name, 
-+			*rd_monitor, 
-+			*(rd_monitor+1),
-+			*(rd_monitor+2),
-+			*(rd_monitor+3),
-+			(*(rd_monitor+4) & 0xFFFF));
-+	}
-+	*eof=1;
-+	return len;
-+}
-+/*
-+ * function to clear and start all the timers mainly together.
-+ */
-+#define MAX_CMD 5
-+static int
-+oxnas_test_control(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+	int len;
-+	int i;
-+	long unsigned *rd_monitor;
-+	unsigned cmd = 0;
-+	
-+	char local[MAX_CMD];
-+	int result;
-+
-+	if (count > MAX_CMD-1)
-+		len= MAX_CMD-1;
-+	else 
-+		len=count;
-+		
-+	if (copy_from_user(&local, buf, len))
-+		return -EFAULT;
-+	
-+	result=sscanf(local, "%d", &cmd);
-+	
-+	switch (cmd) 
-+	{
-+		case 0: 
-+			printk(KERN_INFO "oxnas-test: stop command\n");
-+			break;
-+		case 1:
-+			printk(KERN_INFO "oxnas-test: run command\n");
-+			break;
-+		case 2:
-+			printk(KERN_INFO "oxnas-test: reset command\n");
-+			break;
-+		default:
-+			printk(KERN_INFO "oxnas-test: ignored command\n");
-+			return len;
-+			break;
-+	}
-+	
-+	for (i=0; i < NO_MONITORS; i++)
-+	{
-+		rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
-+		*rd_monitor = (long unsigned) cmd;
-+	}
-+	return len;
-+}
-+
-+
-+/*
-+ * The write function accepts a line as below:
-+ * start_addr, end_addr, mode, burst, burst_mask, hprot, hprot_mask 
-+ * expected string length is 10 + 10 + 3 + 3 + 4 + 3 + 4 < 40char.
-+ * This is decoded by the scanf function into the separate items. - missing items are defaulted.
-+ */
-+ 
-+#define MAX_STRING 40
-+static int
-+oxnas_test_config_write(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+	
-+	int len;	
-+	int i = (int) data;
-+	char local[MAX_STRING];
-+	int result;
-+	unsigned long * mon_ptr;
-+
-+	if (count > MAX_STRING-1)
-+		len= MAX_STRING-1;
-+	else 
-+		len=count;
-+		
-+	if (copy_from_user(&local, buf, len))
-+		return -EFAULT;
-+	
-+	/* extract value from buffer and store */
-+	
-+	result = sscanf(local, "%li,%li,%i,%i,%i,%i,%i", 
-+		&monitor[i].low_add, 
-+		&monitor[i].high_add, 
-+		&monitor[i].mode, 
-+		&monitor[i].burst, 
-+		&monitor[i].burst_mask, 
-+		&monitor[i].hprot,
-+		&monitor[i].hprot_mask
-+	);
-+	if (result != 7)
-+		return -EINVAL;
-+		
-+	/* load values on hardware */
-+	
-+	mon_ptr=(unsigned long *) (AHB_MON_BASE + monitor[i].address);
-+
-+	*(mon_ptr + 1) = monitor[i].mode & 0x3;
-+	*(mon_ptr + 2) = monitor[i].low_add;
-+	*(mon_ptr + 3) = monitor[i].high_add;
-+	*(mon_ptr + 4) = ((monitor[i].burst & 0x7) << 4 | (monitor[i].burst_mask & 0x7));
-+	*(mon_ptr + 5) = ((monitor[i].hprot & 0xf) << 4 | (monitor[i].hprot_mask &0xf));
-+		
-+	return len;
-+}
-+
-+static int
-+oxnas_test_config_read(char *buf, char **start, off_t offset,
-+		  int count, int *eof, void *data)
-+{
-+	
-+	int len = 0;	
-+	int i = (int) data;
-+	
-+	len += sprintf(buf+len, "name low  high  mode burst/mask hprot/mask\n"); 
-+
-+	len += sprintf(buf+len, "%s	0x%08lx 0x%08lx %d 0x%x/0x%x 0x%x/0x%x\n", 
-+		monitor[i].name, 
-+		monitor[i].low_add, 
-+		monitor[i].high_add, 
-+		monitor[i].mode, 
-+		monitor[i].burst, 
-+		monitor[i].burst_mask, 
-+		monitor[i].hprot,
-+		monitor[i].hprot_mask);
-+		
-+		
-+	*eof=1;
-+	return len;
-+}
-+
-+static int __init oxnas_test_init(void)
-+{
-+	int rv=0;
-+	int i;
-+	
-+	oxnas_test_dir = proc_mkdir(MODULE_NAME, NULL);
-+	if (oxnas_test_dir == NULL) {
-+		printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test\n");
-+		rv= -ENOMEM;
-+		goto out;
-+	}
-+	
-+	oxnas_test_dir->owner= THIS_MODULE;
-+	
-+	proc_dir_usb_test_read = create_proc_entry("read", 0444, oxnas_test_dir);
-+	if (proc_dir_usb_test_read) {
-+		proc_dir_usb_test_read->read_proc = oxnas_test_read;
-+	} else {
-+		printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test/read\n");
-+		rv = -ENOMEM;
-+		goto no_read;
-+	}
-+
-+	/* create port write file entries */
-+	for (i=0;i<NO_MONITORS;i++) 
-+	{
-+		rv = usb_test_write_entries(monitor[i].name, &oxnas_test_config_write, &oxnas_test_config_read, i);
-+		if (rv < 0)
-+		{
-+			while (i != 0)
-+			{
-+				i--;
-+				/* remove any allocated entries */
-+				remove_proc_entry (monitor[i].name, oxnas_test_dir);
-+			} 
-+			goto no_write;
-+		}
-+	}
-+
-+	{
-+		struct proc_dir_entry * entry = create_proc_entry("control", 0666, oxnas_test_dir);
-+		if (entry) {
-+			entry->write_proc = oxnas_test_control;
-+			entry->owner = THIS_MODULE;
-+			return 0;
-+		}
-+		else
-+		{
-+			goto no_control;
-+		}
-+	}
-+
-+
-+	printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
-+
-+	return 0;
-+
-+	no_control:
-+		for (i = NO_MONITORS; i != 0; )
-+		{
-+			i--;
-+			/* remove any allocated entries */
-+			remove_proc_entry (monitor[i].name, oxnas_test_dir);
-+		} 
-+	
-+	no_write:
-+		remove_proc_entry("read", oxnas_test_dir);
-+	no_read:
-+		remove_proc_entry(MODULE_NAME, NULL);
-+	out:
-+		return rv;
-+}
-+
-+
-+static void __exit oxnas_test_exit(void)
-+{
-+	int i;
-+	
-+	remove_proc_entry("control", oxnas_test_dir);
-+	
-+	for (i = 0; i < NO_MONITORS; i++)
-+	{
-+		remove_proc_entry(monitor[i].name, oxnas_test_dir);
-+	}
-+	
-+	remove_proc_entry("read", oxnas_test_dir);
-+	remove_proc_entry(MODULE_NAME, NULL);
-+
-+	printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
-+	
-+}
-+
-+
-+module_init(oxnas_test_init);
-+module_exit(oxnas_test_exit);
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1021 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/oxnas-wd810-leds.c
-+ *
-+ * Copyright (c) 2008 Oxford Semiconductor Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/leds.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+
-+/* Timer Values and Pulse Width Modulation */
-+#define PWM_RESOLUTION  255
-+#define TIMER_LED_MODE  TIMER_MODE_PERIODIC
-+
-+#define LED100  (PWM_RESOLUTION)	/* 100% duty cycle */
-+#define LED50   (PWM_RESOLUTION / 2)	/* 50%  duty cycle */
-+#define LED25   (PWM_RESOLUTION / 4)	/* 25%  duty cycle */
-+
-+#define STEP_RESOLUTION (16)	/* change intensity in 16 steps */
-+
-+
-+/* Setup Timer2 prescaler, operation mode, and start it */
-+#define PERIODIC_INTERRUPT                          \
-+   (                                                \
-+      (TIMER_PRESCALE_256   << TIMER_PRESCALE_BIT) | \
-+      (TIMER_LED_MODE      << TIMER_MODE_BIT)     | \
-+      (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT)     \
-+   )
-+
-+/*
-+ * Target frame rate is 60Hz.  Slower frame rates flicker badly.
-+ * Since each frame has 16 divisions to perform the pulse width
-+ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
-+ *
-+ * With a system clock of 25Mhz and a load register value of (1627) prescaled 256 
-+ * to achieve 2Hz:
-+ *   25Mhz / 256 / 24414 =~4Hz          //1627 = ~60
-+ *
-+ * PWM clock = 183MHz/256/814=~877kHz
-+ */
-+#define FAST_TIMER_INT      24414	//48828//(1627)      /* Timer2 count down      */
-+#define SYS_CLOCK       CONFIG_NOMINAL_RPSCLK_FREQ	/* System clock frequency */
-+#define PRESCALE_VALUE        (256)	/* Value set in prescaler */
-+#define PWM_PRESCALE       814	/* Value loaded on PWM clock register */
-+#define MAX_PWM   255
-+#define SLOW_TPS   ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT)	//=~4Hz, 250ms
-+
-+
-+																																												/**** if GPIO31~GPIO16 is used, sift left 16 bits ****//* GPIO bits dedicated to LEDs *///Need to modify if different GPIO used
-+#define LED_MASK_CG5   (1 << GPIO_34)	/* Capacity Gauge TOP LED  */
-+#define LED_MASK_CG4   (1 << GPIO_7)	/* Capacity Gauge 4th LED  */
-+#define LED_MASK_CG3   (1 << GPIO_6)	/* Capacity Gauge 3rd LED  */
-+#define LED_MASK_CG2   (1 << GPIO_5)	/* Capacity Gauge 2nd LED  */
-+#define LED_MASK_CG1   ((1 << GPIO_26)>>16)	//sift left 16 bits for PWM10 /* Capacity Gauge 1st LED  */
-+#define LED_MASK_CG0   ((1 << GPIO_25)>>16)	//sift left 16 bits for PWM9  /* Capacity Gauge BOTTOM LED */
-+
-+/* Mask for all the LEDs in the Fuel Gauge.*/
-+/* Mask for all the LEDs on GPIO_A */
-+
-+#define LED_MASK_GPIO_A \
-+   (                    \
-+      (LED_MASK_CG0<<16)   |  \
-+      (LED_MASK_CG1<<16)   |  \
-+      LED_MASK_CG2   |   \
-+      LED_MASK_CG3   |   \
-+      LED_MASK_CG4   \
-+   )
-+
-+/* Mask for all the LEDs on GPIO_B */
-+#define LED_MASK_GPIO_B \
-+   (                    \
-+      LED_MASK_CG5  \
-+   )
-+
-+#define LED_MASK_GAUGE \
-+   (                        \
-+      LED_MASK_CG0 |       \
-+      LED_MASK_CG1 |       \
-+      LED_MASK_CG2  |       \
-+      LED_MASK_CG3  |       \
-+      LED_MASK_CG4  |       \
-+      LED_MASK_CG5          \
-+   )
-+
-+#define LED_MASK_GAUGE_ODD \
-+   (                        \
-+      LED_MASK_CG0 |       \
-+      LED_MASK_CG2 |       \
-+      LED_MASK_CG4        \
-+   )
-+
-+#define LED_MASK_GAUGE_EVEN \
-+   (                        \
-+      LED_MASK_CG1  |       \
-+      LED_MASK_CG3  |       \
-+      LED_MASK_CG5          \
-+   )
-+
-+#define LED_MASK_GAUGE_CENTER \
-+   (                        \
-+      LED_MASK_CG2 |       \
-+      LED_MASK_CG3         \
-+   )
-+
-+#define LED_MASK_GAUGE_MID \
-+   (                        \
-+      LED_MASK_CG1  |       \
-+      LED_MASK_CG4         \
-+   )
-+
-+#define LED_MASK_GAUGE_OUTER \
-+   (                        \
-+      LED_MASK_CG0  |       \
-+      LED_MASK_CG5         \
-+   )
-+
-+#define CLEAR(addr, mask)     writel(readl(addr) & ~mask, addr)
-+
-+
-+/* Variables to hold the number of LED classes created */
-+static int leds_created;
-+
-+/* Variables to save/restore timer register values */
-+static u32 timer_load;
-+static u32 timer_control;
-+
-+/* LED polarity */
-+static int negative_led_logic = 0;
-+module_param(negative_led_logic, bool, 0);
-+
-+/*
-+ * States for the main LED behavior state machine.  
-+ */
-+enum {
-+	STATE_NOP,
-+	STANDBY,
-+	SHOW_CAPACITY,
-+	ACTIVITY,
-+	POWER_OFF,
-+	RESET,
-+	ATTENTION,
-+	FAILURE,
-+	BOOT_OK,
-+	BOOT_stage1,
-+	BOOT_stage2,
-+	BOOT_stage3,
-+	BOOT_stage4,
-+	BOOT_stage5,
-+	BOOT_stage6,
-+};
-+
-+/*Various LED state timing*/
-+#define BOOTOK_RAMP_DIV	11
-+#define STANBY_RAMP_DIV	9
-+#define STANBY_ALT_STEP	(SLOW_TPS*4)	//16//8//250      //~4sec
-+#define POWEROFF_RAMP_DIV	6
-+#define POWEROFF_ALT_STEP	((SLOW_TPS/2)*7)	//14//7//200     //~3.5sec
-+#define ATTENTION_ALT_STEP	(SLOW_TPS/2)	// 2                 //~2Hz, 0.5sec
-+#define FAILURE_RAMP_DIV	6
-+#define FAILURE_ALT_STEP	(SLOW_TPS/2)	// 2              //~2Hz, 0.5sec
-+#define ACTIVITY_RAMP_DIV	1	// 2
-+#define ACTIVITY_ALT_STEP	(SLOW_TPS/4)	// 2             //~2Hz, 0.5sec
-+#define RESET_ALT_STEP		(SLOW_TPS/2)	// 2             //~2Hz, 0.5sec
-+
-+
-+/* Variables for main LED behavior state machine */
-+static int state;
-+static u8 start;
-+static u8 act;
-+static u8 mark;
-+static u16 act_led[6] = {
-+	LED_MASK_CG0,
-+	LED_MASK_CG1,
-+	LED_MASK_CG2,
-+	LED_MASK_CG3,
-+	LED_MASK_CG4,
-+	LED_MASK_CG5,
-+};
-+static u32 alt = 0;
-+static int count;
-+static u16 capacity_gauge_bits;	/* see LED frame buffer design assumption */
-+static u8 leds_switch;
-+static u8 activity_block = 1;
-+
-+
-+/*
-+ * Declare tasklet for the LED behavior state machine.
-+ */
-+void oxnas_wd810_leds_behavior(unsigned long);
-+DECLARE_TASKLET(oxnas_wd810_leds_behavior_tasklet,
-+				oxnas_wd810_leds_behavior, 0);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_interrupt                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Interrupt handler for the oxnas-wd810-leds pulse width modulation             */
-+/***************************************************************************/
-+static irqreturn_t oxnas_wd810_leds_interrupt(int irq, void *dev_id)
-+{
-+	writel(0, TIMER2_CLEAR);
-+
-+	tasklet_schedule(&oxnas_wd810_leds_behavior_tasklet);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_vbar_bits                                           */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Convert the bit map of V-bar LEDs into the GPIO bit map          */
-+/***************************************************************************/
-+static u16 get_vbar_bits(u16 value)
-+{
-+	u16 pattern = 0;
-+
-+	// Convert the bit map to the GPIO bit pattern
-+	if (value & (1 << 0))
-+		pattern |= LED_MASK_CG0;
-+	if (value & (1 << 1))
-+		pattern |= LED_MASK_CG1;
-+	if (value & (1 << 2))
-+		pattern |= LED_MASK_CG2;
-+	if (value & (1 << 3))
-+		pattern |= LED_MASK_CG3;
-+	if (value & (1 << 4))
-+		pattern |= LED_MASK_CG4;
-+	if (value & (1 << 5))
-+		pattern |= LED_MASK_CG5;
-+
-+	return pattern;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_percentage_pattern                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Convert a percentage to a V-bar bit map.  Note, we never display */
-+/*   less than 1 LED for a percentage so that something is alway visible.  */
-+/***************************************************************************/
-+static u16 get_percentage_pattern(u16 percentage)
-+{
-+	if (percentage >= 50) {
-+		if (percentage >= 67) {
-+			if (percentage >= 83) {
-+				if (percentage >= 97) {
-+					return 0x3F;	// 6 LEDs is >= 97%
-+				} else {
-+					return 0x1F;	// 5 LEDs is >=  83%
-+				}
-+			} else {
-+				return 0x0F;	// 4 LEDs is >=  67%
-+			}
-+		} else {
-+			return 0x07;		// 3 LEDs is >=  50%
-+		}
-+	} else {
-+		if (percentage >= 33) {
-+			return 0x03;		// 2 LEDs is >=  33%
-+		} else {
-+			return 0x01;		// 1 LED  is >=   0%
-+		}
-+	}
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: set_led                                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set requested brightness on the requested LED(s) */
-+/***************************************************************************/
-+static void set_led(u16 led_bits, u8 value, u16 ramp, u16 ramp_div)
-+{
-+	u16 bit;
-+	s8 count = 0;
-+	u32 reg;
-+
-+	if (negative_led_logic) {
-+		value = MAX_PWM - value;
-+		if (ramp & 0x100) {
-+			ramp = ((MAX_PWM - (ramp & 0xFF)) | 0x100);
-+		} else
-+			ramp = ((MAX_PWM - (ramp & 0xFF)));
-+	}
-+
-+	reg = ((ramp << 16) | value);
-+//printk(KERN_INFO "set_led:  reg=%x\n", reg);  
-+	if (ramp & 0x100) {
-+		writel(ramp_div, (PWM_DATA_REGISTER_BASE + 0x404));
-+	}
-+	for (bit = 1; bit > 0; bit <<= 1, ++count) {
-+		if (bit & led_bits) {
-+			writel(reg, ((u32 *) PWM_DATA_REGISTER_BASE + count));
-+		}
-+	}
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_vbar                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set bits for the requested V-bar map                 */
-+/***************************************************************************/
-+static void display_vbar(u16 vbar_bits)
-+{
-+	//printk(KERN_INFO "display_vbar:  vbar_bits=%x\n", vbar_bits);
-+
-+	//set_led(~vbar_bits & LED_MASK_GAUGE, 0, 0, 0);
-+	set_led(LED_MASK_GAUGE, 0, 0, 0);
-+	set_led(vbar_bits, LED100, 0, 0);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_behavior_init                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Initialization for LED behavior main state machine                    */
-+/***************************************************************************/
-+void oxnas_wd810_leds_behavior_init(void)
-+{
-+	/* State machine variables */
-+	state = BOOT_OK;
-+	count = 0;
-+	capacity_gauge_bits = 0;
-+	leds_switch = 0xFF;
-+}
-+
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_behavior                                             */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   LED behavior main state machine                                       */
-+/***************************************************************************/
-+void oxnas_wd810_leds_behavior(unsigned long unused)
-+{
-+//printk(KERN_INFO "oxnas_wd810_leds_behavior state=%d count=%d\n", state, count);
-+	switch (state) {
-+	case STANDBY:
-+		//All LEDs dim-up and dim-down every 4sec.
-+		if (leds_switch & (1 << 0)) {	//LEDS display turn on
-+			if (count-- != 0)
-+				break;
-+			alt++;
-+			if ((alt % 2) == 1) {
-+				set_led(LED_MASK_GAUGE, 0, 0x1FF, STANBY_RAMP_DIV);
-+			} else {
-+				set_led(LED_MASK_GAUGE, 255, 0x100, STANBY_RAMP_DIV);
-+			}
-+			count = STANBY_ALT_STEP;
-+		} else {
-+			printk(KERN_INFO " state STANDBY LED display off \n");
-+			state = STATE_NOP;
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		break;
-+
-+	case SHOW_CAPACITY:
-+		//Each LED represents 1/6 of the total available capacity.
-+		if (leds_switch & (1 << 1)) {	//LEDS display turn on
-+			display_vbar(capacity_gauge_bits);
-+		} else {
-+			printk(KERN_INFO " state SHOW_CAPACITY LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+
-+	case ACTIVITY:
-+		//LEDs illuminate in a up and down "cylon" motion.      
-+		if (leds_switch & (1 << 2)) {	//LEDS display turn on
-+			if (count-- != 0)
-+				break;
-+
-+			if (start == 0) {
-+				set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+				set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+				start = 1;
-+			} else {
-+				if ((mark == 0) && (++act < 6)) {
-+					set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+					set_led(act_led[act - 1], 255, 0x100,
-+							ACTIVITY_RAMP_DIV);
-+					goto NEXT;
-+				}
-+				mark = 1;
-+				if ((mark == 1) && (act-- > 1)) {
-+					set_led(act_led[act], 255, 0x100, ACTIVITY_RAMP_DIV);
-+					set_led(act_led[act - 1], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+					goto NEXT;
-+				}
-+				mark = 0;
-+				state = SHOW_CAPACITY;	//Michael TBD
-+			}
-+		  NEXT:
-+			count = ACTIVITY_ALT_STEP;
-+		} else {
-+			printk(KERN_INFO " state ACTIVITY LED display off \n");
-+			state = STATE_NOP;
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		break;
-+
-+	case POWER_OFF:
-+		//LEDs in the array dim-up/dim-down in an odd/even alternating pattern.
-+		if (leds_switch & (1 << 3)) {	//LEDS display turn on
-+			if (count-- != 0)
-+				break;
-+			alt++;
-+			if ((alt % 2) == 1) {
-+				set_led(LED_MASK_GAUGE_ODD, 0, 0x1FF, POWEROFF_RAMP_DIV);
-+				set_led(LED_MASK_GAUGE_EVEN, 255, 0x100,
-+						POWEROFF_RAMP_DIV);
-+			} else {
-+				set_led(LED_MASK_GAUGE_ODD, 255, 0x100, POWEROFF_RAMP_DIV);
-+				set_led(LED_MASK_GAUGE_EVEN, 0, 0x1FF, POWEROFF_RAMP_DIV);
-+			}
-+			count = POWEROFF_ALT_STEP;
-+		} else {
-+			printk(KERN_INFO " state POWER_OFF LED display off \n");
-+			state = STATE_NOP;
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+
-+		break;
-+
-+	case RESET:
-+		//Alternately blink the upper LED and lower LED at 1/2 sec rate.        
-+		if (leds_switch & (1 << 4)) {	//LEDS display turn on
-+			if (count-- != 0)
-+				break;
-+			alt++;
-+			if ((alt % 2) == 1) {
-+				set_led(act_led[0], 255, 0x000, 0);
-+				set_led(act_led[5], 0, 0x000, 0);
-+			} else {
-+				set_led(act_led[0], 0, 0x000, 0);
-+				set_led(act_led[5], 255, 0x000, 0);
-+			}
-+			count = RESET_ALT_STEP;
-+		} else {
-+			printk(KERN_INFO " state RESET LED display off \n");
-+			state = STATE_NOP;
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+
-+		break;
-+
-+	case ATTENTION:
-+		//All LEDs flash simultaneously at a 1/2 sec. rate      
-+		if (count-- != 0)
-+			break;
-+		alt++;
-+		if ((alt % 2) == 1) {
-+			set_led(LED_MASK_GAUGE, 255, 0x000, 0);
-+
-+		} else {
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		count = ATTENTION_ALT_STEP;
-+
-+		break;
-+
-+	case FAILURE:
-+		//LEDs illuminate in a continous "center out" sweep pattern.
-+		if (count-- != 0)
-+			break;
-+
-+		switch ((alt % 4)) {
-+		case 0:
-+			set_led(LED_MASK_GAUGE_CENTER, 0, 0x1FF, FAILURE_RAMP_DIV);
-+			break;
-+		case 1:
-+			set_led(LED_MASK_GAUGE_MID, 0, 0x1FF, FAILURE_RAMP_DIV);
-+			break;
-+		case 2:
-+			set_led(LED_MASK_GAUGE_OUTER, 0, 0x1FF, FAILURE_RAMP_DIV);
-+			break;
-+		case 3:
-+			set_led(LED_MASK_GAUGE, 0, 0, 0);
-+			break;
-+		}
-+		alt++;
-+		count = FAILURE_ALT_STEP;
-+
-+		break;
-+
-+	case BOOT_OK:
-+		//All 6 LEDs ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 5)) {	//LEDS display turn on
-+			set_led(LED_MASK_GAUGE, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_OK LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage1:
-+		//Bottom LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 6)) {	//LEDS display turn on
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+			set_led(LED_MASK_CG0, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage2:
-+		// 2nd LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 6)) {	//LEDS display turn on
-+			set_led(LED_MASK_CG1, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage3:
-+		// 3rd LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 6)) {	//LEDS display turn on
-+			set_led(LED_MASK_CG2, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage4:
-+		// 4th LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 7)) {	//LEDS display turn on      
-+			set_led(LED_MASK_CG3, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage5:
-+		//5th LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 7)) {	//LEDS display turn on  
-+			set_led(LED_MASK_CG4, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case BOOT_stage6:
-+		//Top LED ramp up smoothly to full intensity.
-+		if (leds_switch & (1 << 7)) {	//LEDS display turn on          
-+			set_led(LED_MASK_CG5, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+		} else {
-+			printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+			set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+		}
-+		state = STATE_NOP;
-+		break;
-+
-+	case STATE_NOP:
-+	default:
-+		return;
-+	}
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_switch                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the LED display "on/off" of each state by Web GUI                      */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_switch
-+	(struct led_classdev *led_cdev, enum led_brightness value) {
-+	leds_switch = value;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_state                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the "state" LED to the requested behavior                         */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_state
-+	(struct led_classdev *led_cdev, enum led_brightness value) {
-+	count = 0;
-+	alt = 0;
-+	state = value;
-+	start = 0;
-+	act = 0;
-+	mark = 0;
-+	printk(KERN_INFO "oxnas_wd810_leds_state state=%d\n", state);
-+
-+	if (state > 3)
-+		activity_block = 1;
-+	else
-+		activity_block = 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_activity                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Trigger activity display behavior                                     */
-+/***************************************************************************/
-+//TBD Michael 
-+static void oxnas_wd810_leds_set_activity
-+	(struct led_classdev *led_cdev, enum led_brightness value) {
-+	if (activity_block == 0) {
-+//printk("<1> oxnas_wd810_leds_set_activity value=%x\n", value);
-+		state = ACTIVITY;
-+	}
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_capacity_gauge                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the fuel gauge to the requested value (treated as a percentage)   */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_capacity_gauge
-+	(struct led_classdev *led_cdev, enum led_brightness value) {
-+	capacity_gauge_bits = get_vbar_bits(get_percentage_pattern(value));
-+//printk("<1> oxnas_wd810_leds_set_capacity_gauge capacity_gauge_bits=%x\n", capacity_gauge_bits);
-+	state = SHOW_CAPACITY;
-+	activity_block = 0;
-+}
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_switch                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the oxnas-wd810-leds "switch" on/off                            */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_switch = {
-+	.name = "oxnas-wd810-leds:switch",.brightness_set =
-+		oxnas_wd810_leds_set_switch,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_state                                          */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the oxnas-wd810-leds "power" pseudo-LED                              */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_state = {
-+	.name = "oxnas-wd810-leds:state",
-+	.brightness_set = oxnas_wd810_leds_set_state,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_activity                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the oxnas-wd810-leds "activity" pseudo-LED                           */
-+/***************************************************************************/
-+//TBD Michael 
-+static struct led_classdev oxnas_wd810_leds_activity = {
-+	.name = "oxnas-wd810-leds:activity",
-+	.brightness_set = oxnas_wd810_leds_set_activity,
-+	.default_trigger = "sata-disk"
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_capacity_gauge                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the oxnas-wd810-leds "capacity-gauge" LEDs (brightness = % full)         */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_capacity_gauge = {
-+	.name = "oxnas-wd810-leds:capacity",
-+	.brightness_set = oxnas_wd810_leds_set_capacity_gauge,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_classes[]                                      */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Array of LED classes to create/destroy                                */
-+/***************************************************************************/
-+static struct led_classdev *oxnas_led_classes[] = {
-+	&oxnas_wd810_leds_switch,
-+	&oxnas_wd810_leds_state,
-+	&oxnas_wd810_leds_activity,	//TBD
-+	&oxnas_wd810_leds_capacity_gauge,
-+};
-+
-+#ifdef DEBUG
-+static ssize_t
-+show_registers(struct device *dev, struct device_attribute *attr,
-+			   char *buf)
-+{
-+	char *out = buf;
-+	u32 clock_data = readl(PWM_CLOCK_REGISTER);
-+	u32 data_ptr = PWM_CLOCK_REGISTER;
-+	u8 no_pwms = (clock_data >> 16);
-+	u8 i;
-+	/* report hardware status here */
-+	out += sprintf(buf, "PWM drive registers\n");
-+	out +=
-+		sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data,
-+				data_ptr);
-+
-+	for (i = 0; i < no_pwms; ++i) {
-+		data_ptr = (u32) ((u32 *) PWM_BASE + i);
-+		out +=
-+			sprintf(out, "%d:%d @ 0x%08x\n", i, (u8) readl(data_ptr),
-+					data_ptr);
-+	}
-+
-+	return out - buf;
-+}
-+
-+/* create a register 'file' to enbale reading back the pwm drive register status */
-+static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
-+
-+static void create_debug_files(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	device_create_file(dev, &dev_attr_registers);
-+}
-+
-+static void remove_debug_files(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	device_remove_file(dev, &dev_attr_registers);
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_PM
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_suspend                                              */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Suspend all LED class devices created by this driver                  */
-+/***************************************************************************/
-+static int
-+oxnas_wd810_leds_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+	int n = leds_created;
-+	while (n > 0) {
-+		if (--n < ARRAY_SIZE(oxnas_led_classes)) {
-+			led_classdev_suspend(oxnas_led_classes[n]);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_resume                                               */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Wake up all LED class devices created by this driver                  */
-+/***************************************************************************/
-+static int
-+oxnas_wd810_leds_resume(struct platform_device *pdev, pm_message_t state)
-+{
-+	int n = leds_created;
-+	while (n > 0) {
-+		if (--n < ARRAY_SIZE(oxnas_led_classes)) {
-+			led_classdev_resume(oxnas_led_classes[n]);
-+		}
-+	}
-+
-+	return 0;
-+}
-+#endif							/* CONFIG_PM */
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_probe                                                */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform any necessary probing and initial setup for oxnas-wd810-leds device   */
-+/***************************************************************************/
-+static int oxnas_wd810_leds_probe(struct platform_device *pdev)
-+{
-+	int rc;
-+	int timer_changed = 0;
-+	int interrupt_allocated = 0;
-+	leds_created = 0;
-+
-+	/* Turn off all the LEDs */
-+	if (negative_led_logic) {
-+		writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+		writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+	} else {
-+		writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+		writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+	}
-+	/* put PWM module back into  reset and disable clock */
-+	writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+	// writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+	do {
-+		/* Enable LED output drivers and disable other uses */
-+		CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
-+		CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
-+		CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
-+
-+		CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
-+		CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
-+		CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
-+		/* Turn off all the LEDs */
-+		if (negative_led_logic) {
-+			writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+			writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+		} else {
-+			writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+			writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+		}
-+
-+		/* bring PWM module out of reset and enable clock */
-+		writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+		//writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
-+
-+		/* enable PWM clock */
-+		writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
-+
-+		/* Initialize frame buffer to everything off */
-+//printk(KERN_INFO "oxnas_wd810_leds_probe:  LED_MASK_GAUGE=%x\n",LED_MASK_GAUGE);
-+		set_led(LED_MASK_GAUGE, 0, 0, 0);
-+		/* Enable output to the LEDs */
-+		writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+		writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+
-+		/* Initialize the LED behavior state machine */
-+		oxnas_wd810_leds_behavior_init();
-+		/* Save Timer2 state for restoring later */
-+		timer_load = readl(TIMER2_LOAD);
-+		timer_control = readl(TIMER2_CONTROL);
-+		writel(0, TIMER2_CONTROL);
-+		timer_changed = 1;
-+		/* Setup Timer2 for LED control */
-+		rc = request_irq(TIMER_2_INTERRUPT, oxnas_wd810_leds_interrupt, 0,
-+						 "led_pwm", 0);
-+
-+		//       rc = request_irq(TIMER_2_INTERRUPT, wdc_leds_interrupt, 0, "led_pwm", 0);
-+		if (rc < 0) {
-+			printk(KERN_ERR "failed to get IRQ\n");
-+			break;
-+		}
-+
-+		interrupt_allocated = 1;
-+		writel(FAST_TIMER_INT, TIMER2_LOAD);
-+		writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
-+
-+		/* Register each LED class device */
-+		while (leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+			rc = led_classdev_register(&pdev->dev,
-+									   oxnas_led_classes[leds_created]);
-+			if (rc < 0) {
-+				printk(KERN_ERR "failed to register led class \"%s\"\n",
-+					   oxnas_led_classes[leds_created]->name);
-+				break;
-+			}
-+
-+			++leds_created;
-+		}
-+	}
-+	while (0);
-+	/* If we failed then perform any needed clean up */
-+	if (rc < 0) {
-+		/* Unregister any classes we registered */
-+		while (leds_created > 0) {
-+			if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+				led_classdev_unregister(oxnas_led_classes[leds_created]);
-+			}
-+		}
-+
-+		/* Free the interrupt if we allocated one */
-+		if (interrupt_allocated) {
-+			free_irq(TIMER_2_INTERRUPT, 0);
-+		}
-+
-+		/* Restore Timer2 if we changed it */
-+		if (timer_changed) {
-+			writel(timer_load, TIMER2_LOAD);
-+			writel(timer_control, TIMER2_CONTROL);
-+		}
-+	}
-+#ifdef DEBUG
-+	create_debug_files(pdev);
-+#endif
-+	return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_remove                                               */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform steps to remove the oxnas-wd810-leds device                           */
-+/***************************************************************************/
-+static int oxnas_wd810_leds_remove(struct platform_device *pdev)
-+{
-+	while (leds_created > 0) {
-+		if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+			led_classdev_unregister(oxnas_led_classes[leds_created]);
-+		}
-+	}
-+
-+	writel(0, TIMER2_CONTROL);
-+	free_irq(TIMER_2_INTERRUPT, 0);
-+	writel(timer_load, TIMER2_LOAD);
-+	writel(timer_control, TIMER2_CONTROL);
-+	/* Turn off all the LEDs */
-+	if (negative_led_logic) {
-+		writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+		writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+	} else {
-+		writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+		writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+	}
-+	/* put PWM module back into  reset and disable clock */
-+	writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+	// writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+#ifdef DEBUG
-+	remove_debug_files(pdev);
-+#endif
-+	return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_driver                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the oxnas-wd810-leds platform device driver                          */
-+/***************************************************************************/
-+static struct platform_driver oxnas_wd810_leds_driver = {
-+	.probe = oxnas_wd810_leds_probe,
-+	.remove = oxnas_wd810_leds_remove,
-+#ifdef CONFIG_PM
-+	.suspend = oxnas_wd810_leds_suspend,.resume = oxnas_wd810_leds_resume,
-+#endif							/* CONFIG_PM */
-+	.driver = {.name = "oxnas-wd810-leds",},
-+};
-+
-+/* Pointer to device returned by platform_device_register_simple */
-+static struct platform_device *oxnas_wd810_leds;
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_init                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module initialization                                         */
-+/***************************************************************************/
-+static int __init oxnas_wd810_leds_init(void)
-+{
-+	int ret;
-+	printk(KERN_INFO "oxnas-wd810-leds:  SLOW_TPS=%d\n", SLOW_TPS);
-+	ret = platform_driver_register(&oxnas_wd810_leds_driver);
-+	if (!ret) {
-+		oxnas_wd810_leds =
-+			platform_device_register_simple("oxnas-wd810-leds", -1, NULL,
-+											0);
-+	}
-+
-+	return ret;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_exit                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module unloading and cleanup                                  */
-+/***************************************************************************/
-+static void __exit oxnas_wd810_leds_exit(void)
-+{
-+	if (oxnas_wd810_leds) {
-+		platform_device_unregister(oxnas_wd810_leds);
-+	}
-+	platform_driver_unregister(&oxnas_wd810_leds_driver);
-+}
-+
-+
-+module_init(oxnas_wd810_leds_init);
-+module_exit(oxnas_wd810_leds_exit);
-+MODULE_DESCRIPTION("oxnas wd810 1NC/2NC LEDs");
-+MODULE_AUTHOR("Oxford Semiconductor Ltd");
-+MODULE_LICENSE("GPL");
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1104 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/oxnas.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/delay.h>
-+#include <linux/platform_device.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/completion.h>
-+#include <linux/serial.h>
-+#include <linux/serial_core.h>
-+#include <linux/serial_8250.h>
-+
-+#include <asm/sizes.h>
-+#include <asm/setup.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+#include <linux/dma-mapping.h>
-+#include <asm/io.h>
-+#include <asm/arch/ahb_mon.h>
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#include <asm/io.h>
-+
-+#ifdef CONFIG_LEON_START_EARLY
-+#include <asm/arch/leon.h>
-+#include <asm/arch/leon-early-prog.h>
-+#endif // CONFIG_LEON_START_EARLY
-+
-+#ifdef CONFIG_OXNAS_PCI_RESET_GPIO
-+#if (CONFIG_OXNAS_PCI_RESET_GPIO < 32)
-+#define PCI_RESET_NUM               CONFIG_OXNAS_PCI_RESET_GPIO
-+#define PCI_RESET_PRISEL_REG        SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define PCI_RESET_SECSEL_REG        SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define PCI_RESET_TERSEL_REG        SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define PCI_RESET_SET_OE_REG        GPIO_A_OUTPUT_ENABLE_SET
-+#define PCI_RESET_OUTPUT_SET_REG    GPIO_A_OUTPUT_SET
-+#define PCI_RESET_OUTPUT_CLR_REG    GPIO_A_OUTPUT_CLEAR
-+#else
-+#define PCI_RESET_NUM               ((CONFIG_OXNAS_PCI_RESET_GPIO) - 32)
-+#define PCI_RESET_PRISEL_REG        SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define PCI_RESET_SECSEL_REG        SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define PCI_RESET_TERSEL_REG        SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define PCI_RESET_SET_OE_REG        GPIO_B_OUTPUT_ENABLE_SET
-+#define PCI_RESET_OUTPUT_SET_REG    GPIO_B_OUTPUT_SET
-+#define PCI_RESET_OUTPUT_CLR_REG    GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define PCI_RESET_MASK (1UL << (PCI_RESET_NUM))
-+#endif // CONFIG_OXNAS_PCI_RESET_GPIO
-+
-+#define PCI_CLOCK_NUM               10
-+#define PCI_CLOCK_PRISEL_REG        SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define PCI_CLOCK_SET_OE_REG        GPIO_A_OUTPUT_ENABLE_SET
-+#define PCI_CLOCK_MASK              (1UL << (PCI_CLOCK_NUM))
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_1
-+#if (CONFIG_OXNAS_SATA_POWER_GPIO_1 < 32)
-+#define SATA_POWER_1_NUM            CONFIG_OXNAS_SATA_POWER_GPIO_1
-+#define SATA_POWER_1_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SATA_POWER_1_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SATA_POWER_1_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SATA_POWER_1_SET_OE_REG     GPIO_A_OUTPUT_ENABLE_SET
-+#define SATA_POWER_1_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define SATA_POWER_1_NUM            ((CONFIG_OXNAS_SATA_POWER_GPIO_1) - 32)
-+#define SATA_POWER_1_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SATA_POWER_1_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SATA_POWER_1_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SATA_POWER_1_SET_OE_REG     GPIO_B_OUTPUT_ENABLE_SET
-+#define SATA_POWER_1_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define SATA_POWER_1_MASK   (1UL << (SATA_POWER_1_NUM))
-+#endif // CONFIG_OXNAS_SATA_POWER_GPIO_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_2
-+#if (CONFIG_OXNAS_SATA_POWER_GPIO_2 < 32)
-+#define SATA_POWER_2_NUM            CONFIG_OXNAS_SATA_POWER_GPIO_2
-+#define SATA_POWER_2_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SATA_POWER_2_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SATA_POWER_2_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SATA_POWER_2_SET_OE_REG     GPIO_A_OUTPUT_ENABLE_SET
-+#define SATA_POWER_2_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define SATA_POWER_2_NUM            ((CONFIG_OXNAS_SATA_POWER_GPIO_2) - 32)
-+#define SATA_POWER_2_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SATA_POWER_2_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SATA_POWER_2_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SATA_POWER_2_SET_OE_REG     GPIO_B_OUTPUT_ENABLE_SET
-+#define SATA_POWER_2_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define SATA_POWER_2_MASK   (1UL << (SATA_POWER_2_NUM))
-+#endif // CONFIG_OXNAS_SATA_POWER_GPIO_2
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+#if (CONFIG_OXNAS_USB_HUB_RESET_GPIO < 32)
-+#define USB_HUB_RESET_NUM            CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+#define USB_HUB_RESET_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define USB_HUB_RESET_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define USB_HUB_RESET_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define USB_HUB_RESET_SET_OE_REG     GPIO_A_OUTPUT_ENABLE_SET
-+#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define USB_HUB_RESET_NUM            ((CONFIG_OXNAS_USB_HUB_RESET_GPIO) - 32)
-+#define USB_HUB_RESET_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define USB_HUB_RESET_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define USB_HUB_RESET_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define USB_HUB_RESET_SET_OE_REG     GPIO_B_OUTPUT_ENABLE_SET
-+#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define USB_HUB_RESET_MASK	(1UL << (USB_HUB_RESET_NUM))
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+
-+extern void oxnas_init_irq(void);
-+extern struct sys_timer oxnas_timer;
-+
-+// The spinlock exported to allow atomic use of GPIO register set
-+spinlock_t oxnas_gpio_spinlock;
-+
-+// To hold LED inversion state
-+int oxnas_global_invert_leds = 0;
-+#include <linux/module.h>
-+EXPORT_SYMBOL(oxnas_global_invert_leds);
-+
-+static struct map_desc oxnas_io_desc[] __initdata = {
-+    { CORE_MODULE_BASE,     __phys_to_pfn(CORE_MODULE_BASE_PA),     SZ_4K,   MT_DEVICE },
-+    { APB_BRIDGE_A_BASE,    __phys_to_pfn(APB_BRIDGE_A_BASE_PA),    SZ_16M,  MT_DEVICE },
-+    { STATIC_CONTROL_BASE,  __phys_to_pfn(STATIC_CONTROL_BASE_PA),  SZ_4K,   MT_DEVICE },
-+    { STATIC_CS0_BASE,      __phys_to_pfn(STATIC_CS0_BASE_PA),      SZ_4K,   MT_DEVICE },
-+    { STATIC_CS1_BASE,      __phys_to_pfn(STATIC_CS1_BASE_PA),      SZ_4K,   MT_DEVICE },
-+    { STATIC_CS2_BASE,      __phys_to_pfn(STATIC_CS2_BASE_PA),      SZ_4K,   MT_DEVICE },
-+    { APB_BRIDGE_B_BASE,    __phys_to_pfn(APB_BRIDGE_B_BASE_PA),    SZ_16M,  MT_DEVICE },
-+    { USB_BASE,             __phys_to_pfn(USB_BASE_PA),             SZ_4M,   MT_DEVICE },
-+    { MAC_BASE,             __phys_to_pfn(MAC_BASE_PA),             SZ_4M,   MT_DEVICE },
-+    { ROM_BASE,             __phys_to_pfn(ROM_BASE_PA),             SZ_16K,  MT_DEVICE },
-+    { PCI_CSRS_BASE,        __phys_to_pfn(PCI_CSRS_BASE_PA),        SZ_4K,   MT_DEVICE }
-+#ifdef CONFIG_SUPPORT_LEON
-+#if (CONFIG_LEON_PAGES == 1)
-+   ,{ LEON_IMAGE_BASE,			__phys_to_pfn(LEON_IMAGE_BASE_PA),			SZ_4K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 2)
-+   ,{ LEON_IMAGE_BASE,			__phys_to_pfn(LEON_IMAGE_BASE_PA),			SZ_8K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 3)
-+   ,{ LEON_IMAGE_BASE,		    __phys_to_pfn(LEON_IMAGE_BASE_PA),			SZ_8K, MT_DEVICE }
-+   ,{ LEON_IMAGE_BASE+0x2000,	__phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000),	SZ_4K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 4)
-+   ,{ LEON_IMAGE_BASE,		    __phys_to_pfn(LEON_IMAGE_BASE_PA),	  		SZ_8K, MT_DEVICE }
-+   ,{ LEON_IMAGE_BASE+0x2000,	__phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000),	SZ_8K, MT_DEVICE }
-+#else
-+#error "Unsupported number of Leon code pages"
-+#endif // CONFIG_LEON_PAGES
-+#endif // CONFIG_SUPPORT_LEON
-+	/*
-+	 * Upto 8 pages for GMAC/DMA descriptors plus ARM/Leon TSO workspace if
-+	 * Leon TSO is in use
-+	 */
-+   ,{ SRAM_BASE,            __phys_to_pfn(SRAM_PA),                 SZ_16K, MT_DEVICE }
-+   ,{ SRAM_BASE+0x4000,     __phys_to_pfn(SRAM_PA+0x4000),          SZ_16K, MT_DEVICE }
-+};
-+
-+static struct resource usb_resources[] = {
-+	[0] = {
-+		.start		= USB_BASE_PA,
-+		.end		= USB_BASE_PA + 0x10000 - 1,
-+		.flags		= IORESOURCE_MEM,
-+	},
-+	[1] = {
-+		.start		= USB_FS_INTERRUPT,
-+		.end		= USB_FS_INTERRUPT,
-+		.flags		= IORESOURCE_IRQ,
-+	},
-+};
-+
-+static u64 usb_dmamask = ~(u32)0;
-+
-+static struct platform_device usb_device = {
-+	.name		= "oxnas-ehci",
-+	.id		= 0,
-+	.dev = {
-+		.dma_mask		= &usb_dmamask,
-+		.coherent_dma_mask	= 0xffffffff,
-+	},
-+	.num_resources	= ARRAY_SIZE(usb_resources),
-+	.resource	= usb_resources,
-+};
-+
-+static struct platform_device *platform_devices[] __initdata = {
-+	&usb_device,
-+};
-+
-+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-+
-+#define INT_UART_BASE_BAUD (NOMINAL_SYSCLK)
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+static struct uart_port internal_serial_port_1 = {
-+	.membase	= (char *)(UART_1_BASE),
-+	.mapbase	= UART_1_BASE_PA,
-+	.irq		= UART_1_INTERRUPT,
-+	.flags		= STD_COM_FLAGS,
-+	.iotype		= UPIO_MEM,
-+	.regshift	= 0,
-+	.uartclk	= INT_UART_BASE_BAUD,
-+	.line		= 0,
-+	.type		= PORT_16550A,
-+	.fifosize	= 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART1
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2
-+static struct uart_port internal_serial_port_2 = {
-+	.membase	= (char *)(UART_2_BASE),
-+	.mapbase	= UART_2_BASE_PA,
-+	.irq		= UART_2_INTERRUPT,
-+	.flags		= STD_COM_FLAGS,
-+	.iotype		= UPIO_MEM,
-+	.regshift	= 0,
-+	.uartclk	= INT_UART_BASE_BAUD,
-+	.line		= 0,
-+	.type		= PORT_16550A,
-+	.fifosize	= 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART2
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3
-+static struct uart_port internal_serial_port_3 = {
-+	.membase	= (char *)(UART_3_BASE),
-+	.mapbase	= UART_3_BASE_PA,
-+	.irq		= UART_3_INTERRUPT,
-+	.flags		= STD_COM_FLAGS,
-+	.iotype		= UPIO_MEM,
-+	.regshift	= 0,
-+	.uartclk	= INT_UART_BASE_BAUD,
-+	.line		= 0,
-+	.type		= PORT_16550A,
-+	.fifosize	= 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART4
-+static struct uart_port internal_serial_port_4 = {
-+	.membase	= (char *)(UART_4_BASE),
-+	.mapbase	= UART_4_BASE_PA,
-+	.irq		= UART_4_INTERRUPT,
-+	.flags		= STD_COM_FLAGS,
-+	.iotype		= UPIO_MEM,
-+	.regshift	= 0,
-+	.uartclk	= INT_UART_BASE_BAUD,
-+	.line		= 0,
-+	.type		= PORT_16550A,
-+	.fifosize	= 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART4
-+
-+static void __init oxnas_mapio(void)
-+{
-+    unsigned int uart_line=0;
-+
-+//printk("oxnas_mapio()\n");
-+
-+    // Setup kernel mappings for hardware cores
-+    iotable_init(oxnas_io_desc, ARRAY_SIZE(oxnas_io_desc));
-+
-+#ifdef CONFIG_ARCH_OXNAS_FPGA    
-+    // Setup the ARM926-EJ-S integrator module clock and bus clock divider
-+    asm volatile(
-+        "mov r3,%2,LSL #4;"     /* Bus clock divider = ((n+1) << 4) */
-+        "sub r3,r3,#16;"
-+        "mov r0,%1;"            /* Processor clock frequency */
-+        "sub r0,r0,#8;"         /* correction for MHz */
-+        "and r0,r0,#0xFF;"      /* ensure byte value */
-+        "mov r2,%0;"            /* read CM base value */
-+        "ldr r1,[r2,#8];"       /* read CM_OSC */
-+        "bic r1,r1,#0x0FF;"     /* clear bottom byte r1 */
-+        "orr r1,r1,r0;"         /* write in new clock values */
-+        "ldr r4,[r2,#0x24];"    /* read CM_INIT */
-+        "bic r4,r4,#0x070;"     /* clear bits [6:4] */
-+        "orr r4,r4,r3;"         /* write in new clock values */
-+        "mov r0,#0xA000;"
-+        "orr r0,r0,#0x5F;"      /* build 0xA05F in r0 */
-+        "str r0,[r2,#0x14];"    /* write to unlock CM_LOCK */
-+        "str r1,[r2,#8];"       /* write value back */
-+        "str r4,[r2,#0x24];"    /* write HCLK value back */
-+        "str r1,[r2,#0x14];"    /* write in any value to relock CM_LOCK */
-+        :
-+        : "r" (CORE_MODULE_BASE), "r" (CONFIG_OXNAS_CORE_CLK), "r" (CONFIG_OXNAS_CORE_BUS_CLK_DIV)
-+        : "r0","r1","r2","r3","r4");
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    // Configure the DDR controller arbitration scheme
-+    *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
-+                                   (1UL << DDR_ARB_DATDIR_EN_BIT)  |
-+                                   (1UL << DDR_ARB_REQAGE_EN_BIT)  |
-+                                   (1UL << DDR_ARB_LRUBANK_EN_BIT) |
-+                                   (1UL << DDR_ARB_MIDBUF_BIT));
-+
-+    // Setup the DDR client read buffers
-+    // NB 0X800 ASIC bug means DMA read buffers should never be enabled
-+    *(volatile u32*)DDR_AHB_REG = ((1UL << DDR_AHB_NO_RCACHE_ARMD_BIT)  |
-+                                   /*(1UL << DDR_AHB_NO_RCACHE_ARMI_BIT)  |*/
-+                                   (1UL << DDR_AHB_NO_RCACHE_COPRO_BIT) |
-+                                   (1UL << DDR_AHB_NO_RCACHE_DMAA_BIT)  |
-+                                   (1UL << DDR_AHB_NO_RCACHE_DMAB_BIT)  |
-+                                   /* (1UL << DDR_AHB_NO_RCACHE_PCI_BIT)   |
-+                                   (1UL << DDR_AHB_NO_RCACHE_GMAC_BIT)  |*/
-+                                   (1UL << DDR_AHB_NO_RCACHE_USB_BIT));
-+
-+    // Ignore HPROT for all clients except ARM data, as ARM Linux interrupt
-+	// latency will mask any slight delay in data written by cores getting to
-+	// memory after the core raises an interrupt
-+	*(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT)  |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT)  |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT)  |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT)   |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT)  |
-+									 (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
-+#elif CONFIG_OXNAS_VERSION_0X810
-+    // Configure the DDR controller arbitration scheme
-+    *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
-+                                   (1UL << DDR_ARB_DATDIR_EN_BIT)  |
-+                                   (1UL << DDR_ARB_REQAGE_EN_BIT)  |
-+                                   (1UL << DDR_ARB_LRUBANK_EN_BIT) |
-+                                   (1UL << DDR_ARB_MIDBUF_BIT));
-+
-+	// Configure read buffers - Do not disable any read buffers
-+	*(volatile u32*)DDR_AHB_REG = 0UL;
-+
-+	// Configure wrapping - Ignore wrap
-+	// Configure HPROT - Ignore all HPROT except ARM data
-+	*(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_WRAP_ARMD_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_ARMI_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_COPRO_BIT)  |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_DMAA_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_DMAB_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_PCI_BIT)    |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_GMAC_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_WRAP_US_BIT)     |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT)  |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT)  |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT)  |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT)   |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT)  |
-+                                    (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
-+
-+	// Configure burst ordering - Do not disable burst ordering
-+	// Configure non-cachable - Do not prevent non-cachable accesses from using read buffers
-+	*(volatile u32*)DDR_AHB3_REG = 0UL;
-+
-+	// Configure read buffer timeout - Do not enable read buffer invalidate after timeout
-+	// Configure write behind - Enable write behind coherency
-+	*(volatile u32*)DDR_AHB4_REG = ((1UL << DDR_AHB4_EN_WRBEHIND_ARMD_BIT)  |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_ARMI_BIT)  |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_COPRO_BIT) |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_DMAA_BIT)  |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_DMAB_BIT)  |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_PCI_BIT)   |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_GMAC_BIT)  |
-+									 (1UL << DDR_AHB4_EN_WRBEHIND_USB_BIT));
-+
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+
-+    // Enable all DDR client interfaces
-+    *(volatile u32*)DDR_BLKEN_REG |= (((1UL << DDR_BLKEN_CLIENTS_NUM_BITS) - 1) << DDR_BLKEN_CLIENTS_BIT);
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+    // Block reset UART1
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+
-+    // Route UART1 SOUT onto external pin
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x80000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x80000000;
-+
-+    // Route UART1 SIN onto external pin
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1  &= ~0x00000001;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |=  0x00000001;
-+
-+    // Setup GPIO line direction for UART1 SOUT
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x80000000;
-+
-+    // Setup GPIO line direction for UART1 SIN
-+    *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000001;
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1_MODEM
-+    // Route UART1 modem control lines onto external pins
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x78000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x78000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x78000000;
-+
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000006;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1  &= ~0x00000006;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |=  0x00000006;
-+
-+    // Setup GPIO line directions for UART1 modem control lines
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x08000000;
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x70000000;
-+
-+    *(volatile u32*)GPIO_B_OUTPUT_ENABLE_SET   |= 0x00000004;
-+    *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000002;
-+#endif // CONFIG_ARCH_OXNAS_UART1_MODEM
-+
-+    // Give Linux a contiguous numbering scheme for available UARTs
-+    internal_serial_port_1.line = uart_line++;
-+    early_serial_setup(&internal_serial_port_1);
-+#endif // CONFIG_ARCH_OXNAS_UART1
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2
-+    // Block reset UART2
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+
-+    // Route UART2 SIN/SOUT onto external pin
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x00500000;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x00500000;
-+
-+    // Setup GPIO line directions for UART2 SIN/SOUT
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x00100000;
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00400000;
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2_MODEM
-+    // Route UART2 modem control lines onto external pins
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x07800300;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x07800300;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x07800300;
-+
-+    // Setup GPIO line directions for UART2 modem control lines
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x02000200;
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x05800100;
-+#endif // CONFIG_ARCH_OXNAS_UART2_MODEM
-+
-+    // Give Linux a contiguous numbering scheme for available UARTs
-+    internal_serial_port_2.line = uart_line++;
-+    early_serial_setup(&internal_serial_port_2);
-+#endif // CONFIG_ARCH_OXNAS_UART2
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3
-+    // Block reset UART3
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+
-+    // Route UART3 SIN/SOUT onto external pin
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x000000C0;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x000000C0;
-+
-+    // Setup GPIO line directions for UART3 SIN/SOUT
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x00000080;
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00000040;
-+
-+    // Enable UART3 interrupt
-+    *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART3_IQ_EN);
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3_MODEM
-+    // Route UART3 modem control lines onto external pins
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x0000003f;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x0000003f;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x0000003f;
-+
-+    // Setup GPIO line directions for UART3 modem control lines
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET   |= 0x00000030;
-+    *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x0000000f;
-+#endif // CONFIG_ARCH_OXNAS_UART3_MODEM
-+
-+    // Give Linux a contiguous numbering scheme for available UARTs
-+    internal_serial_port_3.line = uart_line++;
-+    early_serial_setup(&internal_serial_port_3);
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART4
-+    // Block reset UART4
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+
-+    // Enable UART4 interrupt
-+    *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_IQ_EN);
-+
-+    // Enable UART4 to override PCI functions onto GPIOs
-+    *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
-+
-+    internal_serial_port_4.line = uart_line++;
-+    early_serial_setup(&internal_serial_port_4);
-+#endif // CONFIG_ARCH_OXNAS_UART4
-+
-+#ifdef CONFIG_PCI
-+    // Block reset PCI core
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+
-+    // Setup the PCI clock divider
-+    {
-+    static const u32 PCIDIV_MASK = (((1UL << SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS) - 1) << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
-+    *(volatile u32*)SYS_CTRL_CKCTRL_CTRL &= ~PCIDIV_MASK;
-+    *(volatile u32*)SYS_CTRL_CKCTRL_CTRL |= (PCI_CLOCK_DIVIDER << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
-+    }
-+
-+    // Enable clock to PCI core
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+
-+    // Enable auto-arbitration between static and PCI
-+    *(u32*)SYS_CTRL_PCI_CTRL1 &= ~(1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ);
-+
-+    // Enable primary function on PCI clock line to be looped back
-+    writel(readl(PCI_CLOCK_PRISEL_REG) | PCI_CLOCK_MASK, PCI_CLOCK_PRISEL_REG);
-+
-+    // Enable GPIO output on PCI clock line to be looped back
-+    writel(PCI_CLOCK_MASK, PCI_CLOCK_SET_OE_REG);
-+
-+#ifdef CONFIG_OXNAS_PCI_RESET
-+    // Disable primary, secondary and teriary GPIO functions on PCI reset line
-+    writel(readl(PCI_RESET_PRISEL_REG) & ~PCI_RESET_MASK, PCI_RESET_PRISEL_REG);
-+    writel(readl(PCI_RESET_SECSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_SECSEL_REG);
-+    writel(readl(PCI_RESET_TERSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_TERSEL_REG);
-+
-+    // Assert PCI reset from GPIO line
-+    writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_CLR_REG);
-+
-+    // Enable GPIO output on PCI reset line
-+    writel(PCI_RESET_MASK, PCI_RESET_SET_OE_REG);
-+
-+    // Wait awhile for PCI reset to take effect
-+    mdelay(100);
-+
-+    // Deassert PCI reset from GPIO line
-+    writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_PCI_RESET
-+#endif // CONFIG_PCI
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_1
-+    // Disable primary, secondary and teriary GPIO functions on SATA 1 power line
-+    writel(readl(SATA_POWER_1_PRISEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_PRISEL_REG);
-+    writel(readl(SATA_POWER_1_SECSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_SECSEL_REG);
-+    writel(readl(SATA_POWER_1_TERSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_TERSEL_REG);
-+
-+    // Enable power to SATA 1
-+    writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_SET_REG);
-+
-+    // Enable GPIO output on SATA 1 power line
-+    writel(SATA_POWER_1_MASK, SATA_POWER_1_SET_OE_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_2
-+    // Disable primary, secondary and teriary GPIO functions on SATA 2 power line
-+    writel(readl(SATA_POWER_2_PRISEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_PRISEL_REG);
-+    writel(readl(SATA_POWER_2_SECSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_SECSEL_REG);
-+    writel(readl(SATA_POWER_2_TERSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_TERSEL_REG);
-+
-+    // Enable power to SATA 2
-+    writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_SET_REG);
-+
-+    // Enable GPIO output on SATA 2 power line
-+    writel(SATA_POWER_2_MASK, SATA_POWER_2_SET_OE_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_2
-+
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
-+    // Use GPIO 6 (normally PCI Req 6) for copies instrumentation
-+    #define INSTRUMENT_COPIES_GPIO_MASK ((1UL << 6) | (1UL << 7))
-+
-+    // Enable normal GPIO on line
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+    // Set line inactive to begin with
-+    writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_CLEAR);
-+
-+    // Enable line as an output
-+    writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
-+
-+#ifdef CONFIG_OXNAS_USB_CKOUT
-+    // Enable secondary function (USB clock out) on GPIO 10
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~(1UL << 10), SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  |  (1UL << 10), SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+#endif // CONFIG_OXNAS_USB_CKOUT
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_CONTROL
-+    // Disable primary, secondary and teriary GPIO functions on USB hub reset control line
-+    writel(readl(USB_HUB_RESET_PRISEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_PRISEL_REG);
-+    writel(readl(USB_HUB_RESET_SECSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_SECSEL_REG);
-+    writel(readl(USB_HUB_RESET_TERSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_TERSEL_REG);
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+	// Assert USB hub reset
-+	writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_SET_REG : USB_HUB_RESET_OUTPUT_CLR_REG);
-+#else
-+	// Deassert USB hub reset
-+	writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+
-+    // Enable GPIO output on USB hub reset line
-+    writel(USB_HUB_RESET_MASK, USB_HUB_RESET_SET_OE_REG);
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+	if (CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS > 0) {
-+		// Wait for USB hub reset toggle assertion time
-+		mdelay(CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS);
-+	}
-+
-+	// Deassert USB hub reset
-+	writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_CONTROL
-+}
-+
-+static void __init oxnas_fixup(
-+    struct machine_desc *desc,
-+    struct tag *tags,
-+    char **cmdline,
-+    struct meminfo *mi)
-+{
-+
-+    mi->nr_banks = 0;
-+    mi->bank[mi->nr_banks].start = SDRAM_PA;
-+    mi->bank[mi->nr_banks].size  = SDRAM_SIZE;
-+    mi->bank[mi->nr_banks].node = mi->nr_banks;
-+    ++mi->nr_banks;
-+#ifdef CONFIG_DISCONTIGMEM
-+    mi->bank[mi->nr_banks].start = SRAM_PA;
-+    mi->bank[mi->nr_banks].size  = SRAM_SIZE;
-+#ifdef LEON_IMAGE_IN_SRAM
-+    mi->bank[mi->nr_banks].size -= LEON_IMAGE_SIZE;
-+#endif
-+    mi->bank[mi->nr_banks].node = mi->nr_banks;
-+    ++mi->nr_banks;
-+#endif
-+
-+//printk(KERN_NOTICE "%d memory %s\n", mi->nr_banks, (mi->nr_banks > 1) ? "regions" : "region");
-+}
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+static void __init oxnas_asm_copy(void* dst, void* src, u32 length)
-+{
-+    // Assume the length is consistent with transfering 8 quads per load/store
-+    asm volatile(
-+        "1:ldmia %0!, {r3, r4, r5, r6, r7, r8, r9, r12};"
-+        "subs %2, %2, #32;"
-+        "stmia %1!, {r3, r4, r5, r6, r7, r8, r9, r12};"
-+        "bne 1b;"
-+        :
-+        : "r" (src), "r" (dst), "r" (length)
-+        : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12");
-+}
-+
-+static void __init oxnas_mem_test(void)
-+{
-+    static const unsigned BUFFER_SIZE_CHARS = 16*1024;
-+    static const unsigned BUFFER_ELEMENTS = (BUFFER_SIZE_CHARS / sizeof(unsigned long));
-+
-+    dma_addr_t dma_address;
-+    unsigned long* buffer;
-+
-+    buffer = dma_alloc_coherent(0, BUFFER_SIZE_CHARS, &dma_address, GFP_KERNEL | GFP_DMA);
-+    if (!buffer) {
-+        printk(KERN_ERR "$RFailed to allocate ucached/unbuffered memory test buffer\n");
-+    } else {
-+        static const int ITERATIONS = 10;
-+
-+        unsigned long* buf1 = buffer;
-+        unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
-+        int j;
-+        u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+        u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+
-+        BUG_ON(!time1 || !time2);
-+        
-+        printk("Uncached/unbuffered: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u, dma_address = 0x%08x\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2, dma_address);
-+
-+        printk("\nAll accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nNon-burst accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_SINGLE, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nINCR accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nWRAP4 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP4, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nINCR4 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR4, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nWRAP8 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP8, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nINCR8 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR8, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nWRAP16 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP16, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        printk("\nINCR16 accesses:\n");
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR16, 0, 0);
-+        for (j=0; j < ITERATIONS; j++) {
-+            unsigned long* src = buf1;
-+            unsigned long* dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+        for (j=0; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        dma_free_coherent(0, BUFFER_SIZE_CHARS, buffer, dma_address);
-+
-+        kfree(time1);
-+        kfree(time2);
-+    }
-+
-+    buffer = kmalloc(BUFFER_SIZE_CHARS, GFP_KERNEL | GFP_DMA);
-+    if (!buffer) {
-+        printk(KERN_ERR "$RFailed to allocate cached memory test buffer\n");
-+    } else {
-+        static const int ITERATIONS = 100;
-+
-+        unsigned long* buf1 = buffer;
-+        unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
-+        unsigned long* src = buf1;
-+        unsigned long* dst = buf2;
-+        int j;
-+        u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+        u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+
-+        BUG_ON(!time1 || !time2);
-+
-+        printk("Cached/: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2);
-+
-+        init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+
-+        // Measure the first cached iteration separately
-+        printk("1st iteration:\n");
-+        restart_ahb_monitors();
-+        time1[0] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+        oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+        time2[0] = readl(TIMER2_VALUE);
-+        read_ahb_monitors();
-+        printk("%u->%lu Bytes/s\n", time1[0]-time2[0], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[0]-time2[0]));
-+
-+        printk("Subsequent iterations:\n");
-+        restart_ahb_monitors();
-+        for (j=1; j < ITERATIONS; j++) {
-+            src = buf1;
-+            dst = buf2;
-+//            int i;
-+
-+            time1[j] = readl(TIMER2_VALUE);
-+//            memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+            oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+//            for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+//                *dst++ = *src++;
-+//            }
-+            time2[j] = readl(TIMER2_VALUE);
-+        }
-+        read_ahb_monitors();
-+
-+        for (j=1; j < ITERATIONS; j++) {
-+            printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+        }
-+
-+        kfree(time1);
-+        kfree(time2);
-+
-+        kfree(buffer);
-+    }
-+}
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#ifdef CONFIG_OXNAS_LED_TEST
-+
-+#define LED_D1  (1UL << 6)
-+#define LED_D2  (1UL << 7)
-+#define LED_D3  (1UL << 13)
-+#define LED_D4  (1UL << 14)
-+#define LED_D5  (1UL << 19)
-+#define LED_D6  (1UL << 21)
-+#define LED_D7  (1UL << 25)
-+#define LED_D8  (1UL << 26)
-+#define LED_D9  (1UL << 27)
-+#define FIRST_LEDS_MASK (LED_D1 | LED_D2 | LED_D3 | LED_D4 | LED_D5 | LED_D6 | LED_D7 | LED_D8 | LED_D9)
-+
-+#define LED_D10 (1UL << 1)
-+#define SECOND_LEDS_MASK (LED_D10)
-+
-+#define PWM_MASK (1UL << 8)
-+
-+static void test_leds_and_pwm(void)
-+{
-+    // Disable primary, secondary and teriary GPIO functions for first nine LEDS
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+    // Disable primary, secondary and teriary GPIO functions for last LED
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_1)  & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_1);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_1);
-+
-+    // Turn off first nine LEDs
-+    writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_SET);
-+
-+    // Turn off tenth LED
-+    writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_SET);
-+
-+    // Enable first nine LEDs as outputs
-+    writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+    // Enable tenth LED as output
-+    writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_ENABLE_SET);
-+
-+    // Turn on first nine LEDs sequentially
-+    mdelay(1000);
-+    writel(LED_D1, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D2, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D3, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D4, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D5, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D6, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D7, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D8, GPIO_A_OUTPUT_CLEAR);
-+    mdelay(1000);
-+    writel(LED_D9, GPIO_A_OUTPUT_CLEAR);
-+
-+    // Turn on tenth LED
-+    mdelay(1000);
-+    writel(LED_D10, GPIO_B_OUTPUT_CLEAR);
-+
-+    // Disable primary, secondary and teriary GPIO functions for PWN line
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  & ~PWM_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+    // Turn off PWM line
-+    writel(PWM_MASK, GPIO_A_OUTPUT_SET);
-+
-+    // Enable PWM line as output
-+    writel(PWM_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+    // Turn on PWM line
-+    mdelay(1000);
-+    writel(PWM_MASK, GPIO_A_OUTPUT_CLEAR);
-+}
-+#endif // CONFIG_OXNAS_LED_TEST
-+
-+static void __init oxnas_init_machine(void)
-+{
-+//printk("oxnas_init_machine()\n");
-+    /* Initialise the spinlock used to make GPIO register set access atomic */
-+    spin_lock_init(&oxnas_gpio_spinlock);
-+
-+    /*
-+     * Initialise the support for our multi-channel memory-to-memory DMAC
-+     * The interrupt subsystem needs to be available before we can initialise
-+     * the DMAC support
-+     */
-+    oxnas_dma_init();
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+    /*
-+     * Do memory performance test
-+     */
-+    oxnas_mem_test();
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#ifdef CONFIG_LEON_START_EARLY
-+    init_copro(leon_early_srec, 0);
-+#endif // CONFIG_LEON_START_EARLY
-+
-+#ifdef CONFIG_OXNAS_LED_TEST
-+    test_leds_and_pwm();
-+#endif // CONFIG_OXNAS_LED_TEST
-+
-+	// Add any platform bus devices
-+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-+}
-+
-+void sata_power_off(void)
-+{
-+#ifdef CONFIG_OXNAS_SATA_POWER_1
-+    // Disable power to SATA 1
-+    printk(KERN_INFO "Turning off disk 1\n");
-+    writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_CLR_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_2
-+    // Disable power to SATA 2
-+    printk(KERN_INFO "Turning off disk 2\n");
-+    writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_CLR_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_2
-+}
-+
-+MACHINE_START(OXNAS, "Oxsemi NAS")
-+    /* Maintainer: Oxford Semiconductor Ltd */
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+    .phys_io = UART_1_BASE_PA,
-+    .io_pg_offst = (((u32)UART_1_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART2)
-+    .phys_io = UART_2_BASE_PA,
-+    .io_pg_offst = (((u32)UART_2_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART3)
-+    .phys_io = UART_3_BASE_PA,
-+    .io_pg_offst = (((u32)UART_3_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART4)
-+    .phys_io = UART_4_BASE_PA,
-+    .io_pg_offst = (((u32)UART_4_BASE) >> 18) & 0xfffc,
-+#endif
-+    .boot_params = SDRAM_PA + 0x100,
-+    .fixup = oxnas_fixup,
-+    .map_io = oxnas_mapio,
-+    .init_irq = oxnas_init_irq,
-+    .timer = &oxnas_timer,
-+    .init_machine = oxnas_init_machine,
-+MACHINE_END
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/pci.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c
---- linux-2.6.24/arch/arm/mach-oxnas/pci.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,678 @@
-+/*
-+ *  arch/arm/mach-oxnas/pci.c
-+ *
-+ *  Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+#include <linux/kernel.h>
-+
-+#include <linux/pci.h>
-+#include <linux/ptrace.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/mach/pci.h>
-+#include <asm/mach-types.h>
-+
-+#ifndef CONFIG_PCI
-+
-+inline void outb(unsigned char  v, u32 p)	{ *((volatile  u8*)(__io(p))) = (v);   	 	}
-+inline void outw(unsigned short v, u32 p)	{ *((volatile u16*)(__io(p))) = cpu_to_le16(v); }
-+inline void outl(unsigned long  v, u32 p)	{ *((volatile u32*)(__io(p))) = cpu_to_le32(v); }
-+
-+inline unsigned char   inb(u32 p)		{ return            (*((volatile  u8*)(__io(p)))); }
-+inline unsigned short  inw(u32 p)		{ return le16_to_cpu(*((volatile u16*)(__io(p)))); }
-+inline unsigned long   inl(u32 p)		{ return le32_to_cpu(*((volatile u32*)(__io(p)))); }
-+
-+inline void outsb(u32 p, unsigned char  * from, u32 len)	{ while (len--) { outb((*from++),(p) ); } }
-+inline void outsw(u32 p, unsigned short * from, u32 len)	{ while (len--) { outw((*from++),(p) ); } }
-+inline void outsl(u32 p, unsigned long  * from, u32 len)	{ while (len--) { outl((*from++),(p) ); } }
-+                                         
-+inline void insb(u32 p, unsigned char  * to, u32 len)	{ while (len--) { *to++ = inb(p); } }
-+inline void insw(u32 p, unsigned short * to, u32 len)	{ while (len--) { *to++ = inw(p); } }
-+inline void insl(u32 p, unsigned long  * to, u32 len)	{ while (len--) { *to++ = inl(p); } }
-+
-+EXPORT_SYMBOL( inb );
-+EXPORT_SYMBOL( inw );
-+EXPORT_SYMBOL( inl );
-+
-+EXPORT_SYMBOL( outb );
-+EXPORT_SYMBOL( outw );
-+EXPORT_SYMBOL( outl );
-+
-+EXPORT_SYMBOL( insb );
-+EXPORT_SYMBOL( insw );
-+EXPORT_SYMBOL( insl );
-+
-+EXPORT_SYMBOL( outsb );
-+EXPORT_SYMBOL( outsw );
-+EXPORT_SYMBOL( outsl );
-+
-+#else // #ifdef CONFIG_PCI
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+#define PCI_BUS_NONMEM_START			0x00000000
-+#define PCI_BUS_NONMEM_SIZE	    		0x00080000
-+                               
-+                               
-+#define PCI_BUS_PREMEM_START			PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
-+#define PCI_BUS_PREMEM_SIZE	    		0x00080000
-+
-+#define SYNOPSYS_PCI_MEMORY_BASE_ADDRESS        PCI_BASE_ADDRESS_0
-+#define SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS    PCI_BASE_ADDRESS_2
-+#define SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS        PCI_BASE_ADDRESS_1  // PLEASE NOTE - THESE ARE INCORRECT IN THE DOCUMENT!!
-+
-+
-+inline void outb(unsigned char  v, u32 p)	{ pciio_write(v,(u32)__io(p),             sizeof(char ) );  }
-+inline void outw(unsigned short v, u32 p)	{ pciio_write(cpu_to_le16(v),(u32)__io(p),sizeof(short) );  }
-+inline void outl(unsigned long  v, u32 p)	{ pciio_write(cpu_to_le32(v),(u32)__io(p),sizeof(long ) );  }
-+
-+inline unsigned char   inb(u32 p)		{ unsigned int __v =            (pciio_read((u32)__io(p),sizeof(char ))); return __v; }
-+inline unsigned short  inw(u32 p)		{ unsigned int __v = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); return __v; }
-+inline unsigned long   inl(u32 p)		{ unsigned int __v = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); return __v; }
-+
-+inline void outsb(volatile u32 p, unsigned char  * from, u32 len)	{ while (len--) { pciio_write(	         (*from++),(u32)__io(p),sizeof(char ) ); } }
-+inline void outsw(volatile u32 p, unsigned short * from, u32 len)	{ while (len--) { pciio_write(cpu_to_le16(*from++),(u32)__io(p),sizeof(short) ); } }
-+inline void outsl(volatile u32 p, unsigned long  * from, u32 len)	{ while (len--) { pciio_write(cpu_to_le32(*from++),(u32)__io(p),sizeof(long ) ); } }
-+                                         
-+inline void insb(volatile u32 p, unsigned char  * to, u32 len)	{ while (len--) { *to++ =            (pciio_read((u32)__io(p),sizeof(char ))); } }
-+inline void insw(volatile u32 p, unsigned short * to, u32 len)	{ while (len--) { *to++ = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); } }
-+inline void insl(volatile u32 p, unsigned long  * to, u32 len)	{ while (len--) { *to++ = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); } }
-+
-+EXPORT_SYMBOL( inb );
-+EXPORT_SYMBOL( inw );
-+EXPORT_SYMBOL( inl );
-+
-+EXPORT_SYMBOL( outb );
-+EXPORT_SYMBOL( outw );
-+EXPORT_SYMBOL( outl );
-+
-+EXPORT_SYMBOL( insb );
-+EXPORT_SYMBOL( insw );
-+EXPORT_SYMBOL( insl );
-+
-+EXPORT_SYMBOL( outsb );
-+EXPORT_SYMBOL( outsw );
-+EXPORT_SYMBOL( outsl );
-+
-+EXPORT_SYMBOL( pciio_read );
-+EXPORT_SYMBOL( pciio_write );
-+
-+static spinlock_t oxnas_lock = SPIN_LOCK_UNLOCKED;
-+
-+//static int oxnas_pci_read_core_config( unsigned int config_register )
-+//{
-+//	unsigned long val, flags;
-+//	//printk(KERN_DEBUG "PCI: oxnas_pci_read_core_config( 0x%x )\n", config_register );
-+//	spin_lock_irqsave(&oxnas_lock, flags);
-+//	writel(
-+//		0x00                            << PCI_CRP_BYTE_ENABLES_START | 
-+//		PCI_BUS_CMD_CONFIGURATION_READ  << PCI_CRP_CMD_START          |
-+//		config_register                 << PCI_CRP_ADDRESS_START, 
-+//		PCI_CRP_CMD_AND_ADDR );
-+//    	wmb();
-+//	val = readl( PCI_CRP_READ_DATA );
-+//   	spin_unlock_irqrestore(&oxnas_lock, flags);
-+//	return val; 
-+//}
-+
-+
-+static void oxnas_pci_write_core_config( unsigned int value, unsigned int config_register )
-+{
-+	unsigned long flags;
-+
-+	//printk(KERN_DEBUG "PCI: oxnas_pci_write_core_config( 0x%x, 0x%x )\n", config_register , value);
-+	/* printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", 
-+		0x00                            << PCI_CRP_BYTE_ENABLES_START | 
-+		PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START          |
-+		config_register                 << PCI_CRP_ADDRESS_START,
-+		PCI_CRP_CMD_AND_ADDR ); */
-+    
-+	spin_lock_irqsave(&oxnas_lock, flags);
-+	writel(
-+		0x00                            << PCI_CRP_BYTE_ENABLES_START | 
-+		PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START          |
-+		config_register                 << PCI_CRP_ADDRESS_START,
-+		PCI_CRP_CMD_AND_ADDR );
-+	wmb();
-+
-+	// printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", value, PCI_CRP_WRITE_DATA ); 
-+	writel( value, PCI_CRP_WRITE_DATA ); 
-+	spin_unlock_irqrestore(&oxnas_lock, flags);    
-+}
-+
-+
-+
-+inline unsigned int CheckAndClearBusError(void)
-+{
-+    unsigned int value = readl( PCI_ERROR_MSG ) & 0x00000003;
-+    if ( value )
-+    {
-+//        printk(KERN_DEBUG "PCI: %s ERROR ON PCI BUS Clearing error\n", value & 0x00000001 ? "FATAL" : "PARITY" );
-+        writel( ( value ), PCI_ERROR_MSG );
-+    }
-+    
-+    return value;    
-+}
-+
-+
-+void pciio_write(unsigned int  data, u32 addr, unsigned int size)
-+{
-+	// setup byte enables
-+	unsigned long flags;
-+	unsigned int be     = 0x0000000f >> (4-size);
-+	unsigned int trunc  = (addr & 0x00000003);
-+	be                <<= trunc;
-+	be	            = (~be) & 0x00000000f;
-+	
-+
-+	data  &= (0xffffffff >> ((4-size)*8));
-+	data <<= (trunc*8);
-+
-+	 //printk(KERN_DEBUG "$YPCI: pciio_write( 0x%08x = 0x%08x (%x:%x) )\n", addr, data, size, be);
-+	
-+	/* Setup the io read address (rounded down to word boundry) */
-+	spin_lock_irqsave(&oxnas_lock, flags);
-+	writel( addr , PCI_CONFIG_IO_CYCLE_ADDR );
-+	wmb();
-+	
-+	/* issue the config io read command to the config io cmd reg */
-+	writel( ( be                     << PCI_CONFIG_IO_BYTE_ENABLES_START) | 
-+	        ( PCI_BUS_CMD_IO_WRITE   << PCI_CONFIG_IO_CMD_START ), 
-+	          PCI_CONFIG_IO_BYTE_CMD );
-+	wmb();
-+	
-+	writel( data, PCI_CONFIG_IO_WRITE_DATA );	
-+	
-+	if ( CheckAndClearBusError() )
-+	{
-+	    printk(KERN_DEBUG "PCI: failed to write io\n");
-+	}
-+	spin_unlock_irqrestore(&oxnas_lock, flags);
-+}
-+	
-+
-+unsigned int pciio_read(u32 addr, unsigned int size)
-+{
-+	// setup byte enables
-+	unsigned long flags;
-+	unsigned int be     = 0x0000000f >> (4-size);
-+	unsigned int trunc  = (addr & 0x00000003);
-+	be                <<= trunc;
-+	be	            = (~be) & 0x00000000f;
-+	
-+		
-+	//printk(KERN_DEBUG "$YPCI: pciio_read[ 0x%x ] ( 0x%x == ", size, addr );
-+	
-+	/* Setup the io read address (rounded down to word boundry) */
-+	spin_lock_irqsave(&oxnas_lock, flags);
-+	writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+	wmb();
-+	
-+	/* issue the config io read command to the config io cmd reg */
-+	writel( ( be                     << PCI_CONFIG_IO_BYTE_ENABLES_START) | 
-+	        ( PCI_BUS_CMD_IO_READ    << PCI_CONFIG_IO_CMD_START ), 
-+	          PCI_CONFIG_IO_BYTE_CMD );
-+	wmb();
-+	
-+	if ( CheckAndClearBusError() )
-+	{
-+	    printk(KERN_DEBUG "PCI: failed to read io\n");
-+	}
-+	
-+	be   = readl( PCI_CONFIG_IO_READ_DATA );	
-+	//printk("0x%x )\n", be);
-+	
-+	if ( CheckAndClearBusError() )
-+	{
-+	    printk(KERN_DEBUG "PCI: failed to read io\n");
-+	}
-+	
-+	spin_unlock_irqrestore(&oxnas_lock, flags);
-+	
-+	be >>= (trunc*8);
-+	be  &= (0xffffffff >> ((4-size)*8));
-+	
-+	
-+	return be;	
-+}
-+
-+
-+static int oxnas_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-+			  int size, u32 *value)
-+{
-+	// unsigned long flags;
-+	unsigned long flags;
-+	unsigned int temp;
-+	unsigned long addr = ( 0x00000800      << (PCI_SLOT(devfn)-1) )  | 
-+        			     ( PCI_FUNC(devfn) << 8 )                    |  
-+			     ( where & 0xfc );
-+    
-+	/* Setup the config io read address (rounded down to word boundry) */
-+	temp = addr;
-+
-+        // printk(KERN_DEBUG "PCI: %s::%u oxnas_read_config( %u, %d, %d, )\n", bus->name, bus->number, devfn, where, size );
-+	spin_lock_irqsave(&oxnas_lock, flags);
-+	CheckAndClearBusError();
-+
-+	// printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_CYCLE_ADDR );
-+	writel( temp, PCI_CONFIG_IO_CYCLE_ADDR );
-+	wmb();
-+    
-+	/* issue the config io read command to the config io cmd reg */
-+	temp = ( ( 0x00                           << PCI_CONFIG_IO_BYTE_ENABLES_START) | 
-+		 ( PCI_BUS_CMD_CONFIGURATION_READ << PCI_CONFIG_IO_CMD_START ) ); 
-+	// printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_BYTE_CMD);
-+	writel( temp, PCI_CONFIG_IO_BYTE_CMD );
-+	wmb();
-+
-+	if ( CheckAndClearBusError() )
-+	{
-+		spin_unlock_irqrestore(&oxnas_lock, flags);
-+//		printk(KERN_DEBUG "PCI: failed to read config\n" );
-+		*value = 0xffffffff;
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+	}
-+    
-+	wmb();
-+	*value=readl(PCI_CONFIG_IO_READ_DATA);
-+	spin_unlock_irqrestore(&oxnas_lock, flags);
-+    
-+	/* Read the result from the config io read data reg */
-+	switch (size) {
-+	case 1:
-+		// printk(KERN_DEBUG "PCI: readb( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+		*value>>=(where&3);
-+		*value&=0x000000ff;
-+		break;
-+	case 2:
-+		// printk(KERN_DEBUG "PCI: readw( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+		*value>>=(where&2);
-+		*value&=0x0000ffff;
-+		break;
-+	case 4:
-+		// printk(KERN_DEBUG "PCI: readl( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+		break;
-+	}
-+	// printk(KERN_DEBUG "PCI: $Goxnas_read_config_%s( 0x%lx ) == 0x%lx\n", 
-+	//       size == 1 ? "byte" : size == 2 ? "short" : "word",
-+	//        (unsigned long) addr,
-+	//        (unsigned long) *value);
-+    
-+	return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int oxnas_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-+			   int size, u32 value)
-+{   
-+	unsigned long flags;
-+	unsigned long byteEnables = ~(( 0xffffffff >> (32 - size) ) << (where&3));
-+	unsigned long addr        =   ( 0x00000800      << (PCI_SLOT(devfn)-1) )  | 
-+				      ( PCI_FUNC(devfn) << 8 )                    |  
-+				      ( where & 0xfc );
-+	value                   <<= 8*(where & 0x00000003);
-+    
-+    	// printk(KERN_DEBUG "$GPCI: %s::%u oxnas_write_config_%s( 0x%lx, 0x%lx & 0x%lx)\n",
-+	// 	bus->name,
-+	// 	bus->number,
-+	// 	size == 1 ? "byte" : size == 2 ? "short" : "word",
-+	// 	(unsigned long) addr,
-+	// 	(unsigned long) value, 
-+	// 	(unsigned long) byteEnables );
-+
-+    	if ( PCI_SLOT(devfn) > 15 )
-+    	{
-+	    	/* only 16 devices supported */
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+    	}
-+    
-+        
-+	spin_lock_irqsave(&oxnas_lock, flags);
-+	CheckAndClearBusError();
-+    
-+	/* Setup the config io read address (rounded down to word boundry) */
-+	// printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx)\n", addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+	writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+	wmb();
-+
-+	/* issue the config io read command to the config io cmd reg */
-+	// printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", 
-+	//         ( (byteEnables & 0xf)             << PCI_CONFIG_IO_BYTE_ENABLES_START) | 
-+	//         ( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
-+	//           PCI_CONFIG_IO_BYTE_CMD );
-+              
-+	writel( 	( (byteEnables & 0xf)             << PCI_CONFIG_IO_BYTE_ENABLES_START) | 
-+		( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
-+		  PCI_CONFIG_IO_BYTE_CMD );
-+	wmb();
-+        
-+	/* write the value... */
-+	// printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n",  value, PCI_CONFIG_IO_WRITE_DATA );
-+	writel( value, PCI_CONFIG_IO_WRITE_DATA );
-+	wmb();
-+    
-+	if ( CheckAndClearBusError() )
-+	{
-+		printk(KERN_DEBUG "PCI: failed to write config\n");
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+	}
-+    
-+	spin_unlock_irqrestore(&oxnas_lock, flags);
-+	return PCIBIOS_SUCCESSFUL;
-+}
-+
-+
-+// #if PCI_BUS_NONMEM_START & 0x000fffff
-+// #error PCI_BUS_NONMEM_START must be megabyte aligned
-+// #endif
-+// #if PCI_BUS_PREMEM_START & 0x000fffff
-+// #error PCI_BUS_PREMEM_START must be megabyte aligned
-+// #endif
-+// 
-+
-+static struct resource io_mem = {
-+	.name	= "PCI I/O Space",
-+	.start	= 0x00001000,
-+	.end	= 0xffff0000,
-+	.flags	= IORESOURCE_IO,
-+};
-+
-+static struct resource non_mem = {
-+	.name	= "PCI non-prefetchable",
-+	.start	= PCI_BASE_PA + PCI_BUS_NONMEM_START,
-+	.end	= PCI_BASE_PA + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
-+	.flags	= IORESOURCE_MEM,
-+};
-+
-+static struct resource pre_mem = {
-+	.name	= "PCI prefetchable",
-+	.start	= PCI_BASE_PA + PCI_BUS_PREMEM_START,
-+	.end	= PCI_BASE_PA + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
-+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
-+};
-+
-+
-+/*
-+ * This routine handles multiple bridges.
-+ */
-+static u8 __init oxnas_swizzle(struct pci_dev *dev, u8 *pinp)
-+{
-+//	printk(KERN_DEBUG "PCI: oxnas_swizzle\n");
-+	return pci_std_swizzle(dev, pinp);
-+}
-+
-+
-+// static int irq_tab[4] __initdata = {
-+//  	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
-+// };
-+
-+
-+/*
-+ * map the specified device/slot/pin to an IRQ.  This works out such
-+ * that ..
-+ */
-+static int __init oxnas_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+	BUG_ON(pin < 1 || pin > 4);
-+
-+//	printk(KERN_DEBUG "PCI: oxnas_map_irq %d,%d,%d = %d\n", dev->bus->number, dev->devfn, slot, PCI_A_INTERRUPT /*pci_irq_table[pin-1]*/ );
-+	return PCI_A_INTERRUPT;
-+}
-+
-+
-+static int __init  oxnas_pci_setup_resources(struct resource **resource)
-+{	
-+	/*
-+	 * bus->resource[0] is the IO resource for this bus
-+	 * bus->resource[1] is the mem resource for this bus
-+	 * bus->resource[2] is the prefetch mem resource for this bus
-+	 */
-+    
-+	resource[0] = &io_mem;
-+	resource[1] = &pre_mem;
-+	resource[2] = &non_mem;
-+    
-+	// these regions apply to incomming transactions on PCI
-+    oxnas_pci_write_core_config( 0xffffffff ,  SYNOPSYS_PCI_MEMORY_BASE_ADDRESS      );
-+    oxnas_pci_write_core_config( 0xffffffff ,  SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS  );
-+    oxnas_pci_write_core_config( 0xffffffff ,  SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS      );
-+    	
-+//    printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_MEMORY_BASE_ADDRESS     $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS     ) );
-+//    printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
-+//    printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS     $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS     ) );
-+
-+    oxnas_pci_write_core_config( SDRAM_PA   ,  SYNOPSYS_PCI_MEMORY_BASE_ADDRESS      );
-+    oxnas_pci_write_core_config( SDRAM_PA   ,  SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS  );
-+    oxnas_pci_write_core_config( SDRAM_PA   ,  SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS      );
-+    	
-+//	printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_MEMORY_BASE_ADDRESS     == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS     ) );
-+//	printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
-+//	printk(KERN_DEBUG "PCI:  SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS     == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS     ) );
-+	return 1;
-+}
-+
-+
-+int __init oxnas_pci_setup(int nr, struct pci_sys_data *sys)
-+{
-+	int ret = 0;
-+
-+//	printk(KERN_DEBUG "PCI: oxnas_pci_setup nr == %u\n", nr);
-+	if (nr == 0) {
-+        /* the PCI core has been setup so that the top nybble is forced to 0, so 
-+        we need to offset by whatever is in the top nybble or the devices won't 
-+        recognise their memory accesses */ 
-+        sys->mem_offset = PCI_BASE_PA & 0xf0000000 ; 
-+    
-+		// ioremap is not called on IO ports. this should shift the physical 
-+		// address to the statically mapped virtual one after the BARS have been
-+		// setup.
-+		sys->io_offset  = 0;
-+
-+		spin_lock_init(&oxnas_lock);
-+		ret = oxnas_pci_setup_resources(sys->resource);
-+	}
-+
-+	return ret;
-+}
-+
-+
-+static struct pci_ops oxnas_pci_ops = {
-+	.read	= oxnas_read_config,
-+	.write	= oxnas_write_config,
-+};
-+
-+
-+struct pci_bus *oxnas_pci_scan_bus(int nr, struct pci_sys_data *sys)
-+{
-+//	printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus\n");
-+	return pci_scan_bus(sys->busnr, &oxnas_pci_ops, sys);
-+}
-+
-+void __init oxnas_pci_preinit(void)
-+{
-+	unsigned int temp; 
-+	unsigned long flags;
-+//	printk(KERN_DEBUG "PCI: oxnas_pci_preinit\n");
-+
-+    // Configure GPIO lines which map PCI INTA for both minipci and planar as active low
-+    spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+	*((volatile unsigned long*)GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE) |= ((1UL <<  PCI_GPIO_INTA_MINIPCI) | (1UL <<  PCI_GPIO_INTA_PLANAR));
-+	*((volatile unsigned long*)GPIO_A_LEVEL_INTERRUPT_ENABLE) |= ((1UL <<  PCI_GPIO_INTA_MINIPCI) | (1UL <<  PCI_GPIO_INTA_PLANAR));
-+    spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	/*
-+	printk(KERN_DEBUG "\n\nPCI: GPIO ABse 0x%08x\n", GPIO_1_BASE );
-+	for ( temp=0;temp<0x40; temp += 4 )
-+	{
-+		printk(KERN_DEBUG "       GPIO ABse + 0x%02x == 0x%08x\n",temp, readl( GPIO_1_BASE+temp ) );
-+	}
-+	*/
-+
-+	// put pci into host mode
-+	temp = 	( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_ENPU                 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_ENCB                 ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ    ) |
-+		    ( 1 << SYSCTL_PCI_CTRL1_SS_HOST_E            ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE  ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SS_CADBUS_E          ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SS_MINIPCI_          ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_SS_INT_MASK_0        ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_INT_STATUS_0         ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK   ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_APP_CBUS_INT_N       ) |
-+		    ( 0 << SYSCTL_PCI_CTRL1_APP_CSTSCHG_N        );
-+
-+//	printk(KERN_DEBUG "PCI: pci into host mode - writel( 0x%08x, 0x%08x )\n", (u32) temp, (u32) (SYS_CTRL_PCI_CTRL1) );
-+	writel( temp, SYS_CTRL_PCI_CTRL1 );
-+
-+	/* the interrupt lines map directly to the GPIO lines, so disable any 
-+    primary, secondary and tertiary functionality */ 
-+    spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+
-+    // Interrupt line the cardbus/mini-PCI slot
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+
-+    // Interrupt line for VIA-SATA PCI device
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  |= (1UL << PCI_GPIO_CLKO_0);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  |= (1UL << PCI_GPIO_CLKO_1);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  |= (1UL << PCI_GPIO_CLKO_2);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0)  |= (1UL << PCI_GPIO_CLKO_3);
-+	*((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
-+
-+//	printk(KERN_DEBUG "PCI: set gnt and req functions for pci arbiters\n" );
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_0
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N0);
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N0);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_0
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_1
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N1);
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N1);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_1
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_2
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_2
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_3
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
-+	*((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_3
-+
-+    spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	// no eeprom to setup core, so perform eeporm functions --------------------
-+	// setup the data to write to enable pci config
-+//	printk(KERN_DEBUG "PCI: enable core features\n" );
-+	oxnas_pci_write_core_config( 
-+		PCI_COMMAND_IO              |
-+		PCI_COMMAND_MEMORY          |
-+		PCI_COMMAND_MASTER          |
-+		PCI_COMMAND_SPECIAL         |
-+		PCI_COMMAND_INVALIDATE      |
-+		PCI_COMMAND_VGA_PALETTE     |
-+		PCI_COMMAND_PARITY          |
-+		PCI_COMMAND_WAIT            | 
-+		PCI_COMMAND_SERR            |
-+		PCI_COMMAND_FAST_BACK /*    |       
-+		PCI_COMMAND_INTX_DISABLE, */, 
-+		PCI_COMMAND );    
-+		
-+//	printk(KERN_DEBUG "PCI:  PCI_COMMAND == 0x%08x\n", (u32) oxnas_pci_read_core_config(PCI_COMMAND) );
-+}
-+
-+void __init oxnas_pci_postinit(void)
-+{
-+//	printk(KERN_DEBUG "PCI: oxnas_pci_postinit\n");
-+}
-+
-+static struct hw_pci oxnas_pci __initdata = {
-+	.swizzle			= oxnas_swizzle,
-+	.map_irq			= oxnas_map_irq,
-+	.setup			= oxnas_pci_setup,
-+	.nr_controllers		= 1,
-+	.scan			= oxnas_pci_scan_bus,
-+	.preinit			= oxnas_pci_preinit,
-+	.postinit		= oxnas_pci_postinit,
-+};
-+
-+static int __init oxnas_pci_init(void)
-+{
-+    pci_common_init(&oxnas_pci);
-+	return 0;
-+}
-+
-+static void __exit oxnas_pci_exit(void)
-+{
-+	// if ( resource[0] ) {
-+	//     int errVal = release_resource(resource[0];
-+	//     if ( errVal ) {
-+	//         printk(KERN_ERR "PCI: unable to release csrRegister space %d", errVal );
-+	//     }
-+	// }
-+
-+    // Put the PCI core into reset, but don't stop the clock as the PCI arbiter
-+    // still requires it in order to be able to grant the static bus access to
-+    // the PCI I/Os
-+    writel(1UL << SYS_CTRL_RSTEN_PCI_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+	return;
-+}
-+
-+subsys_initcall(oxnas_pci_init);
-+module_exit(oxnas_pci_exit);
-+
-+#endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/power_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c
---- linux-2.6.24/arch/arm/mach-oxnas/power_button.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,270 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/power_button.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/timer.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+// Global variable to hold LED inversion state
-+extern int oxnas_global_invert_leds;
-+
-+// Make a module parameter to set whether LED are inverted 
-+static int invert_leds = 0;
-+module_param(invert_leds, bool, S_IRUGO|S_IWUSR);
-+
-+#if (CONFIG_OXNAS_POWER_BUTTON_GPIO < 32)
-+#define SWITCH_NUM          CONFIG_OXNAS_POWER_BUTTON_GPIO
-+#define IRQ_NUM             GPIO_1_INTERRUPT
-+#define INT_STATUS_REG      GPIO_A_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG   SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SWITCH_SECSEL_REG   SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SWITCH_TERSEL_REG   SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SWITCH_CLR_OE_REG   GPIO_A_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG        GPIO_A_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG       GPIO_A_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG     GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG            GPIO_A_DATA
-+#else
-+#define SWITCH_NUM          ((CONFIG_OXNAS_POWER_BUTTON_GPIO) - 32)
-+#define IRQ_NUM             GPIO_2_INTERRUPT
-+#define INT_STATUS_REG      GPIO_B_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG   SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SWITCH_SECSEL_REG   SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SWITCH_TERSEL_REG   SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SWITCH_CLR_OE_REG   GPIO_B_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG        GPIO_B_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG       GPIO_B_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG     GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG            GPIO_B_DATA
-+#endif
-+
-+#define SWITCH_MASK (1UL << (SWITCH_NUM))
-+
-+#define TIMER_INTERVAL_JIFFIES  ((HZ) >> 3) /* An eigth of a second */
-+#define TIMER_COUNT_LIMIT       24          /* In eigths of a second */
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static unsigned long count;
-+static struct timer_list timer;
-+
-+/** Have to use active low level interupt generation, as otherwise might miss
-+ *  interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
-+ *  are generated via GPIO pins and std PCI drivers will not know that there
-+ *  may be other pending GPIO interrupt sources waiting to be serviced and will
-+ *  simply return IRQ_HANDLED if they see themselves as having generated the
-+ *  interrupt, thus preventing later chained handlers from being called
-+ */
-+static irqreturn_t int_handler(int irq, void* dev_id)
-+{
-+	int status = IRQ_NONE;
-+	unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
-+
-+	/* Is the interrupt for us? */
-+	if (int_status & SWITCH_MASK) {
-+		/* Disable the power button GPIO line interrupt */
-+		spin_lock(&oxnas_gpio_spinlock);
-+		writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+		spin_unlock(&oxnas_gpio_spinlock);
-+
-+		/* Zeroise button hold down counter */
-+		count = 0;
-+
-+		/* Start hold down timer with a timeout of 1/8 second */
-+		mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+
-+		/* Only mark interrupt as serviced if no other unmasked GPIO interrupts
-+		are pending */
-+		if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
-+			status = IRQ_HANDLED;
-+		}
-+	}
-+
-+	return status;
-+}
-+
-+/*
-+ * Device driver object
-+ */
-+typedef struct power_button_driver_s {
-+	/** sysfs dir tree root for power button driver */
-+	struct kset kset;
-+	struct kobject power_button;
-+} power_button_driver_t;
-+
-+static power_button_driver_t power_button_driver;
-+
-+static void work_handler(struct work_struct * not_used) {
-+	kobject_uevent(&power_button_driver.power_button, KOBJ_OFFLINE);
-+}
-+
-+DECLARE_WORK(power_button_hotplug_work, work_handler);
-+
-+static void timer_handler(unsigned long data)
-+{
-+	unsigned long flags;
-+
-+	/* Is the power button still pressed? */
-+	if (!(readl(DATA_REG) & SWITCH_MASK)) {
-+		/* Yes, so increment count of how many timer intervals have passed since
-+		power button was pressed */
-+		if (++count == TIMER_COUNT_LIMIT) {
-+			schedule_work(&power_button_hotplug_work);
-+		} else {
-+			/* Restart timer with a timeout of 1/8 second */
-+			mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+		}
-+	} else {
-+		/* The h/w debounced power button has been released, so reenable the
-+		active low interrupt detection to trap the user's next attempt to
-+		power down */
-+		spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+		writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+		spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+	}
-+}
-+
-+static struct kobj_type ktype_power_button = {
-+	.release = 0,
-+	.sysfs_ops = 0,
-+	.default_attrs = 0,
-+};
-+
-+static int power_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+	return get_ktype(kobj) == &ktype_power_button;
-+}
-+
-+static const char* power_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+	return "oxnas_power_button";
-+}
-+
-+static struct kset_uevent_ops power_button_uevent_ops = {
-+	.filter = power_button_hotplug_filter,
-+	.name   = power_button_hotplug_name,
-+	.uevent = NULL,
-+};
-+
-+static int power_button_prep_sysfs(void)
-+{
-+	int err = 0;
-+
-+	/* prep the sysfs interface for use */
-+	kobject_set_name(&power_button_driver.kset.kobj, "power-button");
-+	power_button_driver.kset.ktype = &ktype_power_button;
-+
-+	err = subsystem_register(&power_button_driver.kset);
-+	if (err)
-+		return err;
-+
-+	/* setup hotplugging */
-+	power_button_driver.kset.uevent_ops = &power_button_uevent_ops;
-+
-+	/* setup the heirarchy, the name will be set on detection */
-+	kobject_init(&power_button_driver.power_button);
-+	power_button_driver.power_button.kset = kset_get(&power_button_driver.kset);
-+	power_button_driver.power_button.parent = &power_button_driver.kset.kobj;
-+
-+	return 0;
-+}
-+
-+static int power_button_build_sysfs(void) {
-+	kobject_set_name(&power_button_driver.power_button, "power-button-1");
-+	return kobject_add(&power_button_driver.power_button);
-+}
-+
-+static int __init power_button_init(void)
-+{
-+	int err = 0;
-+	unsigned long flags;
-+
-+	/* Copy the LED inversion module parameter into the global variable */
-+	oxnas_global_invert_leds = invert_leds;
-+
-+	err = power_button_prep_sysfs();
-+	if (err)
-+		return -EINVAL;
-+
-+	err = power_button_build_sysfs();
-+	if (err)
-+		return -EINVAL;
-+
-+	/* Setup the timer that will time how long the user holds down the power
-+	button */
-+	init_timer(&timer);
-+	timer.data = 0;
-+	timer.function = timer_handler;
-+
-+	/* Install a shared interrupt handler on the appropriate GPIO bank's
-+	interrupt line */
-+	if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "Power Button", &power_button_driver)) {
-+		printk(KERN_ERR "Power Button: cannot register IRQ %d\n", IRQ_NUM);
-+		del_timer_sync(&timer);
-+		return -EIO;
-+	}
-+
-+	spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+	/* Disable primary, secondary and teriary GPIO functions on switch lines */
-+	writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
-+	writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
-+	writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
-+
-+	/* Enable GPIO input on switch line */
-+	writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
-+
-+	/* Set up the power button GPIO line for active low, debounced interrupt */
-+	writel(readl(DEBOUNCE_REG)    | SWITCH_MASK, DEBOUNCE_REG);
-+	writel(readl(LEVEL_INT_REG)   | SWITCH_MASK, LEVEL_INT_REG);
-+	writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+	spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	printk(KERN_INFO "Power button driver registered\n");
-+	return 0;
-+}
-+
-+static void __exit power_button_exit(void)
-+{
-+	unsigned long flags;
-+
-+	kobject_del(&power_button_driver.power_button);
-+	subsystem_unregister(&power_button_driver.kset);
-+
-+	/* Deactive the timer */
-+	del_timer_sync(&timer);
-+
-+	/* Disable interrupt generation by the power button GPIO line */
-+	spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+	writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+	spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	/* Remove the handler for the shared interrupt line */
-+	free_irq(IRQ_NUM, &power_button_driver);
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(power_button_init);
-+module_exit(power_button_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c
---- linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/samba_receive.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/errno.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+
-+typedef struct xfs_flock64 {
-+	__s16		l_type;
-+	__s16		l_whence;
-+	__s64		l_start;
-+	__s64		l_len;		/* len == 0 means until end of file */
-+	__s32		l_sysid;
-+	__u32		l_pid;
-+	__s32		l_pad[4];	/* reserve area			    */
-+} xfs_flock64_t;
-+
-+#define XFS_IOC_RESVSP64	_IOW ('X', 42, struct xfs_flock64)
-+
-+asmlinkage long sys_samba_reserve(
-+	int          fd,
-+	void __user *info)
-+{
-+	struct file *file = fget(fd);
-+	long         ret = -EINVAL;
-+
-+	/* Do I need any locking around the unlocked_ioctl() call? */
-+	ret = file->f_op->unlocked_ioctl(file, XFS_IOC_RESVSP64, (unsigned long)info);
-+
-+	fput(file);
-+
-+	return ret;
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c
---- linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,738 @@
-+/*
-+ * Device driver for the i2c thermostat found on the iBook G4, Albook G4
-+ *
-+ * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
-+ *
-+ * Documentation from
-+ * http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf
-+ * http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf
-+ *
-+ */
-+ 
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+#include <linux/freezer.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include "asm/arch-oxnas/taco.h"
-+#include "thermistorCalibration.h"
-+
-+//#define DEBUG 1
-+#undef DEBUG
-+
-+/* Set this define to simulate different temperature values and test the 
-+ * working of the fan control module
-+ */
-+//#define SIMULATE_TEMPERATURE 1
-+#undef SIMULATE_TEMPERATURE
-+
-+/******************************************************************************     
-+ *                                                                            *
-+ *  delta t = dutyCycle.Period                                                *
-+ *                                                                            *
-+ *  PWM in  >----+    V' =   Vcc - Vt                                         *
-+ *               |           --------                                         *
-+ *              _|_             Vcc                                           *
-+ *            | | |                                                           *
-+ *             \| |   Rt =    delta t                                         *
-+ *              | |        -------------                                      *
-+ *              |\|         -C.ln( V' )                                       *
-+ *              | |                                                           *
-+ *              | |\  delta t is discovered by the hardware which performs a  *   
-+ *              !_! \ varies the PWM duty cycle until one is found that just  *
-+ *               |    trips the Vt threshold.                                 *
-+ *               |                                                            *
-+ *               |----------->  V in (Schmidt trigger @ Vt)                   *
-+ *               |                                                            *
-+ *            ___!___                                                         *
-+ *            _______  C ( eg 100nF )                                         *
-+ *               |                                                            *
-+ *               |                                                            *
-+ *               |                                                            *
-+ *            ---+---                                                         *
-+ *                                                                            *
-+ *  Steinhart Thermistor approximation:                                       *
-+ *                                                                            *
-+ *    1/T = A + B.ln(Rt) + C.ln(Rt)^3                                         *
-+ *                                                                            *
-+ ******************************************************************************/           
-+
-+#define MAX_FAN_RATIO_CHANGE        20
-+#define OXSEMI_FAN_SPEED_RATIO_MIN	0
-+#define OXSEMI_FAN_SPEED_RATIO_MAX	255
-+#define FAN_SPEED_RATIO_SET			(PWM_DATA_2)
-+#define MIN_TEMP_COUNT_CHANGE 		2
-+
-+/* This is not absolute temperature but counter val - thermistorCalibration*/
-+static int hot_limit = 16; 
-+
-+#ifdef OXNAS_TACHO_Ox810
-+static int cold_limit = 104;
-+#else /* OXNAS_TACHO_Ox810 */
-+static int cold_limit = 200;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+static int min_fan_speed_ratio  = 64;
-+
-+#ifdef OXNAS_TACHO_Ox810
-+static int fan_pulse_per_rev = 1;
-+static int output_flag = 0;
-+static int current_temp = 0;
-+static int current_speed = 0;
-+#endif /* OXNAS_TACHO_Ox810 */
-+                                       	
-+MODULE_AUTHOR(		"Chris Ford"					);
-+
-+#ifdef OXNAS_TACHO_Ox810
-+MODULE_DESCRIPTION(	"Driver for Temperature sense and Fan control of ox810" 		);
-+#else /* OXNAS_TACHO_Ox810 */
-+MODULE_DESCRIPTION(	"Driver for Fan and temp sense of ox800" 		);
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+MODULE_LICENSE(		"GPL"						);
-+
-+module_param(hot_limit, int, 0644);
-+MODULE_PARM_DESC(hot_limit, "Thermistor input for maximum fan drive");
-+
-+module_param(cold_limit, int, 0644);
-+MODULE_PARM_DESC(cold_limit,"Thermistor input for minimum fan drive");
-+
-+module_param(min_fan_speed_ratio, int, 0644);
-+MODULE_PARM_DESC(min_fan_speed_ratio,"Specify starting( minimum) fan drive (0-255) (default 64)");
-+
-+#ifdef OXNAS_TACHO_Ox810
-+module_param(fan_pulse_per_rev, int, 0644);
-+MODULE_PARM_DESC(fan_pulse_per_rev,"Specify the number of pulses per revolution of fan - 1(default) or 2");
-+
-+module_param(output_flag, bool, 0644);
-+MODULE_PARM_DESC(output_flag,"Flag to specify whether temperature and speed output to user is required");
-+
-+module_param(current_temp, int, S_IRUGO);
-+MODULE_PARM_DESC(current_temp,"Read only for the current temperature in counts");
-+
-+module_param(current_speed, int, S_IRUGO);
-+MODULE_PARM_DESC(current_speed,"Read only for the current speed in rpm");
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+struct thermostat {
-+	int			temps;
-+	int			cached_temp;
-+	int			curr_speed;
-+	int			last_speed;
-+	int	        set_speed;
-+	int			last_var;
-+	struct semaphore 	sem;
-+//	struct cdev		cdev;
-+};
-+
-+static struct thermostat* 	thermostat   = NULL;
-+static struct task_struct*	thread_therm = NULL;
-+
-+
-+static int write_reg( int reg, u32 data )
-+{
-+	writel( data, reg );
-+	return 0;
-+}
-+
-+static int read_reg( int reg )
-+{
-+	int data = 0;
-+	data = readl( reg );
-+	return data;
-+}
-+
-+/** GetTemperatureCounter is an internal function to the module that reads the
-+ * temperature as a counter value and returns it to the caller. The counter 
-+ * value is used in all the internal calculations avoiding the necessity to 
-+ * convert to Kelvin for interpretation. For corresponding temperature values 
-+ * in Kelvin look at thermistoCalilbration.h
-+ */
-+int GetTemperatureCounter(void)
-+{
-+	u32 res;
-+	
-+/*	printk(KERN_INFO "T&F?::GetTemperatureCounter ----\n");
-+ */
-+	/* Test to ensure we are ready.
-+	 */
-+	if ( !thermostat ) {
-+		printk(KERN_INFO "T&F?::$RERROR - Temperature conv not started\n");
-+		return -1;
-+	}
-+		
-+	while ( !(     read_reg( TACHO_THERMISTOR_CONTROL ) & 
-+		   (1 << TACHO_THERMISTOR_CONTROL_THERM_VALID) ) ) {
-+		printk(KERN_INFO "T&F?::$rWarning - Temperature reading not stabalised\n");
-+		msleep(100);
-+	}
-+	
-+	res = read_reg( TACHO_THERMISTOR_RC_COUNTER ) & TACHO_THERMISTOR_RC_COUNTER_MASK;
-+
-+#ifdef DEBUG
-+	printk(KERN_INFO "Therm&Fan - Temperature Counter - %d \n",res);
-+#endif
-+
-+	return res;
-+}
-+
-+/** This function converts the unit of the temperature from counts to
-+ * temperature in Kelvin
-+ */
-+int ConverttoKelvin(int tempCount)
-+{
-+	u32 res, arrayIndex;
-+
-+	/* Convert the Counter Value to Temperature in Kelvin */
-+	arrayIndex = tempCount/THERM_INTERPOLATION_STEP;
-+	res = TvsCnt[arrayIndex];
-+	if ((THERM_ENTRIES_IN_CALIB_TABLE - 2) > arrayIndex)
-+		res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[arrayIndex] - TvsCnt[arrayIndex + 1])  / THERM_INTERPOLATION_STEP;
-+	else
-+		res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 2] - TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 1]) / THERM_INTERPOLATION_STEP;
-+			
-+#ifdef DEBUG
-+	printk(KERN_INFO "Get Temperature- Temperature in Kelvin = %d\n", res);
-+#endif
-+	return res;
-+}
-+
-+/**
-+ * GetTemperature reads the temperature from the thermistor and converts it
-+ * to the corresponding Kelvin equivalent
-+ */
-+int GetTemperature(void)
-+{
-+	u32 tempCount;
-+	tempCount = GetTemperatureCounter();
-+	return 	ConverttoKelvin(tempCount);
-+}
-+
-+/**
-+ * GetFanRPM will read the fan tacho register and convert the value to 
-+ * RPM.
-+ * @return an int that represents the fan speed in RPM, or a
-+ * negative value in the case of error.
-+ */
-+int GetFanRPM(void)
-+{
-+	u32 res;
-+	u32 iCounterValue;
-+	
-+#ifdef OXNAS_TACHO_Ox810
-+	
-+	if(thermostat->last_speed == OXSEMI_FAN_SPEED_RATIO_MIN)
-+	{
-+#ifdef DEBUG
-+		printk(KERN_INFO "ThernAndFan::GetFanRPM - Fan Speed %d \n", OXSEMI_FAN_SPEED_RATIO_MIN);
-+#endif
-+		return OXSEMI_FAN_SPEED_RATIO_MIN;
-+	}
-+
-+	write_reg( TACHO_FAN_ONE_SHOT_CONTROL, (1 << TACHO_FAN_ONE_SHOT_CONTROL_START));
-+	
-+	while ( !(read_reg( TACHO_FAN_SPEED_COUNTER ) & 
-+			   (1 << TACHO_FAN_SPEED_COUNTER_COUNT_VALID) ) ) {
-+/*			printk(KERN_INFO "ThernAndFan::$rWarning - Fan Counter reading not stabalised\n");
-+	*/		msleep(100);
-+		}
-+	
-+#endif /* OXNAS_TACHO_Ox810 */
-+	
-+	iCounterValue = read_reg( TACHO_FAN_SPEED_COUNTER ) 
-+											& TACHO_FAN_SPEED_COUNTER_MASK; 
-+
-+#ifndef OXNAS_TACHO_Ox810 /* Code thats only for non ox810 versions */
-+	if(iCounterValue == TACHO_FAN_SPEED_COUNTER_MASK)
-+	{
-+		/* speed less than measurable */
-+#ifdef DEBUG
-+		printk(KERN_INFO "ThernAndFan::GetFanRPM - RPM < 117 - returning 0\n");
-+#endif
-+		return 0;
-+	}
-+#endif
-+	
-+	++iCounterValue;
-+	
-+#ifdef OXNAS_TACHO_Ox810
-+	/* Fan Speed (rpm) = 60 * 2000 / (counter value +1) * pulses per rev */
-+	res = (60 * 2000 ) / (iCounterValue * fan_pulse_per_rev);
-+#else /* OXNAS_TACHO_Ox810 */
-+	/* Fan Speed (rpm) = 60 * 2000 / (counter value +1) */
-+	res = 60 * 2000 / iCounterValue;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#ifdef SIMULATE_TEMPERATURE
-+	printk(KERN_INFO "thermAndFan::GetFanRPM == %d\n", res);
-+#endif /*SIMULATE_TEMPERATURE */
-+
-+	return res;
-+}
-+
-+#ifdef OXNAS_TACHO_Ox810
-+
-+static void read_sensors(struct thermostat *th)
-+{
-+	static int state;
-+#ifdef SIMULATE_TEMPERATURE
-+	static int curTemp =  30;
-+#endif /* SIMULATE_TEMPERATURE */
-+
-+	if ( !th ) {
-+		printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");		
-+		return;
-+	}
-+	switch(state){
-+	case 0:
-+		th->temps  = GetTemperatureCounter();
-+
-+		/* Set to speed measurement */
-+		write_reg( TACHO_FAN_SPEED_CONTROL, 
-+				(1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE 
-+								+ TACHO_FAN_SPEED_CONTROL_PWM_USED)) 
-+					| (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
-+		state = 1;
-+
-+		if(output_flag) /* Set the temperature to user space here */
-+		{
-+			current_temp = th->temps;
-+		}
-+
-+	#ifdef SIMULATE_TEMPERATURE
-+		th->temps = curTemp;
-+		curTemp += 5;
-+		if(curTemp > cold_limit + 20)
-+			curTemp = hot_limit - 20;
-+		printk(KERN_INFO "thermAndFan::read_sensors Temp Set to - %d\n", curTemp);
-+	#endif /* SIMULATE_TEMPERATURE */
-+	break;
-+
-+	case 1:
-+	default:
-+		
-+		th->curr_speed  = GetFanRPM();
-+
-+		/* Set to Temperature measurement */
-+		write_reg( TACHO_THERMISTOR_CONTROL, ((1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) 
-+							| (0 << TACHO_THERMISTOR_CONTROL_THERM_VALID)) );
-+		state = 0;
-+		
-+		if(output_flag) /* Set the speed to user space here */
-+		{
-+			current_speed = th->curr_speed;
-+		}
-+	break;
-+	}
-+}
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+static void read_sensors(struct thermostat *th)
-+{
-+	static int state;
-+	
-+	if ( !th ) {
-+		printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");		
-+		return;
-+	}
-+
-+	switch (state) {		
-+	case 0: /* Get the temperature */
-+		th->temps  = GetTemperatureCounter();
-+		write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
-+		state = 1;
-+		break;
-+		
-+	case 1:
-+		/* Get the fan speed */
-+		th->curr_speed  = GetFanRPM();
-+		/* free fall to default case needed */
-+/*		break; 
-+	*/	
-+	default:
-+		/* Stop the thermister measuring */
-+		write_reg( TACHO_THERMISTOR_CONTROL, 0 );
-+		write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
-+		/* Start the thermister measuring */
-+		write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
-+		state = 0;
-+		break;
-+	}
-+}
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+#ifdef DEBUG
-+/**
-+ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
-+ */
-+void DumpTachoRegisters(void)
-+{
-+
-+	printk(KERN_INFO \
-+		"\n<Taco Registers> ---------------------------------\n"
-+		"      TACHO_FAN_SPEED_COUNTER          == 0x%08x\n"
-+		"      TACHO_THERMISTOR_RC_COUNTER      == 0x%08x\n"
-+		"      TACHO_THERMISTOR_CONTROL         == 0x%08x\n"
-+		"      TACHO_CLOCK_DIVIDER              == 0x%08x\n"
-+		"      PWM_CORE_CLK_DIVIDER_VALUE       == 0x%08x\n"
-+		"      FAN_SPEED_RATIO_SET              == 0x%08x\n"
-+		"<\\Taco Registers> --------------------------------\n\n",
-+		(u32) (read_reg( TACHO_FAN_SPEED_COUNTER) & TACHO_FAN_SPEED_COUNTER_MASK),	
-+		(u32) (read_reg( TACHO_THERMISTOR_RC_COUNTER) & TACHO_THERMISTOR_RC_COUNTER_MASK),	
-+		(u32) read_reg( TACHO_THERMISTOR_CONTROL	),	
-+		(u32) (read_reg( TACHO_CLOCK_DIVIDER) & TACHO_CLOCK_DIVIDER_MASK),	
-+		(u32) read_reg( PWM_CLOCK_DIVIDER        ),	
-+		(u32) read_reg( FAN_SPEED_RATIO_SET 			 ) );	
-+}
-+#else
-+void DumpTachoRegisters(void) {}
-+#endif
-+
-+static void write_fan_speed(struct thermostat *th, int speed)
-+{
-+/*	printk(KERN_INFO "thermAndFan::write_fan_speed %u\n", speed);
-+*/
-+	/* The fan speed can vary between the max and the min speed ratio or 
-+	 * it can be min ratio value of 0 
-+	 */
-+	if (speed > OXSEMI_FAN_SPEED_RATIO_MAX) 
-+		speed = OXSEMI_FAN_SPEED_RATIO_MAX;
-+	else if ((speed < min_fan_speed_ratio) && (speed > OXSEMI_FAN_SPEED_RATIO_MIN))
-+		speed = min_fan_speed_ratio;
-+	else if (speed < OXSEMI_FAN_SPEED_RATIO_MIN) 
-+		speed = OXSEMI_FAN_SPEED_RATIO_MIN;
-+	
-+	if (th->last_speed == speed)
-+		return;
-+	
-+	write_reg( FAN_SPEED_RATIO_SET, speed );
-+
-+#ifdef SIMULATE_TEMPERATURE
-+	printk(KERN_INFO "Speed Ratio Written - %d\n", speed);
-+#endif /* SIMULATE_TEMPERATURE */
-+		
-+	th->last_speed = speed;			
-+}
-+
-+#ifdef DEBUG
-+static void display_stats(struct thermostat *th)
-+{
-+	if ( 1 || th->temps != th->cached_temp) {
-+		printk(KERN_INFO 
-+			 "thermAndFan:: Temperature infos:\n"
-+			 "  * thermostats: %d;\n"
-+			 "  * pwm: %d;\n"
-+			 "  * fan speed: %d RPM\n\n",
-+			 th->temps,
-+			 min_fan_speed_ratio,
-+			 GetFanRPM());
-+		th->cached_temp = th->temps;
-+	}
-+}
-+#endif
-+
-+/* 
-+ * Use fuzzy logic type approach to creating the new fan speed. 
-+ * if count < cold_limit fan should be off.
-+ * if count > hot_limit fan should be full on.
-+ * if count between limits set proportionally to base speed + proportional element.
-+ */
-+static void update_fan_speed(struct thermostat *th)
-+{
-+	int var = th->temps;
-+	
-+/* remember that var = 1/T ie smaller var higher temperature and faster fan speed needed */
-+	if (abs(var - th->last_var) >= MIN_TEMP_COUNT_CHANGE) {
-+		int new_speed;
-+
-+		if(var < cold_limit){
-+			
-+			if (var < hot_limit)
-+			{
-+				th->last_var = var;
-+				/* too hot for proportional control */
-+				new_speed = OXSEMI_FAN_SPEED_RATIO_MAX;
-+			}
-+			else
-+			{
-+				/* fan speed it the user selected starting value for the fan 
-+				 * so scale operatation from nominal at cold limit to max at hot limit. 
-+				 */
-+				new_speed = OXSEMI_FAN_SPEED_RATIO_MAX - 
-+					(OXSEMI_FAN_SPEED_RATIO_MAX - min_fan_speed_ratio) * (var - hot_limit)/(cold_limit - hot_limit);
-+
-+				if (th->set_speed == 0 ) th->set_speed = min_fan_speed_ratio;
-+								
-+				if ((new_speed - th->set_speed) > MAX_FAN_RATIO_CHANGE)
-+					new_speed = th->set_speed + MAX_FAN_RATIO_CHANGE; 
-+				else if ((new_speed - th->set_speed) < -MAX_FAN_RATIO_CHANGE)
-+					new_speed = th->set_speed - MAX_FAN_RATIO_CHANGE;
-+				else
-+					th->last_var = var;
-+			}
-+		}
-+		else {
-+			
-+			th->last_var = var;
-+			/* var greater than low limit - too cold for fan. */
-+			new_speed = OXSEMI_FAN_SPEED_RATIO_MIN;
-+		}
-+
-+		write_fan_speed(th, new_speed);
-+		th->set_speed = new_speed;
-+	}
-+}
-+
-+static int monitor_task(void *arg)
-+{
-+	struct thermostat* th = arg;
-+	
-+	while(!kthread_should_stop()) {
-+		if (unlikely(freezing(current)))
-+			refrigerator();
-+
-+		msleep_interruptible(2000);
-+
-+#ifdef DEBUG
-+		DumpTachoRegisters();
-+#endif
-+
-+		read_sensors(th);
-+
-+		update_fan_speed(th);
-+
-+#ifdef DEBUG
-+		/* be carefule with the stats displayed. The Fan Counter value depends 
-+		 * on what value is written in the register during the read sensors 
-+		 * call. If its in temperature read setting, the fan counter and hence 
-+		 * the rpm will be WRONG
-+		 */
-+		display_stats(th);
-+#endif
-+	}
-+
-+	return 0;
-+}
-+
-+static int
-+oxsemi_therm_read(char *buf, char **start, off_t offset,
-+		  int len, int *eof, void *unused)
-+{
-+	len = sprintf(buf, 
-+		"Thermostat And Fan state ---------\n"
-+		"      temps_counter          	== %d\n"
-+		"      speed_ratio_set  	== %d\n"
-+		"      measured-fan_speed    	== %d\n"
-+		"      last_temp_counter      	== %d\n\n",
-+		thermostat->temps,
-+		thermostat->last_speed,
-+		thermostat->curr_speed,
-+		thermostat->last_var );
-+	//*start = buf; 
-+	return len;
-+}
-+
-+static struct proc_dir_entry *proc_oxsemi_therm;
-+
-+
-+static struct file_operations oxsemi_therm_fops = {
-+	.owner		= THIS_MODULE,
-+	.open		= nonseekable_open,
-+};
-+
-+static struct miscdevice oxsemi_therm_miscdev = {
-+	TEMP_MINOR,
-+	"temp",
-+	&oxsemi_therm_fops
-+};
-+
-+static int __init oxsemi_therm_init(void)
-+{
-+	struct thermostat* th;
-+	int rc, ret;
-+
-+	if (thermostat)
-+		return 0;
-+
-+	read_reg(SYS_CTRL_RSTEN_CTRL);
-+
-+/* release fan/tacho from system reset */		
-+	*((volatile unsigned long *) SYS_CTRL_RSTEN_CLR_CTRL) = (1UL << SYS_CTRL_RSTEN_MISC_BIT);
-+
-+/* Pull Down the GPIO 29 from the software */
-+#ifdef OXNAS_TACHO_Ox810
-+	*((volatile unsigned long *) SYSCTRL_GPIO_PULLUP_CTRL_0) |= TEMP_TACHO_PULLUP_CTRL_VALUE;
-+#endif /* OXNAS_TACHO_Ox810 */		
-+
-+/*	printk(KERN_INFO "thermAndFan: mux out therm and fan pins onto GPIO)\n" );
-+ */
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+
-+/* disable secondary use */
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+
-+/* disable tertiary use */
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+	*((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+	
-+	read_reg(SYS_CTRL_RSTEN_CTRL);
-+	read_reg(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+	read_reg(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+	read_reg(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+	th = (struct thermostat *)
-+		kmalloc(sizeof(struct thermostat), GFP_KERNEL);
-+
-+	if (!th)
-+		return -ENOMEM;
-+
-+	memset(th, 0, sizeof(struct thermostat));
-+	init_MUTEX( &th->sem );
-+
-+	rc = read_reg(TACHO_CLOCK_DIVIDER);
-+	if (rc < 0) {
-+		printk(KERN_ERR "thermAndFan: Thermostat failed to read config ");
-+		kfree(th);
-+		return -ENODEV;
-+	}
-+	
-+	/* Set the Tacho clock divider up */
-+/*	printk(KERN_INFO "thermAndFan: Setting tacho core frequency divider to %d\n", TACHO_CORE_THERM_DIVIDER_VALUE );
-+ */
-+#ifdef OXNAS_TACHO_Ox810
-+	write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
-+		
-+	/* check tacho divider set correctly */	
-+	rc = read_reg(TACHO_CLOCK_DIVIDER);
-+	/* Comparing a 10 bit value to a 32 bit return value */
-+	if ((rc & TACHO_CORE_TACHO_DIVIDER_VALUE) != TACHO_CORE_TACHO_DIVIDER_VALUE) {
-+		printk(KERN_ERR "thermAndFan: Set Tacho Divider Value Failed readback:%d\n", rc);
-+		kfree(th);
-+		return -ENODEV;
-+	}
-+	
-+#else /* OXNAS_TACHO_Ox810 */
-+	write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
-+	
-+/* check tacho divider set correctly */	
-+	rc = read_reg(TACHO_CLOCK_DIVIDER);
-+	/* Comparing a 10 bit value to a 32 bit return value */
-+	if ((rc & TACHO_CORE_THERM_DIVIDER_VALUE) != TACHO_CORE_THERM_DIVIDER_VALUE) {
-+		printk(KERN_ERR "thermAndFan: Thermostat failed to set config tacho divider readback:%d\n", rc);
-+		kfree(th);
-+		return -ENODEV;
-+	}
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+	
-+/*	printk(KERN_INFO "thermAndFan: Setting PWM core frequency divider to %d\n", PWM_CORE_CLK_DIVIDER_VALUE );
-+ */
-+	write_reg( PWM_CLOCK_DIVIDER, PWM_CORE_CLK_DIVIDER_VALUE );
-+	
-+#ifdef OXNAS_TACHO_Ox810
-+	printk(KERN_INFO "thermAndFan: initializing - ox810\n");
-+#else /* OXNAS_TACHO_Ox810 */
-+	printk(KERN_INFO "thermAndFan: initializing\n");
-+#endif /* OXNAS_TACHO_Ox810 */
-+	
-+#ifdef DEBUG
-+	DumpTachoRegisters();
-+#endif
-+	
-+	thermostat = th;
-+	
-+	/* Start the thermister measuring */
-+	write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
-+	
-+	/* Start Speed measuring */
-+#ifdef OXNAS_TACHO_Ox810
-+	write_reg( TACHO_FAN_SPEED_CONTROL, 
-+			(1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE 
-+							+ TACHO_FAN_SPEED_CONTROL_PWM_USED)) 
-+				| (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
-+#endif /* OXNAS_TACHO_Ox810 */
-+	
-+	/* be sure to really write fan speed the first time */
-+	th->last_speed    = -2;
-+	th->last_var	  = -80;
-+
-+	/* Set fan to initial speed */
-+	write_fan_speed(th, min_fan_speed_ratio);
-+	
-+	thread_therm = kthread_run(monitor_task, th, "kfand");
-+
-+	if (thread_therm == ERR_PTR(-ENOMEM)) {
-+		printk(KERN_INFO "thermAndFan: Kthread creation failed\n");
-+		thread_therm = NULL;
-+		return -ENOMEM;
-+	}
-+	
-+	ret = misc_register(&oxsemi_therm_miscdev);
-+	if (ret < 0)
-+		return ret;
-+	
-+	proc_oxsemi_therm = create_proc_entry("therm-fan", 0, NULL);
-+	if (proc_oxsemi_therm) {
-+		proc_oxsemi_therm->read_proc = oxsemi_therm_read;
-+	} else {
-+		printk(KERN_ERR "therm-fan: unable to register /proc/therm\n");
-+	}
-+
-+	return 0;
-+}
-+
-+
-+static void __exit oxsemi_therm_exit(void)
-+{
-+	if ( thread_therm )
-+	{
-+		kthread_stop(thread_therm);
-+	}
-+	
-+	remove_proc_entry("therm-fan", NULL);
-+	misc_deregister(&oxsemi_therm_miscdev);
-+	
-+	kfree(thermostat);
-+	thermostat = NULL;
-+/* return fan/tacho to system reset */		
-+	*((volatile unsigned long *) SYS_CTRL_RSTEN_SET_CTRL) |= (1UL << SYS_CTRL_RSTEN_MISC_BIT);
-+}
-+
-+
-+module_init(oxsemi_therm_init);
-+module_exit(oxsemi_therm_exit);
-+
-+
-+/* End of File */
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h
---- linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,149 @@
-+#ifndef __THERMISTOR_LOOKUP_TABLE_10K3A_H
-+#define __THERMISTOR_LOOKUP_TABLE_10K3A_H
-+
-+/* Thermistor is a 10K3A*/
-+/* THERM_COEF_A == 0.001129241*/
-+/* THERM_COEF_B == 0.0002341077. */
-+/* THERM_COEF_C == 0.00000008775468. */
-+
-+/* Capacitor is 100 nF */
-+/* Stepped frequency increment is 128000 Hz */
-+/* Schmitdt trigger threshold assumed:  1 / 3.3 V */
-+
-+
-+/* Inverse C.ln(V') == 216 */
-+#define THERM_INTERPOLATION_STEP  8
-+#define THERM_ENTRIES_IN_CALIB_TABLE  128
-+
-+static const unsigned long TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE] = {
-+    416,    /* == 143.37 deg C: Count == 0, R == 216 Ohms */
-+    340,    /* == 67.07 deg C: Count == 8, R == 1948 Ohms */
-+    323,    /* == 49.59 deg C: Count == 16, R == 3679 Ohms */
-+    313,    /* == 39.76 deg C: Count == 24, R == 5410 Ohms */
-+    306,    /* == 33 deg C: Count == 32, R == 7141 Ohms */
-+    301,    /* == 27.9 deg C: Count == 40, R == 8873 Ohms */
-+    297,    /* == 23.82 deg C: Count == 48, R == 10604 Ohms */
-+    293,    /* == 20.43 deg C: Count == 56, R == 12335 Ohms */
-+    291,    /* == 17.55 deg C: Count == 64, R == 14066 Ohms */
-+    288,    /* == 15.04 deg C: Count == 72, R == 15798 Ohms */
-+    286,    /* == 12.82 deg C: Count == 80, R == 17529 Ohms */
-+    284,    /* == 10.84 deg C: Count == 88, R == 19260 Ohms */
-+    282,    /* == 9.04 deg C: Count == 96, R == 20991 Ohms */
-+    280,    /* == 7.41 deg C: Count == 104, R == 22722 Ohms */
-+    279,    /* == 5.91 deg C: Count == 112, R == 24454 Ohms */
-+    278,    /* == 4.53 deg C: Count == 120, R == 26185 Ohms */
-+    276,    /* == 3.25 deg C: Count == 128, R == 27916 Ohms */
-+    275,    /* == 2.05 deg C: Count == 136, R == 29647 Ohms */
-+    274,    /* == 0.93 deg C: Count == 144, R == 31379 Ohms */
-+    273,    /* == -0.12 deg C: Count == 152, R == 33110 Ohms */
-+    272,    /* == -1.12 deg C: Count == 160, R == 34841 Ohms */
-+    271,    /* == -2.06 deg C: Count == 168, R == 36572 Ohms */
-+    270,    /* == -2.95 deg C: Count == 176, R == 38304 Ohms */
-+    269,    /* == -3.8 deg C: Count == 184, R == 40035 Ohms */
-+    268,    /* == -4.6 deg C: Count == 192, R == 41766 Ohms */
-+    268,    /* == -5.37 deg C: Count == 200, R == 43497 Ohms */
-+    267,    /* == -6.11 deg C: Count == 208, R == 45229 Ohms */
-+    266,    /* == -6.81 deg C: Count == 216, R == 46960 Ohms */
-+    266,    /* == -7.49 deg C: Count == 224, R == 48691 Ohms */
-+    265,    /* == -8.14 deg C: Count == 232, R == 50422 Ohms */
-+    264,    /* == -8.77 deg C: Count == 240, R == 52154 Ohms */
-+    264,    /* == -9.37 deg C: Count == 248, R == 53885 Ohms */
-+    263,    /* == -9.95 deg C: Count == 256, R == 55616 Ohms */
-+    262,    /* == -10.52 deg C: Count == 264, R == 57347 Ohms */
-+    262,    /* == -11.06 deg C: Count == 272, R == 59078 Ohms */
-+    261,    /* == -11.59 deg C: Count == 280, R == 60810 Ohms */
-+    261,    /* == -12.1 deg C: Count == 288, R == 62541 Ohms */
-+    260,    /* == -12.59 deg C: Count == 296, R == 64272 Ohms */
-+    260,    /* == -13.07 deg C: Count == 304, R == 66003 Ohms */
-+    259,    /* == -13.53 deg C: Count == 312, R == 67735 Ohms */
-+    259,    /* == -13.99 deg C: Count == 320, R == 69466 Ohms */
-+    259,    /* == -14.43 deg C: Count == 328, R == 71197 Ohms */
-+    258,    /* == -14.86 deg C: Count == 336, R == 72928 Ohms */
-+    258,    /* == -15.27 deg C: Count == 344, R == 74660 Ohms */
-+    257,    /* == -15.68 deg C: Count == 352, R == 76391 Ohms */
-+    257,    /* == -16.08 deg C: Count == 360, R == 78122 Ohms */
-+    257,    /* == -16.46 deg C: Count == 368, R == 79853 Ohms */
-+    256,    /* == -16.84 deg C: Count == 376, R == 81585 Ohms */
-+    256,    /* == -17.21 deg C: Count == 384, R == 83316 Ohms */
-+    255,    /* == -17.57 deg C: Count == 392, R == 85047 Ohms */
-+    255,    /* == -17.92 deg C: Count == 400, R == 86778 Ohms */
-+    255,    /* == -18.26 deg C: Count == 408, R == 88510 Ohms */
-+    254,    /* == -18.6 deg C: Count == 416, R == 90241 Ohms */
-+    254,    /* == -18.93 deg C: Count == 424, R == 91972 Ohms */
-+    254,    /* == -19.25 deg C: Count == 432, R == 93703 Ohms */
-+    253,    /* == -19.57 deg C: Count == 440, R == 95434 Ohms */
-+    253,    /* == -19.88 deg C: Count == 448, R == 97166 Ohms */
-+    253,    /* == -20.18 deg C: Count == 456, R == 98897 Ohms */
-+    253,    /* == -20.48 deg C: Count == 464, R == 100628 Ohms */
-+    252,    /* == -20.77 deg C: Count == 472, R == 102359 Ohms */
-+    252,    /* == -21.06 deg C: Count == 480, R == 104091 Ohms */
-+    252,    /* == -21.34 deg C: Count == 488, R == 105822 Ohms */
-+    251,    /* == -21.62 deg C: Count == 496, R == 107553 Ohms */
-+    251,    /* == -21.89 deg C: Count == 504, R == 109284 Ohms */
-+    251,    /* == -22.16 deg C: Count == 512, R == 111016 Ohms */
-+    251,    /* == -22.42 deg C: Count == 520, R == 112747 Ohms */
-+    250,    /* == -22.68 deg C: Count == 528, R == 114478 Ohms */
-+    250,    /* == -22.93 deg C: Count == 536, R == 116209 Ohms */
-+    250,    /* == -23.18 deg C: Count == 544, R == 117941 Ohms */
-+    250,    /* == -23.43 deg C: Count == 552, R == 119672 Ohms */
-+    249,    /* == -23.67 deg C: Count == 560, R == 121403 Ohms */
-+    249,    /* == -23.91 deg C: Count == 568, R == 123134 Ohms */
-+    249,    /* == -24.14 deg C: Count == 576, R == 124866 Ohms */
-+    249,    /* == -24.37 deg C: Count == 584, R == 126597 Ohms */
-+    248,    /* == -24.6 deg C: Count == 592, R == 128328 Ohms */
-+    248,    /* == -24.82 deg C: Count == 600, R == 130059 Ohms */
-+    248,    /* == -25.04 deg C: Count == 608, R == 131790 Ohms */
-+    248,    /* == -25.26 deg C: Count == 616, R == 133522 Ohms */
-+    248,    /* == -25.47 deg C: Count == 624, R == 135253 Ohms */
-+    247,    /* == -25.68 deg C: Count == 632, R == 136984 Ohms */
-+    247,    /* == -25.89 deg C: Count == 640, R == 138715 Ohms */
-+    247,    /* == -26.1 deg C: Count == 648, R == 140447 Ohms */
-+    247,    /* == -26.3 deg C: Count == 656, R == 142178 Ohms */
-+    247,    /* == -26.5 deg C: Count == 664, R == 143909 Ohms */
-+    246,    /* == -26.69 deg C: Count == 672, R == 145640 Ohms */
-+    246,    /* == -26.89 deg C: Count == 680, R == 147372 Ohms */
-+    246,    /* == -27.08 deg C: Count == 688, R == 149103 Ohms */
-+    246,    /* == -27.27 deg C: Count == 696, R == 150834 Ohms */
-+    246,    /* == -27.46 deg C: Count == 704, R == 152565 Ohms */
-+    245,    /* == -27.64 deg C: Count == 712, R == 154297 Ohms */
-+    245,    /* == -27.82 deg C: Count == 720, R == 156028 Ohms */
-+    245,    /* == -28 deg C: Count == 728, R == 157759 Ohms */
-+    245,    /* == -28.18 deg C: Count == 736, R == 159490 Ohms */
-+    245,    /* == -28.36 deg C: Count == 744, R == 161222 Ohms */
-+    244,    /* == -28.53 deg C: Count == 752, R == 162953 Ohms */
-+    244,    /* == -28.7 deg C: Count == 760, R == 164684 Ohms */
-+    244,    /* == -28.87 deg C: Count == 768, R == 166415 Ohms */
-+    244,    /* == -29.04 deg C: Count == 776, R == 168146 Ohms */
-+    244,    /* == -29.21 deg C: Count == 784, R == 169878 Ohms */
-+    244,    /* == -29.37 deg C: Count == 792, R == 171609 Ohms */
-+    243,    /* == -29.53 deg C: Count == 800, R == 173340 Ohms */
-+    243,    /* == -29.69 deg C: Count == 808, R == 175071 Ohms */
-+    243,    /* == -29.85 deg C: Count == 816, R == 176803 Ohms */
-+    243,    /* == -30.01 deg C: Count == 824, R == 178534 Ohms */
-+    243,    /* == -30.16 deg C: Count == 832, R == 180265 Ohms */
-+    243,    /* == -30.32 deg C: Count == 840, R == 181996 Ohms */
-+    243,    /* == -30.47 deg C: Count == 848, R == 183728 Ohms */
-+    242,    /* == -30.62 deg C: Count == 856, R == 185459 Ohms */
-+    242,    /* == -30.77 deg C: Count == 864, R == 187190 Ohms */
-+    242,    /* == -30.92 deg C: Count == 872, R == 188921 Ohms */
-+    242,    /* == -31.06 deg C: Count == 880, R == 190653 Ohms */
-+    242,    /* == -31.21 deg C: Count == 888, R == 192384 Ohms */
-+    242,    /* == -31.35 deg C: Count == 896, R == 194115 Ohms */
-+    242,    /* == -31.49 deg C: Count == 904, R == 195846 Ohms */
-+    241,    /* == -31.63 deg C: Count == 912, R == 197578 Ohms */
-+    241,    /* == -31.77 deg C: Count == 920, R == 199309 Ohms */
-+    241,    /* == -31.91 deg C: Count == 928, R == 201040 Ohms */
-+    241,    /* == -32.04 deg C: Count == 936, R == 202771 Ohms */
-+    241,    /* == -32.18 deg C: Count == 944, R == 204502 Ohms */
-+    241,    /* == -32.31 deg C: Count == 952, R == 206234 Ohms */
-+    241,    /* == -32.44 deg C: Count == 960, R == 207965 Ohms */
-+    240,    /* == -32.58 deg C: Count == 968, R == 209696 Ohms */
-+    240,    /* == -32.71 deg C: Count == 976, R == 211427 Ohms */
-+    240,    /* == -32.83 deg C: Count == 984, R == 213159 Ohms */
-+    240,    /* == -32.96 deg C: Count == 992, R == 214890 Ohms */
-+    240,    /* == -33.09 deg C: Count == 1000, R == 216621 Ohms */
-+    240,    /* == -33.21 deg C: Count == 1008, R == 218352 Ohms */
-+    240,    /* == -33.34 deg C: Count == 1016, R == 220084 Ohms */
-+};
-+
-+#endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/time.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c
---- linux-2.6.24/arch/arm/mach-oxnas/time.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,159 @@
-+/*
-+ *  linux/arch/arm/mach-oxnas/irq.c
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/mach/time.h>
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+#include <asm/arch/ahb_mon.h>
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+static int client = 0;
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+static irqreturn_t OXNAS_timer_interrupt(int irq, void *dev_id)
-+{
-+#ifdef CONFIG_OXNAS_DDR_MON
-+    static const int NUM_MON_CLIENTS = 8;
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+	write_seqlock(&xtime_lock);
-+
-+    // Clear the timer interrupt - any write will do
-+    *((volatile unsigned long*)TIMER1_CLEAR) = 0;
-+
-+    timer_tick();
-+
-+	write_sequnlock(&xtime_lock);
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+    if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
-+        // Read the DDR core bus monitors
-+        u32 diag_reg_contents = readl(DDR_DIAG_REG);
-+        u32 holdoffs = (diag_reg_contents >> DDR_DIAG_HOLDOFFS_BIT) & ((1UL << DDR_DIAG_HOLDOFFS_NUM_BITS) - 1);
-+        u32 writes   = (diag_reg_contents >> DDR_DIAG_WRITES_BIT)   & ((1UL << DDR_DIAG_WRITES_NUM_BITS) - 1);
-+        u32 reads    = (diag_reg_contents >> DDR_DIAG_READS_BIT)    & ((1UL << DDR_DIAG_READS_NUM_BITS) - 1);
-+    
-+        printk(KERN_INFO "$WC %d: H=%u, W=%u, R=%u\n", client, holdoffs, writes, reads);
-+        // Re-arm the DDR core bus monitors
-+        writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
-+        if (++client >= NUM_MON_CLIENTS) {
-+            client = 0;
-+        }
-+    }
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+    if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
-+        read_ahb_monitors();
-+        restart_ahb_monitors();
-+    }
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-+    return IRQ_HANDLED;
-+}
-+
-+static struct irqaction oxnas_timer_irq = {
-+    .name    = "Jiffy tick",
-+	.flags	 = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-+    .handler = OXNAS_timer_interrupt
-+};
-+
-+static void /*__init*/ oxnas_init_time(void)
-+{
-+    // Connect the timer interrupt handler
-+    oxnas_timer_irq.handler = OXNAS_timer_interrupt;
-+    setup_irq(TIMER_1_INTERRUPT, &oxnas_timer_irq);
-+
-+    // Stop both timers before programming them
-+    *((volatile unsigned long*)TIMER1_CONTROL) = 0;
-+    *((volatile unsigned long*)TIMER2_CONTROL) = 0;
-+
-+    // Setup timer 1 load value
-+    *((volatile unsigned long*)TIMER1_LOAD) = TIMER_1_LOAD_VALUE;
-+
-+    // Setup timer 1 prescaler, periodic operation and start it
-+    *((volatile unsigned long*)TIMER1_CONTROL) =
-+        (TIMER_1_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+        (TIMER_1_MODE          << TIMER_MODE_BIT)     |
-+        (TIMER_ENABLE_ENABLE   << TIMER_ENABLE_BIT);
-+
-+    // Setup timer 2 prescaler, free-running operation and start it
-+    // This will not be used to generate interrupt, just as a hi-res source of
-+    // timing information
-+    *((volatile unsigned long*)TIMER2_CONTROL) =
-+        (TIMER_2_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+        (TIMER_2_MODE          << TIMER_MODE_BIT)     |
-+        (TIMER_ENABLE_ENABLE   << TIMER_ENABLE_BIT);
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+    // Arm the DDR core bus monitors, start with client zero
-+    writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+    // Monitor all accesses
-+    init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+#endif // CONFIG_OXNAS_AHB_MON
-+}
-+
-+/*
-+ * Returns number of microseconds since last clock tick interrupt.
-+ * Note that interrupts will be disabled when this is called
-+ * Should take account of any pending timer tick interrupt
-+ */
-+static unsigned long oxnas_gettimeoffset(void)
-+{
-+	// How long since last timer interrupt?
-+    unsigned long ticks_since_last_intr =
-+		(unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
-+
-+    // Is there a timer interrupt pending
-+    int timer_int_pending =
-+		*((volatile unsigned long*)RPS_IRQ_RAW_STATUS) & (1UL << TIMER_1_INTERRUPT);
-+
-+    if (timer_int_pending) {
-+		// Sample time since last timer interrupt again. Theoretical race between
-+		// interrupt occuring and ARM reading value before reload has taken
-+		// effect, but in practice it's not going to happen because it takes
-+		// multiple clock cycles for the ARM to read the timer value register
-+		unsigned long ticks2 = (unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
-+
-+		// If the timer interrupt which hasn't yet been serviced, and thus has
-+		// not yet contributed to the tick count, occured before our initial
-+		// read of the current timer value then we need to account for a whole
-+		// timer interrupt period
-+		if (ticks_since_last_intr <= ticks2) {
-+			// Add on a whole timer interrupt period, as the tick count will have
-+			// wrapped around since the previously seen timer interrupt (?)
-+			ticks_since_last_intr += TIMER_1_LOAD_VALUE;
-+		}
-+    }
-+
-+    return TICKS_TO_US(ticks_since_last_intr);
-+}
-+
-+struct sys_timer oxnas_timer = {
-+    .init   = oxnas_init_time,
-+    .offset = oxnas_gettimeoffset,
-+};
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c
---- linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,253 @@
-+/*
-+ *  arch/arm/mach-oxnas/usb-test-mode.c
-+ *
-+ *  Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include <asm/hardware.h>
-+
-+
-+/* usb test masks and offsets */
-+#define TEST_MASK    0xF
-+#define TEST_OFFSET  16
-+
-+#define MODULE_VERS "0.1"
-+#define MODULE_NAME "usb_test_mode"
-+MODULE_AUTHOR(		"John Larkworthy"					);
-+MODULE_DESCRIPTION(	"Driver to put usb ports in test modes"		);
-+MODULE_LICENSE(		"GPL"						);
-+
-+
-+static struct proc_dir_entry *proc_dir_usb_test_read, *usb_test_dir;
-+
-+
-+/* create proc filing system entries to accept configuration data */
-+static int usb_test_write_entries(const char *name, write_proc_t *w, int data)
-+{
-+	struct proc_dir_entry * entry = create_proc_entry(name, 0222, usb_test_dir);
-+	if (entry) {
-+		entry->write_proc = w;
-+		entry->data = (void *)data;
-+		entry->owner = THIS_MODULE;
-+		return 0;
-+	}
-+	else
-+	{
-+		return -ENOMEM;
-+	}
-+}
-+
-+
-+
-+#if 0
-+static int
-+oxsemi_usb_test_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+	//int i = (int __user *)arg;
-+
-+	printk(KERN_INFO "usb test:: usb_test_ioctl\n");
-+	switch(cmd) {
-+	case SET_TEST_MODE:
-+		break;
-+	// etc...
-+		
-+	default:
-+		return -ENOIOCTLCMD;
-+	}
-+
-+	return 0;
-+}
-+#endif
-+
-+static int
-+oxsemi_usb_test_read(char *buf, char **start, off_t offset,
-+		  int count, int *eof, void *unused)
-+{
-+	
-+	int i;
-+	int len = 0;
-+	long unsigned *usbport;
-+	
-+	usbport = (long unsigned *) (USB_BASE+0x184);
-+	
-+	for (i=0; i < 3; i++)
-+	{
-+		len += sprintf(buf+len, "usb port %d [%p]:%08lx \n", i, (usbport+4*i) , *(usbport+i));
-+	}
-+	*eof=1;
-+	return len;
-+}
-+
-+static int
-+oxsemi_usb_test_write(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+	int len;	
-+	long int *usbport;
-+	char local[10];
-+	int result;
-+	int test_mode;
-+	unsigned long flags;
-+	
-+	if (count > 9)
-+		len= 9;
-+	else 
-+		len=count;
-+		
-+	if (copy_from_user(&local, buf, len))
-+		return -EFAULT;
-+	
-+	/* extract value from buffer and store */
-+	result = sscanf(local, "%1d", &test_mode);
-+	if (result != 1)
-+		return -EINVAL;
-+		
-+	usbport = (long int *) (USB_BASE+0X184 + (4* (int) data));
-+	printk(KERN_ERR "usb-test-write : [%08lx] <- %08lx \n",
-+        (long unsigned) usbport,
-+        (long unsigned) ((test_mode & TEST_MASK) << TEST_OFFSET));
-+	/* lock system while this is updated */
-+	local_irq_save(flags);
-+ 	*usbport = (*usbport & ~(TEST_MASK<<TEST_OFFSET)) | ((test_mode & TEST_MASK) << TEST_OFFSET);
-+	local_irq_restore(flags);
-+	printk(KERN_ERR "usb-test-writen: [%08lx]:%08lx \n", (long unsigned) usbport, (long unsigned) *usbport);
-+	return len;
-+}
-+
-+
-+static int __init oxsemi_usb_test_init(void)
-+{
-+	int rv;
-+	int i;
-+	char name[] = "usb-test/write0"; /* overwritten with new name below */
-+	
-+	usb_test_dir = proc_mkdir(MODULE_NAME, NULL);
-+	if (usb_test_dir == NULL) {
-+		printk(KERN_ERR "usb-test: unable to register /proc/usb-test\n");
-+		rv= -ENOMEM;
-+		goto out;
-+	}
-+	
-+	usb_test_dir->owner= THIS_MODULE;
-+	
-+	proc_dir_usb_test_read = create_proc_entry("read", 0444, usb_test_dir);
-+	if (proc_dir_usb_test_read) {
-+		proc_dir_usb_test_read->read_proc = oxsemi_usb_test_read;
-+	} else {
-+		printk(KERN_ERR "usb-test: unable to register /proc/usb-test/read\n");
-+		rv = -ENOMEM;
-+		goto no_read;
-+	}
-+	/* create port write file entries */
-+	for (i=0;i<3;i++) 
-+	{
-+		sprintf(name,"write%d",i+1);
-+		rv = usb_test_write_entries(name, &oxsemi_usb_test_write, i);
-+		if (rv < 0)
-+		{
-+			while (i != 0)
-+			{
-+				i--;
-+				/* remove any allocated entries */
-+				sprintf(name,"usb-test/write%d",i+1);
-+				remove_proc_entry (name, usb_test_dir);
-+			} 
-+			goto no_write;
-+		}
-+	}
-+	printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
-+
-+	return 0;
-+	no_write:
-+		remove_proc_entry("usb-test/read", usb_test_dir);
-+	no_read:
-+		remove_proc_entry(MODULE_NAME, NULL);
-+	out:
-+		return rv;
-+}
-+
-+
-+static void __exit oxsemi_usb_test_exit(void)
-+{
-+	char name[] =  "usb-test/write0";
-+	int i;
-+	
-+	for (i = 0; i < 3; i++)
-+	{
-+		sprintf(name, "write%1d", (i+1));
-+		remove_proc_entry(name, usb_test_dir);
-+	}
-+	
-+	remove_proc_entry("read", usb_test_dir);
-+	remove_proc_entry(MODULE_NAME, NULL);
-+
-+	printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
-+	
-+}
-+
-+
-+module_init(oxsemi_usb_test_init);
-+module_exit(oxsemi_usb_test_exit);
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c
---- linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,260 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/user_recovery_button.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/timer.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+#if (CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO < 32)
-+#define SWITCH_NUM          CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO
-+#define IRQ_NUM             GPIO_1_INTERRUPT
-+#define INT_STATUS_REG      GPIO_A_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG   SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SWITCH_SECSEL_REG   SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SWITCH_TERSEL_REG   SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SWITCH_CLR_OE_REG   GPIO_A_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG        GPIO_A_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG       GPIO_A_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG     GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG            GPIO_A_DATA
-+#else
-+#define SWITCH_NUM          ((CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO) - 32)
-+#define IRQ_NUM             GPIO_2_INTERRUPT
-+#define INT_STATUS_REG      GPIO_B_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG   SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SWITCH_SECSEL_REG   SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SWITCH_TERSEL_REG   SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SWITCH_CLR_OE_REG   GPIO_B_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG        GPIO_B_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG       GPIO_B_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG     GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG            GPIO_B_DATA
-+#endif
-+
-+#define SWITCH_MASK (1UL << (SWITCH_NUM))
-+
-+#define TIMER_INTERVAL_JIFFIES  ((HZ) >> 3) /* An eigth of a second */
-+#define TIMER_COUNT_LIMIT       32          /* In eigths of a second */
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static unsigned long count;
-+static struct timer_list timer;
-+
-+/** Have to use active low level interupt generation, as otherwise might miss
-+ *  interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
-+ *  are generated via GPIO pins and std PCI drivers will not know that there
-+ *  may be other pending GPIO interrupt sources waiting to be serviced and will
-+ *  simply return IRQ_HANDLED if they see themselves as having generated the
-+ *  interrupt, thus preventing later chained handlers from being called
-+ */
-+static irqreturn_t int_handler(int irq, void* dev_id)
-+{
-+	int status = IRQ_NONE;
-+	unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
-+
-+	/* Is the interrupt for us? */
-+	if (int_status & SWITCH_MASK) {
-+		/* Disable the user recovery button GPIO line interrupt */
-+		spin_lock(&oxnas_gpio_spinlock);
-+		writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+		spin_unlock(&oxnas_gpio_spinlock);
-+
-+		/* Zeroise button hold down counter */
-+		count = 0;
-+
-+		/* Start hold down timer with a timeout of 1/8 second */
-+		mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+
-+		/* Only mark interrupt as serviced if no other unmasked GPIO interrupts
-+		are pending */
-+		if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
-+			status = IRQ_HANDLED;
-+		}
-+	}
-+
-+	return status;
-+}
-+
-+/*
-+ * Device driver object
-+ */
-+typedef struct recovery_button_driver_s {
-+	/** sysfs dir tree root for recovery button driver */
-+	struct kset kset;
-+	struct kobject recovery_button;
-+} recovery_button_driver_t;
-+
-+static recovery_button_driver_t recovery_button_driver;
-+
-+static void work_handler(struct work_struct * not_used) {
-+	kobject_uevent(&recovery_button_driver.recovery_button, KOBJ_OFFLINE);
-+}
-+
-+DECLARE_WORK(recovery_button_hotplug_work, work_handler);
-+
-+static void timer_handler(unsigned long data)
-+{
-+	unsigned long flags;
-+
-+	/* Is the user recovery button still pressed? */
-+	if (!(readl(DATA_REG) & SWITCH_MASK)) {
-+		/* Yes, so increment count of how many timer intervals have passed since
-+		   user recovery button was pressed */
-+		if (++count == TIMER_COUNT_LIMIT) {
-+			schedule_work(&recovery_button_hotplug_work);
-+		} else {
-+			/* Restart timer with a timeout of 1/8 second */
-+			mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+		}
-+	} else {
-+		/* The h/w debounced user recovery button has been released, so reenable the
-+		   active low interrupt detection to trap the user's next attempt to
-+		   recover */
-+		spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+		writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+		spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+	}
-+}
-+
-+static struct kobj_type ktype_recovery_button = {
-+	.release = 0,
-+	.sysfs_ops = 0,
-+	.default_attrs = 0,
-+};
-+
-+static int recovery_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+	return get_ktype(kobj) == &ktype_recovery_button;
-+}
-+
-+static const char* recovery_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+	return "oxnas_user_recovery";
-+}
-+
-+static struct kset_uevent_ops recovery_button_uevent_ops = {
-+	.filter = recovery_button_hotplug_filter,
-+	.name   = recovery_button_hotplug_name,
-+	.uevent = NULL,
-+};
-+
-+static int recovery_button_prep_sysfs(void)
-+{
-+	int err = 0;
-+
-+	/* prep the sysfs interface for use */
-+	kobject_set_name(&recovery_button_driver.kset.kobj, "recovery-button");
-+	recovery_button_driver.kset.ktype = &ktype_recovery_button;
-+
-+	err = subsystem_register(&recovery_button_driver.kset);
-+	if (err)
-+		return err;
-+
-+	/* setup hotplugging */
-+	recovery_button_driver.kset.uevent_ops = &recovery_button_uevent_ops;
-+
-+	/* setup the heirarchy, the name will be set on detection */
-+	kobject_init(&recovery_button_driver.recovery_button);
-+	recovery_button_driver.recovery_button.kset = kset_get(&recovery_button_driver.kset);
-+	recovery_button_driver.recovery_button.parent = &recovery_button_driver.kset.kobj;
-+
-+	return 0;
-+}
-+
-+static int recovery_button_build_sysfs(void) {
-+	kobject_set_name(&recovery_button_driver.recovery_button, "recovery-button-1");
-+	return kobject_add(&recovery_button_driver.recovery_button);
-+}
-+
-+static int __init recovery_button_init(void)
-+{
-+	int err = 0;
-+	unsigned long flags;
-+
-+	err = recovery_button_prep_sysfs();
-+	if (err)
-+		return -EINVAL;
-+
-+	err = recovery_button_build_sysfs();
-+	if (err)
-+		return -EINVAL;
-+
-+	/* Setup the timer that will time how long the user holds down the recovery
-+	button */
-+	init_timer(&timer);
-+	timer.data = 0;
-+	timer.function = timer_handler;
-+
-+	/* Install a shared interrupt handler on the appropriate GPIO bank's
-+	interrupt line */
-+	if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "User Recovery Button", &recovery_button_driver)) {
-+		printk(KERN_ERR "User Recovery Button: cannot register IRQ %d\n", IRQ_NUM);
-+		del_timer_sync(&timer);
-+		return -EIO;
-+	}
-+
-+	spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+	/* Disable primary, secondary and teriary GPIO functions on switch lines */
-+	writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
-+	writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
-+	writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
-+
-+	/* Enable GPIO input on switch line */
-+	writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
-+
-+	/* Set up the user recovery button GPIO line for active low, debounced interrupt */
-+	writel(readl(DEBOUNCE_REG)    | SWITCH_MASK, DEBOUNCE_REG);
-+	writel(readl(LEVEL_INT_REG)   | SWITCH_MASK, LEVEL_INT_REG);
-+	writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+	spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	printk(KERN_INFO "Recovery button driver registered\n");
-+	return 0;
-+}
-+
-+static void __exit recovery_button_exit(void)
-+{
-+	unsigned long flags;
-+
-+	kobject_del(&recovery_button_driver.recovery_button);
-+	subsystem_unregister(&recovery_button_driver.kset);
-+
-+	/* Deactive the timer */
-+	del_timer_sync(&timer);
-+
-+	/* Disable interrupt generation by the recovery button GPIO line */
-+	spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+	writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+	spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	/* Remove the handler for the shared interrupt line */
-+	free_irq(IRQ_NUM, &recovery_button_driver);
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(recovery_button_init);
-+module_exit(recovery_button_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,336 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-fan.c
-+ *
-+ * Copyright (C) 2006-2007 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/err.h>
-+#include <linux/ctype.h>
-+#include <linux/platform_device.h>
-+#include <asm/hardware.h>
-+
-+/* Human recognizable driver name. */
-+#define DRIVER_NAME           "WDC_Fan"
-+
-+/* GPIOs for the fan on the Galaxy 2NC platform. All are on GPIO_A */
-+#define FAN_MASK_LOW          (1 << GPIO_29)
-+#define FAN_MASK_HIGH         (1 << GPIO_8)
-+
-+#define FAN_MASK              ( FAN_MASK_LOW  | FAN_MASK_HIGH )
-+
-+
-+/* I/O register access (FIXME: why not use the standard linux macros?) */
-+#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
-+#define ox_readl(addr)        (*(volatile unsigned long*)addr)
-+#define writel(data, addr)    (*(volatile u32*)addr = (data))
-+#define readl(addr)           (*(volatile u32*)addr)
-+#define CLEAR(addr, mask)     writel(readl(addr) & ~mask, addr)
-+
-+enum fan_speeds
-+{
-+   FAN_OFF  = 0,
-+   FAN_SPEED_MAX  = 100
-+};
-+
-+typedef struct s_fan_device_state
-+{
-+   unsigned char speed;       /* Range FAN_OFF .. FAN_SPEED_MAX */
-+} fan_device_state;
-+
-+
-+/*
-+ * Driver-global variables.
-+ */
-+
-+/* Number of successful probes. */
-+/* TODO: protect this variable??!? */
-+static int  fans_found;
-+
-+/* This spinlock protects the GPIO setup code from
-+   interrupts but is not SMP-correct. */
-+static spinlock_t oxnas_gpio_spinlock;
-+
-+/* Device instance state.
-+   Only one fan is supported, so this can be a global variable. */
-+static fan_device_state  fan_state;
-+
-+
-+/*
-+ * Device attribute getter/setters
-+ */
-+static ssize_t fan_speed_show (struct device*, struct device_attribute*,
-+                               char *buf);
-+
-+static ssize_t fan_speed_store(struct device*, struct device_attribute*,
-+                               const char *buf, size_t count);
-+
-+/* Declare device attributes using the functions above.
-+   Contrary to the macro's name, DEVICE_ATTR declares a dev_attr_...  */
-+static DEVICE_ATTR(speed, 0644, fan_speed_show, fan_speed_store);
-+
-+
-+static void set_fan_speed(unsigned char speed);
-+
-+static int  fan_probe (struct platform_device *pdev);
-+static int  fan_remove(struct platform_device *pdev);
-+
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: fan_probe                                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Look for fans and do initialize.                                      */
-+/***************************************************************************/
-+int fan_probe(struct platform_device *pdev)
-+{
-+   int  rc = 0;
-+
-+   do {
-+      unsigned long lock_flags;
-+
-+      printk(KERN_DEBUG "Fan probe\n");
-+
-+      memset(&fan_state, sizeof(fan_state), 0);
-+
-+      /* Setup the fan-control GPIO lines properly. */
-+      spin_lock_irqsave(&oxnas_gpio_spinlock, lock_flags);
-+
-+      do {
-+         /* Enable desired GPIO drivers by disabling other functions. */
-+         CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, FAN_MASK);
-+         CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0,  FAN_MASK);
-+         CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, FAN_MASK);
-+
-+         /* Turn off the fan... then enable its outputs. */
-+         writel(FAN_MASK, GPIO_A_OUTPUT_CLEAR);
-+         writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+      } while (0);
-+
-+      spin_unlock_irqrestore(&oxnas_gpio_spinlock, lock_flags);
-+
-+
-+      /* Create an entry in sysfs so user apps can control the fan. */
-+      rc = device_create_file(&pdev->dev, &dev_attr_speed);
-+      if (rc < 0)  break;
-+
-+      fans_found++;
-+
-+      set_fan_speed(FAN_OFF);
-+
-+   } while(0);
-+
-+
-+   /* Cleanup if any errors occured. */
-+   if(rc < 0)
-+   {
-+      fan_remove(pdev);
-+   }
-+
-+   return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: fan_remove                                                    */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Deactive the fan device(s)                                            */
-+/***************************************************************************/
-+int fan_remove(struct platform_device *pdev)
-+{
-+   printk(KERN_DEBUG "Fan remove\n");
-+
-+   /* Undo everything that might have been done by  fan_probe() */
-+
-+   device_remove_file(&pdev->dev, &dev_attr_speed);
-+
-+   writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+
-+   return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/*                                                                         */
-+/* sysfs attribute I/O - user-space control points                         */
-+/*                                                                         */
-+/***************************************************************************/
-+
-+/* fan_speed_show()
-+ *
-+ * Called when the speed setting attribute is read;
-+ * returns the current fan speed.
-+ */
-+ssize_t fan_speed_show(struct device *dev, struct device_attribute *attr,
-+                       char *buf)
-+{
-+   /* TODO: Check sizeof  buf?  Nobody else does*/
-+
-+	return  sprintf(buf, "%u\n", fan_state.speed);
-+}
-+
-+/* fan_speed_store()
-+ *
-+ * Called when the speed setting attribute is written;
-+ * sets a new fan speed.
-+ */
-+ssize_t fan_speed_store(struct device *dev, struct device_attribute *attr,
-+                        const char *buf, size_t count)
-+{
-+   char *end;
-+   long newSpeed;
-+
-+   newSpeed = simple_strtol(buf, &end, 10);
-+   while (*end)
-+   {
-+      if (!isspace(*end++))  return -EINVAL;
-+   }
-+
-+   if (newSpeed < 0)  newSpeed = 0;
-+   if (newSpeed > FAN_SPEED_MAX)  newSpeed = FAN_SPEED_MAX;
-+
-+   set_fan_speed( (unsigned char)newSpeed );
-+
-+   return count;              /* Entire string was consumed and validated. */
-+}
-+
-+/* set_fan_speed()
-+ *
-+ * Sets the fan's speed by twiddling its power control (GPO) lines.
-+ */
-+void set_fan_speed(unsigned char newSpeed)
-+{
-+int oldSpeed = fan_state.speed;
-+
-+   /* Round the requested fan speed to the nearest supported
-+      value and set the fan's power lines appropriately. */
-+
-+   /* The 2NC platform has three fan settings: off, low, hi-speed. */
-+
-+   if (newSpeed < 10)
-+   {
-+      fan_state.speed = FAN_OFF;       /* Turn off the fan. */
-+      writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
-+   }
-+   else if (newSpeed < 75)
-+   {
-+      fan_state.speed = 50;            /* Set to low speed. */
-+      writel(FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
-+      writel(FAN_MASK_LOW,  GPIO_A_OUTPUT_SET);
-+   }
-+   else
-+   {
-+      fan_state.speed = FAN_SPEED_MAX; /* Set to max (high) speed. */
-+      writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_SET);
-+   }
-+
-+   if (oldSpeed != fan_state.speed)
-+   {
-+#if 0
-+      printk(KERN_DEBUG "WDC Fan speed set %u\n", fan_state.speed);
-+#endif
-+   }
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_driver                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds platform device driver                          */
-+/***************************************************************************/
-+static struct platform_driver fan_driver =
-+{
-+   .probe    = fan_probe,
-+   .remove   = fan_remove,
-+   .driver   =
-+   {
-+      .name  = "wdc-fan",
-+   },
-+};
-+
-+static struct platform_device *fan_device;
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_init                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module initialization                                         */
-+/***************************************************************************/
-+static int __init wdc_fan_init(void)
-+{
-+   int rc = 0;
-+
-+   fans_found = 0;
-+   spin_lock_init(&oxnas_gpio_spinlock);
-+
-+   rc = platform_driver_register(&fan_driver);
-+   if (rc)  goto quit;
-+
-+   fan_device = platform_device_register_simple("wdc-fan", -1, NULL, 0);
-+   if (IS_ERR(fan_device))
-+   {
-+      rc = PTR_ERR(fan_device);
-+      fan_device = NULL;
-+
-+      platform_driver_unregister(&fan_driver);
-+      goto quit;
-+   }
-+
-+
-+quit:
-+   if (rc)
-+   {
-+      printk(KERN_ERR  DRIVER_NAME " init failed, rc=%i\n", rc);
-+   }
-+   else
-+   {
-+      printk(KERN_INFO DRIVER_NAME " initialized\n");
-+   }
-+
-+   return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_exit                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module unloading and cleanup                                  */
-+/***************************************************************************/
-+static void __exit wdc_fan_exit(void)
-+{
-+   platform_device_unregister(fan_device);
-+   platform_driver_unregister(&fan_driver);
-+
-+   printk(KERN_INFO DRIVER_NAME " goodbye!\n");
-+}
-+
-+
-+module_init(wdc_fan_init);
-+module_exit(wdc_fan_exit);
-+
-+MODULE_AUTHOR("James Lin");
-+MODULE_DESCRIPTION("Western Digital NetCenter/2NC Fan Control");
-+MODULE_LICENSE("GPL");
-+
-+/*EOF*/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1299 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-leds.c
-+ *
-+ * Copyright (C) 2006 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/leds.h>
-+#include <asm/hardware.h>
-+
-+#define DEBUG
-+
-+#ifdef DEBUG
-+   #define DUMP(A,B)  printk(KERN_INFO A,B);
-+#else
-+    #define DUMP(A,B)
-+#endif
-+
-+/* Number of LEDs */
-+#define NUM_ACTIVITY_LEDS   4
-+#define NUM_FUEL_GAUGE_LEDS 6
-+
-+/* Timer Values and Pulse Width Modulation */
-+#define PWM_RESOLUTION  255
-+#define TIMER_LED_MODE  TIMER_MODE_PERIODIC
-+
-+#define PWM_CLOCK_DATA (
-+
-+#define LED100  (PWM_RESOLUTION)        /* 100% duty cycle */
-+#define LED50   (PWM_RESOLUTION / 2)    /* 50%  duty cycle */
-+#define LED25   (PWM_RESOLUTION / 4)    /* 25%  duty cycle */
-+
-+#define STEP_RESOLUTION (16)                /* change intensity in 16 steps */
-+
-+/* Setup Timer2 prescaler, operation mode, and start it */
-+#define PERIODIC_INTERRUPT                          \
-+   (                                                \
-+      (TIMER_PRESCALE_256   << TIMER_PRESCALE_BIT) | \
-+      (TIMER_LED_MODE      << TIMER_MODE_BIT)     | \
-+      (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT)     \
-+   )
-+
-+/*
-+ * Target frame rate is 60Hz.  Slower frame rates flicker badly.
-+ * Since each frame has 16 divisions to perform the pulse width
-+ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
-+ *
-+ * With a system clock of 25Mhz and a load register value of 1627 prescaled 256 
-+ * to achieve 60Hz:
-+ *   25Mhz / 256 / 1627 = ~60
-+ */
-+#define FAST_TIMER_INT      (1627)      /* Timer2 count down      */
-+#define SYS_CLOCK       (25000000)      /* System clock frequency */
-+#define PRESCALE_VALUE        (256)      /* Value set in prescaler */
-+#define PWM_PRESCALE       814  /* Value loaded on PWM clock register */
-+#define MAX_PWM   255
-+#define SLOW_TPS   ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT)
-+
-+/* The GPIO assignent to LED Masks need to make sure that the 
-+ * LED_MASK_GPIO_A and LED_MASK_GPIO_B are set appropriately 
-+ * based on the GPIOs assigned
-+ */
-+
-+/* GPIO bits dedicated to LEDs */
-+#define LED_MASK_ACT12 (1 << GPIO_6)    /* Activity 12 o'clock   */
-+#define LED_MASK_ACT3  (1 << GPIO_7)    /* Activity 3 o'clock    */
-+#define LED_MASK_ACT6  (1 << GPIO_5)    /* Activity 6 o'clock    */
-+#define LED_MASK_ACT9  (1 << GPIO_34)   /* Activity 9 o'clock    */
-+#define LED_MASK_FG12  (1 << GPIO_10)   /* Fuel Gauge 10 o'clock */
-+#define LED_MASK_FG2   (1 << GPIO_9)    /* Fuel Gauge 8 o'clock  */
-+#define LED_MASK_FG4   (1 << GPIO_25)   /* Fuel Gauge 6 o'clock  */
-+#define LED_MASK_FG6   (1 << GPIO_26)   /* Fuel Gauge 4 o'clock  */
-+#define LED_MASK_FG8   (1 << GPIO_27)   /* Fuel Gauge 2 o'clock  */
-+#define LED_MASK_FG10  (1 << GPIO_33)   /* Fuel Gauge 12 o'clock */
-+
-+/*
-+ * Mask for all the LEDs in the Fuel Gauge.  This is in frame buffer format
-+ * (see LED frame buffer design assumption comments below, near the
-+ * frame_buffer declaration).
-+ */
-+#define LED_MASK_FUEL_GAUGE \
-+   (                        \
-+      LED_MASK_FG12 |       \
-+      LED_MASK_FG2  |       \
-+      LED_MASK_FG4  |       \
-+      LED_MASK_FG6  |       \
-+      LED_MASK_FG8  |       \
-+      LED_MASK_FG10         \
-+   )
-+
-+/* Mask for all the Activity LEDs */
-+#define LED_MASK_ACTIVITY \
-+   (                      \
-+      LED_MASK_ACT12 |    \
-+      LED_MASK_ACT3  |    \
-+      LED_MASK_ACT6  |    \
-+      LED_MASK_ACT9       \
-+   )
-+
-+/* The GPIO_A and GPIO_B Masks below need to be set based on the 
-+ * GPIO numbers that are assigned for the LED MASKS
-+ */
-+
-+/* Mask for all the LEDs on GPIO_A */
-+#define LED_MASK_GPIO_A \
-+   (                    \
-+      LED_MASK_ACT12 |  \
-+      LED_MASK_ACT3  |  \
-+      LED_MASK_ACT6  |  \
-+      LED_MASK_FG12  |  \
-+      LED_MASK_FG2   |  \
-+      LED_MASK_FG4   |  \
-+      LED_MASK_FG6   |  \
-+      LED_MASK_FG8      \
-+   )
-+
-+/* Mask for all the LEDs on GPIO_B */
-+#define LED_MASK_GPIO_B \
-+   (                    \
-+      LED_MASK_ACT9  |  \
-+      LED_MASK_FG10     \
-+   )
-+
-+/* I/O register access (FIXME: why not use the standard linux macros?) */
-+#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
-+#define ox_readl(addr)        (*(volatile unsigned long*)addr)
-+#define writel(data, addr)    (*(volatile u32*)addr = (data))
-+#define readl(addr)           (*(volatile u32*)addr)
-+#define CLEAR(addr, mask)     writel(readl(addr) & ~mask, addr)
-+
-+
-+/* Variables to hold the number of LED classes created */
-+static int leds_created;
-+
-+/* Variables to save/restore timer register values */
-+static u32 timer_load;
-+static u32 timer_control;
-+
-+/* LED polarity */
-+static int negative_led_logic = 0;
-+module_param(negative_led_logic, bool, 0);
-+
-+/*
-+ * States for the main LED behavior state machine.  The order of these states
-+ * is important.  In particular, the TRANS states use this ordering so that
-+ * incrementing the state variable walks through the ordering shown below.
-+ * This allows most of the TRANS states to share common code.
-+ */
-+enum {
-+    FULLY_ON__ENTRY,            /* FullyOn    - Initialize                       */
-+    FULLY_ON__RE_ENTRY,         /* FullyOn    - Initialize (skipping POR)        */
-+    FULLY_ON__POR_RAMP_UP,      /* FullyOn    - Ramp up full ring                */
-+    FULLY_ON__POR_HOLD,         /* FullyOn    - Hold a while with full ring      */
-+    FULLY_ON__RAMP_UP,          /* FullyOn    - Ramp up full ring (skipping POR) */
-+    FULLY_ON__ACTIVITY,         /* FullyOn    - Read/write activity              */
-+    FULLY_ON__IDLE_HOLD,        /* FullyOn    - Hold a while for no R/W activity */
-+    FULLY_ON__RAMP_DOWN,        /* FullyOn    - Ramp down full ring              */
-+    STANDBY__ENTRY,             /* Standby    - Initialize                       */
-+    STANDBY__DARK,              /* Standby    - Full ring off                    */
-+    STANDBY__RAMP_UP,           /* Standby    - Ramp up full ring                */
-+    STANDBY__RAMP_DOWN,         /* Standby    - Ramp down full ring              */
-+    POWER_OFF__ENTRY,           /* PowerOff   - Initialize                       */
-+    POWER_OFF__DARK,            /* PowerOff   - Full ring off                    */
-+    DEGRADED__ENTRY,            /* Degraded   - Initialize                       */
-+    DEGRADED__BLINK1,           /* Degraded   - Blink step1                      */
-+    DEGRADED__BLINK2,           /* Degraded   - Blink step2                      */
-+    OVERTEMP__ENTRY,            /* OverTemp   - Initialize                       */
-+    OVERTEMP__BLINK1,           /* OverTemp   - Blink step1                      */
-+    OVERTEMP__BLINK2,           /* OverTemp   - Blink step2                      */
-+    TRANS__ENTRY,               /* Transition - Initialize                       */
-+    TRANS__1_UP,                /* 1st cycle  - up   12 & 6 - down 9 & 3 o'clock */
-+    TRANS__1_DN,                /* 1st cycle  - down 12 & 6 - up   9 & 3 o'clock */
-+    TRANS__2_UP,                /* 2nd cycle  - up   12 & 6 - down 9 & 3 o'clock */
-+    TRANS__2_DN,                /* 2nd cycle  - down 12 & 6 - up   9 & 3 o'clock */
-+    TRANS__3_UP,                /* 3rd cycle  - up   12 & 6 - down 9 & 3 o'clock */
-+    TRANS__3_DN,                /* 3rd cycle  - down 12 & 6 - up   9 & 3 o'clock */
-+    TRANS__4_UP,                /* 4th cycle  - up   12 & 6 - down 9 & 3 o'clock */
-+    TRANS__4_DN                 /* 4th cycle  - down 12 & 6 - down 9 & 3 o'clock */
-+};
-+
-+
-+/* Pattern for the activity behavior */
-+const u16 activity_pattern[NUM_ACTIVITY_LEDS] = {
-+    LED100,
-+    LED25,
-+    0,
-+    0
-+};
-+
-+
-+/* Various LED state machine constants */
-+#define TRANS_STEP           (1)
-+#define SLEEP_HI             (0)
-+#define SLEEP_LO             (-STEP_RESOLUTION)
-+#define NUM_POWER_STEPS      (STEP_RESOLUTION)
-+#define NUM_BREATHE_STEPS    (SLEEP_HI - SLEEP_LO)
-+#define NUM_TRANS_STEPS      ((SLEEP_HI - SLEEP_LO) / TRANS_STEP)
-+#define BIT_MASK_FUEL_GAUGE  ((1 << NUM_FUEL_GAUGE_LEDS) - 1)
-+
-+/*
-+ * Calculate various speeds of the LED state machine based on the system 
-+ * clock frequency, the hardware timer prescaler, and the hardware timer
-+ * load register value.  This results in a calculation of the ticks per
-+ * second (TPS) of the timer interrupt used to perform the pulse width
-+ * modulation and the slower TPS of the tasklet that performs the main
-+ * state machine of the LED behavior.  The remaining speeds are
-+ * calculated from the slow TPS.
-+ */
-+ #define RW_SPEED       (SLOW_TPS / 4)   /* want ~4Hz   */
-+#define BLINK_SPEED    (SLOW_TPS / 2)   /* want ~2Hz   */
-+#define HOLD_BREATH    (SLOW_TPS * 4)   /* want ~4sec  */
-+#define HOLD_ON_ENTER  (SLOW_TPS * 10)  /* want ~10sec */
-+#define POWER_SPEED    (SLOW_TPS / NUM_POWER_STEPS)
-+#define BREATHE_SPEED  (SLOW_TPS / NUM_BREATHE_STEPS)
-+#define TRANS_SPEED    (SLOW_TPS / NUM_TRANS_STEPS)
-+
-+#if \
-+   (!SLOW_TPS)      || \
-+   (!RW_SPEED)      || \
-+   (!BLINK_SPEED)   || \
-+   (!POWER_SPEED)   || \
-+   (!BREATHE_SPEED) || \
-+   (!TRANS_SPEED)
-+#   error TPS calculation(s) resulted in zero!
-+#endif
-+
-+
-+/* Variables for main LED behavior state machine */
-+static int state;
-+static int next_state;
-+static int active_count;
-+static int count;
-+static u32 fuel_gauge_bits;     /* see LED frame buffer design assumption */
-+static u8 need_to_display_current_fuel_gauge;
-+static u8 inner_ring_rotate;
-+static u8 ignore_activity;
-+static s8 active_tail;
-+static s8 ramp1;
-+static s8 ramp2;
-+static s8 activity_led[NUM_ACTIVITY_LEDS];
-+static u16 rebuild_percentage;  /* 0=not rebuilding */
-+
-+
-+/*
-+ * Declare tasklet for the LED behavior state machine.  The interrupt will
-+ * only handle the pulse width modulation which can be performed quickly.
-+ * The slower LED behavior state machine does not need to execute at such
-+ * a high frequency so it will be executed by a tasklet that is
-+ * periodically scheduled by the interrupt.
-+ */
-+void wdc_leds_behavior(unsigned long);
-+DECLARE_TASKLET(wdc_leds_behavior_tasklet, wdc_leds_behavior, 0);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_interrupt                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Interrupt handler for the wdc-leds pulse width modulation             */
-+/***************************************************************************/
-+static irqreturn_t wdc_leds_interrupt
-+    (int irq, void *dev_id) {
-+    ox_writel(0, TIMER2_CLEAR);
-+
-+
-+    tasklet_schedule(&wdc_leds_behavior_tasklet);
-+
-+    return IRQ_HANDLED;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_inner_ring_bits                                           */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Convert the bit map of inner ring LEDs into the GPIO bit map          */
-+/***************************************************************************/
-+static u32 get_inner_ring_bits(u16 value)
-+{
-+    u32 pattern = 0;
-+
-+    // Convert the bit map to the GPIO bit pattern
-+    if (value & (1 << 0))
-+        pattern |= LED_MASK_FG2;
-+    if (value & (1 << 1))
-+        pattern |= LED_MASK_FG4;
-+    if (value & (1 << 2))
-+        pattern |= LED_MASK_FG6;
-+    if (value & (1 << 3))
-+        pattern |= LED_MASK_FG8;
-+    if (value & (1 << 4))
-+        pattern |= LED_MASK_FG10;
-+    if (value & (1 << 5))
-+        pattern |= LED_MASK_FG12;
-+
-+    return pattern;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_percentage_pattern                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Convert a percentage to a inner ring bit map.  Note, we never display */
-+/*   less than 1 LED for a percentage so that something is alway visible.  */
-+/***************************************************************************/
-+static u16 get_percentage_pattern(u16 percentage)
-+{
-+    if (percentage >= 50) {
-+        if (percentage >= 67) {
-+            if (percentage >= 83) {
-+                if (percentage >= 97) {
-+                    return 0x3F;        // 6 LEDs is >= 97%
-+                } else {
-+                    return 0x1F;        // 5 LEDs is >=  83%
-+                }
-+            } else {
-+                return 0x0F;    // 4 LEDs is >=  67%
-+            }
-+        } else {
-+            return 0x07;        // 3 LEDs is >=  50%
-+        }
-+    } else {
-+        if (percentage >= 33) {
-+            return 0x03;        // 2 LEDs is >=  33%
-+        } else {
-+            return 0x01;        // 1 LED  is >=   0%
-+        }
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: set_led                                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set frame buffer for the requested brightness on the requested LED(s) */
-+/***************************************************************************/
-+static void set_led(u32 led_bits, s8 value)
-+{
-+    u32 bit;
-+    s8 count = 0;
-+
-+    if (negative_led_logic) {
-+        value = MAX_PWM - value;
-+    }
-+
-+    for (bit = 1; bit > 0; bit <<= 1, ++count) {
-+        if (bit & led_bits) writel(value, ((u32 *)PWM_DATA_REGISTER_BASE + count ));
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_inner_ring                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set frame buffer for the requested inner ring bit map                 */
-+/***************************************************************************/
-+static void display_inner_ring(u32 inner_ring_bits)
-+{
-+    set_led(~inner_ring_bits & LED_MASK_FUEL_GAUGE, 0);
-+    set_led(inner_ring_bits, LED100);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_current_fuel_gauge                                    */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Display the current Fuel Gauge if it is not already being displayed   */
-+/***************************************************************************/
-+static void display_current_fuel_gauge(void)
-+{
-+    if (need_to_display_current_fuel_gauge) {
-+        display_inner_ring(fuel_gauge_bits);
-+        need_to_display_current_fuel_gauge = 0;
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: handle_inner_ring                                             */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform the LED behavior for the inner ring                           */
-+/***************************************************************************/
-+static void handle_inner_ring(void)
-+{
-+    /* If currently rebuilding then display the rebuild percentage as */
-+    /* a series of LEDs representing the percentage complete rotating */
-+    /* around the inner ring.  Note, the percentage is rotated to     */
-+    /* distinguish it from normal fuel gauge behavior.                */
-+    if (rebuild_percentage) {
-+        /* Convert the rebuild percentage into a bit map of LEDs */
-+        u32 rotated_pattern = get_percentage_pattern(rebuild_percentage);
-+        /* Now rotate that pattern */
-+        rotated_pattern <<= inner_ring_rotate;
-+        rotated_pattern |= (rotated_pattern >> NUM_FUEL_GAUGE_LEDS);
-+        rotated_pattern &= BIT_MASK_FUEL_GAUGE;
-+        /* Now display the rotated pattern on the inner ring */
-+        display_inner_ring(get_inner_ring_bits(rotated_pattern));
-+        if (++inner_ring_rotate >= NUM_FUEL_GAUGE_LEDS) {
-+            inner_ring_rotate = 0;
-+        }
-+
-+        need_to_display_current_fuel_gauge = 1;
-+    }
-+
-+    /* Otherwise not rebuilding so just display normal fuel gauge */
-+    else {
-+        display_current_fuel_gauge();
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_next_state_from_fully_on                                  */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Movement to STANDBY or POWER_OFF requires TRANSITION behavior;        */
-+/*   Otherwise just jump to next_state                                     */
-+/***************************************************************************/
-+static int get_next_state_from_fully_on(void)
-+{
-+    switch (next_state) {
-+    case STANDBY__ENTRY:
-+    case POWER_OFF__ENTRY:
-+        return TRANS__ENTRY;
-+    default:
-+        return next_state;
-+    }
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_behavior_init                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Initialization for LED behavior main state machine                    */
-+/***************************************************************************/
-+void wdc_leds_behavior_init(void)
-+{
-+    /* State machine variables */
-+    state = FULLY_ON__ENTRY;
-+    next_state = FULLY_ON__ENTRY;
-+    /* Outer ring variables */
-+    active_count = 0;
-+    count = 0;
-+    ignore_activity = 0;
-+    active_tail = NUM_ACTIVITY_LEDS - 1;
-+    ramp1 = 0;
-+    ramp2 = 0;
-+    activity_led[0] = 0;
-+    activity_led[1] = 0;
-+    activity_led[2] = 0;
-+    activity_led[3] = 0;
-+    /* Inner ring variables */
-+    inner_ring_rotate = 0;
-+    rebuild_percentage = 0;
-+    fuel_gauge_bits = 0;
-+    need_to_display_current_fuel_gauge = 1;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_behavior                                             */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   LED behavior main state machine                                       */
-+/***************************************************************************/
-+void wdc_leds_behavior(unsigned long unused)
-+{
-+    static u8 been_there_done_that = 0;
-+    s8 j, k;
-+    switch (state) {
-+    case FULLY_ON__ENTRY:
-+    case FULLY_ON__RE_ENTRY:
-+        inner_ring_rotate = 0;
-+        need_to_display_current_fuel_gauge = 1;
-+        activity_led[0] = LED100;
-+        activity_led[1] = LED100;
-+        activity_led[2] = LED100;
-+        activity_led[3] = LED100;
-+        ramp1 = -STEP_RESOLUTION;
-+        ramp2 = -STEP_RESOLUTION;
-+        if (state == FULLY_ON__RE_ENTRY) {
-+            /* Don't go through the POR hold period for a re-entry */
-+            count = 0;
-+            state = FULLY_ON__RAMP_UP;
-+            break;
-+        }
-+        count = 0;
-+        state = FULLY_ON__POR_RAMP_UP;
-+        /* Fall through */
-+    case FULLY_ON__POR_RAMP_UP:
-+        if (--count > 0)
-+            break;
-+        count = POWER_SPEED;
-+        ++ramp2;
-+        if (++ramp1 < 0)
-+            break;
-+        count = HOLD_ON_ENTER;
-+        state = FULLY_ON__POR_HOLD;
-+        break;
-+    case FULLY_ON__POR_HOLD:
-+        display_current_fuel_gauge();
-+        if (--count > 0)
-+            break;
-+        active_count = 0;
-+        count = 0;
-+        state = FULLY_ON__RAMP_UP;
-+        break;
-+    case FULLY_ON__RAMP_UP:
-+        if (next_state != FULLY_ON__ENTRY) {
-+            state = get_next_state_from_fully_on();
-+            break;
-+        }
-+
-+        display_current_fuel_gauge();
-+        if (--count > 0)
-+            break;
-+        count = POWER_SPEED;
-+        ++ramp2;
-+        if (++ramp1 >= 0) {
-+            ramp1 = 0;
-+            ramp2 = 0;
-+        }
-+        if (active_count == 0) {
-+            activity_led[0] = LED100;
-+            activity_led[1] = LED100;
-+            activity_led[2] = LED100;
-+            activity_led[3] = LED100;
-+            break;
-+        }
-+
-+        activity_led[0] = 0;
-+        activity_led[1] = 0;
-+        activity_led[2] = 0;
-+        activity_led[3] = 0;
-+        count = 0;
-+        ramp1 = 0;
-+        ramp2 = 0;
-+        state = FULLY_ON__ACTIVITY;
-+        /* Fall through */
-+    case FULLY_ON__ACTIVITY:
-+        if (next_state != FULLY_ON__ENTRY) {
-+            state = get_next_state_from_fully_on();
-+            break;
-+        }
-+
-+        if (--count > 0)
-+            break;
-+        count = RW_SPEED;
-+        handle_inner_ring();
-+        if (active_count) {
-+            j = active_tail =
-+                ((active_tail >
-+                  0) ? (active_tail - 1) : (NUM_ACTIVITY_LEDS - 1)
-+                );
-+            k = NUM_ACTIVITY_LEDS;
-+            while (k--) {
-+                activity_led[j] = activity_pattern[k];
-+                j = ((j > 0) ? (j - 1) : (NUM_ACTIVITY_LEDS - 1));
-+            }
-+            ramp1 = 0;
-+            ramp2 = 0;
-+        }
-+        if (active_count == 0) {
-+            count = RW_SPEED;
-+            state = FULLY_ON__IDLE_HOLD;
-+        }
-+        active_count = 0;
-+        break;
-+    case FULLY_ON__IDLE_HOLD:
-+        if (--count > 0)
-+            break;
-+        count = 0;
-+        state = FULLY_ON__RAMP_DOWN;
-+        break;
-+    case FULLY_ON__RAMP_DOWN:
-+        if (--count > 0)
-+            break;
-+        count = POWER_SPEED;
-+        --ramp2;
-+        if ((--ramp1 <= -STEP_RESOLUTION) || active_count) {
-+            display_current_fuel_gauge();
-+            ramp1 = -STEP_RESOLUTION;
-+            ramp2 = -STEP_RESOLUTION;
-+            state = FULLY_ON__RAMP_UP;
-+        }
-+        break;
-+    case STANDBY__ENTRY:
-+        activity_led[0] = LED100;
-+        activity_led[1] = LED100;
-+        activity_led[2] = LED100;
-+        activity_led[3] = LED100;
-+        ramp1 = -STEP_RESOLUTION;
-+        ramp2 = -STEP_RESOLUTION;
-+        count = HOLD_BREATH;
-+        state = STANDBY__DARK;
-+        display_current_fuel_gauge();
-+        /* Fall through */
-+    case STANDBY__DARK:
-+        if (next_state != STANDBY__ENTRY) {
-+            state = next_state;
-+            break;
-+        }
-+
-+        if (--count > 0)
-+            break;
-+        state = STANDBY__RAMP_UP;
-+        break;
-+    case STANDBY__RAMP_UP:
-+        ramp2++;
-+        ramp1++;
-+        if (ramp1 < SLEEP_HI)
-+            break;
-+        state = STANDBY__RAMP_DOWN;
-+        break;
-+    case STANDBY__RAMP_DOWN:
-+        ramp2--;
-+        if (ramp1-- > -STEP_RESOLUTION)
-+            break;
-+        state = STANDBY__ENTRY;
-+        break;
-+    case POWER_OFF__ENTRY:
-+        display_inner_ring(0x00);
-+        activity_led[0] = 0;
-+        activity_led[1] = 0;
-+        activity_led[2] = 0;
-+        activity_led[3] = 0;
-+        ramp1 = 0;
-+        ramp2 = 0;
-+        state = POWER_OFF__DARK;
-+        /* Fall through */
-+    case POWER_OFF__DARK:
-+        if (next_state != POWER_OFF__ENTRY) {
-+            state = next_state;
-+            break;
-+        }
-+        break;
-+    case DEGRADED__ENTRY:
-+        display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
-+        ramp1 = 0;
-+        ramp2 = 0;
-+        activity_led[0] = 0;
-+        activity_led[1] = 0;
-+        activity_led[2] = 0;
-+        activity_led[3] = 0;
-+        count = BLINK_SPEED;
-+        state = DEGRADED__BLINK1;
-+        /* Fall through */
-+    case DEGRADED__BLINK1:
-+        if (next_state != DEGRADED__ENTRY) {
-+            display_inner_ring(0);
-+            state = TRANS__ENTRY;
-+            break;
-+        }
-+
-+        if (--count > 0)
-+            break;
-+        display_inner_ring(0);
-+        activity_led[0] = LED100;
-+        activity_led[1] = LED100;
-+        activity_led[2] = LED100;
-+        activity_led[3] = LED100;
-+        count = BLINK_SPEED;
-+        state = DEGRADED__BLINK2;
-+        break;
-+    case DEGRADED__BLINK2:
-+        if (--count > 0)
-+            break;
-+        state = DEGRADED__ENTRY;
-+        break;
-+    case OVERTEMP__ENTRY:
-+        display_inner_ring(0);
-+        ramp1 = 0;
-+        ramp2 = 0;
-+        activity_led[0] = 0;
-+        activity_led[1] = 0;
-+        activity_led[2] = 0;
-+        activity_led[3] = 0;
-+        count = BLINK_SPEED;
-+        state = OVERTEMP__BLINK1;
-+        /* Fall through */
-+    case OVERTEMP__BLINK1:
-+        if (next_state != OVERTEMP__ENTRY) {
-+            display_inner_ring(0);
-+            state = TRANS__ENTRY;
-+            break;
-+        }
-+
-+        if (--count > 0)
-+            break;
-+        display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
-+        activity_led[0] = LED100;
-+        activity_led[1] = LED100;
-+        activity_led[2] = LED100;
-+        activity_led[3] = LED100;
-+        count = BLINK_SPEED;
-+        state = OVERTEMP__BLINK2;
-+        break;
-+    case OVERTEMP__BLINK2:
-+        if (--count > 0)
-+            break;
-+        state = OVERTEMP__ENTRY;
-+        break;
-+    case TRANS__ENTRY:
-+        activity_led[0] = LED100;
-+        activity_led[1] = LED100;
-+        activity_led[2] = LED100;
-+        activity_led[3] = LED100;
-+        ramp1 = SLEEP_LO;
-+        ramp2 = SLEEP_HI;
-+        state = TRANS__1_UP;
-+        /* Fall through */
-+    case TRANS__1_UP:
-+    case TRANS__2_UP:
-+    case TRANS__3_UP:
-+    case TRANS__4_UP:
-+        ramp2 -= TRANS_STEP;
-+        ramp1 += TRANS_STEP;
-+        if ((ramp1 - TRANS_STEP) < SLEEP_HI)
-+            break;
-+        state++;
-+        break;
-+    case TRANS__4_DN:
-+        if (ramp1 <= -STEP_RESOLUTION) {
-+            if (next_state == TRANS__ENTRY) {
-+                /*
-+                 * If no one told us where to go then just go to FullyOn, but
-+                 * don't go through the POR hold period because that makes
-+                 * the next transition display for the next button press wait
-+                 * too long.
-+                 *
-+                 * Note, that next_state needs to be set to FULLY_ON__ENTRY
-+                 * because it is used for the test whether or not to leave
-+                 * the FullyOn state even though we are entering FullyOn
-+                 * through the re-entry path.
-+                 */
-+                next_state = FULLY_ON__ENTRY;
-+                state = FULLY_ON__RE_ENTRY;
-+            } else {
-+                state = next_state;
-+            }
-+            break;
-+        }
-+        ramp2 -= TRANS_STEP;
-+        /* Fall through */
-+    case TRANS__1_DN:
-+    case TRANS__2_DN:
-+    case TRANS__3_DN:
-+        ramp2 += TRANS_STEP;
-+        ramp1 -= TRANS_STEP;
-+        if ((ramp1 + TRANS_STEP) > -STEP_RESOLUTION)
-+            break;
-+        ramp1 = SLEEP_LO;
-+        ramp2 = SLEEP_HI;
-+        state++;
-+        break;
-+    default:
-+        if (!been_there_done_that) {
-+            printk(KERN_ERR "Invalid LED behavior state\n");
-+            been_there_done_that = 1;
-+            return;
-+        }
-+    }
-+
-+    /* Set the activity brightness according to value and ramp */
-+    set_led(LED_MASK_ACT12, activity_led[0] + ramp1);
-+    set_led(LED_MASK_ACT9, activity_led[1] + ramp2);
-+    set_led(LED_MASK_ACT6, activity_led[2] + ramp1);
-+    set_led(LED_MASK_ACT3, activity_led[3] + ramp2);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_power                                            */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the "power" LED to the requested behavior                         */
-+/***************************************************************************/
-+static void wdc_leds_set_power
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    if (value >= 255) {
-+        next_state = FULLY_ON__ENTRY;
-+    } else if (value > 0) {
-+        next_state = STANDBY__ENTRY;
-+    } else {
-+        next_state = POWER_OFF__ENTRY;
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_activity                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Trigger activity display behavior                                     */
-+/***************************************************************************/
-+static void wdc_leds_set_activity
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    if (!ignore_activity && (value > 0)) {
-+        active_count++;
-+    }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_ignore_activity                                  */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the "ignore activity" setting                                     */
-+/***************************************************************************/
-+static void wdc_leds_set_ignore_activity
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    ignore_activity = value;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_transition                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Trigger "transition" display behavior                                 */
-+/***************************************************************************/
-+static void wdc_leds_set_transition
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    next_state = ((value > 0) ? TRANS__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_fuel_gauge                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the fuel gauge to the requested value (treated as a percentage)   */
-+/***************************************************************************/
-+static void wdc_leds_set_fuel_gauge
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    fuel_gauge_bits = get_inner_ring_bits(get_percentage_pattern(value));
-+    need_to_display_current_fuel_gauge = 1;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_fg_bitmap                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the fuel gauge to the requested value (treated as a bitmap)       */
-+/***************************************************************************/
-+static void wdc_leds_set_fg_bitmap
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    fuel_gauge_bits = get_inner_ring_bits((u16) value);
-+    need_to_display_current_fuel_gauge = 1;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_rebuilding                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the rebuilding behavior (value = % complete, 0 = not rebuilding)  */
-+/***************************************************************************/
-+static void wdc_leds_set_rebuilding
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    rebuild_percentage = value;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_degraded                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the degraded mode display behavior                                */
-+/***************************************************************************/
-+static void wdc_leds_set_degraded
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    next_state = ((value > 0) ? DEGRADED__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_over_temp                                        */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Set the over temperature mode display behavior                        */
-+/***************************************************************************/
-+static void wdc_leds_set_over_temp
-+    (struct led_classdev *led_cdev, enum led_brightness value) {
-+    next_state = ((value > 0) ? OVERTEMP__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_power                                          */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "power" pseudo-LED                              */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_power = {
-+    .name = "wdc-leds:power",.brightness_set = wdc_leds_set_power,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_activity                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "activity" pseudo-LED                           */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_activity = {
-+    .name = "wdc-leds:activity",.brightness_set =
-+        wdc_leds_set_activity,.default_trigger = "sata-disk"
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_ignore_activity                                */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "ignore-activity" pseudo-LED                    */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_ignore_activity = {
-+    .name = "wdc-leds:ignore-act",.brightness_set =
-+        wdc_leds_set_ignore_activity,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_transition                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "transition" pseudo-LED                         */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_transition = {
-+    .name = "wdc-leds:transition",.brightness_set =
-+        wdc_leds_set_transition,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_fuel_gauge                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "fuel-gauge" LEDs (brightness = % full)         */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_fuel_gauge = {
-+    .name = "wdc-leds:fuel-gauge",.brightness_set =
-+        wdc_leds_set_fuel_gauge,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_fg_bitmap                                      */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "fuel-gauge" LEDs (brightness = bitmap)         */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_fg_bitmap = {
-+    .name = "wdc-leds:fg-bitmap",.brightness_set = wdc_leds_set_fg_bitmap,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_rebuilding                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds RAID1 "rebuilding" mode pseudo-LED              */
-+/*   (brightness = % complete)                                             */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_rebuilding = {
-+    .name = "wdc-leds:rebuilding",.brightness_set =
-+        wdc_leds_set_rebuilding,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_degraded                                       */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "degraded" mode pseudo-LED                      */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_degraded = {
-+    .name = "wdc-leds:degraded",.brightness_set = wdc_leds_set_degraded,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_over_temp                                      */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds "over-temp" pseudo-LED                          */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_over_temp = {
-+    .name = "wdc-leds:over-temp",.brightness_set = wdc_leds_set_over_temp,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_classes[]                                      */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Array of LED classes to create/destroy                                */
-+/***************************************************************************/
-+static struct led_classdev *wdc_led_classes[] = {
-+    &wdc_leds_power,
-+    &wdc_leds_activity,
-+    &wdc_leds_ignore_activity,
-+    &wdc_leds_transition,
-+    &wdc_leds_fuel_gauge,
-+    &wdc_leds_fg_bitmap,
-+    &wdc_leds_rebuilding, 
-+    &wdc_leds_degraded, 
-+    &wdc_leds_over_temp
-+};
-+
-+#ifdef DEBUG
-+static ssize_t show_registers (struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+    char * out = buf;
-+    u32 clock_data = readl(PWM_CLOCK_REGISTER);
-+    u32 data_ptr = PWM_CLOCK_REGISTER;
-+    u8 no_pwms = (clock_data >> 16);
-+    u8 i;
-+    /* report hardware status here */
-+    out += sprintf(buf,"PWM drive registers\n");
-+    out += sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data, data_ptr); 
-+    
-+    for (i = 0; i < no_pwms; ++i)
-+    {
-+        data_ptr=(u32)((u32 *)PWM_BASE+i);
-+        out+= sprintf(out,"%d:%d @ 0x%08x\n", i, (u8)readl(data_ptr),data_ptr);
-+    }
-+    
-+    return out - buf;
-+}
-+
-+/* create a register 'file' to enbale reading back the pwm drive register status */
-+static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-+
-+static int create_debug_files(struct platform_device *pdev)
-+{
-+    struct device *dev = &pdev->dev;
-+    return device_create_file(dev, &dev_attr_registers);
-+}
-+
-+static void remove_debug_files(struct platform_device *pdev)
-+{
-+    struct device *dev = &pdev->dev;
-+    device_remove_file(dev, &dev_attr_registers);
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_PM
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_suspend                                              */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Suspend all LED class devices created by this driver                  */
-+/***************************************************************************/
-+static int wdc_leds_suspend(struct platform_device *pdev,
-+                            pm_message_t state)
-+{
-+    int n = leds_created;
-+    while (n > 0) {
-+        if (--n < ARRAY_SIZE(wdc_led_classes)) {
-+            led_classdev_suspend(wdc_led_classes[n]);
-+        }
-+    }
-+
-+return 0}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_resume                                               */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Wake up all LED class devices created by this driver                  */
-+/***************************************************************************/
-+static int wdc_leds_resume(struct platform_device *pdev,
-+                           pm_message_t state)
-+{
-+    int n = leds_created;
-+    while (n > 0) {
-+        if (--n < ARRAY_SIZE(wdc_led_classes)) {
-+            led_classdev_resume(wdc_led_classes[n]);
-+        }
-+    }
-+
-+return 0}
-+#endif                          /* CONFIG_PM */
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_probe                                                */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform any necessary probing and initial setup for wdc-leds device   */
-+/***************************************************************************/
-+static int wdc_leds_probe(struct platform_device *pdev)
-+{
-+    int rc;
-+    int timer_changed = 0;
-+    int interrupt_allocated = 0;
-+    leds_created = 0;
-+    do {
-+        /* Enable LED output drivers and disable other uses */
-+        CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
-+        CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
-+        CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
-+        
-+        CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
-+        CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
-+        CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
-+        /* Turn off all the LEDs */
-+        if (negative_led_logic) {
-+            writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+            writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+        } else {
-+            writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+            writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+        }
-+
-+        /* bring PWM module out of reset and enable clock */
-+        writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+        //writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
-+
-+        /* enable PWM clock */
-+        writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
-+
-+            /* Initialize frame buffer to everything off */
-+            set_led(LED_MASK_FUEL_GAUGE | LED_MASK_ACTIVITY, 0);
-+        /* Enable output to the LEDs */
-+        writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+        writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+        /* Initialize the LED behavior state machine */
-+        wdc_leds_behavior_init();
-+        /* Save Timer2 state for restoring later */
-+        timer_load = ox_readl(TIMER2_LOAD);
-+        timer_control = ox_readl(TIMER2_CONTROL);
-+        ox_writel(0, TIMER2_CONTROL);
-+        timer_changed = 1;
-+        /* Setup Timer2 for LED control */
-+        rc = request_irq
-+            (TIMER_2_INTERRUPT,
-+             wdc_leds_interrupt, 0, "led_pwm", 0);
-+        if (rc < 0) {
-+            printk(KERN_ERR "failed to get IRQ\n");
-+            break;
-+        }
-+
-+        interrupt_allocated = 1;
-+        ox_writel(FAST_TIMER_INT, TIMER2_LOAD);
-+        ox_writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
-+        /* Register each LED class device */
-+        while (leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+            rc = led_classdev_register(&pdev->dev,
-+                                       wdc_led_classes[leds_created]);
-+            if (rc < 0) {
-+                printk(KERN_ERR "failed to register led class \"%s\"\n",
-+                       wdc_led_classes[leds_created]->name);
-+                break;
-+            }
-+
-+            ++leds_created;
-+        }
-+    }
-+    while (0);
-+    /* If we failed then perform any needed clean up */
-+    if (rc < 0) {
-+        /* Unregister any classes we registered */
-+        while (leds_created > 0) {
-+            if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+                led_classdev_unregister(wdc_led_classes[leds_created]);
-+            }
-+        }
-+
-+        /* Free the interrupt if we allocated one */
-+        if (interrupt_allocated) {
-+            free_irq(TIMER_2_INTERRUPT, 0);
-+        }
-+
-+        /* Restore Timer2 if we changed it */
-+        if (timer_changed) {
-+            ox_writel(timer_load, TIMER2_LOAD);
-+            ox_writel(timer_control, TIMER2_CONTROL);
-+        }
-+    }
-+#ifdef DEBUG
-+    create_debug_files(pdev);
-+#endif    
-+    return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_remove                                               */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform steps to remove the wdc-leds device                           */
-+/***************************************************************************/
-+static int wdc_leds_remove(struct platform_device *pdev)
-+{
-+    while (leds_created > 0) {
-+        if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+            led_classdev_unregister(wdc_led_classes[leds_created]);
-+        }
-+    }
-+
-+    ox_writel(0, TIMER2_CONTROL);
-+    free_irq(TIMER_2_INTERRUPT, 0);
-+    ox_writel(timer_load, TIMER2_LOAD);
-+    ox_writel(timer_control, TIMER2_CONTROL);
-+    /* Turn off all the LEDs */
-+    if (negative_led_logic) {
-+        writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+        writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+    } else {
-+        writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+        writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+    }
-+    /* put PWM module back into  reset and disable clock */
-+    writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+    // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+#ifdef DEBUG
-+  remove_debug_files(pdev);
-+#endif
-+    return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_driver                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Describe the wdc-leds platform device driver                          */
-+/***************************************************************************/
-+static struct platform_driver wdc_leds_driver = {
-+    .probe = wdc_leds_probe,.remove = wdc_leds_remove,
-+#ifdef CONFIG_PM
-+    .suspend = wdc_leds_suspend,.resume = wdc_leds_resume,
-+#endif                          /* CONFIG_PM */
-+    .driver = {
-+               .name = "wdc-leds",},
-+};
-+
-+/* Pointer to device returned by platform_device_register_simple */
-+static struct platform_device *wdc_leds;
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_init                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module initialization                                         */
-+/***************************************************************************/
-+static int __init wdc_leds_init(void)
-+{
-+    int ret;
-+    printk
-+        (KERN_INFO "wdc-leds:  SLOW_TPS=%d\n",
-+         SLOW_TPS);
-+    ret = platform_driver_register(&wdc_leds_driver);
-+    if (!ret) {
-+        wdc_leds =
-+            platform_device_register_simple("wdc-leds", -1, NULL, 0);
-+    }
-+
-+    return ret;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_exit                                                 */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module unloading and cleanup                                  */
-+/***************************************************************************/
-+static void __exit wdc_leds_exit(void)
-+{
-+    if (wdc_leds) {
-+        platform_device_unregister(wdc_leds);
-+    }
-+    platform_driver_unregister(&wdc_leds_driver);
-+}
-+
-+
-+module_init(wdc_leds_init);
-+module_exit(wdc_leds_exit);
-+MODULE_AUTHOR("Michael Webster");
-+MODULE_DESCRIPTION("WDC 2NC LEDs");
-+MODULE_LICENSE("GPL");
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c	2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
-+ *
-+ * Copyright (C) 2006 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/leds.h>
-+
-+
-+DEFINE_LED_TRIGGER(wdc_ledtrig_sata);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_activity                                     */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Entry point to trip the trigger (called from within SATA driver)      */
-+/***************************************************************************/
-+void wdc_ledtrig_sata_activity(void)
-+{
-+   led_trigger_event(wdc_ledtrig_sata, LED_FULL);
-+}
-+EXPORT_SYMBOL(wdc_ledtrig_sata_activity);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_init                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module initialization                                         */
-+/***************************************************************************/
-+static int __init wdc_ledtrig_sata_init(void)
-+{
-+   printk("<1>Hello, LED trigger\n");
-+
-+   led_trigger_register_simple("sata-disk", &wdc_ledtrig_sata);
-+   return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_exit                                         */
-+/*                                                                         */
-+/* PURPOSE:                                                                */
-+/*   Perform module unloading and cleanup                                  */
-+/***************************************************************************/
-+static void __exit wdc_ledtrig_sata_exit(void)
-+{
-+   led_trigger_unregister_simple(wdc_ledtrig_sata);
-+
-+   printk("<1>Goodbye LED trigger\n");
-+}
-+
-+
-+module_init(wdc_ledtrig_sata_init);
-+module_exit(wdc_ledtrig_sata_exit);
-+
-+MODULE_AUTHOR("Michael Webster");
-+MODULE_DESCRIPTION("WDC 2NC LED trigger");
-+MODULE_LICENSE("GPL");
-+
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-pxa/clock.c linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c
---- linux-2.6.24/arch/arm/mach-pxa/clock.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c	2008-06-11 17:47:55.000000000 +0200
-@@ -23,18 +23,27 @@
- static DEFINE_MUTEX(clocks_mutex);
- static DEFINE_SPINLOCK(clocks_lock);
- 
-+static struct clk *clk_lookup(struct device *dev, const char *id)
-+{
-+	struct clk *p;
-+
-+	list_for_each_entry(p, &clocks, node)
-+		if (strcmp(id, p->name) == 0 && p->dev == dev)
-+			return p;
-+
-+	return NULL;
-+}
-+
- struct clk *clk_get(struct device *dev, const char *id)
- {
- 	struct clk *p, *clk = ERR_PTR(-ENOENT);
- 
- 	mutex_lock(&clocks_mutex);
--	list_for_each_entry(p, &clocks, node) {
--		if (strcmp(id, p->name) == 0 &&
--		    (p->dev == NULL || p->dev == dev)) {
--			clk = p;
--			break;
--		}
--	}
-+	p = clk_lookup(dev, id);
-+	if (!p)
-+		p = clk_lookup(NULL, id);
-+	if (p)
-+		clk = p;
- 	mutex_unlock(&clocks_mutex);
- 
- 	return clk;
-diff -Nurd linux-2.6.24/arch/arm/mm/Kconfig linux-2.6.24-oxe810/arch/arm/mm/Kconfig
---- linux-2.6.24/arch/arm/mm/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/Kconfig	2008-06-11 17:47:57.000000000 +0200
-@@ -171,8 +171,8 @@
- # ARM926T
- config CPU_ARM926T
- 	bool "Support ARM926T processor"
--	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
--	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
-+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
-+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
- 	select CPU_32v5
- 	select CPU_ABRT_EV5TJ
- 	select CPU_CACHE_VIVT
-diff -Nurd linux-2.6.24/arch/arm/mm/init.c linux-2.6.24-oxe810/arch/arm/mm/init.c
---- linux-2.6.24/arch/arm/mm/init.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/init.c	2008-06-11 17:47:57.000000000 +0200
-@@ -173,9 +173,19 @@
- #ifdef CONFIG_MMU
- 	struct map_desc map;
- 
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+	/*
-+	 * Assume only a single bank and stop the overwrite of the first section
-+	 * descriptor
-+	 */
-+	map.pfn = __phys_to_pfn(bank->start + 1024*1024);
-+	map.virtual = __phys_to_virt(bank->start) + 1024*1024;
-+	map.length = bank->size - 1024*1024;
-+#else // CONFIG_OXNAS_MAP_SRAM
- 	map.pfn = __phys_to_pfn(bank->start);
- 	map.virtual = __phys_to_virt(bank->start);
- 	map.length = bank->size;
-+#endif // CONFIG_OXNAS_MAP_SRAM
- 	map.type = MT_MEMORY;
- 
- 	create_mapping(&map);
-diff -Nurd linux-2.6.24/arch/arm/mm/mmu.c linux-2.6.24-oxe810/arch/arm/mm/mmu.c
---- linux-2.6.24/arch/arm/mm/mmu.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/mmu.c	2008-06-11 17:47:57.000000000 +0200
-@@ -617,6 +617,15 @@
- 	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
- 			     PTRS_PER_PGD * sizeof(pgd_t));
- 
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+	/*
-+	 * Reserve the page table describing the first MB of address space in 4KB
-+	 * pages so we can map SRAM over part of it. This didn't work for some reason
-+	 * so instead reserve first 0x4000 as some other archs do
-+	 */
-+	 res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-+#endif // CONFIG_OXNAS_MAP_SRAM
-+
- 	/*
- 	 * Hmm... This should go elsewhere, but we really really need to
- 	 * stop things allocating the low memory; ideally we need a better
-diff -Nurd linux-2.6.24/arch/arm/mm/proc-arm926.S linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S
---- linux-2.6.24/arch/arm/mm/proc-arm926.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S	2008-06-11 17:47:57.000000000 +0200
-@@ -245,6 +245,7 @@
-  *
-  * (same as v4wb)
-  */
-+.section ".text.arm926_dma_clean_range"
- ENTRY(arm926_dma_inv_range)
- #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- 	tst	r0, #CACHE_DLINESIZE - 1
-@@ -259,6 +260,7 @@
- 	blo	1b
- 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
- 	mov	pc, lr
-+.section ".text.other"
- 
- /*
-  *	dma_clean_range(start, end)
-@@ -270,6 +272,7 @@
-  *
-  * (same as v4wb)
-  */
-+.section ".text.arm926_dma_clean_range"
- ENTRY(arm926_dma_clean_range)
- #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- 	bic	r0, r0, #CACHE_DLINESIZE - 1
-@@ -280,6 +283,7 @@
- #endif
- 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
- 	mov	pc, lr
-+.section ".text.other"
- 
- /*
-  *	dma_flush_range(start, end)
-@@ -289,6 +293,7 @@
-  *	- start	- virtual start address
-  *	- end	- virtual end address
-  */
-+.section ".text.arm926_dma_flush_range"
- ENTRY(arm926_dma_flush_range)
- 	bic	r0, r0, #CACHE_DLINESIZE - 1
- 1:
-@@ -302,6 +307,7 @@
- 	blo	1b
- 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
- 	mov	pc, lr
-+.section ".text.other"
- 
- ENTRY(arm926_cache_fns)
- 	.long	arm926_flush_kern_cache_all
-diff -Nurd linux-2.6.24/arch/mips/kernel/i8259.c linux-2.6.24-oxe810/arch/mips/kernel/i8259.c
---- linux-2.6.24/arch/mips/kernel/i8259.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/mips/kernel/i8259.c	2008-06-11 17:48:37.000000000 +0200
-@@ -338,8 +338,10 @@
- 
- 	init_8259A(0);
- 
--	for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++)
-+	for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
- 		set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq);
-+		set_irq_probe(i);
-+	}
- 
- 	setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
- }
-diff -Nurd linux-2.6.24/arch/mips/kernel/irq.c linux-2.6.24-oxe810/arch/mips/kernel/irq.c
---- linux-2.6.24/arch/mips/kernel/irq.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/mips/kernel/irq.c	2008-06-11 17:48:37.000000000 +0200
-@@ -145,6 +145,11 @@
- 
- void __init init_IRQ(void)
- {
-+	int i;
-+
-+	for (i = 0; i < NR_IRQS; i++)
-+		set_irq_noprobe(i);
-+
- 	arch_init_irq();
- 
- #ifdef CONFIG_KGDB
-diff -Nurd linux-2.6.24/arch/powerpc/platforms/chrp/pci.c linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c
---- linux-2.6.24/arch/powerpc/platforms/chrp/pci.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c	2008-06-11 17:47:35.000000000 +0200
-@@ -354,7 +354,7 @@
-  * mode as well. The same fixup must be done to the class-code property in
-  * the IDE node /pci at 80000000/ide at C,1
-  */
--static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
-+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
- {
- 	u8 progif;
- 	struct pci_dev *viaisa;
-@@ -375,4 +375,4 @@
- 
- 	pci_dev_put(viaisa);
- }
--DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
-diff -Nurd linux-2.6.24/arch/powerpc/platforms/powermac/feature.c linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c
---- linux-2.6.24/arch/powerpc/platforms/powermac/feature.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c	2008-06-11 17:47:38.000000000 +0200
-@@ -2565,6 +2565,8 @@
- 
- 	/* Locate core99 Uni-N */
- 	uninorth_node = of_find_node_by_name(NULL, "uni-n");
-+	uninorth_maj = 1;
-+
- 	/* Locate G5 u3 */
- 	if (uninorth_node == NULL) {
- 		uninorth_node = of_find_node_by_name(NULL, "u3");
-@@ -2575,8 +2577,10 @@
- 		uninorth_node = of_find_node_by_name(NULL, "u4");
- 		uninorth_maj = 4;
- 	}
--	if (uninorth_node == NULL)
-+	if (uninorth_node == NULL) {
-+		uninorth_maj = 0;
- 		return;
-+	}
- 
- 	addrp = of_get_property(uninorth_node, "reg", NULL);
- 	if (addrp == NULL)
-@@ -3029,3 +3033,8 @@
- 	pmac_agp_resume(pmac_agp_bridge);
- }
- EXPORT_SYMBOL(pmac_resume_agp_for_card);
-+
-+int pmac_get_uninorth_variant(void)
-+{
-+	return uninorth_maj;
-+}
-diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_pt.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c
---- linux-2.6.24/arch/s390/lib/uaccess_pt.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c	2008-06-11 17:48:25.000000000 +0200
-@@ -406,6 +406,8 @@
- {
- 	int ret;
- 
-+	if (!current->mm)
-+		return -EFAULT;
- 	spin_lock(&current->mm->page_table_lock);
- 	uaddr = (int __user *) __dat_user_addr((unsigned long) uaddr);
- 	if (!uaddr) {
-diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_std.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c
---- linux-2.6.24/arch/s390/lib/uaccess_std.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c	2008-06-11 17:48:25.000000000 +0200
-@@ -293,10 +293,10 @@
- 
- 	asm volatile(
- 		"   sacf 256\n"
--		"   cs   %1,%4,0(%5)\n"
--		"0: lr   %0,%1\n"
--		"1: sacf 0\n"
--		EX_TABLE(0b,1b)
-+		"0: cs   %1,%4,0(%5)\n"
-+		"1: lr   %0,%1\n"
-+		"2: sacf 0\n"
-+		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
- 		: "=d" (ret), "+d" (oldval), "=m" (*uaddr)
- 		: "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
- 		: "cc", "memory" );
-diff -Nurd linux-2.6.24/arch/sparc/kernel/Makefile linux-2.6.24-oxe810/arch/sparc/kernel/Makefile
---- linux-2.6.24/arch/sparc/kernel/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/Makefile	2008-06-11 17:48:46.000000000 +0200
-@@ -1,4 +1,4 @@
--# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
-+#
- # Makefile for the linux kernel.
- #
- 
-@@ -12,7 +12,8 @@
- 	    sys_sparc.o sunos_asm.o systbls.o \
- 	    time.o windows.o cpu.o devices.o sclow.o \
- 	    tadpole.o tick14.o ptrace.o sys_solaris.o \
--	    unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
-+	    unaligned.o una_asm.o muldiv.o semaphore.o \
-+	    prom.o of_device.o devres.o
- 
- devres-y = ../../../kernel/irq/devres.o
- 
-diff -Nurd linux-2.6.24/arch/sparc/kernel/una_asm.S linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S
---- linux-2.6.24/arch/sparc/kernel/una_asm.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S	2008-06-11 17:48:46.000000000 +0200
-@@ -0,0 +1,153 @@
-+/* una_asm.S: Kernel unaligned trap assembler helpers.
-+ *
-+ * Copyright (C) 1996,2005,2008 David S. Miller (davem at davemloft.net)
-+ * Copyright (C) 1996,1997 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
-+ */
-+
-+#include <linux/errno.h>
-+
-+	.text
-+
-+retl_efault:
-+	retl
-+	 mov	-EFAULT, %o0
-+
-+	/* int __do_int_store(unsigned long *dst_addr, int size,
-+	 *                    unsigned long *src_val)
-+	 *
-+	 * %o0 = dest_addr
-+	 * %o1 = size
-+	 * %o2 = src_val
-+	 *
-+	 * Return '0' on success, -EFAULT on failure.
-+	 */
-+	.globl	__do_int_store
-+__do_int_store:
-+	ld	[%o2], %g1
-+	cmp	%1, 2
-+	be	2f
-+	 cmp	%1, 4
-+	be	1f
-+	 srl	%g1, 24, %g2
-+	srl	%g1, 16, %g7
-+4:	stb	%g2, [%o0]
-+	srl	%g1, 8, %g2
-+5:	stb	%g7, [%o0 + 1]
-+	ld	[%o2 + 4], %g7
-+6:	stb	%g2, [%o0 + 2]
-+	srl	%g7, 24, %g2
-+7:	stb	%g1, [%o0 + 3]
-+	srl	%g7, 16, %g1
-+8:	stb	%g2, [%o0 + 4]
-+	srl	%g7, 8, %g2
-+9:	stb	%g1, [%o0 + 5]
-+10:	stb	%g2, [%o0 + 6]
-+	b	0f
-+11:	 stb	%g7, [%o0 + 7]
-+1:	srl	%g1, 16, %g7
-+12:	stb	%g2, [%o0]
-+	srl	%g1, 8, %g2
-+13:	stb	%g7, [%o0 + 1]
-+14:	stb	%g2, [%o0 + 2]
-+	b	0f
-+15:	 stb	%g1, [%o0 + 3]
-+2:	srl	%g1, 8, %g2
-+16:	stb	%g2, [%o0]
-+17:	stb	%g1, [%o0 + 1]
-+0:	retl
-+	 mov	0, %o0
-+
-+	.section __ex_table,#alloc
-+	.word	4b, retl_efault
-+	.word	5b, retl_efault
-+	.word	6b, retl_efault
-+	.word	7b, retl_efault
-+	.word	8b, retl_efault
-+	.word	9b, retl_efault
-+	.word	10b, retl_efault
-+	.word	11b, retl_efault
-+	.word	12b, retl_efault
-+	.word	13b, retl_efault
-+	.word	14b, retl_efault
-+	.word	15b, retl_efault
-+	.word	16b, retl_efault
-+	.word	17b, retl_efault
-+	.previous
-+
-+	/* int do_int_load(unsigned long *dest_reg, int size,
-+	 *                 unsigned long *saddr, int is_signed)
-+	 *
-+	 * %o0 = dest_reg
-+	 * %o1 = size
-+	 * %o2 = saddr
-+	 * %o3 = is_signed
-+	 *
-+	 * Return '0' on success, -EFAULT on failure.
-+	 */
-+	.globl	do_int_load
-+do_int_load:
-+	cmp	%o1, 8
-+	be	9f
-+	 cmp	%o1, 4
-+	be	6f
-+4:	 ldub	[%o2], %g1
-+5:	ldub	[%o2 + 1], %g2
-+	sll	%g1, 8, %g1
-+	tst	%o3
-+	be	3f
-+	 or	%g1, %g2, %g1
-+	sll	%g1, 16, %g1
-+	sra	%g1, 16, %g1
-+3:	b	0f
-+	 st	%g1, [%o0]
-+6:	ldub	[%o2 + 1], %g2
-+	sll	%g1, 24, %g1
-+7:	ldub	[%o2 + 2], %g7
-+	sll	%g2, 16, %g2
-+8:	ldub	[%o2 + 3], %g3
-+	sll	%g7, 8, %g7
-+	or	%g3, %g2, %g3
-+	or	%g7, %g3, %g7
-+	or	%g1, %g7, %g1
-+	b	0f
-+	 st	%g1, [%o0]
-+9:	ldub	[%o2], %g1
-+10:	ldub	[%o2 + 1], %g2
-+	sll	%g1, 24, %g1
-+11:	ldub	[%o2 + 2], %g7
-+	sll	%g2, 16, %g2
-+12:	ldub	[%o2 + 3], %g3
-+	sll	%g7, 8, %g7
-+	or	%g1, %g2, %g1
-+	or	%g7, %g3, %g7
-+	or	%g1, %g7, %g7
-+13:	ldub	[%o2 + 4], %g1
-+	st	%g7, [%o0]
-+14:	ldub	[%o2 + 5], %g2
-+	sll	%g1, 24, %g1
-+15:	ldub	[%o2 + 6], %g7
-+	sll	%g2, 16, %g2
-+16:	ldub	[%o2 + 7], %g3
-+	sll	%g7, 8, %g7
-+	or	%g1, %g2, %g1
-+	or	%g7, %g3, %g7
-+	or	%g1, %g7, %g7
-+	st	%g7, [%o0 + 4]
-+0:	retl
-+	 mov	0, %o0
-+
-+	.section __ex_table,#alloc
-+	.word	4b, retl_efault
-+	.word	5b, retl_efault
-+	.word	6b, retl_efault
-+	.word	7b, retl_efault
-+	.word	8b, retl_efault
-+	.word	9b, retl_efault
-+	.word	10b, retl_efault
-+	.word	11b, retl_efault
-+	.word	12b, retl_efault
-+	.word	13b, retl_efault
-+	.word	14b, retl_efault
-+	.word	15b, retl_efault
-+	.word	16b, retl_efault
-+	.previous
-diff -Nurd linux-2.6.24/arch/sparc/kernel/unaligned.c linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c
---- linux-2.6.24/arch/sparc/kernel/unaligned.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c	2008-06-11 17:48:46.000000000 +0200
-@@ -175,157 +175,31 @@
- 	panic(str);
- }
- 
--#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({		\
--__asm__ __volatile__ (								\
--	"cmp	%1, 8\n\t"							\
--	"be	9f\n\t"								\
--	" cmp	%1, 4\n\t"							\
--	"be	6f\n"								\
--"4:\t"	" ldub	[%2], %%l1\n"							\
--"5:\t"	"ldub	[%2 + 1], %%l2\n\t"						\
--	"sll	%%l1, 8, %%l1\n\t"						\
--	"tst	%3\n\t"								\
--	"be	3f\n\t"								\
--	" add	%%l1, %%l2, %%l1\n\t"						\
--	"sll	%%l1, 16, %%l1\n\t"						\
--	"sra	%%l1, 16, %%l1\n"						\
--"3:\t"	"b	0f\n\t"								\
--	" st	%%l1, [%0]\n"							\
--"6:\t"	"ldub	[%2 + 1], %%l2\n\t"						\
--	"sll	%%l1, 24, %%l1\n"						\
--"7:\t"	"ldub	[%2 + 2], %%g7\n\t"						\
--	"sll	%%l2, 16, %%l2\n"						\
--"8:\t"	"ldub	[%2 + 3], %%g1\n\t"						\
--	"sll	%%g7, 8, %%g7\n\t"						\
--	"or	%%l1, %%l2, %%l1\n\t"						\
--	"or	%%g7, %%g1, %%g7\n\t"						\
--	"or	%%l1, %%g7, %%l1\n\t"						\
--	"b	0f\n\t"								\
--	" st	%%l1, [%0]\n"							\
--"9:\t"	"ldub	[%2], %%l1\n"							\
--"10:\t"	"ldub	[%2 + 1], %%l2\n\t"						\
--	"sll	%%l1, 24, %%l1\n"						\
--"11:\t"	"ldub	[%2 + 2], %%g7\n\t"						\
--	"sll	%%l2, 16, %%l2\n"						\
--"12:\t"	"ldub	[%2 + 3], %%g1\n\t"						\
--	"sll	%%g7, 8, %%g7\n\t"						\
--	"or	%%l1, %%l2, %%l1\n\t"						\
--	"or	%%g7, %%g1, %%g7\n\t"						\
--	"or	%%l1, %%g7, %%g7\n"						\
--"13:\t"	"ldub	[%2 + 4], %%l1\n\t"						\
--	"st	%%g7, [%0]\n"							\
--"14:\t"	"ldub	[%2 + 5], %%l2\n\t"						\
--	"sll	%%l1, 24, %%l1\n"						\
--"15:\t"	"ldub	[%2 + 6], %%g7\n\t"						\
--	"sll	%%l2, 16, %%l2\n"						\
--"16:\t"	"ldub	[%2 + 7], %%g1\n\t"						\
--	"sll	%%g7, 8, %%g7\n\t"						\
--	"or	%%l1, %%l2, %%l1\n\t"						\
--	"or	%%g7, %%g1, %%g7\n\t"						\
--	"or	%%l1, %%g7, %%g7\n\t"						\
--	"st	%%g7, [%0 + 4]\n"						\
--"0:\n\n\t"									\
--	".section __ex_table,#alloc\n\t"					\
--	".word	4b, " #errh "\n\t"						\
--	".word	5b, " #errh "\n\t"						\
--	".word	6b, " #errh "\n\t"						\
--	".word	7b, " #errh "\n\t"						\
--	".word	8b, " #errh "\n\t"						\
--	".word	9b, " #errh "\n\t"						\
--	".word	10b, " #errh "\n\t"						\
--	".word	11b, " #errh "\n\t"						\
--	".word	12b, " #errh "\n\t"						\
--	".word	13b, " #errh "\n\t"						\
--	".word	14b, " #errh "\n\t"						\
--	".word	15b, " #errh "\n\t"						\
--	".word	16b, " #errh "\n\n\t"						\
--	".previous\n\t"								\
--	: : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed)		\
--	: "l1", "l2", "g7", "g1", "cc");					\
--})
--	
--#define store_common(dst_addr, size, src_val, errh) ({				\
--__asm__ __volatile__ (								\
--	"ld	[%2], %%l1\n"							\
--	"cmp	%1, 2\n\t"							\
--	"be	2f\n\t"								\
--	" cmp	%1, 4\n\t"							\
--	"be	1f\n\t"								\
--	" srl	%%l1, 24, %%l2\n\t"						\
--	"srl	%%l1, 16, %%g7\n"						\
--"4:\t"	"stb	%%l2, [%0]\n\t"							\
--	"srl	%%l1, 8, %%l2\n"						\
--"5:\t"	"stb	%%g7, [%0 + 1]\n\t"						\
--	"ld	[%2 + 4], %%g7\n"						\
--"6:\t"	"stb	%%l2, [%0 + 2]\n\t"						\
--	"srl	%%g7, 24, %%l2\n"						\
--"7:\t"	"stb	%%l1, [%0 + 3]\n\t"						\
--	"srl	%%g7, 16, %%l1\n"						\
--"8:\t"	"stb	%%l2, [%0 + 4]\n\t"						\
--	"srl	%%g7, 8, %%l2\n"						\
--"9:\t"	"stb	%%l1, [%0 + 5]\n"						\
--"10:\t"	"stb	%%l2, [%0 + 6]\n\t"						\
--	"b	0f\n"								\
--"11:\t"	" stb	%%g7, [%0 + 7]\n"						\
--"1:\t"	"srl	%%l1, 16, %%g7\n"						\
--"12:\t"	"stb	%%l2, [%0]\n\t"							\
--	"srl	%%l1, 8, %%l2\n"						\
--"13:\t"	"stb	%%g7, [%0 + 1]\n"						\
--"14:\t"	"stb	%%l2, [%0 + 2]\n\t"						\
--	"b	0f\n"								\
--"15:\t"	" stb	%%l1, [%0 + 3]\n"						\
--"2:\t"	"srl	%%l1, 8, %%l2\n"						\
--"16:\t"	"stb	%%l2, [%0]\n"							\
--"17:\t"	"stb	%%l1, [%0 + 1]\n"						\
--"0:\n\n\t"									\
--	".section __ex_table,#alloc\n\t"					\
--	".word	4b, " #errh "\n\t"						\
--	".word	5b, " #errh "\n\t"						\
--	".word	6b, " #errh "\n\t"						\
--	".word	7b, " #errh "\n\t"						\
--	".word	8b, " #errh "\n\t"						\
--	".word	9b, " #errh "\n\t"						\
--	".word	10b, " #errh "\n\t"						\
--	".word	11b, " #errh "\n\t"						\
--	".word	12b, " #errh "\n\t"						\
--	".word	13b, " #errh "\n\t"						\
--	".word	14b, " #errh "\n\t"						\
--	".word	15b, " #errh "\n\t"						\
--	".word	16b, " #errh "\n\t"						\
--	".word	17b, " #errh "\n\n\t"						\
--	".previous\n\t"								\
--	: : "r" (dst_addr), "r" (size), "r" (src_val)				\
--	: "l1", "l2", "g7", "g1", "cc");					\
--})
-+/* una_asm.S */
-+extern int do_int_load(unsigned long *dest_reg, int size,
-+		       unsigned long *saddr, int is_signed);
-+extern int __do_int_store(unsigned long *dst_addr, int size,
-+			  unsigned long *src_val);
- 
--#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({		\
--	unsigned long *src_val;							\
--	static unsigned long zero[2] = { 0, };					\
--										\
--	if (reg_num) src_val = fetch_reg_addr(reg_num, regs);			\
--	else {									\
--		src_val = &zero[0];						\
--		if (size == 8)							\
--			zero[1] = fetch_reg(1, regs);				\
--	}									\
--	store_common(dst_addr, size, src_val, errh);				\
--})
-+static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
-+			struct pt_regs *regs)
-+{
-+	unsigned long zero[2] = { 0, 0 };
-+	unsigned long *src_val;
-+
-+	if (reg_num)
-+		src_val = fetch_reg_addr(reg_num, regs);
-+	else {
-+		src_val = &zero[0];
-+		if (size == 8)
-+			zero[1] = fetch_reg(1, regs);
-+	}
-+	return __do_int_store(dst_addr, size, src_val);
-+}
- 
- extern void smp_capture(void);
- extern void smp_release(void);
- 
--#define do_atomic(srcdest_reg, mem, errh) ({					\
--	unsigned long flags, tmp;						\
--										\
--	smp_capture();								\
--	local_irq_save(flags);							\
--	tmp = *srcdest_reg;							\
--	do_integer_load(srcdest_reg, 4, mem, 0, errh);				\
--	store_common(mem, 4, &tmp, errh);					\
--	local_irq_restore(flags);						\
--	smp_release();								\
--})
--
- static inline void advance(struct pt_regs *regs)
- {
- 	regs->pc   = regs->npc;
-@@ -342,9 +216,7 @@
- 	return !floating_point_load_or_store_p(insn);
- }
- 
--void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
--
--void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
-+static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
- {
- 	unsigned long g2 = regs->u_regs [UREG_G2];
- 	unsigned long fixup = search_extables_range(regs->pc, &g2);
-@@ -379,48 +251,34 @@
- 		printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
- 		       regs->pc);
- 		unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
--
--		__asm__ __volatile__ ("\n"
--"kernel_unaligned_trap_fault:\n\t"
--		"mov	%0, %%o0\n\t"
--		"call	kernel_mna_trap_fault\n\t"
--		" mov	%1, %%o1\n\t"
--		:
--		: "r" (regs), "r" (insn)
--		: "o0", "o1", "o2", "o3", "o4", "o5", "o7",
--		  "g1", "g2", "g3", "g4", "g5", "g7", "cc");
- 	} else {
- 		unsigned long addr = compute_effective_address(regs, insn);
-+		int err;
- 
- #ifdef DEBUG_MNA
- 		printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
- 		       regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
- #endif
--		switch(dir) {
-+		switch (dir) {
- 		case load:
--			do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
--					size, (unsigned long *) addr,
--					decode_signedness(insn),
--					kernel_unaligned_trap_fault);
-+			err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
-+							 regs),
-+					  size, (unsigned long *) addr,
-+					  decode_signedness(insn));
- 			break;
- 
- 		case store:
--			do_integer_store(((insn>>25)&0x1f), size,
--					 (unsigned long *) addr, regs,
--					 kernel_unaligned_trap_fault);
--			break;
--#if 0 /* unsupported */
--		case both:
--			do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
--				  (unsigned long *) addr,
--				  kernel_unaligned_trap_fault);
-+			err = do_int_store(((insn>>25)&0x1f), size,
-+					   (unsigned long *) addr, regs);
- 			break;
--#endif
- 		default:
- 			panic("Impossible kernel unaligned trap.");
- 			/* Not reached... */
- 		}
--		advance(regs);
-+		if (err)
-+			kernel_mna_trap_fault(regs, insn);
-+		else
-+			advance(regs);
- 	}
- }
- 
-@@ -459,9 +317,7 @@
- 	return 0;
- }
- 
--void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
--
--void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
-+static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
- {
- 	siginfo_t info;
- 
-@@ -485,7 +341,7 @@
- 	if(!ok_for_user(regs, insn, dir)) {
- 		goto kill_user;
- 	} else {
--		int size = decode_access_size(insn);
-+		int err, size = decode_access_size(insn);
- 		unsigned long addr;
- 
- 		if(floating_point_load_or_store_p(insn)) {
-@@ -496,48 +352,34 @@
- 		addr = compute_effective_address(regs, insn);
- 		switch(dir) {
- 		case load:
--			do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
--					size, (unsigned long *) addr,
--					decode_signedness(insn),
--					user_unaligned_trap_fault);
-+			err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
-+							 regs),
-+					  size, (unsigned long *) addr,
-+					  decode_signedness(insn));
- 			break;
- 
- 		case store:
--			do_integer_store(((insn>>25)&0x1f), size,
--					 (unsigned long *) addr, regs,
--					 user_unaligned_trap_fault);
-+			err = do_int_store(((insn>>25)&0x1f), size,
-+					   (unsigned long *) addr, regs);
- 			break;
- 
- 		case both:
--#if 0 /* unsupported */
--			do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
--				  (unsigned long *) addr,
--				  user_unaligned_trap_fault);
--#else
- 			/*
- 			 * This was supported in 2.4. However, we question
- 			 * the value of SWAP instruction across word boundaries.
- 			 */
- 			printk("Unaligned SWAP unsupported.\n");
--			goto kill_user;
--#endif
-+			err = -EFAULT;
- 			break;
- 
- 		default:
- 			unaligned_panic("Impossible user unaligned trap.");
--
--			__asm__ __volatile__ ("\n"
--"user_unaligned_trap_fault:\n\t"
--			"mov	%0, %%o0\n\t"
--			"call	user_mna_trap_fault\n\t"
--			" mov	%1, %%o1\n\t"
--			:
--			: "r" (regs), "r" (insn)
--			: "o0", "o1", "o2", "o3", "o4", "o5", "o7",
--			  "g1", "g2", "g3", "g4", "g5", "g7", "cc");
- 			goto out;
- 		}
--		advance(regs);
-+		if (err)
-+			goto kill_user;
-+		else
-+			advance(regs);
- 		goto out;
- 	}
- 
-diff -Nurd linux-2.6.24/arch/sparc/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S
---- linux-2.6.24/arch/sparc/lib/rwsem.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S	2008-06-11 17:48:47.000000000 +0200
-@@ -7,7 +7,7 @@
- #include <asm/ptrace.h>
- #include <asm/psr.h>
- 
--	.section .sched.text
-+	.section .sched.text, "ax"
- 	.align	4
- 
- 	.globl		___down_read
-diff -Nurd linux-2.6.24/arch/sparc64/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S
---- linux-2.6.24/arch/sparc64/lib/rwsem.S	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S	2008-06-11 17:48:11.000000000 +0200
-@@ -6,7 +6,7 @@
- 
- #include <asm/rwsem-const.h>
- 
--	.section	.sched.text
-+	.section	.sched.text, "ax"
- 
- 	.globl		__down_read
- __down_read:
-diff -Nurd linux-2.6.24/arch/sparc64/mm/fault.c linux-2.6.24-oxe810/arch/sparc64/mm/fault.c
---- linux-2.6.24/arch/sparc64/mm/fault.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc64/mm/fault.c	2008-06-11 17:48:12.000000000 +0200
-@@ -244,16 +244,8 @@
- 	if (regs->tstate & TSTATE_PRIV) {
- 		const struct exception_table_entry *entry;
- 
--		if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
--			if (insn & 0x2000)
--				asi = (regs->tstate >> 24);
--			else
--				asi = (insn >> 5);
--		}
--	
--		/* Look in asi.h: All _S asis have LS bit set */
--		if ((asi & 0x1) &&
--		    (entry = search_exception_tables(regs->tpc))) {
-+		entry = search_exception_tables(regs->tpc);
-+		if (entry) {
- 			regs->tpc = entry->fixup;
- 			regs->tnpc = regs->tpc + 4;
- 			return;
-@@ -294,7 +286,7 @@
- 		unsigned long tpc = regs->tpc;
- 
- 		/* Sanity check the PC. */
--		if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
-+		if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
- 		    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
- 			/* Valid, no problems... */
- 		} else {
-diff -Nurd linux-2.6.24/arch/x86/ia32/ia32_signal.c linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c
---- linux-2.6.24/arch/x86/ia32/ia32_signal.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c	2008-06-11 17:48:21.000000000 +0200
-@@ -494,7 +494,7 @@
- 	regs->ss = __USER32_DS; 
- 
- 	set_fs(USER_DS);
--	regs->eflags &= ~TF_MASK;
-+	regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- 	if (test_thread_flag(TIF_SINGLESTEP))
- 		ptrace_notify(SIGTRAP);
- 
-@@ -600,7 +600,7 @@
- 	regs->ss = __USER32_DS; 
- 
- 	set_fs(USER_DS);
--	regs->eflags &= ~TF_MASK;
-+	regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- 	if (test_thread_flag(TIF_SINGLESTEP))
- 		ptrace_notify(SIGTRAP);
- 
-diff -Nurd linux-2.6.24/arch/x86/kernel/Makefile_32 linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32
---- linux-2.6.24/arch/x86/kernel/Makefile_32	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32	2008-06-11 17:48:20.000000000 +0200
-@@ -19,7 +19,8 @@
- obj-$(CONFIG_X86_CPUID)		+= cpuid.o
- obj-$(CONFIG_MICROCODE)		+= microcode.o
- obj-$(CONFIG_PCI)		+= early-quirks.o
--obj-$(CONFIG_APM)		+= apm_32.o
-+apm-y				:= apm_32.o
-+obj-$(CONFIG_APM)		+= apm.o
- obj-$(CONFIG_X86_SMP)		+= smp_32.o smpboot_32.o tsc_sync.o
- obj-$(CONFIG_SMP)		+= smpcommon_32.o
- obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline_32.o
-diff -Nurd linux-2.6.24/arch/x86/kernel/apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c
---- linux-2.6.24/arch/x86/kernel/apic_32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c	2008-06-11 17:48:20.000000000 +0200
-@@ -154,7 +154,7 @@
- /**
-  * enable_NMI_through_LVT0 - enable NMI through local vector table 0
-  */
--void enable_NMI_through_LVT0 (void * dummy)
-+void __cpuinit enable_NMI_through_LVT0(void)
- {
- 	unsigned int v = APIC_DM_NMI;
- 
-diff -Nurd linux-2.6.24/arch/x86/kernel/apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c
---- linux-2.6.24/arch/x86/kernel/apic_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c	2008-06-11 17:48:20.000000000 +0200
-@@ -151,7 +151,7 @@
- 	return send_status;
- }
- 
--void enable_NMI_through_LVT0 (void * dummy)
-+void enable_NMI_through_LVT0(void)
- {
- 	unsigned int v;
- 
-diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c
---- linux-2.6.24/arch/x86/kernel/io_apic_32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c	2008-06-11 17:48:20.000000000 +0200
-@@ -2080,7 +2080,7 @@
- 	.eoi		= ack_apic,
- };
- 
--static void setup_nmi (void)
-+static void __init setup_nmi(void)
- {
- 	/*
-  	 * Dirty trick to enable the NMI watchdog ...
-@@ -2093,7 +2093,7 @@
- 	 */ 
- 	apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
- 
--	on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
-+	enable_NMI_through_LVT0();
- 
- 	apic_printk(APIC_VERBOSE, " done.\n");
- }
-diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c
---- linux-2.6.24/arch/x86/kernel/io_apic_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c	2008-06-11 17:48:20.000000000 +0200
-@@ -1565,7 +1565,7 @@
- 	.end = end_lapic_irq,
- };
- 
--static void setup_nmi (void)
-+static void __init setup_nmi(void)
- {
- 	/*
-  	 * Dirty trick to enable the NMI watchdog ...
-@@ -1578,7 +1578,7 @@
- 	 */ 
- 	printk(KERN_INFO "activating NMI Watchdog ...");
- 
--	enable_NMI_through_LVT0(NULL);
-+	enable_NMI_through_LVT0();
- 
- 	printk(" done.\n");
- }
-@@ -1654,7 +1654,7 @@
-  *
-  * FIXME: really need to revamp this for modern platforms only.
-  */
--static inline void check_timer(void)
-+static inline void __init check_timer(void)
- {
- 	struct irq_cfg *cfg = irq_cfg + 0;
- 	int apic1, pin1, apic2, pin2;
-diff -Nurd linux-2.6.24/arch/x86/kernel/process_64.c linux-2.6.24-oxe810/arch/x86/kernel/process_64.c
---- linux-2.6.24/arch/x86/kernel/process_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/process_64.c	2008-06-11 17:48:20.000000000 +0200
-@@ -212,14 +212,13 @@
- 	current_thread_info()->status |= TS_POLLING;
- 	/* endless idle loop with no priority at all */
- 	while (1) {
-+		tick_nohz_stop_sched_tick();
- 		while (!need_resched()) {
- 			void (*idle)(void);
- 
- 			if (__get_cpu_var(cpu_idle_state))
- 				__get_cpu_var(cpu_idle_state) = 0;
- 
--			tick_nohz_stop_sched_tick();
--
- 			rmb();
- 			idle = pm_idle;
- 			if (!idle)
-diff -Nurd linux-2.6.24/arch/x86/kernel/signal_32.c linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c
---- linux-2.6.24/arch/x86/kernel/signal_32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c	2008-06-11 17:48:20.000000000 +0200
-@@ -396,7 +396,7 @@
- 	 * The tracer may want to single-step inside the
- 	 * handler too.
- 	 */
--	regs->eflags &= ~TF_MASK;
-+	regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- 	if (test_thread_flag(TIF_SINGLESTEP))
- 		ptrace_notify(SIGTRAP);
- 
-@@ -489,7 +489,7 @@
- 	 * The tracer may want to single-step inside the
- 	 * handler too.
- 	 */
--	regs->eflags &= ~TF_MASK;
-+	regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- 	if (test_thread_flag(TIF_SINGLESTEP))
- 		ptrace_notify(SIGTRAP);
- 
-diff -Nurd linux-2.6.24/arch/x86/kernel/signal_64.c linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c
---- linux-2.6.24/arch/x86/kernel/signal_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c	2008-06-11 17:48:20.000000000 +0200
-@@ -295,7 +295,7 @@
- 	   see include/asm-x86_64/uaccess.h for details. */
- 	set_fs(USER_DS);
- 
--	regs->eflags &= ~TF_MASK;
-+	regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- 	if (test_thread_flag(TIF_SINGLESTEP))
- 		ptrace_notify(SIGTRAP);
- #ifdef DEBUG_SIG
-diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_32.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c
---- linux-2.6.24/arch/x86/kernel/smpboot_32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c	2008-06-11 17:48:20.000000000 +0200
-@@ -405,7 +405,7 @@
- 	setup_secondary_clock();
- 	if (nmi_watchdog == NMI_IO_APIC) {
- 		disable_8259A_irq(0);
--		enable_NMI_through_LVT0(NULL);
-+		enable_NMI_through_LVT0();
- 		enable_8259A_irq(0);
- 	}
- 	/*
-diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_64.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c
---- linux-2.6.24/arch/x86/kernel/smpboot_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c	2008-06-11 17:48:20.000000000 +0200
-@@ -338,7 +338,7 @@
- 
- 	if (nmi_watchdog == NMI_IO_APIC) {
- 		disable_8259A_irq(0);
--		enable_NMI_through_LVT0(NULL);
-+		enable_NMI_through_LVT0();
- 		enable_8259A_irq(0);
- 	}
- 
-diff -Nurd linux-2.6.24/arch/x86/mm/pageattr_64.c linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c
---- linux-2.6.24/arch/x86/mm/pageattr_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c	2008-06-11 17:48:22.000000000 +0200
-@@ -207,7 +207,7 @@
- 		if (__pa(address) < KERNEL_TEXT_SIZE) {
- 			unsigned long addr2;
- 			pgprot_t prot2;
--			addr2 = __START_KERNEL_map + __pa(address);
-+			addr2 = __START_KERNEL_map + __pa(address) - phys_base;
- 			/* Make sure the kernel mappings stay executable */
- 			prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
- 			err = __change_page_attr(addr2, pfn, prot2,
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig-shared.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c
---- linux-2.6.24/arch/x86/pci/mmconfig-shared.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c	2008-06-11 17:48:22.000000000 +0200
-@@ -22,42 +22,9 @@
- #define MMCONFIG_APER_MIN	(2 * 1024*1024)
- #define MMCONFIG_APER_MAX	(256 * 1024*1024)
- 
--DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
--
- /* Indicate if the mmcfg resources have been placed into the resource table. */
- static int __initdata pci_mmcfg_resources_inserted;
- 
--/* K8 systems have some devices (typically in the builtin northbridge)
--   that are only accessible using type1
--   Normally this can be expressed in the MCFG by not listing them
--   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
--   Instead try to discover all devices on bus 0 that are unreachable using MM
--   and fallback for them. */
--static void __init unreachable_devices(void)
--{
--	int i, bus;
--	/* Use the max bus number from ACPI here? */
--	for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
--		for (i = 0; i < 32; i++) {
--			unsigned int devfn = PCI_DEVFN(i, 0);
--			u32 val1, val2;
--
--			pci_conf1_read(0, bus, devfn, 0, 4, &val1);
--			if (val1 == 0xffffffff)
--				continue;
--
--			if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
--				raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
--				if (val1 == val2)
--					continue;
--			}
--			set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
--			printk(KERN_NOTICE "PCI: No mmconfig possible on device"
--			       " %02x:%02x\n", bus, i);
--		}
--	}
--}
--
- static const char __init *pci_mmcfg_e7520(void)
- {
- 	u32 win;
-@@ -270,8 +237,6 @@
- 		return;
- 
- 	if (pci_mmcfg_arch_init()) {
--		if (type == 1)
--			unreachable_devices();
- 		if (known_bridge)
- 			pci_mmcfg_insert_resources(IORESOURCE_BUSY);
- 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_32.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c
---- linux-2.6.24/arch/x86/pci/mmconfig_32.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c	2008-06-11 17:48:22.000000000 +0200
-@@ -30,10 +30,6 @@
- 	struct acpi_mcfg_allocation *cfg;
- 	int cfg_num;
- 
--	if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
--	    test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots))
--		return 0;
--
- 	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
- 		cfg = &pci_mmcfg_config[cfg_num];
- 		if (cfg->pci_segment == seg &&
-@@ -68,13 +64,16 @@
- 	u32 base;
- 
- 	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
--		*value = -1;
-+err:		*value = -1;
- 		return -EINVAL;
- 	}
- 
-+	if (reg < 256)
-+		return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+
- 	base = get_base_addr(seg, bus, devfn);
- 	if (!base)
--		return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+		goto err;
- 
- 	spin_lock_irqsave(&pci_config_lock, flags);
- 
-@@ -105,9 +104,12 @@
- 	if ((bus > 255) || (devfn > 255) || (reg > 4095))
- 		return -EINVAL;
- 
-+	if (reg < 256)
-+		return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+
- 	base = get_base_addr(seg, bus, devfn);
- 	if (!base)
--		return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+		return -EINVAL;
- 
- 	spin_lock_irqsave(&pci_config_lock, flags);
- 
-@@ -134,12 +136,6 @@
- 	.write =	pci_mmcfg_write,
- };
- 
--int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
--				    unsigned int devfn)
--{
--	return get_base_addr(seg, bus, devfn) != 0;
--}
--
- int __init pci_mmcfg_arch_init(void)
- {
- 	printk(KERN_INFO "PCI: Using MMCONFIG\n");
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_64.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c
---- linux-2.6.24/arch/x86/pci/mmconfig_64.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c	2008-06-11 17:48:22.000000000 +0200
-@@ -40,9 +40,7 @@
- static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
- {
- 	char __iomem *addr;
--	if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
--		test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots))
--		return NULL;
-+
- 	addr = get_virt(seg, bus);
- 	if (!addr)
- 		return NULL;
-@@ -56,13 +54,16 @@
- 
- 	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
- 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
--		*value = -1;
-+err:		*value = -1;
- 		return -EINVAL;
- 	}
- 
-+	if (reg < 256)
-+		return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+
- 	addr = pci_dev_base(seg, bus, devfn);
- 	if (!addr)
--		return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+		goto err;
- 
- 	switch (len) {
- 	case 1:
-@@ -88,9 +89,12 @@
- 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
- 		return -EINVAL;
- 
-+	if (reg < 256)
-+		return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+
- 	addr = pci_dev_base(seg, bus, devfn);
- 	if (!addr)
--		return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+		return -EINVAL;
- 
- 	switch (len) {
- 	case 1:
-@@ -126,12 +130,6 @@
- 	return addr;
- }
- 
--int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
--				    unsigned int devfn)
--{
--	return pci_dev_base(seg, bus, devfn) != NULL;
--}
--
- int __init pci_mmcfg_arch_init(void)
- {
- 	int i;
-diff -Nurd linux-2.6.24/arch/x86/pci/pci.h linux-2.6.24-oxe810/arch/x86/pci/pci.h
---- linux-2.6.24/arch/x86/pci/pci.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/pci.h	2008-06-11 17:48:22.000000000 +0200
-@@ -98,13 +98,6 @@
- 
- /* pci-mmconfig.c */
- 
--/* Verify the first 16 busses. We assume that systems with more busses
--   get MCFG right. */
--#define PCI_MMCFG_MAX_CHECK_BUS 16
--extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
--
--extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
--					   unsigned int devfn);
- extern int __init pci_mmcfg_arch_init(void);
- 
- /*
-diff -Nurd linux-2.6.24/block/ll_rw_blk.c linux-2.6.24-oxe810/block/ll_rw_blk.c
---- linux-2.6.24/block/ll_rw_blk.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/block/ll_rw_blk.c	2008-06-11 17:46:40.000000000 +0200
-@@ -1424,6 +1424,13 @@
- 	else
- 		max_sectors = q->max_sectors;
- 
-+    /*
-+     * If the RAID modes of the bio associated with the request differs
-+     * from the merge candidate bio, it can't be merged
-+     */
-+    if (req->bio->bi_raid != bio->bi_raid)
-+        return 0;
-+
- 	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- 		req->cmd_flags |= REQ_NOMERGE;
- 		if (req == q->last_merge)
-@@ -1462,6 +1469,12 @@
- 	else
- 		max_sectors = q->max_sectors;
- 
-+    /*
-+     * If the RAID modes of the bio associated with the request differs
-+     * from the merge candidate bio, it can't be merged
-+     */
-+    if (req->bio->bi_raid != bio->bi_raid)
-+        return 0;
- 
- 	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- 		req->cmd_flags |= REQ_NOMERGE;
-@@ -1502,6 +1515,17 @@
- 	 */
- 	if (req->special || next->special)
- 		return 0;
-+    
-+    /*
-+     * If the RAID modes of the bio associated with the two requests differ
-+     * then they cannot be merged.
-+     *
-+    BUG_ON(!req);
-+    BUG_ON(!req->bio);
-+    BUG_ON(!next);
-+    BUG_ON(!next->bio);
-+    if (req->bio->bi_raid != next->bio->bi_raid)
-+        return 0;*/
- 
- 	/*
- 	 * Will it become too large?
-@@ -2965,7 +2989,7 @@
- 
- static int __make_request(struct request_queue *q, struct bio *bio)
- {
--	struct request *req;
-+	struct request *req = 0;
- 	int el_ret, nr_sectors, barrier, err;
- 	const unsigned short prio = bio_prio(bio);
- 	const int sync = bio_sync(bio);
-@@ -2992,6 +3016,15 @@
- 		goto get_rq;
- 
- 	el_ret = elv_merge(q, &req, bio);
-+    
-+    /* if the bio raid modes differ, force a no-merge */
-+    if ((!ELEVATOR_NO_MERGE) &&
-+        (req) &&
-+        (req->bio) &&
-+        (bio->bi_raid != req->bio->bi_raid )) {
-+        el_ret = ELEVATOR_NO_MERGE;
-+    }
-+        
- 	switch (el_ret) {
- 		case ELEVATOR_BACK_MERGE:
- 			BUG_ON(!rq_mergeable(req));
-diff -Nurd linux-2.6.24/crypto/async_tx/async_xor.c linux-2.6.24-oxe810/crypto/async_tx/async_xor.c
---- linux-2.6.24/crypto/async_tx/async_xor.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/async_tx/async_xor.c	2008-06-11 17:43:37.000000000 +0200
-@@ -264,7 +264,7 @@
- 
- 	BUG_ON(src_cnt <= 1);
- 
--	if (tx) {
-+	if (tx && src_cnt <= device->max_xor) {
- 		dma_addr_t dma_addr;
- 		enum dma_data_direction dir;
- 
-diff -Nurd linux-2.6.24/crypto/xcbc.c linux-2.6.24-oxe810/crypto/xcbc.c
---- linux-2.6.24/crypto/xcbc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/xcbc.c	2008-06-11 17:43:39.000000000 +0200
-@@ -124,6 +124,11 @@
- 		unsigned int offset = sg[i].offset;
- 		unsigned int slen = sg[i].length;
- 
-+		if (unlikely(slen > nbytes))
-+			slen = nbytes;
-+
-+		nbytes -= slen;
-+
- 		while (slen > 0) {
- 			unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
- 			char *p = crypto_kmap(pg, 0) + offset;
-@@ -177,7 +182,6 @@
- 			offset = 0;
- 			pg++;
- 		}
--		nbytes-=sg[i].length;
- 		i++;
- 	} while (nbytes>0);
- 
-diff -Nurd linux-2.6.24/crypto/xts.c linux-2.6.24-oxe810/crypto/xts.c
---- linux-2.6.24/crypto/xts.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/xts.c	2008-06-11 17:43:39.000000000 +0200
-@@ -77,16 +77,16 @@
- }
- 
- struct sinfo {
--	be128 t;
-+	be128 *t;
- 	struct crypto_tfm *tfm;
- 	void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
- };
- 
- static inline void xts_round(struct sinfo *s, void *dst, const void *src)
- {
--	be128_xor(dst, &s->t, src);		/* PP <- T xor P */
-+	be128_xor(dst, s->t, src);		/* PP <- T xor P */
- 	s->fn(s->tfm, dst, dst);		/* CC <- E(Key1,PP) */
--	be128_xor(dst, dst, &s->t);		/* C <- T xor CC */
-+	be128_xor(dst, dst, s->t);		/* C <- T xor CC */
- }
- 
- static int crypt(struct blkcipher_desc *d,
-@@ -101,7 +101,6 @@
- 		.tfm = crypto_cipher_tfm(ctx->child),
- 		.fn = fn
- 	};
--	be128 *iv;
- 	u8 *wsrc;
- 	u8 *wdst;
- 
-@@ -109,20 +108,20 @@
- 	if (!w->nbytes)
- 		return err;
- 
-+	s.t = (be128 *)w->iv;
- 	avail = w->nbytes;
- 
- 	wsrc = w->src.virt.addr;
- 	wdst = w->dst.virt.addr;
- 
- 	/* calculate first value of T */
--	iv = (be128 *)w->iv;
--	tw(crypto_cipher_tfm(ctx->tweak), (void *)&s.t, w->iv);
-+	tw(crypto_cipher_tfm(ctx->tweak), w->iv, w->iv);
- 
- 	goto first;
- 
- 	for (;;) {
- 		do {
--			gf128mul_x_ble(&s.t, &s.t);
-+			gf128mul_x_ble(s.t, s.t);
- 
- first:
- 			xts_round(&s, wdst, wsrc);
-diff -Nurd linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c
---- linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c	2008-06-11 17:49:37.000000000 +0200
-@@ -347,40 +347,40 @@
- };
- 
- struct kbdiacruc accent_table[MAX_DIACR] = {
--	{'`', 'A', '\300'},	{'`', 'a', '\340'},
--	{'\'', 'A', '\301'},	{'\'', 'a', '\341'},
--	{'^', 'A', '\302'},	{'^', 'a', '\342'},
--	{'~', 'A', '\303'},	{'~', 'a', '\343'},
--	{'"', 'A', '\304'},	{'"', 'a', '\344'},
--	{'O', 'A', '\305'},	{'o', 'a', '\345'},
--	{'0', 'A', '\305'},	{'0', 'a', '\345'},
--	{'A', 'A', '\305'},	{'a', 'a', '\345'},
--	{'A', 'E', '\306'},	{'a', 'e', '\346'},
--	{',', 'C', '\307'},	{',', 'c', '\347'},
--	{'`', 'E', '\310'},	{'`', 'e', '\350'},
--	{'\'', 'E', '\311'},	{'\'', 'e', '\351'},
--	{'^', 'E', '\312'},	{'^', 'e', '\352'},
--	{'"', 'E', '\313'},	{'"', 'e', '\353'},
--	{'`', 'I', '\314'},	{'`', 'i', '\354'},
--	{'\'', 'I', '\315'},	{'\'', 'i', '\355'},
--	{'^', 'I', '\316'},	{'^', 'i', '\356'},
--	{'"', 'I', '\317'},	{'"', 'i', '\357'},
--	{'-', 'D', '\320'},	{'-', 'd', '\360'},
--	{'~', 'N', '\321'},	{'~', 'n', '\361'},
--	{'`', 'O', '\322'},	{'`', 'o', '\362'},
--	{'\'', 'O', '\323'},	{'\'', 'o', '\363'},
--	{'^', 'O', '\324'},	{'^', 'o', '\364'},
--	{'~', 'O', '\325'},	{'~', 'o', '\365'},
--	{'"', 'O', '\326'},	{'"', 'o', '\366'},
--	{'/', 'O', '\330'},	{'/', 'o', '\370'},
--	{'`', 'U', '\331'},	{'`', 'u', '\371'},
--	{'\'', 'U', '\332'},	{'\'', 'u', '\372'},
--	{'^', 'U', '\333'},	{'^', 'u', '\373'},
--	{'"', 'U', '\334'},	{'"', 'u', '\374'},
--	{'\'', 'Y', '\335'},	{'\'', 'y', '\375'},
--	{'T', 'H', '\336'},	{'t', 'h', '\376'},
--	{'s', 's', '\337'},	{'"', 'y', '\377'},
--	{'s', 'z', '\337'},	{'i', 'j', '\377'},
-+	{'`', 'A', 0300},	{'`', 'a', 0340},
-+	{'\'', 'A', 0301},	{'\'', 'a', 0341},
-+	{'^', 'A', 0302},	{'^', 'a', 0342},
-+	{'~', 'A', 0303},	{'~', 'a', 0343},
-+	{'"', 'A', 0304},	{'"', 'a', 0344},
-+	{'O', 'A', 0305},	{'o', 'a', 0345},
-+	{'0', 'A', 0305},	{'0', 'a', 0345},
-+	{'A', 'A', 0305},	{'a', 'a', 0345},
-+	{'A', 'E', 0306},	{'a', 'e', 0346},
-+	{',', 'C', 0307},	{',', 'c', 0347},
-+	{'`', 'E', 0310},	{'`', 'e', 0350},
-+	{'\'', 'E', 0311},	{'\'', 'e', 0351},
-+	{'^', 'E', 0312},	{'^', 'e', 0352},
-+	{'"', 'E', 0313},	{'"', 'e', 0353},
-+	{'`', 'I', 0314},	{'`', 'i', 0354},
-+	{'\'', 'I', 0315},	{'\'', 'i', 0355},
-+	{'^', 'I', 0316},	{'^', 'i', 0356},
-+	{'"', 'I', 0317},	{'"', 'i', 0357},
-+	{'-', 'D', 0320},	{'-', 'd', 0360},
-+	{'~', 'N', 0321},	{'~', 'n', 0361},
-+	{'`', 'O', 0322},	{'`', 'o', 0362},
-+	{'\'', 'O', 0323},	{'\'', 'o', 0363},
-+	{'^', 'O', 0324},	{'^', 'o', 0364},
-+	{'~', 'O', 0325},	{'~', 'o', 0365},
-+	{'"', 'O', 0326},	{'"', 'o', 0366},
-+	{'/', 'O', 0330},	{'/', 'o', 0370},
-+	{'`', 'U', 0331},	{'`', 'u', 0371},
-+	{'\'', 'U', 0332},	{'\'', 'u', 0372},
-+	{'^', 'U', 0333},	{'^', 'u', 0373},
-+	{'"', 'U', 0334},	{'"', 'u', 0374},
-+	{'\'', 'Y', 0335},	{'\'', 'y', 0375},
-+	{'T', 'H', 0336},	{'t', 'h', 0376},
-+	{'s', 's', 0337},	{'"', 'y', 0377},
-+	{'s', 'z', 0337},	{'i', 'j', 0377},
- };
- 
- unsigned int accent_table_size = 68;
-diff -Nurd linux-2.6.24/drivers/acpi/blacklist.c linux-2.6.24-oxe810/drivers/acpi/blacklist.c
---- linux-2.6.24/drivers/acpi/blacklist.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acpi/blacklist.c	2008-06-11 17:49:40.000000000 +0200
-@@ -208,24 +208,24 @@
- 	 * Disable OSI(Linux) warnings on all "Acer, inc."
- 	 *
- 	 * _OSI(Linux) disables the latest Windows BIOS code:
-+	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
-+	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
- 	 * _OSI(Linux) effect unknown:
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
- 	 */
--	{
--	.callback = dmi_disable_osi_linux,
--	.ident = "Acer, inc.",
--	.matches = {
--		     DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."),
--		},
--	},
-+	/*
-+	 * note that dmi_check_system() uses strstr()
-+	 * to match sub-strings rather than !strcmp(),
-+	 * so "Acer" below matches "Acer, inc." above.
-+	 */
- 	/*
- 	 * Disable OSI(Linux) warnings on all "Acer"
- 	 *
- 	 * _OSI(Linux) effect unknown:
--	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
-+	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
-@@ -300,7 +300,7 @@
- 		     DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
- 		},
- 	},
--	{ /* OSI(Linux) touches USB, breaks suspend to disk */
-+	{ /* OSI(Linux) touches USB, unknown side-effect */
- 	.callback = dmi_disable_osi_linux,
- 	.ident = "Dell Dimension 5150",
- 	.matches = {
-@@ -474,6 +474,11 @@
- 	 *
- 	 * _OSI(Linux) confirmed to be a NOP:
- 	 * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
-+	 * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
-+	 *
-+	 * unknown:
-+	 * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"),
-+	 * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
- 	 */
- 	{
- 	.callback = dmi_disable_osi_linux,
-diff -Nurd linux-2.6.24/drivers/acpi/osl.c linux-2.6.24-oxe810/drivers/acpi/osl.c
---- linux-2.6.24/drivers/acpi/osl.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acpi/osl.c	2008-06-11 17:49:40.000000000 +0200
-@@ -120,7 +120,7 @@
-  */
- #define OSI_LINUX_ENABLE 0
- 
--struct osi_linux {
-+static struct osi_linux {
- 	unsigned int	enable:1;
- 	unsigned int	dmi:1;
- 	unsigned int	cmdline:1;
-@@ -1213,24 +1213,24 @@
-  *
-  *	Returns 0 on success
-  */
--int acpi_dmi_dump(void)
-+static int acpi_dmi_dump(void)
- {
- 
- 	if (!dmi_available)
- 		return -1;
- 
- 	printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
--		dmi_get_slot(DMI_SYS_VENDOR));
-+		dmi_get_system_info(DMI_SYS_VENDOR));
- 	printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
--		dmi_get_slot(DMI_PRODUCT_NAME));
-+		dmi_get_system_info(DMI_PRODUCT_NAME));
- 	printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
--		dmi_get_slot(DMI_PRODUCT_VERSION));
-+		dmi_get_system_info(DMI_PRODUCT_VERSION));
- 	printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
--		dmi_get_slot(DMI_BOARD_NAME));
-+		dmi_get_system_info(DMI_BOARD_NAME));
- 	printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
--		dmi_get_slot(DMI_BIOS_VENDOR));
-+		dmi_get_system_info(DMI_BIOS_VENDOR));
- 	printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
--		dmi_get_slot(DMI_BIOS_DATE));
-+		dmi_get_system_info(DMI_BIOS_DATE));
- 
- 	return 0;
- }
-diff -Nurd linux-2.6.24/drivers/ata/Kconfig linux-2.6.24-oxe810/drivers/ata/Kconfig
---- linux-2.6.24/drivers/ata/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/Kconfig	2008-06-11 17:50:32.000000000 +0200
-@@ -182,15 +182,49 @@
- 	  firmware in the BIOS. This driver can sometimes handle
- 	  otherwise unsupported hardware.
- 
-+config SATA_OX800
-+	bool "Oxford Semiconductor OX800 SATA support"
-+	depends on ARCH_OXNAS && OXNAS_VERSION_0X800
-+	default n
-+	help
-+	  This option enables support for the 924 based sata core
-+
-+config SATA_OX810
-+	bool "Oxford Semiconductor OX810 SATA support"
-+	depends on ARCH_OXNAS && OXNAS_VERSION_0X810
-+	default n
-+	help
-+	  This option enables support for the 934 based sata core
-+
- config SATA_FSL
- 	tristate "Freescale 3.0Gbps SATA support"
- 	depends on PPC_MPC837x
- 	help
- 	  This option enables support for Freescale 3.0Gbps SATA controller.
- 	  It can be found on MPC837x and MPC8315.
--
- 	  If unsure, say N.
- 
-+config SATA_OXNAS_SINGLE_SATA
-+	bool "Force OXNAS family devices to only use one SATA port"
-+	depends on SATA_OX800 || SATA_OX810
-+	default n
-+	help 
-+  	  Prevents the ox800sata module from registering its second sata port, this
-+	  reduces startup time on systems where only one port is physically present
-+	  on the board/chip periphery.
-+
-+config SATA_OXNAS_DISK_LIGHT
-+	bool "Whether OXNAS family device should use a SATA disk activity light"
-+	depends on SATA_OX800 || SATA_OX810
-+	default n
-+
-+config SATA_OXNAS_DISK_LIGHT_GPIO_LINE
-+	int  "GPIO line of the disk light"
-+	depends on SATA_OXNAS_DISK_LIGHT
-+	default 29
-+	help
-+  	  Selects the GPIO line of the disk activity light.
-+
- config PATA_ALI
- 	tristate "ALi PATA support (Experimental)"
- 	depends on PCI && EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/ata/Makefile linux-2.6.24-oxe810/drivers/ata/Makefile
---- linux-2.6.24/drivers/ata/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/Makefile	2008-06-11 17:50:32.000000000 +0200
-@@ -18,6 +18,8 @@
- obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
- obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
- obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
-+obj-$(CONFIG_SATA_OX800)	+= ox800sata.o
-+obj-$(CONFIG_SATA_OX810)	+= ox810sata.o
- 
- obj-$(CONFIG_PATA_ALI)		+= pata_ali.o
- obj-$(CONFIG_PATA_AMD)		+= pata_amd.o
-diff -Nurd linux-2.6.24/drivers/ata/libata-core.c linux-2.6.24-oxe810/drivers/ata/libata-core.c
---- linux-2.6.24/drivers/ata/libata-core.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-core.c	2008-06-11 17:50:32.000000000 +0200
-@@ -140,6 +140,8 @@
-  */
- void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
- {
-+
-+    VPRINTK("\n");
- 	fis[0] = 0x27;			/* Register - Host to Device FIS */
- 	fis[1] = pmp & 0xf;		/* Port multiplier number*/
- 	if (is_cmd)
-@@ -182,6 +184,8 @@
- 
- void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
- {
-+
-+    VPRINTK("\n");
- 	tf->command	= fis[2];	/* status */
- 	tf->feature	= fis[3];	/* error */
- 
-@@ -245,6 +249,8 @@
- 
- 	int index, fua, lba48, write;
- 
-+
-+    VPRINTK("\n");
- 	fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
- 	lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
- 	write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
-@@ -288,6 +294,8 @@
- {
- 	u64 block = 0;
- 
-+
-+    VPRINTK("\n");
- 	if (tf->flags & ATA_TFLAG_LBA) {
- 		if (tf->flags & ATA_TFLAG_LBA48) {
- 			block |= (u64)tf->hob_lbah << 40;
-@@ -336,6 +344,8 @@
- 		    u64 block, u32 n_block, unsigned int tf_flags,
- 		    unsigned int tag)
- {
-+
-+    VPRINTK("\n");
- 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- 	tf->flags |= tf_flags;
- 
-@@ -454,6 +464,8 @@
- 				      unsigned int mwdma_mask,
- 				      unsigned int udma_mask)
- {
-+
-+    VPRINTK("\n");
- 	return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) |
- 		((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
- 		((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
-@@ -474,6 +486,7 @@
- 				unsigned int *mwdma_mask,
- 				unsigned int *udma_mask)
- {
-+    VPRINTK("\n");
- 	if (pio_mask)
- 		*pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO;
- 	if (mwdma_mask)
-@@ -510,6 +523,7 @@
- 	int highbit = fls(xfer_mask) - 1;
- 	const struct ata_xfer_ent *ent;
- 
-+    VPRINTK("\n");
- 	for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- 		if (highbit >= ent->shift && highbit < ent->shift + ent->bits)
- 			return ent->base + highbit - ent->shift;
-@@ -532,6 +546,7 @@
- {
- 	const struct ata_xfer_ent *ent;
- 
-+    VPRINTK("\n");
- 	for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- 		if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
- 			return 1 << (ent->shift + xfer_mode - ent->base);
-@@ -554,6 +569,7 @@
- {
- 	const struct ata_xfer_ent *ent;
- 
-+    VPRINTK("\n");
- 	for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- 		if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
- 			return ent->shift;
-@@ -600,6 +616,7 @@
- 	};
- 	int highbit;
- 
-+    VPRINTK("\n");
- 	highbit = fls(xfer_mask) - 1;
- 	if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str))
- 		return xfer_mode_str[highbit];
-@@ -613,6 +630,7 @@
- 		"3.0 Gbps",
- 	};
- 
-+    VPRINTK("\n");
- 	if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
- 		return "<unknown>";
- 	return spd_str[spd - 1];
-@@ -620,6 +638,7 @@
- 
- void ata_dev_disable(struct ata_device *dev)
- {
-+    VPRINTK("\n");
- 	if (ata_dev_enabled(dev)) {
- 		if (ata_msg_drv(dev->link->ap))
- 			ata_dev_printk(dev, KERN_WARNING, "disabled\n");
-@@ -638,6 +657,7 @@
- 	unsigned int err_mask;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	/*
- 	 * disallow DIPM for drivers which haven't set
- 	 * ATA_FLAG_IPM.  This is because when DIPM is enabled,
-@@ -732,6 +752,7 @@
- 	int rc = 0;
- 	struct ata_port *ap = dev->link->ap;
- 
-+    VPRINTK("\n");
- 	/* set HIPM first, then DIPM */
- 	if (ap->ops->enable_pm)
- 		rc = ap->ops->enable_pm(ap, policy);
-@@ -764,6 +785,7 @@
- {
- 	struct ata_port *ap = dev->link->ap;
- 
-+    VPRINTK("\n");
- 	ata_dev_set_dipm(dev, MAX_PERFORMANCE);
- 	if (ap->ops->disable_pm)
- 		ap->ops->disable_pm(ap);
-@@ -772,6 +794,7 @@
- 
- void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
- {
-+    VPRINTK("\n");
- 	ap->pm_policy = policy;
- 	ap->link.eh_info.action |= ATA_EHI_LPM;
- 	ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY;
-@@ -786,6 +809,7 @@
- 	struct ata_device *dev;
- 	int i;
- 
-+    VPRINTK("\n");
- 	for (i = 0; i < host->n_ports; i++) {
- 		ap = host->ports[i];
- 		ata_port_for_each_link(link, ap) {
-@@ -799,6 +823,7 @@
- {
- 	int i;
- 
-+    VPRINTK("\n");
- 	for (i = 0; i < host->n_ports; i++) {
- 		struct ata_port *ap = host->ports[i];
- 		ata_lpm_schedule(ap, ap->pm_policy);
-@@ -828,6 +853,11 @@
- static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
- {
- 	struct ata_ioports *ioaddr = &ap->ioaddr;
-+    VPRINTK("\n");
-+    if (ap->ops->dev_chk) {
-+        return ap->ops->dev_chk(ap,device);
-+    } else {
-+    
- 	u8 nsect, lbal;
- 
- 	ap->ops->dev_select(ap, device);
-@@ -848,6 +878,7 @@
- 		return 1;	/* we found a device */
- 
- 	return 0;		/* nothing found */
-+    }
- }
- 
- /**
-@@ -938,6 +969,7 @@
- 	unsigned int class;
- 	u8 err;
- 
-+    VPRINTK("\n");
- 	ap->ops->dev_select(ap, dev->devno);
- 
- 	memset(&tf, 0, sizeof(tf));
-@@ -998,6 +1030,7 @@
- {
- 	unsigned int c;
- 
-+    VPRINTK("\n");
- 	while (len > 0) {
- 		c = id[ofs] >> 8;
- 		*s = c;
-@@ -1031,6 +1064,7 @@
- {
- 	unsigned char *p;
- 
-+    VPRINTK("\n");
- 	WARN_ON(!(len & 1));
- 
- 	ata_id_string(id, s, ofs, len - 1);
-@@ -1043,6 +1077,7 @@
- 
- static u64 ata_id_n_sectors(const u16 *id)
- {
-+    VPRINTK("\n");
- 	if (ata_id_has_lba(id)) {
- 		if (ata_id_has_lba48(id))
- 			return ata_id_u64(id, 100);
-@@ -1060,6 +1095,7 @@
- {
- 	u64 sectors = 0;
- 
-+    VPRINTK("\n");
- 	sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
- 	sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
- 	sectors |= (tf->hob_lbal & 0xff) << 24;
-@@ -1074,6 +1110,7 @@
- {
- 	u64 sectors = 0;
- 
-+    VPRINTK("\n");
- 	sectors |= (tf->device & 0x0f) << 24;
- 	sectors |= (tf->lbah & 0xff) << 16;
- 	sectors |= (tf->lbam & 0xff) << 8;
-@@ -1100,6 +1137,7 @@
- 	struct ata_taskfile tf;
- 	int lba48 = ata_id_has_lba48(dev->id);
- 
-+    VPRINTK("\n");
- 	ata_tf_init(dev, &tf);
- 
- 	/* always clear all address registers */
-@@ -1150,6 +1188,7 @@
- 	struct ata_taskfile tf;
- 	int lba48 = ata_id_has_lba48(dev->id);
- 
-+    VPRINTK("\n");
- 	new_sectors--;
- 
- 	ata_tf_init(dev, &tf);
-@@ -1208,6 +1247,7 @@
- 	u64 native_sectors;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	/* do we need to do it? */
- 	if (dev->class != ATA_DEV_ATA ||
- 	    !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
-@@ -1305,6 +1345,7 @@
- 	unsigned int mask;
- 	u8 mode;
- 
-+    VPRINTK("\n");
- 	/* Pack the DMA modes */
- 	mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA;
- 	if (dev->id[53] & 0x04)
-@@ -1341,6 +1382,7 @@
-  */
- void ata_noop_dev_select(struct ata_port *ap, unsigned int device)
- {
-+    VPRINTK("\n");
- }
- 
- 
-@@ -1363,6 +1405,7 @@
- {
- 	u8 tmp;
- 
-+    VPRINTK("\n");
- 	if (device == 0)
- 		tmp = ATA_DEVICE_OBS;
- 	else
-@@ -1394,6 +1437,7 @@
- void ata_dev_select(struct ata_port *ap, unsigned int device,
- 			   unsigned int wait, unsigned int can_sleep)
- {
-+    VPRINTK("\n");
- 	if (ata_msg_probe(ap))
- 		ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
- 				"device %u, wait %u\n", device, wait);
-@@ -1469,6 +1513,7 @@
- 	unsigned int pio_mask, mwdma_mask, udma_mask;
- 
- 	/* Usual case. Word 53 indicates word 64 is valid */
-+    VPRINTK("\n");
- 	if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
- 		pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
- 		pio_mask <<= 3;
-@@ -1571,6 +1616,7 @@
- {
- 	struct completion *waiting = qc->private_data;
- 
-+    VPRINTK("\n");
- 	complete(waiting);
- }
- 
-@@ -1613,6 +1659,7 @@
- 	unsigned int err_mask;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	spin_lock_irqsave(ap->lock, flags);
- 
- 	/* no internal command while frozen */
-@@ -1729,7 +1776,11 @@
- 	*tf = qc->result_tf;
- 	err_mask = qc->err_mask;
- 
--	ata_qc_free(qc);
-+	if (ap->ops->qc_free) {
-+        ap->ops->qc_free(qc);
-+    } else {
-+        ata_qc_free(qc);
-+    }
- 	link->active_tag = preempted_tag;
- 	link->sactive = preempted_sactive;
- 	ap->qc_active = preempted_qc_active;
-@@ -1783,6 +1834,7 @@
- 	struct scatterlist *psg = NULL, sg;
- 	unsigned int n_elem = 0;
- 
-+    VPRINTK("\n");
- 	if (dma_dir != DMA_NONE) {
- 		WARN_ON(!buf);
- 		sg_init_one(&sg, buf, buflen);
-@@ -1812,6 +1864,7 @@
- {
- 	struct ata_taskfile tf;
- 
-+    VPRINTK("\n");
- 	ata_tf_init(dev, &tf);
- 
- 	tf.command = cmd;
-@@ -1831,6 +1884,7 @@
- 
- unsigned int ata_pio_need_iordy(const struct ata_device *adev)
- {
-+    VPRINTK("\n");
- 	/* Controller doesn't support  IORDY. Probably a pointless check
- 	   as the caller should know this */
- 	if (adev->link->ap->flags & ATA_FLAG_NO_IORDY)
-@@ -1854,6 +1908,7 @@
- 
- static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
- {
-+    VPRINTK("\n");
- 	/* If we have no drive specific rule, then PIO 2 is non IORDY */
- 	if (adev->id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE */
- 		u16 pio = adev->id[ATA_ID_EIDE_PIO];
-@@ -1900,12 +1955,15 @@
- 	int may_fallback = 1, tried_spinup = 0;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	if (ata_msg_ctl(ap))
- 		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
- 
- 	ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
-  retry:
- 	ata_tf_init(dev, &tf);
-+    
-+    tf.device |= ATA_LBA ;
- 
- 	switch (class) {
- 	case ATA_DEV_ATA:
-@@ -2043,6 +2101,7 @@
- static inline u8 ata_dev_knobble(struct ata_device *dev)
- {
- 	struct ata_port *ap = dev->link->ap;
-+    VPRINTK("\n");
- 	return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
- }
- 
-@@ -2052,6 +2111,7 @@
- 	struct ata_port *ap = dev->link->ap;
- 	int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
- 
-+    VPRINTK("\n");
- 	if (!ata_id_has_ncq(dev->id)) {
- 		desc[0] = '\0';
- 		return;
-@@ -2096,6 +2156,7 @@
- 	char modelbuf[ATA_ID_PROD_LEN+1];
- 	int rc;
- 
-+    VPRINTK("\n");
- 	if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
- 		ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",
- 			       __FUNCTION__);
-@@ -2334,7 +2395,7 @@
- 	}
- 
- 	if (ap->ops->dev_config)
--		ap->ops->dev_config(dev);
-+		ap->ops->dev_config(ap, dev);
- 
- 	if (ata_msg_probe(ap))
- 		ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
-@@ -2358,6 +2419,7 @@
- 
- int ata_cable_40wire(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	return ATA_CBL_PATA40;
- }
- 
-@@ -2371,6 +2433,7 @@
- 
- int ata_cable_80wire(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	return ATA_CBL_PATA80;
- }
- 
-@@ -2383,6 +2446,7 @@
- 
- int ata_cable_unknown(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	return ATA_CBL_PATA_UNK;
- }
- 
-@@ -2395,6 +2459,7 @@
- 
- int ata_cable_sata(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	return ATA_CBL_SATA;
- }
- 
-@@ -2420,6 +2485,7 @@
- 	int rc;
- 	struct ata_device *dev;
- 
-+    VPRINTK("\n");
- 	ata_port_probe(ap);
- 
- 	ata_link_for_each_dev(dev, &ap->link)
-@@ -2560,6 +2626,7 @@
- 
- void ata_port_probe(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	ap->flags &= ~ATA_FLAG_DISABLED;
- }
- 
-@@ -2576,6 +2643,7 @@
- {
- 	u32 sstatus, scontrol, tmp;
- 
-+    VPRINTK("\n");
- 	if (sata_scr_read(link, SCR_STATUS, &sstatus))
- 		return;
- 	sata_scr_read(link, SCR_CONTROL, &scontrol);
-@@ -2604,6 +2672,7 @@
- {
- 	struct ata_link *link = adev->link;
- 	struct ata_device *pair = &link->device[1 - adev->devno];
-+    VPRINTK("\n");
- 	if (!ata_dev_enabled(pair))
- 		return NULL;
- 	return pair;
-@@ -2624,6 +2693,7 @@
- 
- void ata_port_disable(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	ap->link.device[0].class = ATA_DEV_NONE;
- 	ap->link.device[1].class = ATA_DEV_NONE;
- 	ap->flags |= ATA_FLAG_DISABLED;
-@@ -2648,6 +2718,7 @@
- 	u32 sstatus, spd, mask;
- 	int rc, highbit;
- 
-+    VPRINTK("\n");
- 	if (!sata_scr_valid(link))
- 		return -EOPNOTSUPP;
- 
-@@ -2693,6 +2764,7 @@
- 	struct ata_link *host_link = &link->ap->link;
- 	u32 limit, target, spd;
- 
-+    VPRINTK("\n");
- 	limit = link->sata_spd_limit;
- 
- 	/* Don't configure downstream link faster than upstream link.
-@@ -2732,6 +2804,7 @@
- {
- 	u32 scontrol;
- 
-+    VPRINTK("\n");
- 	if (sata_scr_read(link, SCR_CONTROL, &scontrol))
- 		return 1;
- 
-@@ -2756,6 +2829,7 @@
- 	u32 scontrol;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
- 		return rc;
- 
-@@ -2822,6 +2896,7 @@
- 
- static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
- {
-+    VPRINTK("\n");
- 	q->setup   = EZ(t->setup   * 1000,  T);
- 	q->act8b   = EZ(t->act8b   * 1000,  T);
- 	q->rec8b   = EZ(t->rec8b   * 1000,  T);
-@@ -2835,6 +2910,7 @@
- void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
- 		      struct ata_timing *m, unsigned int what)
- {
-+    VPRINTK("\n");
- 	if (what & ATA_TIMING_SETUP  ) m->setup   = max(a->setup,   b->setup);
- 	if (what & ATA_TIMING_ACT8B  ) m->act8b   = max(a->act8b,   b->act8b);
- 	if (what & ATA_TIMING_REC8B  ) m->rec8b   = max(a->rec8b,   b->rec8b);
-@@ -2849,6 +2925,7 @@
- {
- 	const struct ata_timing *t;
- 
-+    VPRINTK("\n");
- 	for (t = ata_timing; t->mode != speed; t++)
- 		if (t->mode == 0xFF)
- 			return NULL;
-@@ -2861,6 +2938,7 @@
- 	const struct ata_timing *s;
- 	struct ata_timing p;
- 
-+    VPRINTK("\n");
- 	/*
- 	 * Find the mode.
- 	 */
-@@ -2948,6 +3026,7 @@
- 	unsigned int pio_mask, mwdma_mask, udma_mask;
- 	int quiet, highbit;
- 
-+    VPRINTK("\n");
- 	quiet = !!(sel & ATA_DNXFER_QUIET);
- 	sel &= ~ATA_DNXFER_QUIET;
- 
-@@ -3021,6 +3100,7 @@
- 	unsigned int err_mask;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	dev->flags &= ~ATA_DFLAG_PIO;
- 	if (dev->xfer_shift == ATA_SHIFT_PIO)
- 		dev->flags |= ATA_DFLAG_PIO;
-@@ -3087,6 +3167,7 @@
- 	struct ata_device *dev;
- 	int rc = 0, used_dma = 0, found = 0;
- 
-+    VPRINTK("\n");
- 	/* step 1: calculate xfer_mask */
- 	ata_link_for_each_dev(dev, link) {
- 		unsigned int pio_mask, dma_mask;
-@@ -3191,6 +3272,7 @@
- {
- 	struct ata_port *ap = link->ap;
- 
-+    VPRINTK("\n");
- 	/* has private set_mode? */
- 	if (ap->ops->set_mode)
- 		return ap->ops->set_mode(link, r_failed_dev);
-@@ -3213,6 +3295,7 @@
- static inline void ata_tf_to_host(struct ata_port *ap,
- 				  const struct ata_taskfile *tf)
- {
-+    VPRINTK("\n");
- 	ap->ops->tf_load(ap, tf);
- 	ap->ops->exec_command(ap, tf);
- }
-@@ -3238,6 +3321,7 @@
- 	unsigned long timer_start, timeout;
- 	u8 status;
- 
-+    VPRINTK("\n");
- 	status = ata_busy_wait(ap, ATA_BUSY, 300);
- 	timer_start = jiffies;
- 	timeout = timer_start + tmout_pat;
-@@ -3291,6 +3375,7 @@
- {
- 	unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
- 
-+    VPRINTK("\n");
- 	if (time_before(until, deadline))
- 		deadline = until;
- 
-@@ -3346,6 +3431,7 @@
- 	unsigned long start = jiffies;
- 	int warned = 0;
- 
-+    VPRINTK("\n");
- 	while (1) {
- 		u8 status = ata_chk_status(ap);
- 		unsigned long now = jiffies;
-@@ -3377,6 +3463,7 @@
- 	unsigned int dev1 = devmask & (1 << 1);
- 	int rc, ret = 0;
- 
-+    VPRINTK("\n");
- 	/* if device 0 was found in ata_devchk, wait for its
- 	 * BSY bit to clear
- 	 */
-@@ -3432,19 +3519,36 @@
- static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
- 			     unsigned long deadline)
- {
--	struct ata_ioports *ioaddr = &ap->ioaddr;
-+	/* create a task file to control ctl register */
-+	struct ata_taskfile tf ; 
- 
- 	DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
- 
-+	memset(&tf, 0, sizeof(tf));
-+#if 0 
- 	/* software reset.  causes dev0 to be selected */
--	iowrite8(ap->ctl, ioaddr->ctl_addr);
-+	tf.ctl = ap->ctl;
-+	ap->ops->tf_load(ap,&tf);
- 	udelay(20);	/* FIXME: flush */
--	iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-+
-+	tf.ctl = ap->ctl | ATA_SRST;
-+	ap->ops->tf_load(ap,&tf);
- 	udelay(20);	/* FIXME: flush */
--	iowrite8(ap->ctl, ioaddr->ctl_addr);
-+    
-+	tf.ctl = ap->ctl;
-+	ap->ops->tf_load(ap,&tf);
- 
--	/* wait a while before checking status */
--	ata_wait_after_reset(ap, deadline);
-+	/* spec mandates ">= 2ms" before checking status.
-+	 * We wait 150ms, because that was the magic delay used for
-+	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-+	 * between when the ATA command register is written, and then
-+	 * status is checked.  Because waiting for "a while" before
-+	 * checking status is fine, post SRST, we perform this magic
-+	 * delay here as well.
-+	 *
-+	 * Old drivers/ide uses the 2mS rule and then waits for ready
-+	 */
-+	msleep(150);
- 
- 	/* Before we perform post reset processing we want to see if
- 	 * the bus shows 0xFF because the odd clown forgets the D7
-@@ -3452,7 +3556,7 @@
- 	 */
- 	if (ata_chk_status(ap) == 0xFF)
- 		return -ENODEV;
--
-+#endif
- 	return ata_bus_post_reset(ap, devmask, deadline);
- }
- 
-@@ -3479,7 +3583,6 @@
- void ata_bus_reset(struct ata_port *ap)
- {
- 	struct ata_device *device = ap->link.device;
--	struct ata_ioports *ioaddr = &ap->ioaddr;
- 	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
- 	u8 err;
- 	unsigned int dev0, dev1 = 0, devmask = 0;
-@@ -3530,8 +3633,11 @@
- 		goto err_out;
- 
- 	if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
-+        /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+        #if 0
- 		/* set up device control for ATA_FLAG_SATA_RESET */
- 		iowrite8(ap->ctl, ioaddr->ctl_addr);
-+        #endif
- 	}
- 
- 	DPRINTK("EXIT\n");
-@@ -3575,6 +3681,7 @@
- 	u32 last, cur;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	t = jiffies + msecs_to_jiffies(params[2]);
- 	if (time_before(t, deadline))
- 		deadline = t;
-@@ -3633,6 +3740,7 @@
- 	u32 scontrol;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
- 		return rc;
- 
-@@ -3673,6 +3781,7 @@
- 	const unsigned long *timing = sata_ehc_deb_timing(ehc);
- 	int rc;
- 
-+    VPRINTK("\n");
- 	/* handle link resume */
- 	if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
- 	    (link->flags & ATA_LFLAG_HRST_TO_RESUME))
-@@ -3939,9 +4048,12 @@
- 		return;
- 	}
- 
-+    /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+    #if 0
- 	/* set up device control */
- 	if (ap->ioaddr.ctl_addr)
- 		iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-+    #endif
- 
- 	DPRINTK("EXIT\n");
- }
-@@ -3969,6 +4081,7 @@
- 	unsigned char model[2][ATA_ID_PROD_LEN + 1];
- 	unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
- 
-+    VPRINTK("\n");
- 	if (dev->class != new_class) {
- 		ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
- 			       dev->class, new_class);
-@@ -4015,6 +4128,7 @@
- 	u16 *id = (void *)dev->link->ap->sector_buf;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	/* read ID data */
- 	rc = ata_dev_read_id(dev, &class, readid_flags, id);
- 	if (rc)
-@@ -4049,6 +4163,7 @@
- 	u64 n_sectors = dev->n_sectors;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	if (!ata_dev_enabled(dev))
- 		return -ENODEV;
- 
-@@ -4186,6 +4301,7 @@
- 	const char *p;
- 	int len;
- 
-+    VPRINTK("\n");
- 	/*
- 	 * check for trailing wildcard: *\0
- 	 */
-@@ -4210,6 +4326,7 @@
- 	unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
- 	const struct ata_blacklist_entry *ad = ata_device_blacklist;
- 
-+    VPRINTK("\n");
- 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- 	ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
- 
-@@ -4227,6 +4344,7 @@
- 
- static int ata_dma_blacklisted(const struct ata_device *dev)
- {
-+    VPRINTK("\n");
- 	/* We don't support polling DMA.
- 	 * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
- 	 * if the LLDD handles only interrupts in the HSM_ST_LAST state.
-@@ -4247,6 +4365,7 @@
- 
- static int ata_is_40wire(struct ata_device *dev)
- {
-+    VPRINTK("\n");
- 	if (dev->horkage & ATA_HORKAGE_IVB)
- 		return ata_drive_40wire_relaxed(dev->id);
- 	return ata_drive_40wire(dev->id);
-@@ -4271,6 +4390,7 @@
- 	struct ata_host *host = ap->host;
- 	unsigned long xfer_mask;
- 
-+    VPRINTK("\n");
- 	/* controller modes available */
- 	xfer_mask = ata_pack_xfermask(ap->pio_mask,
- 				      ap->mwdma_mask, ap->udma_mask);
-@@ -4525,6 +4645,7 @@
- 	struct scatterlist *sg;
- 	unsigned int idx;
- 
-+    VPRINTK("\n");
- 	WARN_ON(qc->__sg == NULL);
- 	WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
- 
-@@ -4579,6 +4700,7 @@
- 	struct scatterlist *sg;
- 	unsigned int idx;
- 
-+    VPRINTK("\n");
- 	WARN_ON(qc->__sg == NULL);
- 	WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
- 
-@@ -4640,6 +4762,7 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
- 	/* Don't allow DMA if it isn't multiple of 16 bytes.  Quite a
- 	 * few ATAPI devices choke on such DMA requests.
- 	 */
-@@ -4669,6 +4792,7 @@
-  */
- static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	if (qc->tf.protocol != ATA_PROT_ATAPI &&
- 	    qc->tf.protocol != ATA_PROT_ATAPI_DMA)
- 		return 0;
-@@ -4708,6 +4832,7 @@
- {
- 	struct ata_link *link = qc->dev->link;
- 
-+    VPRINTK("\n");
- 	if (qc->tf.protocol == ATA_PROT_NCQ) {
- 		if (!ata_tag_valid(link->active_tag))
- 			return 0;
-@@ -4730,6 +4855,7 @@
-  */
- void ata_qc_prep(struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- 		return;
- 
-@@ -4747,6 +4873,7 @@
-  */
- void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- 		return;
- 
-@@ -4770,6 +4897,7 @@
- 
- void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
- {
-+    VPRINTK("\n");
- 	qc->flags |= ATA_QCFLAG_SINGLE;
- 
- 	qc->__sg = &qc->sgent;
-@@ -4799,6 +4927,7 @@
- void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
- 		 unsigned int n_elem)
- {
-+    VPRINTK("\n");
- 	qc->flags |= ATA_QCFLAG_SG;
- 	qc->__sg = sg;
- 	qc->n_elem = n_elem;
-@@ -4827,6 +4956,7 @@
- 	dma_addr_t dma_address;
- 	int trim_sg = 0;
- 
-+    VPRINTK("\n");
- 	/* we must lengthen transfers to end on a 32-bit boundary */
- 	qc->pad_len = sg->length & 3;
- 	if (qc->pad_len) {
-@@ -5001,6 +5131,7 @@
- 	struct ata_port *ap = adev->link->ap;
- 	unsigned int words = buflen >> 1;
- 
-+    VPRINTK("\n");
- 	/* Transfer multiple of 2 bytes */
- 	if (write_data)
- 		iowrite16_rep(ap->ioaddr.data_addr, buf, words);
-@@ -5039,6 +5170,7 @@
- 			 unsigned int buflen, int write_data)
- {
- 	unsigned long flags;
-+    VPRINTK("\n");
- 	local_irq_save(flags);
- 	ata_data_xfer(adev, buf, buflen, write_data);
- 	local_irq_restore(flags);
-@@ -5063,6 +5195,7 @@
- 	unsigned int offset;
- 	unsigned char *buf;
- 
-+    VPRINTK("\n");
- 	if (qc->curbytes == qc->nbytes - qc->sect_size)
- 		ap->hsm_task_state = HSM_ST_LAST;
- 
-@@ -5114,6 +5247,7 @@
- 
- static void ata_pio_sectors(struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	if (is_multi_taskfile(&qc->tf)) {
- 		/* READ/WRITE MULTIPLE */
- 		unsigned int nsect;
-@@ -5187,6 +5321,7 @@
- 	unsigned char *buf;
- 	unsigned int offset, count;
- 
-+    VPRINTK("\n");
- next_sg:
- 	sg = qc->cursg;
- 	if (unlikely(!sg)) {
-@@ -5287,6 +5422,7 @@
- 	unsigned int ireason, bc_lo, bc_hi, bytes;
- 	int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
- 
-+    VPRINTK("\n");
- 	/* Abuse qc->result_tf for temp storage of intermediate TF
- 	 * here to save some kernel stack usage.
- 	 * For normal completion, qc->result_tf is not relevant. For
-@@ -5333,6 +5469,7 @@
- 
- static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	if (qc->tf.flags & ATA_TFLAG_POLLING)
- 		return 1;
- 
-@@ -5365,6 +5502,7 @@
- 	struct ata_port *ap = qc->ap;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
- 	if (ap->ops->error_handler) {
- 		if (in_wq) {
- 			spin_lock_irqsave(ap->lock, flags);
-@@ -5415,6 +5553,7 @@
- 	unsigned long flags = 0;
- 	int poll_next;
- 
-+    VPRINTK("\n");
- 	WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
- 
- 	/* Make sure ata_qc_issue_prot() does not throw things
-@@ -5649,6 +5788,7 @@
- 	u8 status;
- 	int poll_next;
- 
-+    VPRINTK("\n");
- fsm_start:
- 	WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
- 
-@@ -5664,6 +5804,9 @@
- 		msleep(2);
- 		status = ata_busy_wait(ap, ATA_BUSY, 10);
- 		if (status & ATA_BUSY) {
-+        if (ap->ops->pio_task)
-+            ata_port_queue_task(ap, ap->ops->pio_task, qc, ATA_SHORT_PAUSE);
-+        else
- 			ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE);
- 			return;
- 		}
-@@ -5693,6 +5836,7 @@
- 	struct ata_queued_cmd *qc = NULL;
- 	unsigned int i;
- 
-+    VPRINTK("\n");
- 	/* no command while frozen */
- 	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
- 		return NULL;
-@@ -5723,7 +5867,14 @@
- 	struct ata_port *ap = dev->link->ap;
- 	struct ata_queued_cmd *qc;
- 
--	qc = ata_qc_new(ap);
-+    VPRINTK("\n");
-+    /* if a specialised version is not available, call the default */
-+    if (ap->ops->qc_new) {
-+        qc = ap->ops->qc_new(ap);
-+    } else {
-+        qc = ata_qc_new(ap);
-+    }
-+
- 	if (qc) {
- 		qc->scsicmd = NULL;
- 		qc->ap = ap;
-@@ -5750,6 +5901,7 @@
- 	struct ata_port *ap = qc->ap;
- 	unsigned int tag;
- 
-+    VPRINTK("\n");
- 	WARN_ON(qc == NULL);	/* ata_qc_from_tag _might_ return NULL */
- 
- 	qc->flags = 0;
-@@ -5765,6 +5917,7 @@
- 	struct ata_port *ap = qc->ap;
- 	struct ata_link *link = qc->dev->link;
- 
-+    VPRINTK("\n");
- 	WARN_ON(qc == NULL);	/* ata_qc_from_tag _might_ return NULL */
- 	WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
- 
-@@ -5801,6 +5954,7 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
- 	qc->result_tf.flags = qc->tf.flags;
- 	ap->ops->tf_read(ap, &qc->result_tf);
- }
-@@ -5820,6 +5974,7 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
- 	/* XXX: New EH and old EH use different mechanisms to
- 	 * synchronize EH with regular execution path.
- 	 *
-@@ -5913,6 +6068,7 @@
- 	u32 done_mask;
- 	int i;
- 
-+    VPRINTK("\n");
- 	done_mask = ap->qc_active ^ qc_active;
- 
- 	if (unlikely(done_mask & qc_active)) {
-@@ -5942,6 +6098,7 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
- 	switch (qc->tf.protocol) {
- 	case ATA_PROT_NCQ:
- 	case ATA_PROT_DMA:
-@@ -5979,6 +6136,7 @@
- 	struct ata_port *ap = qc->ap;
- 	struct ata_link *link = qc->dev->link;
- 
-+    VPRINTK("\n");
- 	/* Make sure only one non-NCQ command is outstanding.  The
- 	 * check is skipped for old EH because it reuses active qc to
- 	 * request ATAPI sense.
-@@ -6057,6 +6215,7 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
- 	/* Use polling pio if the LLD doesn't handle
- 	 * interrupt driven pio and atapi CDB interrupt.
- 	 */
-@@ -6084,18 +6243,24 @@
- 	/* start the command */
- 	switch (qc->tf.protocol) {
- 	case ATA_PROT_NODATA:
-+        VPRINTK("ATA_PROT_NODATA\n");
- 		if (qc->tf.flags & ATA_TFLAG_POLLING)
- 			ata_qc_set_polling(qc);
- 
- 		ata_tf_to_host(ap, &qc->tf);
- 		ap->hsm_task_state = HSM_ST_LAST;
- 
--		if (qc->tf.flags & ATA_TFLAG_POLLING)
-+		if (qc->tf.flags & ATA_TFLAG_POLLING) {
-+            if (ap->ops->pio_task)
-+                ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+            else
- 			ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+        }
- 
- 		break;
- 
- 	case ATA_PROT_DMA:
-+        VPRINTK("ATA_PROT_DMA\n");
- 		WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
- 
- 		ap->ops->tf_load(ap, &qc->tf);	 /* load tf registers */
-@@ -6105,6 +6270,7 @@
- 		break;
- 
- 	case ATA_PROT_PIO:
-+        VPRINTK("ATA_PROT_PIO\n");
- 		if (qc->tf.flags & ATA_TFLAG_POLLING)
- 			ata_qc_set_polling(qc);
- 
-@@ -6113,6 +6279,9 @@
- 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
- 			/* PIO data out protocol */
- 			ap->hsm_task_state = HSM_ST_FIRST;
-+            if (ap->ops->pio_task)
-+                ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+            else
- 			ata_port_queue_task(ap, ata_pio_task, qc, 0);
- 
- 			/* always send first data block using
-@@ -6122,8 +6291,12 @@
- 			/* PIO data in protocol */
- 			ap->hsm_task_state = HSM_ST;
- 
--			if (qc->tf.flags & ATA_TFLAG_POLLING)
-+			if (qc->tf.flags & ATA_TFLAG_POLLING) {
-+                if (ap->ops->pio_task)
-+                    ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+                else
- 				ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+            }
- 
- 			/* if polling, ata_pio_task() handles the rest.
- 			 * otherwise, interrupt handler takes over from here.
-@@ -6134,6 +6307,7 @@
- 
- 	case ATA_PROT_ATAPI:
- 	case ATA_PROT_ATAPI_NODATA:
-+        VPRINTK("ATA_PROT_ATAPI / ATA_PROT_ATAPI_NODATA\n");
- 		if (qc->tf.flags & ATA_TFLAG_POLLING)
- 			ata_qc_set_polling(qc);
- 
-@@ -6143,11 +6317,16 @@
- 
- 		/* send cdb by polling if no cdb interrupt */
- 		if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
--		    (qc->tf.flags & ATA_TFLAG_POLLING))
-+		    (qc->tf.flags & ATA_TFLAG_POLLING)) {
-+            if (ap->ops->pio_task)
-+                ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+            else
- 			ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+        }
- 		break;
- 
- 	case ATA_PROT_ATAPI_DMA:
-+        VPRINTK("ATA_PROT_ATAPI_DMA\n");
- 		WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
- 
- 		ap->ops->tf_load(ap, &qc->tf);	 /* load tf registers */
-@@ -6155,8 +6334,12 @@
- 		ap->hsm_task_state = HSM_ST_FIRST;
- 
- 		/* send cdb by polling if no cdb interrupt */
--		if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
-+		if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) {
-+            if (ap->ops->pio_task)
-+                ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+            else
- 			ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+        }
- 		break;
- 
- 	default:
-@@ -6291,6 +6474,7 @@
- 	unsigned int handled = 0;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
- 	/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
- 	spin_lock_irqsave(&host->lock, flags);
- 
-@@ -6330,6 +6514,7 @@
- {
- 	struct ata_port *ap = link->ap;
- 
-+    VPRINTK("\n");
- 	return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
- }
- 
-@@ -6351,6 +6536,7 @@
-  */
- int sata_scr_read(struct ata_link *link, int reg, u32 *val)
- {
-+    VPRINTK("\n");
- 	if (ata_is_host_link(link)) {
- 		struct ata_port *ap = link->ap;
- 
-@@ -6380,6 +6566,7 @@
-  */
- int sata_scr_write(struct ata_link *link, int reg, u32 val)
- {
-+    VPRINTK("\n");
- 	if (ata_is_host_link(link)) {
- 		struct ata_port *ap = link->ap;
- 
-@@ -6408,6 +6595,7 @@
-  */
- int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
- {
-+    VPRINTK("\n");
- 	if (ata_is_host_link(link)) {
- 		struct ata_port *ap = link->ap;
- 		int rc;
-@@ -6442,6 +6630,7 @@
- {
- 	u32 sstatus;
- 
-+    VPRINTK("\n");
- 	if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- 	    (sstatus & 0xf) == 0x3)
- 		return 1;
-@@ -6466,6 +6655,7 @@
- {
- 	u32 sstatus;
- 
-+    VPRINTK("\n");
- 	if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- 	    (sstatus & 0xf) != 0x3)
- 		return 1;
-@@ -6477,6 +6667,7 @@
- 	unsigned int err_mask;
- 	u8 cmd;
- 
-+    VPRINTK("\n");
- 	if (!ata_try_flush_cache(dev))
- 		return 0;
- 
-@@ -6506,6 +6697,7 @@
- 	unsigned long flags;
- 	int i, rc;
- 
-+    VPRINTK("\n");
- 	for (i = 0; i < host->n_ports; i++) {
- 		struct ata_port *ap = host->ports[i];
- 		struct ata_link *link;
-@@ -6568,6 +6760,7 @@
- {
- 	int rc;
- 
-+    VPRINTK("\n");
- 	/*
- 	 * disable link pm on all ports before requesting
- 	 * any pm activity
-@@ -6593,6 +6786,7 @@
-  */
- void ata_host_resume(struct ata_host *host)
- {
-+    VPRINTK("\n");
- 	ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
- 			    ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
- 	host->dev->power.power_state = PMSG_ON;
-@@ -6619,6 +6813,7 @@
- 	struct device *dev = ap->dev;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
- 				      GFP_KERNEL);
- 	if (!ap->prd)
-@@ -6648,6 +6843,7 @@
- 	struct ata_port *ap = link->ap;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
- 	/* SATA spd limit is bound to the first device */
- 	link->sata_spd_limit = link->hw_sata_spd_limit;
- 	link->sata_spd = 0;
-@@ -6683,6 +6879,7 @@
- {
- 	int i;
- 
-+    VPRINTK("\n");
- 	/* clear everything except for devices */
- 	memset(link, 0, offsetof(struct ata_link, device[0]));
- 
-@@ -6719,6 +6916,7 @@
- 	u32 scontrol, spd;
- 	int rc;
- 
-+    VPRINTK("\n");
- 	rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
- 	if (rc)
- 		return rc;
-@@ -6797,6 +6995,7 @@
- 	struct ata_host *host = dev_get_drvdata(gendev);
- 	int i;
- 
-+    VPRINTK("\n");
- 	for (i = 0; i < host->n_ports; i++) {
- 		struct ata_port *ap = host->ports[i];
- 
-@@ -6903,6 +7102,7 @@
- 	struct ata_host *host;
- 	int i, j;
- 
-+    VPRINTK("\n");
- 	host = ata_host_alloc(dev, n_ports);
- 	if (!host)
- 		return NULL;
-@@ -6934,6 +7134,7 @@
- 	struct ata_host *host = dev_get_drvdata(gendev);
- 	int i;
- 
-+    VPRINTK("\n");
- 	WARN_ON(!(host->flags & ATA_HOST_STARTED));
- 
- 	for (i = 0; i < host->n_ports; i++) {
-@@ -6969,6 +7170,8 @@
- 	void *start_dr = NULL;
- 	int i, rc;
- 
-+    VPRINTK("\n");
-+
- 	if (host->flags & ATA_HOST_STARTED)
- 		return 0;
- 
-@@ -7007,6 +7210,7 @@
- 		ata_eh_freeze_port(ap);
- 	}
- 
-+    
- 	if (start_dr)
- 		devres_add(host->dev, start_dr);
- 	host->flags |= ATA_HOST_STARTED;
-@@ -7038,6 +7242,7 @@
- void ata_host_init(struct ata_host *host, struct device *dev,
- 		   unsigned long flags, const struct ata_port_operations *ops)
- {
-+    VPRINTK("\n");
- 	spin_lock_init(&host->lock);
- 	host->dev = dev;
- 	host->flags = flags;
-@@ -7064,6 +7269,7 @@
- {
- 	int i, rc;
- 
-+    VPRINTK("\n");
- 	/* host must have been started */
- 	if (!(host->flags & ATA_HOST_STARTED)) {
- 		dev_printk(KERN_ERR, host->dev,
-@@ -7203,6 +7409,7 @@
- {
- 	int i, rc;
- 
-+    VPRINTK("\n");
- 	rc = ata_host_start(host);
- 	if (rc)
- 		return rc;
-@@ -7246,6 +7453,7 @@
- 	struct ata_link *link;
- 	struct ata_device *dev;
- 
-+    VPRINTK("\n");
- 	if (!ap->ops->error_handler)
- 		goto skip_eh;
- 
-@@ -7293,6 +7501,7 @@
- {
- 	int i;
- 
-+    VPRINTK("\n");
- 	for (i = 0; i < host->n_ports; i++)
- 		ata_port_detach(host->ports[i]);
- 
-@@ -7314,6 +7523,7 @@
- 
- void ata_std_ports(struct ata_ioports *ioaddr)
- {
-+    VPRINTK("\n");
- 	ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
- 	ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
- 	ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
-@@ -7345,6 +7555,7 @@
- 	struct device *dev = &pdev->dev;
- 	struct ata_host *host = dev_get_drvdata(dev);
- 
-+    VPRINTK("\n");
- 	ata_host_detach(host);
- }
- 
-@@ -7353,6 +7564,7 @@
- {
- 	unsigned long tmp = 0;
- 
-+    VPRINTK("\n");
- 	switch (bits->width) {
- 	case 1: {
- 		u8 tmp8 = 0;
-@@ -7385,6 +7597,7 @@
- #ifdef CONFIG_PM
- void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
- {
-+    VPRINTK("\n");
- 	pci_save_state(pdev);
- 	pci_disable_device(pdev);
- 
-@@ -7396,6 +7609,7 @@
- {
- 	int rc;
- 
-+    VPRINTK("\n");
- 	pci_set_power_state(pdev, PCI_D0);
- 	pci_restore_state(pdev);
- 
-@@ -7415,6 +7629,7 @@
- 	struct ata_host *host = dev_get_drvdata(&pdev->dev);
- 	int rc = 0;
- 
-+    VPRINTK("\n");
- 	rc = ata_host_suspend(host, mesg);
- 	if (rc)
- 		return rc;
-@@ -7429,6 +7644,7 @@
- 	struct ata_host *host = dev_get_drvdata(&pdev->dev);
- 	int rc;
- 
-+    VPRINTK("\n");
- 	rc = ata_pci_device_do_resume(pdev);
- 	if (rc == 0)
- 		ata_host_resume(host);
-@@ -7442,6 +7658,7 @@
- static int __init ata_init(void)
- {
- 	ata_probe_timeout *= HZ;
-+    VPRINTK("\n");
- 	ata_wq = create_workqueue("ata");
- 	if (!ata_wq)
- 		return -ENOMEM;
-@@ -7458,6 +7675,7 @@
- 
- static void __exit ata_exit(void)
- {
-+    VPRINTK("\n");
- 	destroy_workqueue(ata_wq);
- 	destroy_workqueue(ata_aux_wq);
- }
-@@ -7473,6 +7691,7 @@
- 	int rc;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
- 	spin_lock_irqsave(&ata_ratelimit_lock, flags);
- 
- 	if (time_after(jiffies, ratelimit_time)) {
-@@ -7516,6 +7735,7 @@
- 	unsigned long timeout;
- 	u32 tmp;
- 
-+    VPRINTK("\n");
- 	tmp = ioread32(reg);
- 
- 	/* Calculate timeout _after_ the first read to make sure
-@@ -7541,11 +7761,13 @@
- 
- static u8 ata_dummy_check_status(struct ata_port *ap)
- {
-+    VPRINTK("\n");
- 	return ATA_DRDY;
- }
- 
- static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
- {
-+    VPRINTK("\n");
- 	return AC_ERR_SYSTEM;
- }
- 
-diff -Nurd linux-2.6.24/drivers/ata/libata-eh.c linux-2.6.24-oxe810/drivers/ata/libata-eh.c
---- linux-2.6.24/drivers/ata/libata-eh.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-eh.c	2008-06-11 17:50:32.000000000 +0200
-@@ -89,6 +89,8 @@
- static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
- 				 va_list args)
- {
-+    VPRINTK("\n");
-+
- 	ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
- 				     ATA_EH_DESC_LEN - ehi->desc_len,
- 				     fmt, args);
-@@ -108,6 +110,8 @@
- {
- 	va_list args;
- 
-+    VPRINTK("\n");
-+
- 	va_start(args, fmt);
- 	__ata_ehi_pushv_desc(ehi, fmt, args);
- 	va_end(args);
-@@ -128,6 +132,8 @@
- {
- 	va_list args;
- 
-+    VPRINTK("\n");
-+
- 	if (ehi->desc_len)
- 		__ata_ehi_push_desc(ehi, ", ");
- 
-@@ -147,6 +153,8 @@
-  */
- void ata_ehi_clear_desc(struct ata_eh_info *ehi)
- {
-+    VPRINTK("\n");
-+
- 	ehi->desc[0] = '\0';
- 	ehi->desc_len = 0;
- }
-@@ -168,6 +176,8 @@
- {
- 	va_list args;
- 
-+    VPRINTK("\n");
-+
- 	WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING));
- 
- 	if (ap->link.eh_info.desc_len)
-@@ -202,6 +212,8 @@
- 	char *type = "";
- 	unsigned long long start, len;
- 
-+    VPRINTK("\n");
-+
- 	if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
- 		type = "m";
- 	else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
-@@ -223,6 +235,8 @@
- {
- 	struct ata_ering_entry *ent;
- 
-+    VPRINTK("\n");
-+
- 	WARN_ON(!err_mask);
- 
- 	ering->cursor++;
-@@ -236,6 +250,8 @@
- 
- static void ata_ering_clear(struct ata_ering *ering)
- {
-+    VPRINTK("\n");
-+
- 	memset(ering, 0, sizeof(*ering));
- }
- 
-@@ -246,6 +262,8 @@
- 	int idx, rc = 0;
- 	struct ata_ering_entry *ent;
- 
-+    VPRINTK("\n");
-+
- 	idx = ering->cursor;
- 	do {
- 		ent = &ering->ring[idx];
-@@ -264,6 +282,8 @@
- {
- 	struct ata_eh_context *ehc = &dev->link->eh_context;
- 
-+    VPRINTK("\n");
-+
- 	return ehc->i.action | ehc->i.dev_action[dev->devno];
- }
- 
-@@ -272,6 +292,8 @@
- {
- 	struct ata_device *tdev;
- 
-+    VPRINTK("\n");
-+
- 	if (!dev) {
- 		ehi->action &= ~action;
- 		ata_link_for_each_dev(tdev, link)
-@@ -537,8 +559,11 @@
- void ata_port_wait_eh(struct ata_port *ap)
- {
- 	unsigned long flags;
-+
- 	DEFINE_WAIT(wait);
- 
-+    VPRINTK("\n");
-+
-  retry:
- 	spin_lock_irqsave(ap->lock, flags);
- 
-@@ -564,6 +589,8 @@
- 	unsigned int tag;
- 	int nr = 0;
- 
-+    VPRINTK("\n");
-+
- 	/* count only non-internal commands */
- 	for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++)
- 		if (ata_qc_from_tag(ap, tag))
-@@ -578,6 +605,8 @@
- 	unsigned long flags;
- 	int cnt;
- 
-+    VPRINTK("\n");
-+
- 	spin_lock_irqsave(ap->lock, flags);
- 
- 	cnt = ata_eh_nr_in_flight(ap);
-@@ -627,6 +656,8 @@
- {
- 	int cnt;
- 
-+    VPRINTK("\n");
-+
- 	/* already scheduled? */
- 	if (ap->pflags & ATA_PFLAG_EH_PENDING)
- 		return;
-@@ -661,6 +692,8 @@
- {
- 	struct ata_port *ap = qc->ap;
- 
-+    VPRINTK("\n");
-+
- 	WARN_ON(!ap->ops->error_handler);
- 
- 	qc->flags |= ATA_QCFLAG_FAILED;
-@@ -686,6 +719,8 @@
-  */
- void ata_port_schedule_eh(struct ata_port *ap)
- {
-+    VPRINTK("\n");
-+
- 	WARN_ON(!ap->ops->error_handler);
- 
- 	if (ap->pflags & ATA_PFLAG_INITIALIZING)
-@@ -701,6 +736,8 @@
- {
- 	int tag, nr_aborted = 0;
- 
-+    VPRINTK("\n");
-+
- 	WARN_ON(!ap->ops->error_handler);
- 
- 	/* we're gonna abort all commands, no need for fast drain */
-@@ -736,6 +773,8 @@
-  */
- int ata_link_abort(struct ata_link *link)
- {
-+    VPRINTK("\n");
-+
- 	return ata_do_link_abort(link->ap, link);
- }
- 
-@@ -753,6 +792,8 @@
-  */
- int ata_port_abort(struct ata_port *ap)
- {
-+    VPRINTK("\n");
-+
- 	return ata_do_link_abort(ap, NULL);
- }
- 
-@@ -776,6 +817,8 @@
-  */
- static void __ata_port_freeze(struct ata_port *ap)
- {
-+    VPRINTK("\n");
-+
- 	WARN_ON(!ap->ops->error_handler);
- 
- 	if (ap->ops->freeze)
-@@ -802,6 +845,8 @@
- {
- 	int nr_aborted;
- 
-+    VPRINTK("\n");
-+
- 	WARN_ON(!ap->ops->error_handler);
- 
- 	nr_aborted = ata_port_abort(ap);
-@@ -828,6 +873,8 @@
- 	u32 sntf;
- 	int rc;
- 
-+    VPRINTK("\n");
-+
- 	if (!(ap->flags & ATA_FLAG_AN))
- 		return 0;
- 
-@@ -896,6 +943,8 @@
- {
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
-+
- 	if (!ap->ops->error_handler)
- 		return;
- 
-@@ -917,6 +966,8 @@
- {
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
-+
- 	if (!ap->ops->error_handler)
- 		return;
- 
-@@ -943,6 +994,8 @@
- 	struct scsi_cmnd *scmd = qc->scsicmd;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
-+
- 	spin_lock_irqsave(ap->lock, flags);
- 	qc->scsidone = ata_eh_scsidone;
- 	__ata_qc_complete(qc);
-@@ -962,6 +1015,8 @@
- void ata_eh_qc_complete(struct ata_queued_cmd *qc)
- {
- 	struct scsi_cmnd *scmd = qc->scsicmd;
-+    VPRINTK("\n");
-+
- 	scmd->retries = scmd->allowed;
- 	__ata_eh_qc_complete(qc);
- }
-@@ -980,6 +1035,8 @@
- void ata_eh_qc_retry(struct ata_queued_cmd *qc)
- {
- 	struct scsi_cmnd *scmd = qc->scsicmd;
-+    VPRINTK("\n");
-+
- 	if (!qc->err_mask && scmd->retries)
- 		scmd->retries--;
- 	__ata_eh_qc_complete(qc);
-@@ -1000,6 +1057,8 @@
- 	struct ata_port *ap = link->ap;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
-+
- 	ata_dev_disable(dev);
- 
- 	spin_lock_irqsave(ap->lock, flags);
-@@ -1039,6 +1098,8 @@
- 	struct ata_eh_context *ehc = &link->eh_context;
- 	unsigned long flags;
- 
-+    VPRINTK("\n");
-+
- 	spin_lock_irqsave(ap->lock, flags);
- 
- 	/* Reset is represented by combination of actions and EHI
-@@ -1079,6 +1140,8 @@
- {
- 	struct ata_eh_context *ehc = &link->eh_context;
- 
-+    VPRINTK("\n");
-+
- 	/* if reset is complete, clear all reset actions & reset modifier */
- 	if (action & ATA_EH_RESET_MASK) {
- 		action |= ATA_EH_RESET_MASK;
-@@ -1104,6 +1167,8 @@
-  */
- static const char *ata_err_string(unsigned int err_mask)
- {
-+    VPRINTK("\n");
-+
- 	if (err_mask & AC_ERR_HOST_BUS)
- 		return "host bus error";
- 	if (err_mask & AC_ERR_ATA_BUS)
-@@ -1184,6 +1249,8 @@
- 	u8 csum;
- 	int i;
- 
-+    VPRINTK("\n");
-+
- 	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1);
- 	if (err_mask)
- 		return -EIO;
-@@ -1289,6 +1356,8 @@
- 	unsigned int err_mask = 0, action = 0;
- 	u32 hotplug_mask;
- 
-+    VPRINTK("\n");
-+
- 	if (serror & SERR_PERSISTENT) {
- 		err_mask |= AC_ERR_ATA_BUS;
- 		action |= ATA_EH_HARDRESET;
-@@ -1347,6 +1416,8 @@
- 	struct ata_taskfile tf;
- 	int tag, rc;
- 
-+    VPRINTK("\n");
-+
- 	/* if frozen, we can't do much */
- 	if (ap->pflags & ATA_PFLAG_FROZEN)
- 		return;
-@@ -1408,6 +1479,8 @@
- 	unsigned int tmp, action = 0;
- 	u8 stat = tf->command, err = tf->feature;
- 
-+    VPRINTK("\n");
-+
- 	if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
- 		qc->err_mask |= AC_ERR_HSM;
- 		return ATA_EH_SOFTRESET;
-@@ -1453,6 +1526,8 @@
- 
- static int ata_eh_categorize_error(int is_io, unsigned int err_mask)
- {
-+    VPRINTK("\n");
-+
- 	if (err_mask & AC_ERR_ATA_BUS)
- 		return 1;
- 
-@@ -1480,6 +1555,8 @@
- 	struct speed_down_verdict_arg *arg = void_arg;
- 	int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask);
- 
-+    VPRINTK("\n");
-+
- 	if (ent->timestamp < arg->since)
- 		return -1;
- 
-@@ -1525,6 +1602,8 @@
- 	struct speed_down_verdict_arg arg;
- 	unsigned int verdict = 0;
- 
-+    VPRINTK("\n");
-+
- 	/* scan past 10 mins of error history */
- 	memset(&arg, 0, sizeof(arg));
- 	arg.since = j64 - min(j64, j10mins);
-@@ -1569,6 +1648,8 @@
- 	unsigned int verdict;
- 	unsigned int action = 0;
- 
-+    VPRINTK("\n");
-+
- 	/* don't bother if Cat-0 error */
- 	if (ata_eh_categorize_error(is_io, err_mask) == 0)
- 		return 0;
-@@ -1763,6 +1844,8 @@
- {
- 	struct ata_link *link;
- 
-+    VPRINTK("\n");
-+
- 	ata_port_for_each_link(link, ap)
- 		ata_eh_link_autopsy(link);
- 
-@@ -1790,6 +1873,8 @@
- 	char tries_buf[6];
- 	int tag, nr_failed = 0;
- 
-+    VPRINTK("\n");
-+
- 	if (ehc->i.flags & ATA_EHI_QUIET)
- 		return;
- 
-@@ -1954,6 +2039,8 @@
- {
- 	struct ata_link *link;
- 
-+    VPRINTK("\n");
-+
- 	__ata_port_for_each_link(link, ap)
- 		ata_eh_link_report(link);
- }
-@@ -1964,6 +2051,8 @@
- 	struct ata_device *dev;
- 	int rc;
- 
-+    VPRINTK("\n");
-+
- 	ata_link_for_each_dev(dev, link)
- 		classes[dev->devno] = ATA_DEV_UNKNOWN;
- 
-@@ -1993,6 +2082,8 @@
- 				       int rc, int classify,
- 				       const unsigned int *classes)
- {
-+    VPRINTK("\n");
-+
- 	if (link->flags & ATA_LFLAG_NO_SRST)
- 		return 0;
- 	if (rc == -EAGAIN)
-@@ -2026,6 +2117,8 @@
- 	u32 sstatus;
- 	int rc;
- 
-+    VPRINTK("\n");
-+
- 	/* about to reset */
- 	spin_lock_irqsave(ap->lock, flags);
- 	ap->pflags |= ATA_PFLAG_RESETTING;
-@@ -2334,6 +2427,8 @@
- 	struct ata_device *dev;
- 	int cnt = 0;
- 
-+    VPRINTK("\n");
-+
- 	ata_link_for_each_dev(dev, link)
- 		if (ata_dev_enabled(dev))
- 			cnt++;
-@@ -2345,6 +2440,8 @@
- 	struct ata_device *dev;
- 	int cnt = 0;
- 
-+    VPRINTK("\n");
-+
- 	ata_link_for_each_dev(dev, link)
- 		if (dev->class == ATA_DEV_UNKNOWN)
- 			cnt++;
-@@ -2356,6 +2453,8 @@
- 	struct ata_eh_context *ehc = &link->eh_context;
- 	struct ata_device *dev;
- 
-+    VPRINTK("\n");
-+
- 	/* skip disabled links */
- 	if (link->flags & ATA_LFLAG_DISABLED)
- 		return 1;
-@@ -2379,6 +2478,8 @@
- {
- 	struct ata_eh_context *ehc = &dev->link->eh_context;
- 
-+    VPRINTK("\n");
-+
- 	ehc->tries[dev->devno]--;
- 
- 	switch (err) {
-@@ -2638,6 +2739,8 @@
- {
- 	int tag;
- 
-+    VPRINTK("\n");
-+
- 	/* retry or finish qcs */
- 	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
- 		struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
-@@ -2697,6 +2800,8 @@
- 	struct ata_device *dev;
- 	int rc;
- 
-+    VPRINTK("\n");
-+
- 	ata_eh_autopsy(ap);
- 	ata_eh_report(ap);
- 
-@@ -2725,6 +2830,8 @@
- 	unsigned long flags;
- 	int rc = 0;
- 
-+    VPRINTK("\n");
-+
- 	/* are we suspending? */
- 	spin_lock_irqsave(ap->lock, flags);
- 	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
-@@ -2781,6 +2888,8 @@
- 	unsigned long flags;
- 	int rc = 0;
- 
-+    VPRINTK("\n");
-+
- 	/* are we resuming? */
- 	spin_lock_irqsave(ap->lock, flags);
- 	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
-diff -Nurd linux-2.6.24/drivers/ata/libata-scsi.c linux-2.6.24-oxe810/drivers/ata/libata-scsi.c
---- linux-2.6.24/drivers/ata/libata-scsi.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-scsi.c	2008-06-11 17:50:32.000000000 +0200
-@@ -1477,7 +1477,10 @@
- 
- 	qc->scsidone(cmd);
- 
--	ata_qc_free(qc);
-+	if (ap->ops->qc_free)
-+        ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- }
- 
- /**
-@@ -1552,13 +1555,19 @@
- 	return 0;
- 
- early_finish:
--	ata_qc_free(qc);
-+	if (qc->ap->ops->qc_free)
-+        qc->ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- 	qc->scsidone(cmd);
- 	DPRINTK("EXIT - early finish (good or error)\n");
- 	return 0;
- 
- err_did:
--	ata_qc_free(qc);
-+	if (qc->ap->ops->qc_free)
-+        qc->ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- 	cmd->result = (DID_ERROR << 16);
- 	qc->scsidone(cmd);
- err_mem:
-@@ -1566,7 +1575,10 @@
- 	return 0;
- 
- defer:
--	ata_qc_free(qc);
-+	if (qc->ap->ops->qc_free)
-+        qc->ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- 	DPRINTK("EXIT - defer\n");
- 	if (rc == ATA_DEFER_LINK)
- 		return SCSI_MLQUEUE_DEVICE_BUSY;
-@@ -2314,7 +2326,10 @@
- 	}
- 
- 	qc->scsidone(qc->scsicmd);
--	ata_qc_free(qc);
-+	if (qc->ap->ops->qc_free)
-+        qc->ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- }
- 
- /* is it pointless to prefer PIO for "safety reasons"? */
-@@ -2403,7 +2418,10 @@
- 
- 		qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
- 		qc->scsidone(cmd);
--		ata_qc_free(qc);
-+        if (qc->ap->ops->qc_free)
-+            qc->ap->ops->qc_free(qc);
-+        else
-+            ata_qc_free(qc);
- 		return;
- 	}
- 
-@@ -2448,7 +2466,10 @@
- 	}
- 
- 	qc->scsidone(cmd);
--	ata_qc_free(qc);
-+	if (qc->ap->ops->qc_free)
-+        qc->ap->ops->qc_free(qc);
-+    else
-+        ata_qc_free(qc);
- }
- /**
-  *	atapi_xlat - Initialize PACKET taskfile
-@@ -2694,6 +2715,12 @@
- 	if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
- 		goto invalid_fld;
- 
-+    /** @NOTE: OX800/OX810 driver needs polling for PIO and no data commands */
-+    if ((tf->protocol == ATA_PROT_PIO) ||
-+        (tf->protocol == ATA_PROT_NODATA)) {
-+        tf->flags |= ATA_TFLAG_POLLING;
-+    }
-+
- 	/*
- 	 * 12 and 16 byte CDBs use different offsets to
- 	 * provide the various register values.
-diff -Nurd linux-2.6.24/drivers/ata/ox800sata.c linux-2.6.24-oxe810/drivers/ata/ox800sata.c
---- linux-2.6.24/drivers/ata/ox800sata.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/ox800sata.c	2008-06-11 17:50:32.000000000 +0200
-@@ -0,0 +1,2184 @@
-+/**************************************************************************
-+ *
-+ *  Copyright (c) 2004 Oxford Semiconductor Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, 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.
-+ *
-+ *  Module Name:
-+ *      ox800sata.c
-+ *
-+ *  Abstract:
-+ *      A driver to interface the 924 based sata core present in the ox800
-+ *      with libata and scsi
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/module.h>
-+#include <linux/leds.h>
-+
-+#include <scsi/scsi_host.h>
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_device.h>
-+#include <asm/io.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/sata.h>
-+#include <linux/platform_device.h>
-+
-+/***************************************************************************
-+* DEBUG CONTROL
-+***************************************************************************/
-+//#define SATA_DEBUG
-+//#define SATA_DUMP_REGS
-+//#define SATA_TF_DUMP
-+//#define CRAZY_DUMP_DEBUG
-+
-+#if 0
-+    #ifdef writel
-+    #undef writel
-+    #endif
-+    #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;} 
-+#endif
-+
-+#if 0    
-+    #ifdef readl
-+    #undef readl
-+    #endif
-+    static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
-+    #define readl(a) (myreadl(a))
-+#endif
-+
-+
-+#include <linux/libata.h>
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+
-+#define DRIVER_AUTHOR   "Oxford Semiconductor Ltd."
-+#define DRIVER_DESC     "924 SATA core controler"
-+#define DRIVER_NAME     "oxnassata"
-+
-+#define SATA_ABORT_WAIT_MS 5000
-+#define SATA_SRST_WAIT_MS  5000
-+
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+static int  ox800sata_init_one(struct platform_device *);
-+static int  ox800sata_remove_one(struct platform_device *);
-+
-+static void ox800sata_port_disable(struct ata_port *);
-+static void ox800sata_dev_config(struct ata_device *);
-+static void ox800sata_set_piomode(struct ata_port *, struct ata_device *);
-+static void ox800sata_set_dmamode(struct ata_port *, struct ata_device *);
-+static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
-+static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-+static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
-+static u8   ox800sata_check_status(struct ata_port *ap);
-+static u8   ox800sata_check_altstatus(struct ata_port *ap);
-+static void ox800sata_dev_select(struct ata_port *ap, unsigned int device);
-+static void ox800sata_phy_reset(struct ata_port *ap);
-+static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc);
-+static void ox800sata_bmdma_start(struct ata_queued_cmd *qc);
-+static u8   ox800sata_bmdma_status(struct ata_port *ap);
-+static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap);
-+static void ox800sata_qc_free(struct ata_queued_cmd *qc);
-+static unsigned int  ox800sata_qc_issue(struct ata_queued_cmd *qc);
-+static void ox800sata_eng_timeout(struct ata_port *ap);
-+static irqreturn_t ox800sata_irq_handler(int, void *);
-+static void ox800sata_eng_timeout(struct ata_port *ap);
-+static void ox800sata_irq_clear(struct ata_port *);
-+static int  ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-+static int  ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
-+static int  ox800sata_port_start(struct ata_port *ap);
-+static void ox800sata_port_stop(struct ata_port *ap);
-+static void ox800sata_host_stop(struct ata_host *host_set);
-+static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device);
-+static u32* ox800sata_get_io_base(struct ata_port* ap);
-+static u32* ox800sata_get_bbp_base(void);
-+static u8   ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
-+static u8 ox800sata_irq_on(struct ata_port *ap);
-+static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc);
-+static void CrazyDumpDebug(struct ata_port *ap);
-+static void ox800sata_spot_the_end(struct work_struct *work);
-+static void ox800sata_timeout_cleanup( struct ata_port *ap );
-+static void ox800sata_reset_core( void );
-+static void ox800sata_pio_start(struct work_struct *work);
-+static void ox800sata_pio_task(struct work_struct *work);
-+static void ox800sata_post_reset_init(struct ata_port* ap);
-+static u32  __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg);
-+static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
-+
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef struct
-+{
-+    struct platform_driver driver;
-+    struct ata_port* ap[2];
-+    struct workqueue_struct* spot_the_end_q;
-+} ox800sata_driver_t;
-+
-+/**
-+ * Struct to hold private (specific to this driver) data for each queued
-+ * command, all queued commands will point to a per-port private data
-+ * structure. This is a completely unresearched decision that will surely 
-+ * cause some untracable bug in the future.
-+ */
-+typedef struct
-+{
-+    oxnas_dma_channel_t* DmaChannel;
-+	oxnas_dma_sg_entry_t* sg_entries;
-+    struct spot_the_end_work_s  {
-+        struct work_struct worker;
-+        struct ata_port* ap;
-+    } spot_the_end_work;
-+    int port_disabled;
-+    u32 ErrorsWithNoCommamnd;
-+    u32 int_status;
-+    u32 in_cleanup;
-+} ox800sata_private_data;
-+
-+ox800sata_driver_t ox800sata_driver = 
-+{
-+    .driver =
-+    {
-+        .driver.name = DRIVER_NAME,
-+        .driver.bus = &platform_bus_type,
-+        .probe = ox800sata_init_one, 
-+        .remove = ox800sata_remove_one,
-+    },
-+    .ap = {0,0},
-+};
-+
-+/** If we were writing this in C++ then we would be deriving a subclass of 
-+ata_port, these would be the overridden functions*/
-+static struct ata_port_operations ox800sata_port_ops =
-+{
-+    .port_disable = ox800sata_port_disable,
-+    .dev_config = ox800sata_dev_config,
-+    .set_piomode = ox800sata_set_piomode,
-+    .set_dmamode = ox800sata_set_dmamode,
-+    .tf_load = ox800sata_tf_load,
-+    .tf_read = ox800sata_tf_read,
-+    .exec_command = ox800sata_exec_command,
-+    .check_status = ox800sata_check_status,
-+    .check_altstatus = ox800sata_check_altstatus,
-+    .dev_select = ox800sata_dev_select,
-+    .phy_reset = ox800sata_phy_reset,
-+    .bmdma_setup = ox800sata_bmdma_setup,
-+    .bmdma_start = ox800sata_bmdma_start,
-+    .bmdma_stop = ox800sata_bmdma_stop,
-+    .bmdma_status = ox800sata_bmdma_status,
-+    .qc_new = ox800sata_qc_new,
-+    .qc_free = ox800sata_qc_free,
-+    .qc_prep = ata_qc_prep,
-+    .qc_issue = ox800sata_qc_issue,
-+    .eng_timeout = ox800sata_eng_timeout,
-+    .irq_handler = ox800sata_irq_handler,
-+    .irq_clear = ox800sata_irq_clear,
-+    .scr_read = ox800sata_scr_read,
-+    .scr_write = ox800sata_scr_write,
-+    .port_start = ox800sata_port_start,
-+    .port_stop = ox800sata_port_stop,
-+    .host_stop = ox800sata_host_stop,
-+    .dev_chk = ox800sata_devchk,
-+    .irq_on = ox800sata_irq_on,
-+    .irq_ack = ox800sata_irq_ack,
-+    .pio_task = ox800sata_pio_start,
-+};
-+
-+/** the scsi_host_template structure describes the basic capabilities of libata
-+and our 921 core to the SCSI framework, it contains the addresses of functions 
-+in the libata library that handle top level comands from the SCSI library */
-+static struct scsi_host_template ox800sata_sht = 
-+{
-+    .module             = THIS_MODULE,
-+    .name               = DRIVER_NAME,
-+    .ioctl              = ata_scsi_ioctl,
-+    .queuecommand       = ata_scsi_queuecmd,
-+/*    .eh_strategy_handler= ata_scsi_error,*/
-+    .can_queue          = ATA_DEF_QUEUE,
-+    .this_id            = ATA_SHT_THIS_ID,
-+/*    .sg_tablesize       = LIBATA_MAX_PRD,*/
-+    .sg_tablesize       = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
-+    .max_sectors        = 256,  // Use the full 28-bit SATA value
-+    .cmd_per_lun        = ATA_SHT_CMD_PER_LUN,
-+    .emulated           = ATA_SHT_EMULATED,
-+    .use_clustering     = ATA_SHT_USE_CLUSTERING,
-+    .proc_name          = DRIVER_NAME,
-+    .dma_boundary       = ~0UL, // NAS has no DMA boundary restrictions
-+    .slave_configure    = ata_scsi_slave_config,
-+    .bios_param         = ata_std_bios_param,
-+    .unchecked_isa_dma  = 0,
-+
-+};
-+
-+/** after PIO read operations, DRQ can remain set even when all the data has 
-+been read, when set, PretendDRQIsClear will mask out the DRQ bit in 
-+ox800sata_check_status operation */  
-+static char PretendDRQIsClear;
-+
-+/**
-+ * used as a store for atomic test and set operations used to coordinate so
-+ * that only one port is processing comnmands at any time */
-+static unsigned long ox800sata_command_active;
-+
-+/**
-+ * A record of which drives have accumulated raid faults. A set bit indicates
-+ * a fault has occured on that drive */
-+static u32 ox800sata_accumulated_RAID_faults = 0;
-+
-+/**************************************************************************/
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(1.0);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox800sata_"
-+**************************************************************************/
-+
-+/**
-+ * Gets the base address of the ata core from the ata_port structure
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static u32* ox800sata_get_io_base(struct ata_port* ap)
-+{
-+    // return (u32* )SATA0_REGS_BASE;
-+    
-+    return (u32* )ap->host->iomap;
-+}
-+
-+/**
-+ * Gets the base address of the core that contains the BBP registers
-+ * @return the base address of the SATA core that contains the BBP registers
-+ */
-+static u32* ox800sata_get_bbp_base(void)
-+{
-+    return (u32* )SATA0_REGS_BASE;;
-+}
-+
-+/**
-+ * Gets the base address of the sata link registers core from the
-+ * ata_port structure
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static u32* ox800sata_get_link_base(struct ata_port* ap)
-+{
-+    u8* link_base = (u8* )ap->host->iomap + 
-+        ((u8* )SATA0_LINK_REGS_BASE - (u8* )SATA0_REGS_BASE);
-+        
-+    return (u32* )link_base;
-+}
-+
-+/**
-+ * Turns on the cores clock and resets it
-+ */
-+static void ox800sata_reset_core( void ){
-+    // Enable the clock to the SATA block
-+    writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+    wmb();
-+
-+    // reset both MAC and PHY
-+    writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    wmb();
-+    udelay(50);
-+    
-+    // un-reset both MAC and PHY
-+    writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+    wmb();
-+    udelay(50);
-+}
-+
-+/**
-+ * port capabilities for the ox800 sata ports.
-+ */
-+static const struct ata_port_info ox800sata_port_info = {
-+    .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
-+    .pio_mask   = 0x1f, /* pio modes 0..4*/
-+    .mwdma_mask = 0x07, /* mwdma0-2 */
-+    .udma_mask  = 0x7f, /* udma0-5 */
-+    .port_ops   = &ox800sata_port_ops,
-+};
-+
-+/** 
-+ * The driver probe function.
-+ * Registered with the amba bus driver as a parameter of ox800sata_driver.bus
-+ * it will register the ata device with kernel first performing any 
-+ * initialisation required (if the correct device is present).
-+ * @param pdev Pointer to the 921 device structure 
-+ * @param port where on the bus the port was found, ignored and probably wrong
-+ * @return 0 if no errors
-+ */
-+static int ox800sata_init_one(struct platform_device* pdev)
-+{
-+    
-+    u32 version;
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+    unsigned long reg;
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+    struct ata_host *host;
-+    const struct ata_port_info* port_info[] = { &ox800sata_port_info, NULL };
-+
-+    void __iomem* iomem;
-+    struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
-+    int irq = platform_get_irq(pdev, 0);
-+    
-+    DPRINTK("\n");
-+
-+    /* check resourses for sanity */
-+    if ((memres == NULL) || (irq < 0)) {
-+        return 0;
-+    }
-+    iomem = (void __iomem* ) memres->start;
-+    
-+    /* check we support this version of the core */
-+    version = readl(((u32* )iomem) + OX800SATA_VERSION) & 0xff;
-+    switch (version)
-+    {
-+        case OX800SATA_CORE_VERSION:
-+            printk(KERN_INFO"ox800sata: OX800 sata core.\n");   
-+            break;
-+        default:
-+            printk(KERN_ERR"ox800sata: unknown sata core (version register = 0x%08x)\n",version);     
-+            return 0;
-+            break;
-+    }
-+
-+    /* reset the core */
-+    ox800sata_reset_core();
-+
-+    /* initialise a work queue to spot the end of transfers */
-+    ox800sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
-+    if (!ox800sata_driver.spot_the_end_q) {
-+        printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
-+        return -1;
-+    }
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+    /* setup path */
-+    reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    
-+    /* enable output */
-+    writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
-+    
-+    /* disk light off */
-+    writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif  /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+
-+    /* setup the probe_ent structure which is basically info about the ports 
-+    capabilities */
-+    
-+    /* allocate memory and check */
-+    host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX800SATA_MAX_PORTS );
-+    if (!host) {
-+        printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
-+        destroy_workqueue(ox800sata_driver.spot_the_end_q);
-+    }
-+    
-+    /* set to base of ata core */
-+    host->iomap  = iomem;
-+    
-+    /* call ata_device_add and begin probing for drives*/
-+    ata_host_activate(host,
-+        irq,
-+        ox800sata_irq_handler,
-+        0,
-+        &ox800sata_sht );
-+    
-+    return 0;
-+}
-+
-+/** 
-+ * Called when the amba bus tells this device to remove itself.
-+ * @param pdev pointer to the device that needs to be shutdown
-+ */
-+static int ox800sata_remove_one(struct platform_device* pdev)
-+{
-+    struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
-+    struct ata_port *ap;
-+    unsigned int i;
-+    
-+    
-+    for (i = 0; i < host_set->n_ports; i++) 
-+    {
-+        ap = host_set->ports[i];
-+        scsi_remove_host( ap->scsi_host );
-+    }
-+    
-+    /** @TODO etc. */
-+
-+    // Disable the clock to the SATA block
-+    writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+    
-+    return 0;
-+}
-+
-+/** 
-+ * module initialisation
-+ * @return success
-+ */
-+static int __init ox800sata_init( void )
-+{
-+    int ret;
-+    
-+    printk(KERN_INFO"ox800sata init \n");
-+    
-+    ret = platform_driver_register( &ox800sata_driver.driver );
-+    
-+    return ret; 
-+}
-+
-+/** 
-+ * module cleanup
-+ */
-+static void __exit ox800sata_exit( void )
-+{
-+    platform_driver_unregister( &ox800sata_driver.driver );
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800sata_init);
-+module_exit(ox800sata_exit);
-+
-+/** 
-+ * Called from ata_bus_probe() and ata_bus_reset() error paths, as well as
-+ * when unregistering from the SCSI module (rmmod, hot unplug).
-+ * @param port The port to disable
-+ */
-+static void ox800sata_port_disable(struct ata_port* port)
-+{
-+    DPRINTK("\n");
-+}
-+
-+/** 
-+ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
-+ * Typically used to apply device-specific fixups prior to issue of
-+ * SET FEATURES - XFER MODE, and prior to operation.
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_dev_config(struct ata_device* pdev)
-+{
-+    u32 reg;
-+    u32 *ioaddr = ox800sata_get_io_base(pdev->ap);
-+
-+    DPRINTK("\n");
-+
-+    /* if needed, set the bits to put the interface into 48-bit node */
-+    if (pdev->flags & ATA_DFLAG_LBA48) {
-+        reg = readl( ioaddr + OX800SATA_DRIVE_CONTROL );
-+        
-+        /* mask out the pair of bits associaed with each port */
-+        reg &= ~( 3 << (pdev->ap->port_no * 2) );
-+        
-+        /* set the mode pair associated with each port */
-+        reg |= 2 << (pdev->ap->port_no * 2);
-+        writel(reg  ,ioaddr + OX800SATA_DRIVE_CONTROL);
-+    }
-+}
-+
-+/** 
-+ * Hooks called prior to the issue of SET FEATURES - XFER MODE command. 
-+ * dev->pio_mode is guaranteed to be valid when ->set_piomode() is called
-+ *
-+ * If we're doing PIO, we need to disable the burst buffer port to stop it 
-+ * trying to do a DMA transfer of the data.
-+ * 
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
-+{
-+    u32 Register;
-+    u32 *ioaddr = ox800sata_get_bbp_base();
-+
-+    DPRINTK("\n");
-+
-+    /* disable burst buffer DMA */
-+    Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+    Register |= OX800SATA_BBC_DREQ_DIS ;
-+    writel(Register  ,ioaddr + OX800SATA_BURST_CONTROL);
-+    PretendDRQIsClear = 0;
-+}
-+
-+/** 
-+ * Hooks called prior to the issue of SET FEATURES - XFER MODE command.
-+ * dev->dma_mode is guaranteed to be valid when ->set_dmamode() is called.
-+ *
-+ * When doing a DMA transfer, we need to enable the burst buffer port as this
-+ * may have been disabled by a previous command.
-+ * 
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
-+{
-+    u32 Register;
-+    u32 *ioaddr = ox800sata_get_bbp_base();
-+
-+    DPRINTK("\n");
-+
-+    /* enable burst buffer DMA */
-+    Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+    Register &= ~OX800SATA_BBC_DREQ_DIS;
-+    writel(Register  ,ioaddr + OX800SATA_BURST_CONTROL);
-+}
-+
-+/** 
-+ * Output the taskfile for diagnostic reasons, it will always appear in the 
-+ * debug output as if it's a task file being written.
-+ * @param tf The taskfile to output
-+ */
-+static void tfdump(const struct ata_taskfile* tf)
-+{
-+    if (tf->flags & ATA_TFLAG_LBA48) {
-+#ifdef SATA_TF_DUMP
-+    printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+    DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+        tf->command,
-+        
-+        tf->hob_feature,
-+        tf->feature,
-+        
-+        tf->hob_lbah,
-+        tf->hob_lbam,
-+        tf->hob_lbal,
-+        tf->lbah,
-+        tf->lbam,
-+        tf->lbal,
-+        
-+        tf->hob_nsect,
-+        tf->nsect,
-+        tf->ctl,
-+        tf->device );
-+    }else{
-+#ifdef SATA_TF_DUMP
-+    printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+    DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+        tf->command,
-+        
-+        tf->feature,
-+
-+        tf->device & 0x0f,        
-+        tf->lbah,
-+        tf->lbam,
-+        tf->lbal,
-+        
-+        tf->nsect,
-+        tf->ctl,
-+        tf->device );
-+    }
-+}
-+
-+/** 
-+ * called to write a taskfile into the ORB registers
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+    u32 count = 0;
-+    u32 Orb1 = 0; 
-+    u32 Orb2 = 0; 
-+    u32 Orb3 = 0;
-+    u32 Orb4 = 0;
-+    u32 Command_Reg;
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-+
-+    do {
-+        Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+        if (!(Command_Reg & CMD_CORE_BUSY))
-+            break;
-+        count++;
-+        if ( in_atomic() ) {
-+            mdelay(1);
-+        } else {
-+            msleep(1);
-+        }
-+    } while (count < 10);
-+
-+    /* if the control register has changed, write it */
-+    if (tf->ctl != ap->last_ctl) 
-+    {
-+        //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
-+        Orb4 |= (tf->ctl) << 24;
-+
-+        /* write value to register */
-+        writel(Orb4, ioaddr + OX800SATA_ORB4 );
-+
-+        ap->last_ctl = tf->ctl;
-+    }
-+
-+    /* check if the ctl register has interrupts disabled or enabled and
-+    modify the interrupt enable registers on the ata core as required */
-+    if (tf->ctl & ATA_NIEN)
-+    {
-+        /* interrupts disabled */
-+        ox800sata_irq_clear(ap);
-+    }
-+    else
-+    {
-+        /* interrupts enabled */
-+        ox800sata_irq_on(ap);
-+    }
-+    
-+    /* write 48 or 28 bit tf parameters */
-+    if (is_addr)
-+    {
-+        /* set LBA bit as it's an address */
-+        Orb1 |= (tf->device & ATA_LBA) << 24;
-+        
-+        if (tf->flags & ATA_TFLAG_LBA48) 
-+        {
-+            //DPRINTK(KERN_INFO" 48 bit tf load \n");
-+            Orb1 |= ATA_LBA << 24;
-+            
-+            Orb2 |= (tf->hob_nsect)  << 8 ;
-+
-+            Orb3 |= (tf->hob_lbal)   << 24;
-+
-+            Orb4 |= (tf->hob_lbam)   << 0 ;
-+            Orb4 |= (tf->hob_lbah)   << 8 ;
-+            Orb4 |= (tf->hob_feature)<< 16;
-+        } else {
-+            Orb1 |= (tf->device & 0xf)<< 24;
-+        }
-+
-+        /* write 28-bit lba */
-+        //DPRINTK(KERN_INFO" 28 bit tf load\n");
-+        Orb1 |= (tf->lbal)       << 0 ;
-+        Orb1 |= (tf->lbam)       << 8 ;
-+        Orb1 |= (tf->lbah)       << 16;
-+
-+        Orb2 |= (tf->nsect)      << 0 ;
-+        Orb2 |= (tf->feature)    << 16;
-+        Orb2 |= (tf->command)    << 24;
-+        
-+        Orb3 |= (tf->lbal)       << 0 ;
-+        Orb3 |= (tf->lbam)       << 8 ;
-+        Orb3 |= (tf->lbah)       << 16;
-+
-+        Orb4 |= (tf->ctl)        << 24;
-+        
-+        /* write values to registers */
-+        writel(Orb1, ioaddr + OX800SATA_ORB1 );
-+        writel(Orb2, ioaddr + OX800SATA_ORB2 );
-+        writel(Orb3, ioaddr + OX800SATA_ORB3 );
-+        writel(Orb4, ioaddr + OX800SATA_ORB4 );
-+    }
-+
-+    if (tf->flags & ATA_TFLAG_DEVICE) 
-+    {
-+        Orb1 |= (tf->device)     << 24;
-+
-+        /* write value to register */
-+        writel(Orb1, ioaddr + OX800SATA_ORB1 );
-+    }
-+    
-+    tfdump(tf);
-+    
-+}
-+
-+/** 
-+ * Called to read the hardware registers / DMA buffers, to
-+ * obtain the current set of taskfile register values.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to read the registers into
-+ */
-+static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+    /* read the orb registers */
-+    u32 Orb1 = readl( ioaddr + OX800SATA_ORB1 ); 
-+    u32 Orb2 = readl( ioaddr + OX800SATA_ORB2 ); 
-+    u32 Orb3 = readl( ioaddr + OX800SATA_ORB3 );
-+    u32 Orb4 = readl( ioaddr + OX800SATA_ORB4 );
-+
-+    DPRINTK("\n");
-+
-+    /* read common 28/48 bit tf parameters */
-+    tf->device  = (Orb1 >> 24);
-+    tf->nsect   = (Orb2 >> 0);
-+    tf->feature = (Orb2 >> 16);
-+    tf->command = ox800sata_check_status(ap);
-+
-+    /* read 48 or 28 bit tf parameters */
-+    if (tf->flags & ATA_TFLAG_LBA48) 
-+    {
-+        //DPRINTK(KERN_INFO" 48 bit tf read \n");
-+        tf->hob_nsect = (Orb2 >> 8 ) ;
-+        
-+        tf->lbal      = (Orb3 >> 0 ) ;
-+        tf->lbam      = (Orb3 >> 8 ) ;
-+        tf->lbah      = (Orb3 >> 16) ;
-+        tf->hob_lbal  = (Orb3 >> 24) ;
-+        
-+        tf->hob_lbam  = (Orb4 >> 0 ) ;
-+        tf->hob_lbah  = (Orb4 >> 8 ) ;
-+        /* feature ext and control are write only */
-+
-+    }
-+    else
-+    {
-+        /* read 28-bit lba */
-+        //DPRINTK(KERN_INFO" 28 bit tf read\n");
-+        tf->lbal      = (Orb1 >> 0 ) ;
-+        tf->lbam      = (Orb1 >> 8 ) ;
-+        tf->lbah      = (Orb1 >> 16) ;
-+    }
-+
-+    /* fixup NAS SATA core's non-std status reporting */
-+    if (PretendDRQIsClear)
-+    {
-+         tf->command &= ~ATA_DRQ;
-+    }
-+
-+    tfdump(tf);
-+}
-+
-+/** 
-+ * Causes an ATA command, previously loaded with ->tf_load(), to be
-+ * initiated in hardware. The command is written into the registers again just
-+ * to be sure. All the other registers that are in Orb2 are also written at the 
-+ * same time. The command is initiated in hardware by a poke to the COMMAND
-+ * register.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+    u32 count =0;
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    u32 Orb2 ;
-+    u32 Command_Reg;
-+    ox800sata_private_data* private_data ;
-+
-+    //DPRINTK(KERN_INFO"ox800sata_exec_command cmd %02x\n", tf->command);
-+    do {
-+        Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+        if (!(Command_Reg & CMD_CORE_BUSY))
-+            break;
-+        count++;
-+        if ( in_atomic() ) {
-+            mdelay(1);
-+        } else {
-+            msleep(1);
-+        }
-+    } while (count < 10);
-+    
-+    /* write all the things in Orb 2 */
-+    Orb2  = (tf->nsect)     << 0 ;
-+    if (tf->flags & ATA_TFLAG_LBA48) 
-+    {
-+        Orb2 |= (tf->hob_nsect) << 8 ;
-+    }
-+    Orb2 |= (tf->feature)   << 16;
-+    Orb2 |= (tf->command)   << 24;
-+    writel( Orb2 , ioaddr + OX800SATA_ORB2 );
-+    wmb();
-+
-+    do {
-+        Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+        if (!(Command_Reg & CMD_CORE_BUSY))
-+            break;
-+        count++;
-+        if ( in_atomic() ) {
-+            mdelay(1);
-+        } else {
-+            msleep(1);
-+        }
-+    } while (count < 10);
-+
-+    /* if the drive has become disconnected, executing a command will be a
-+    problem */ 
-+    private_data = (ox800sata_private_data*)ap->private_data;
-+    
-+    /* Command that the orb registers get written to drive */
-+    Command_Reg &= ~SATA_OPCODE_MASK;
-+    Command_Reg |= CMD_WRITE_TO_ORB_REGS;
-+    writel( Command_Reg , ioaddr + OX800SATA_SATA_COMMAND );
-+    wmb();
-+}
-+
-+
-+/** 
-+ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
-+ * transfers, it it sometimes necessary to mask out the DRQ bit
-+ * @param ap hardware with the registers in
-+ * @return The status register
-+ */
-+static u8   ox800sata_check_status(struct ata_port *ap)
-+{
-+    u32 Reg;
-+    u8 result;
-+    u8 state;
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    
-+//    VPRINTK(KERN_INFO"ox800sata_check_status ");
-+    
-+    /* read byte 3 of Orb2 register */
-+    result = readl(ioaddr + OX800SATA_ORB2 ) >> 24;
-+    
-+    /* set DRQ when core is in PIO transfer states */
-+    state = readl(ioaddr + OX800SATA_SATA_CONTROL) & OX800SATA_SATA_CONTROL_TRANS_MASK;
-+    if ((state == OX800SATA_TRANS_PIOITRANS) || (state == OX800SATA_TRANS_PIOOTRANS)) {
-+        result |= ATA_DRQ;
-+    }
-+    
-+    if (PretendDRQIsClear)
-+    {
-+//        VPRINTK("(ignoring DRQ) ");    
-+        result &= ~ATA_DRQ;
-+    }
-+            
-+    /* use error informatian from raw interupt status */
-+    if (readl(ioaddr + OX800SATA_INT_STATUS) & OX800SATA_RAW_ERROR) { 
-+        result |= ATA_ERR;
-+    } else {
-+        result &= ~ATA_ERR;
-+    }
-+    
-+    /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
-+    ox800sata_scr_read(ap, SCR_STATUS, &Reg);
-+    if (!(Reg & 0x1)) { 
-+        result |= ATA_DF;
-+        result |= ATA_ERR;
-+    }
-+    //VPRINTK("%02x\n",result);    
-+
-+    return result;
-+}
-+
-+/** 
-+ * Reads the alt status ATA shadow register from hardware. 
-+ * @param ap hardware with the registers in
-+ * @return The alt status register
-+ */
-+static u8   ox800sata_check_altstatus(struct ata_port *ap)
-+{
-+    u8 result;
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    
-+    //DPRINTK(KERN_INFO"ox800sata_check_altstatus base=%p\n",ioaddr);
-+    
-+    /* read byte 3 of Orb4 register */
-+    result = ( readl(ioaddr + OX800SATA_ORB4 ) >> 24 ) ;
-+
-+    //DPRINTK(KERN_INFO"alternate status register %02x\n",result);    
-+
-+    return result;
-+}
-+
-+/** 
-+ * Use the method defined in the ATA specification to make either device 0,
-+ * or device 1, active on the ATA channel. If we ever get port multipliers
-+ * to work, this will be where they would switch.
-+ *
-+ * @param ap hardware with the registers in
-+ * @param number of the device to talk to (0..)
-+ */
-+static void ox800sata_dev_select(struct ata_port *ap, unsigned int device)
-+{
-+    /* currently only one i/f, but this may not always be the case */
-+    const unsigned char interface_no = 0;
-+    
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    DPRINTK(" i/f=%d dev=%d\n", interface_no, device);
-+    
-+    writel(
-+        (interface_no << 4) | device ,
-+        ioaddr + OX800SATA_DEVICE_SELECT );
-+}
-+
-+/** 
-+ * The very first step in the probe phase. Actions vary depending on the bus
-+ * type, typically. After waking up the device and probing for device presence
-+ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
-+ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
-+ * this hook.
-+ *
-+ * This should reset the SATA core and Phisical layer then jump back into the 
-+ * libata libraries for lots of other resetting
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_phy_reset(struct ata_port *ap)
-+{
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+    //DPRINTK(KERN_INFO"ox800sata_phy_reset base = %p\n", ioaddr);
-+    
-+    /* turn ata core on */
-+    writel( (1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+    
-+    /* stop all the interrupts in the ata core */
-+    writel( ~0, ioaddr + OX800SATA_INT_DISABLE);
-+    writel( ~0, ioaddr + OX800SATA_INT_CLEAR);
-+    
-+    /* get libata to perform a soft reset */
-+    sata_phy_reset(ap);
-+    
-+}
-+
-+/** 
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup) 
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc)
-+{
-+    ox800sata_private_data* PrivateData ;
-+    oxnas_dma_direction_t direction; 
-+
-+#ifdef SATA_DEBUG
-+    printk(KERN_INFO"ox800sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#else // SATA_DEBUG
-+    DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#endif // SATA_DEBUG
-+    
-+    qc->private_data = qc->ap->private_data;
-+    PrivateData = (ox800sata_private_data* )qc->private_data;
-+
-+	// We check for DMA completion from ISR which cannot wait for all DMA channel
-+	// housekeeping to complete, so need to wait here is case we try to reuse
-+	// channel before that housekeeping has completed
-+	while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+		printk("DMA Setup Channel still active\n");
-+	}
-+
-+    /* Do not use DMA callback */
-+	oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+    /* decide on DMA direction */
-+    direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
-+                                                   OXNAS_DMA_TO_DEVICE;
-+
-+/* Expect transfers to be multiples of 4KB */
-+//struct scatterlist* sle = qc->sg;
-+//while (sg_dma_len(sle)) {
-+//    BUG_ON(sg_dma_len(sle) % 4096);
-+//    ++sle;
-+//}
-+
-+    /* now set-up the DMA transfer */
-+    if (qc->n_elem > 1)
-+    {
-+#ifdef SATA_DEBUG
-+    u32 total=0;
-+    int i=0;
-+    struct scatterlist* sg = qc->__sg;
-+    printk("Lengths: ");
-+    do {
-+        u32 len = sg_dma_len(sg++);
-+        printk("%u ", len); 
-+        total += len;
-+    } while (++i < qc->n_elem);
-+    printk("\nTotal len = %u\n", total);
-+#endif //  SATA_DEBUG
-+        /* try and setup scatter gather controller */
-+/*        if (oxnas_dma_device_set_sg(PrivateData->DmaChannel,
-+                                    direction,
-+                                    qc->__sg,
-+                                    qc->n_elem,
-+                                    &oxnas_sata_dma_settings,
-+                                    OXNAS_DMA_MODE_INC )) {
-+            printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+            return;
-+        }*/
-+        if (oxnas_dma_device_set_prd(
-+                PrivateData->DmaChannel,
-+                direction,
-+                qc->ap->prd,
-+                &oxnas_sata_dma_settings,
-+                OXNAS_DMA_MODE_INC,
-+				 PrivateData->sg_entries)) {
-+            printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+            return;
-+        }
-+    }
-+    else
-+    {
-+#ifdef SATA_DEBUG
-+    printk("Total len = %u\n", sg_dma_len(qc->__sg));
-+#endif //  SATA_DEBUG
-+        /* setup a single dma */
-+        oxnas_dma_device_set(   PrivateData->DmaChannel,
-+                                direction,
-+                                (unsigned char* )sg_dma_address(qc->__sg),
-+                                sg_dma_len(qc->__sg),
-+                                &oxnas_sata_dma_settings,
-+                                OXNAS_DMA_MODE_INC,
-+                                1); /* paused */
-+    }
-+}
-+
-+/** 
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup) 
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox800sata_bmdma_start(struct ata_queued_cmd *qc)
-+{
-+    ox800sata_private_data* PrivateData ;
-+    DPRINTK("\n");
-+    PrivateData = (ox800sata_private_data* )(qc->private_data);    
-+
-+    {
-+        /* turn on the fifo */    
-+        u32 Register;
-+        u32 *ioaddr = ox800sata_get_bbp_base();
-+        Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+        Register &= ~OX800SATA_BBC_FIFO_DIS;
-+        writel(Register  ,ioaddr + OX800SATA_BURST_CONTROL);
-+    }
-+    
-+    /* if the drive has become disconnected, executing a command will be a
-+    problem */ 
-+    {
-+        /* start DMA transfer */
-+        oxnas_dma_start( PrivateData->DmaChannel );
-+        qc->ap->ops->exec_command(qc->ap, &(qc->tf));
-+    }
-+}
-+
-+
-+/**
-+ *  ata_qc_new - Request an available ATA command, for queueing
-+ *  @ap: Port associated with device @dev
-+ *  @dev: Device from whom we request an available command structure
-+ *
-+ *  LOCKING:
-+ */
-+
-+static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap)
-+{
-+    struct ata_queued_cmd *qc = NULL;
-+
-+    /* first see if we're not doing a command */
-+    if (!test_and_set_bit(0, &ox800sata_command_active)) {
-+            /* now set the standard bits for compatibility */
-+            set_bit(0, &ap->qc_allocated); 
-+            qc = ata_qc_from_tag(ap, 0);
-+            
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+            /* disk light on */
-+            writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
-+#endif  // CONFIG_SATA_OXNAS_DISK_LIGHT
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+            wdc_ledtrig_sata_activity();
-+#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+    } else
-+        DPRINTK("Command active flag still set\n");
-+
-+    if (qc)
-+        qc->tag = 0;
-+
-+    return qc;
-+}
-+
-+
-+/**
-+ *
-+ */
-+static void ox800sata_qc_free(struct ata_queued_cmd *qc)
-+{
-+    struct ata_port *ap = qc->ap;
-+    unsigned int tag, do_clear = 0;
-+
-+    DPRINTK("\n");
-+
-+    qc->flags = 0;
-+    tag = qc->tag;
-+    if (likely(ata_tag_valid(tag))) {
-+        if (tag == ap->active_tag)
-+            ap->active_tag = ATA_TAG_POISON;
-+        qc->tag = ATA_TAG_POISON;
-+        do_clear = 1;
-+    }
-+
-+    if (likely(do_clear)) {
-+        clear_bit(tag, &ap->qc_allocated);
-+        clear_bit(0, &ox800sata_command_active);
-+        
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT            
-+        /* disk light off */
-+        writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif  /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+    }
-+}
-+
-+/** 
-+ * qc_issue is used to make a command active, once the hardware and S/G tables
-+ * have been prepared. IDE BMDMA drivers use the helper function
-+ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
-+ * roll their own ->qc_issue implementation, using this as the "issue new ATA
-+ * command to hardware" hook.
-+ * @param qc the queued command to issue
-+ */
-+static unsigned int  ox800sata_qc_issue(struct ata_queued_cmd *qc)
-+{
-+    u32 Register;
-+    int this_port_fail;
-+    ox800sata_private_data* private_data = (ox800sata_private_data*)qc->ap->private_data ;
-+    u32 *ioaddr = ox800sata_get_bbp_base();
-+	u32 reg;
-+    u32 raid_reg = 0; /* default to no raid */
-+
-+    DPRINTK("\n");
-+
-+    /* get raid settings from the bio if they exist */    
-+    if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
-+        struct bio* bio;
-+        bio = qc->scsicmd->request->bio;
-+        raid_reg = bio->bi_raid ;
-+        if (raid_reg) DPRINTK(" raid reg 0x%08x\n",raid_reg);
-+    }
-+
-+    /* check cable is still connected */
-+	ox800sata_scr_read(qc->ap, SCR_STATUS, &reg);
-+    private_data->port_disabled |= (!(reg & 1));
-+        
-+    this_port_fail = private_data->port_disabled;
-+    
-+    if (raid_reg) {
-+        int port0fail, port1fail;
-+        port0fail = (! (__ox800sata_scr_read((u32* )SATA0_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) ); 
-+        port1fail = (! (__ox800sata_scr_read((u32* )SATA1_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+        this_port_fail |= port1fail;
-+        
-+        ox800sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
-+        ox800sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
-+    }
-+
-+    if (!this_port_fail ) { 
-+        writel(raid_reg  ,ioaddr + OX800SATA_RAID_CONTROL);
-+
-+        DPRINTK(" enabling burst buffer DMA\n");        
-+        Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+        Register &= ~OX800SATA_BBC_DREQ_DIS;
-+        writel(Register  ,ioaddr + OX800SATA_BURST_CONTROL);
-+        
-+        /* call the default, this should be changed to take advantage of orb
-+        registers, etc... */
-+        return ata_qc_issue_prot(qc);
-+    } else {
-+        /* record the error */
-+        qc->err_mask |= AC_ERR_ATA_BUS;
-+
-+        /* offline the SCSI device */        
-+        printk(KERN_ERR"ata%u offline\n", qc->ap->print_id);
-+        scsi_device_set_state(qc->scsicmd->device, SDEV_OFFLINE);
-+        return 0;
-+    }
-+}
-+
-+/** 
-+ * This is a high level error handling function, called from the error
-+ * handling thread, when a command times out.
-+ *
-+ * @todo possibly remove this function and revert to only calling the default
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_eng_timeout(struct ata_port *ap)
-+{
-+    struct ata_queued_cmd *qc;
-+    ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;    
-+    DPRINTK("\n");
-+    
-+    /* set the in cleanup flag */
-+    pd->in_cleanup = 1;
-+    
-+    /* if we're a PIO command existing cleanup won't be called */
-+	qc = ata_qc_from_tag(ap, ap->active_tag);
-+	if (qc->tf.protocol == ATA_PROT_PIO) {
-+        /* reset the core */
-+        ox800sata_timeout_cleanup(ap);
-+    }
-+        
-+    /* call strandard lib ata function */
-+    ata_eng_timeout( ap );
-+
-+    /* clear the in cleanup flag */
-+    pd->in_cleanup = 0;
-+}
-+
-+/** 
-+ * irq_handler is the interrupt handling routine registered with the system,
-+ * by libata.
-+ */
-+static irqreturn_t ox800sata_irq_handler(int irq,
-+                                        void* dev_instance)
-+{
-+    struct ata_port        *ap = ((struct ata_host *)dev_instance)->ports[0];
-+    ox800sata_private_data *pd;
-+    u32                    *ioaddr;
-+    u32                     int_status;    
-+
-+    DPRINTK("irq = %d\n", irq);
-+
-+    if (!ap || !ap->private_data)
-+        BUG();
-+
-+    pd = (ox800sata_private_data*)ap->private_data;
-+    ioaddr = ox800sata_get_io_base(ap);
-+
-+    int_status = readl(ioaddr + OX800SATA_INT_STATUS);
-+    while (int_status & OX800SATA_INT_MASKABLE) {
-+        /* store interrupt status for the bottom end */
-+        pd->int_status |= int_status;
-+
-+        /* Clear and mask pending interrupts */
-+        writel(int_status, ioaddr + OX800SATA_INT_CLEAR);
-+        writel(int_status, ioaddr + OX800SATA_INT_DISABLE);
-+
-+        int_status = readl(ioaddr + OX800SATA_INT_STATUS);
-+    }
-+
-+	// Wait a short while for the DMA to finish and if it doesn't start a thread
-+	// to poll for the finish
-+    pd->spot_the_end_work.ap = ap;
-+	if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+		ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+	} else {
-+		udelay(100);
-+		if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+			ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+		} else {
-+			/* Start a worker thread looking for the DMA channel to become idle */
-+			queue_work(ox800sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
-+		}
-+	}
-+
-+    return IRQ_HANDLED;
-+}
-+
-+/**
-+ * Work for a work queue, this will check for errors then wait for the DMA to
-+ * complete. On the DMA completing it will call ata_qc_complete
-+ */
-+static void ox800sata_spot_the_end(struct work_struct *work)
-+{
-+    struct spot_the_end_work_s* stew = 
-+        container_of(work, struct spot_the_end_work_s, worker);
-+    struct ata_port* ap = stew->ap;
-+    ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
-+    struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->active_tag);
-+    unsigned long flags = 0;
-+
-+    /* If there's no command ending associated with this IRQ, ignore it. */
-+    if ((qc == NULL) ||
-+        !(PrivateData->int_status & OX800SATA_INT_END_OF_CMD)) {
-+        DPRINTK(" qc=null\n");
-+        return;
-+    }
-+
-+    /* Look to see if the core is indicating an error condition after a RAID 
-+     * command */
-+    if (qc->scsicmd &&
-+        qc->scsicmd->request &&
-+        qc->scsicmd->request->bio &&
-+        qc->scsicmd->request->bio->bi_raid ) {
-+        unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX800SATA_INT_STATUS);
-+        unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX800SATA_INT_STATUS);
-+
-+        if (test_bit(OX800SATA_INT_ERROR,  &Port0Irq)) {
-+            printk("disk 0 error in raid\n");
-+            ox800sata_accumulated_RAID_faults |= 1;
-+        }
-+        if (test_bit(OX800SATA_INT_ERROR,  &Port1Irq)) {
-+            printk("disk 1 error in raid\n");
-+            ox800sata_accumulated_RAID_faults |= 2;
-+        }
-+    }
-+    
-+	if (!in_irq()) {
-+		/* wait for the DMA to finish */
-+		while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+			schedule();
-+		}
-+	}
-+
-+	/* The command may have aborted, this is indicated by the interrupt bit
-+	 * being masked */   
-+	 if (PrivateData->in_cleanup) {
-+		return;
-+	 }
-+
-+	 if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
-+		 printk(KERN_WARNING "**** QC already completed! ****\n");
-+		 return;
-+	 }
-+
-+    /* get the error status */    
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+
-+    /* tell libata we're done */
-+    DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
-+    local_irq_save(flags);
-+    PrivateData->int_status = 0;
-+    local_irq_restore(flags);
-+    ata_qc_complete(qc);
-+}
-+ 
-+/** 
-+ * ox800sata_irq_clear is called during probe just before the interrupt handler is
-+ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
-+ * in the SATA core.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_irq_clear(struct ata_port* ap)
-+{
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    //DPRINTK(KERN_INFO"ox800sata_irq_clear\n");
-+    
-+    writel( ~0, ioaddr + OX800SATA_INT_DISABLE );
-+    writel( ~0, ioaddr + OX800SATA_INT_CLEAR );
-+}
-+
-+static u32  __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg) 
-+{
-+    u32 result;
-+    u32 patience;
-+
-+    /* we've got 8 other registers in before the start of the standard ones */    
-+    writel(sc_reg, core_addr + OX800SATA_LINK_RD_ADDR );
-+
-+    for (patience = 0x100000;patience > 0;--patience)
-+    {
-+        if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+            break;
-+    }
-+
-+    result = readl(core_addr + OX800SATA_LINK_DATA);
-+    
-+    //DPRINTK(KERN_INFO"ox800sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
-+    return result;
-+}
-+
-+/** 
-+ *  Read standard SATA phy registers. Currently only used if 
-+ * ->phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @return the value in the register
-+ */
-+static int ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
-+{
-+    u32* ioaddr = ox800sata_get_link_base(ap);
-+    *val = __ox800sata_scr_read(ioaddr, 0x20 + (sc_reg*4) );
-+	return 0;
-+}
-+
-+static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
-+{
-+    u32 patience;
-+
-+    //DPRINTK(KERN_INFO"ox800sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
-+    writel(val, core_addr + OX800SATA_LINK_DATA );
-+    writel(sc_reg , core_addr + OX800SATA_LINK_WR_ADDR );
-+
-+    for (patience = 0x100000;patience > 0;--patience)
-+    {
-+        if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+            break;
-+    }
-+}
-+/** 
-+ *  Write standard SATA phy registers. Currently only used if 
-+ * phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @param val the value to write into the register
-+ */
-+static int ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
-+{
-+    u32 *ioaddr = ox800sata_get_link_base(ap);
-+    __ox800sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
-+	return 0;
-+}
-+
-+/** 
-+ * port_start() is called just after the data structures for each port are
-+ * initialized. Typically this is used to alloc per-port DMA buffers, tables
-+ * rings, enable DMA engines and similar tasks.
-+ *
-+ * @return 0 = success
-+ * @param ap hardware with the registers in
-+ */
-+static int  ox800sata_port_start(struct ata_port *ap)
-+{
-+    ox800sata_private_data* pd;
-+    struct device* pdev = ap->host->dev;
-+
-+    ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
-+    if (!ap->prd) {
-+        return -ENOMEM;
-+    }
-+
-+    /* allocate port private data memory and attach to port */    
-+    if (!ap->private_data) {
-+        ap->private_data = kmalloc(sizeof(ox800sata_private_data), GFP_KERNEL);
-+    }
-+
-+    if (!ap->private_data) {
-+        return -ENOMEM;
-+    }
-+
-+	pd = (ox800sata_private_data* )ap->private_data;
-+	pd->DmaChannel = 0;
-+	pd->sg_entries = 0;
-+
-+    DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
-+
-+	// Allocate DMA SG entries
-+	if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES)) {
-+		printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA SG entries\n");
-+		return -ENOMEM;
-+	}
-+
-+	// Hold on to a DMA channel for the life of the SATA driver
-+    pd->DmaChannel = oxnas_dma_request(1);
-+	if (!pd->DmaChannel) {
-+		printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA channel\n");
-+        return -ENOMEM;
-+	}
-+
-+    /* declare a work item to spot when a command finishes */
-+    INIT_WORK(&(pd->spot_the_end_work.worker), &ox800sata_spot_the_end);
-+
-+    /* initialise to zero */
-+    pd->ErrorsWithNoCommamnd = 0;
-+    pd->port_disabled = 0;
-+    pd->int_status = 0;
-+    pd->in_cleanup = 0;
-+
-+    /* store the ata_port painter in the driver structure (BAD, should really 
-+    be in the device) */
-+    if (ox800sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
-+        ox800sata_driver.ap[0] = ap;
-+    } else if (ox800sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
-+        ox800sata_driver.ap[1] = ap;
-+	}
-+
-+    // turn ata core on
-+    writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+    /* post reset init needs to be called for both ports as there's one reset
-+    for both ports*/
-+    if (ox800sata_driver.ap[0]) {
-+        ox800sata_post_reset_init(ox800sata_driver.ap[0]);
-+	}
-+    if (ox800sata_driver.ap[1]) {
-+        ox800sata_post_reset_init(ox800sata_driver.ap[1]);
-+	}
-+
-+    return 0;
-+}
-+
-+static void ox800sata_post_reset_init(struct ata_port* ap) 
-+{
-+    u32  patience;
-+    u32* link_addr = ox800sata_get_link_base(ap);
-+    u32* ioaddr = ox800sata_get_io_base(ap);
-+    uint dev;
-+    
-+    /* turn on phy error detection by removing the masks */ 
-+    writel(0x30003, link_addr + OX800SATA_LINK_DATA );
-+    wmb();
-+    writel(0x0C, link_addr + OX800SATA_LINK_WR_ADDR );
-+    wmb();
-+    for (patience = 0x100000;patience > 0;--patience)
-+    {
-+        if (readl(link_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+            break;
-+    }
-+    
-+    /* Set FIS modes to flush rather than softtrans */
-+    writel(0xff, ioaddr + OX800SATA_REG_ACCESS);
-+    
-+    /* go through all the devices and configure them */
-+    for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+        if ( ap->device[dev].class == ATA_DEV_ATA )
-+            ox800sata_dev_config( &(ap->device[dev]) );
-+    }
-+}
-+
-+/** 
-+ * port_stop() is called after ->host_stop(). It's sole function is to 
-+ * release DMA/memory resources, now that they are no longer actively being
-+ * used.
-+ */
-+static void ox800sata_port_stop(struct ata_port *ap)
-+{
-+    ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
-+
-+    DPRINTK("\n");
-+
-+	if (pd->DmaChannel) {
-+		oxnas_dma_free(pd->DmaChannel);
-+		pd->DmaChannel = 0;
-+	}
-+
-+	if (pd->sg_entries) {
-+		oxnas_dma_free_sg_entries(pd->sg_entries);
-+		pd->sg_entries = 0;
-+	}
-+
-+    kfree(pd);
-+}
-+
-+/** 
-+ * host_stop() is called when the rmmod or hot unplug process begins. The
-+ * hook must stop all hardware interrupts, DMA engines, etc.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_host_stop(struct ata_host *host_set)
-+{
-+    DPRINTK("\n");
-+}
-+
-+/** 
-+ * PATA device presence detection
-+ * @param ap ATA channel to examine
-+ * @param device Device to examine (starting at zero)
-+ * @return true if something found 
-+ *
-+ * This technique was originally described in
-+ * Hale Landis's ATADRVR (www.ata-atapi.com), and
-+ * later found its way into the ATA/ATAPI spec.
-+ * 
-+ * Write a pattern to the ATA shadow registers,
-+ * and if a device is present, it will respond by
-+ * correctly storing and echoing back the
-+ * ATA shadow register contents.
-+ * 
-+ * LOCKING:
-+ * caller.
-+ */
-+static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device)
-+{
-+    DPRINTK("\n");
-+
-+    return 0;       /* nothing found */
-+}
-+
-+static void ox800sata_pio_start(struct work_struct *work)
-+{
-+    u32 burst_reg;
-+	struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+	ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;
-+    struct ata_queued_cmd* qc = ap->port_task_data;
-+    u32* ioaddr = ox800sata_get_io_base(ap);
-+    unsigned long flags = 0;
-+
-+    // We check for DMA completion from ISR which cannot wait for all DMA channel
-+	// housekeeping to complete, so need to wait here is case we try to reuse
-+	// channel before that housekeeping has completed
-+	while (oxnas_dma_is_active(pd->DmaChannel)) {
-+		printk(KERN_WARNING "PIO start Channel still active\n");
-+	}
-+
-+	if (qc->tf.protocol != ATA_PROT_NODATA) {
-+		oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
-+										   OXNAS_DMA_FROM_DEVICE :
-+										   OXNAS_DMA_TO_DEVICE;
-+
-+		/* Do not use DMA callback */
-+		oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+		/* map memory for dma */
-+		dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+
-+		/* setup a scatter gather dma */
-+		oxnas_dma_device_set_sg(pd->DmaChannel,
-+								 direction,
-+								 qc->__sg,
-+								 qc->n_elem,
-+								 &oxnas_sata_dma_settings,
-+								 OXNAS_DMA_MODE_INC);
-+
-+		oxnas_dma_start(pd->DmaChannel);
-+
-+		/* turn on the fifo */    
-+		burst_reg = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+		burst_reg &= ~OX800SATA_BBC_DREQ_DIS;
-+		writel(burst_reg, ioaddr + OX800SATA_BURST_CONTROL);
-+
-+		if (oxnas_dma_is_active(pd->DmaChannel)) {
-+			/* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+			ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+			return;
-+		}
-+
-+		/* cleanup DMA */
-+		dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+	} else {
-+        /* if the core is still busy, reschedule */
-+        if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+            ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+            return;
-+        }
-+	}
-+
-+    /* notify of completion */
-+    PretendDRQIsClear = 1;
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+    spin_lock_irqsave(ap->lock, flags);
-+    ap->ops->irq_on(ap);
-+    ata_qc_complete(qc);
-+    spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+/**
-+ * This is the top level of the PIO task. It is responsible for organising the
-+ * transfer of data, collecting and reacting to status changes and notification
-+ * of command completion.
-+ *
-+ */
-+static void ox800sata_pio_task(struct work_struct *work)
-+{
-+	struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+	struct ata_queued_cmd *qc = ap->port_task_data;
-+    unsigned long flags = 0;
-+
-+	if (qc->tf.protocol != ATA_PROT_NODATA) {
-+		ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
-+
-+		if (oxnas_dma_is_active(pd->DmaChannel)) {
-+			/* if the DMA is still busy, re-schedule the task */
-+			/* try again in 1 ms */
-+			ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+			return;
-+		}
-+
-+		/* cleanup DMA */
-+		dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+	} else {
-+		u32* ioaddr = ox800sata_get_io_base(ap);
-+
-+        /* if the core is still busy, reschedule */
-+        if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+            ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+            return;
-+        }
-+	}
-+
-+    /* notify of completion */
-+    PretendDRQIsClear = 1;
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+    spin_lock_irqsave(ap->lock, flags);
-+    ap->ops->irq_on(ap);
-+    ata_qc_complete(qc);
-+    spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc)
-+{
-+    struct ata_port *ap = qc->ap;
-+    ox800sata_private_data* private_data = (ox800sata_private_data*)ap->private_data;
-+
-+    /* Check if DMA is in progress, if so abort */
-+	if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+		/* 
-+		 * Attempt to abort any current transfer:
-+		 *   Abort DMA transfer at the DMA controller,
-+		 */
-+		printk(KERN_ERR "ox800sata_bmdma_stop - aborting DMA\n");
-+
-+		oxnas_dma_abort(private_data->DmaChannel);
-+
-+		/* perform core cleanups and resets */
-+		ox800sata_timeout_cleanup(ap);
-+	}
-+}
-+
-+/**
-+ *
-+ */
-+static void ox800sata_timeout_cleanup( struct ata_port *ap ) {
-+    u32* io_base  = ox800sata_get_io_base(ap);
-+    u32* bbp_base = ox800sata_get_bbp_base();
-+    int idle;
-+    u32 reg;
-+    int loops;
-+    
-+    /* Test SATA core idle state */
-+    CrazyDumpDebug(ap);
-+    idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+    
-+
-+    printk(KERN_ERR "ox800sata_timeout_cleanup() ata%u idle = %d\n", ap->print_id, idle);
-+    
-+    if (!idle) {
-+        /*
-+         * Assert SATA core and burst buffer port Force_EOT
-+         */
-+        printk(KERN_INFO "ox800sata_timeout_cleanup - aborting SATA... (may take upto 5 seconds)\n");
-+
-+        reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
-+        reg |= OX800SATA_DEVICE_CONTROL_ABORT;
-+        writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
-+
-+        reg = readl(bbp_base + OX800SATA_BURST_CONTROL);
-+        reg |= OX800SATA_BBC_FORCE_EOT;
-+        writel(reg, bbp_base + OX800SATA_BURST_CONTROL);
-+
-+        /* Wait for SATA core to go idle */
-+        idle = 0;
-+        loops = SATA_ABORT_WAIT_MS;
-+        while(1) {
-+            /* Test SATA core idle state */
-+            idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+            if (idle || (loops-- <= 0)) {
-+                break;
-+            }
-+            /* Wait a millisecond before testing again */
-+            udelay(1000);
-+        }
-+
-+        /* Deassert SATA core abort - BBP Force_EOT is self-clearing` */
-+        reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
-+        reg &= ~OX800SATA_DEVICE_CONTROL_ABORT;
-+        writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
-+
-+        DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
-+
-+        if (!idle) {
-+            /*
-+             * SATA core did not go idle, so attempt a core reset:
-+             *   Assert both SATA core internal reset and ORB4 srst
-+             *   Deassert both SATA core internal reset and ORB4 srst
-+             */
-+#if 0
-+             printk(KERN_INFO "ox800sata_timeout_cleanup - internal SATA reset... (may take upto 5 seconds)\n");
-+
-+            reg = readl(io_base + OX800SATA_SATA_CONTROL);
-+            reg |= OX800SATA_SCTL_RESET;
-+            writel(reg, io_base + OX800SATA_SATA_CONTROL);
-+
-+            reg = readl(io_base + OX800SATA_ORB4);
-+            reg |= OX800SATA_ORB4_SRST;
-+            writel(reg, io_base + OX800SATA_ORB4);
-+
-+            /* Wait for SATA core to go idle */
-+            idle = 0;
-+            loops = SATA_SRST_WAIT_MS;
-+            while(1) {
-+                /* Test SATA core idle state */
-+                idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+                if (idle || (loops-- <= 0)) {
-+                    break;
-+                }
-+                /* Wait a millisecond before testing again */
-+                udelay(1000);
-+            }
-+
-+            reg = readl(io_base + OX800SATA_ORB4);
-+            reg &= ~OX800SATA_ORB4_SRST;
-+            writel(reg, io_base + OX800SATA_ORB4);
-+
-+            reg = readl(io_base + OX800SATA_SATA_CONTROL);
-+            reg &= ~OX800SATA_SCTL_RESET;
-+            writel(reg, io_base + OX800SATA_SATA_CONTROL);
-+            udelay(1000);
-+
-+            DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
-+#endif
-+            idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+            if (!idle) {
-+                /*
-+                 * SATA core did not go idle, so cause a SATA core reset from the RPS
-+                 *  NB It may be required to reset both SATA cores if have a dual system
-+                 */
-+                printk(KERN_INFO "ox800sata_timeout_cleanup - RPS SATA core reset\n");
-+
-+                writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+                udelay(1000);
-+                writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+                /* Read SATA core idle state */
-+                idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+
-+                printk(KERN_INFO"idle = %d\n", idle);
-+
-+                /* Perform any SATA core re-initialisation after reset */
-+                /* post reset init needs to be called for both ports as there's one reset
-+                for both ports*/
-+                if (ox800sata_driver.ap[0])
-+                    ox800sata_post_reset_init(ox800sata_driver.ap[0]);
-+                if (ox800sata_driver.ap[1])
-+                    ox800sata_post_reset_init(ox800sata_driver.ap[1]);
-+            }
-+        }
-+    }
-+}
-+
-+/** 
-+ * bmdma_status return a made up version of a BMDMA status register
-+ *
-+ * @param ap Hardware with the registers in
-+ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
-+ */
-+static u8   ox800sata_bmdma_status(struct ata_port *ap)
-+{
-+    ox800sata_private_data* PrivateData ;
-+    PrivateData = (ox800sata_private_data* )ap->private_data;    
-+
-+    {
-+    u32 interrupt_status;
-+    u32 *ioaddr = ox800sata_get_io_base(ap);
-+    interrupt_status = readl(ioaddr + OX800SATA_INT_STATUS );
-+    DPRINTK(" irq bits are %08x \n",interrupt_status);
-+    }
-+/*    if( oxnas_dma_is_active( PrivateData->DmaChannel ) )
-+    {
-+        CrazyDumpDebug(ap);
-+        return 0;
-+    }
-+    else*/
-+    {
-+        return ATA_DMA_INTR;
-+    }
-+}
-+ 
-+/** 
-+ * turn on the interrupts from the ata drive
-+ * wait for idle, clear any pending interrupts.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox800sata_irq_on(struct ata_port *ap)
-+{
-+    u32* ioaddr = ox800sata_get_io_base(ap);
-+    u8 tmp;
-+
-+    //DPRINTK(KERN_INFO"ox800sata_irq_on\n");
-+    
-+    /* enable End of command interrupt */
-+    writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
-+    writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_ENABLE);
-+	tmp = ata_wait_idle(ap);
-+
-+    return tmp;
-+}
-+ 
-+/** 
-+ * Acknowledges any pending interrupts, by clearing them, but not disabling 
-+ * them.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
-+{
-+    u32* ioaddr = ox800sata_get_io_base(ap);
-+    unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-+    u8 status;
-+
-+    //DPRINTK(KERN_INFO"921ish_irq_ack\n");
-+    status = ata_busy_wait(ap, bits, 1000);
-+    if (status & bits)
-+    {
-+        DPRINTK("abnormal status 0x%X\n", status);
-+    }
-+
-+    /* clear the end of command interrupt bit */
-+    writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
-+
-+    return status;
-+}
-+ 
-+/** 
-+ * Outputs all the registers in the SATA core for diagnosis of faults.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static void CrazyDumpDebug(struct ata_port *ap)
-+{
-+#ifdef CRAZY_DUMP_DEBUG
-+    u32 offset;
-+    u32 result;
-+    u32 patience;
-+    u32* ioaddr;
-+
-+    /* IRQ flags for calling port */
-+    {
-+        ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
-+        printk("IRQ %08x\n",PrivateData->int_status);
-+    }
-+    
-+    /* port 0 */
-+    ioaddr = (u32* )SATA0_REGS_BASE;
-+    printk("Port 0 High level registers\n");
-+    for(offset = 0; offset < 32;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
-+    }
-+
-+    printk("Port 0 link layer registers\n");
-+    ioaddr = (u32* )SATA0_LINK_REGS_BASE;
-+    for(offset = 0; offset < 15;++offset)
-+    {
-+        writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
-+        wmb();
-+    
-+        for (patience = 0x100000;patience > 0;--patience)
-+        {
-+            if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+                break;
-+        }
-+    
-+        result = readl(ioaddr + OX800SATA_LINK_DATA);
-+        printk("[%02x] %08x\n", offset*4, result);
-+    }
-+
-+    /* port 1 */
-+    ioaddr = (u32* )SATA1_REGS_BASE;
-+    printk("Port 1 High level registers\n");
-+    for(offset = 0; offset < 32;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
-+    }
-+
-+    printk("Port 1 link layer registers\n");
-+    ioaddr = (u32* )SATA1_LINK_REGS_BASE;
-+    for(offset = 0; offset < 15;++offset)
-+    {
-+        writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
-+        wmb();
-+    
-+        for (patience = 0x100000;patience > 0;--patience)
-+        {
-+            if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+                break;
-+        }
-+    
-+        result = readl(ioaddr + OX800SATA_LINK_DATA);
-+        printk("[%02x] %08x\n", offset*4, result);
-+    }
-+    
-+    oxnas_dma_dump_registers();
-+#endif
-+}
-+
-+/**************************************************************************
-+* DEVICE CODE
-+**************************************************************************/
-+
-+/**
-+ * Describes the identity of the SATA core and the resources it requires
-+ */ 
-+static struct resource ox800sata_port0_resources[] = {
-+	{
-+        .name       = "sata_port_0_registers",
-+		.start		= SATA0_REGS_BASE,
-+        .end        = (SATA0_LINK_REGS_BASE + 64),
-+		.flags		= IORESOURCE_MEM,
-+	},
-+    {
-+        .name       = "sata_irq",
-+        .start      = SATA_1_INTERRUPT,
-+		.flags		= IORESOURCE_IRQ,
-+    }
-+};
-+
-+static struct resource ox800sata_port1_resources[] = {
-+	{
-+        .name       = "sata_port_1_registers",
-+		.start		= SATA1_REGS_BASE,
-+        .end        = (SATA1_LINK_REGS_BASE + 64),
-+		.flags		= IORESOURCE_MEM,
-+	},
-+    {
-+        .name       = "sata_irq",
-+        .start      = SATA_2_INTERRUPT,
-+		.flags		= IORESOURCE_IRQ,
-+    },
-+};
-+
-+static struct platform_device ox800sata_dev0 = 
-+{
-+    .name = DRIVER_NAME,
-+    .id = 0,
-+    .num_resources = 2,
-+	.resource  = ox800sata_port0_resources,
-+    .dev.coherent_dma_mask = 0xffffffff,
-+}; 
-+
-+static struct platform_device ox800sata_dev1 = 
-+{
-+    .name = DRIVER_NAME,
-+    .id = 1,
-+    .num_resources = 2,
-+	.resource  = ox800sata_port1_resources,
-+    .dev.coherent_dma_mask = 0xffffffff,
-+}; 
-+
-+/** 
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox800sata_device_init( void )
-+{
-+    int ret;
-+
-+    DPRINTK("\n");
-+
-+    {
-+        // register the ata device for the driver to find
-+        ret = platform_device_register( &ox800sata_dev0 );
-+        DPRINTK(" %i\n", ret);
-+    }
-+    
-+#ifndef SATA_OXNAS_SINGLE_SATA
-+    {
-+        // register the ata device for the driver to find
-+        ret = platform_device_register( &ox800sata_dev1 );
-+        DPRINTK(" %i\n", ret);
-+    }
-+#endif /* SATA_OXNAS_SINGLE_SATA */
-+
-+    return ret;
-+}
-+
-+/** 
-+ * module cleanup
-+ */
-+static void __exit ox800sata_device_exit( void )
-+{
-+    platform_device_unregister( &ox800sata_dev0 );
-+    platform_device_unregister( &ox800sata_dev1 );
-+}
-+
-+/**
-+ * Returns accumulated RAID faults and then clears the accumulation
-+ * @return accumulated RAID faults indicated by set bits
-+ */
-+int  oxnassata_RAID_faults( void ) {
-+    int temp = ox800sata_accumulated_RAID_faults;
-+    ox800sata_accumulated_RAID_faults = 0;
-+    return temp;
-+}
-+
-+/**
-+ * Returns ox800 port number the request queue is serviced by.
-+ *
-+ * @param queue The queue under investigation.
-+ * @return The ox800 sata port number servicing the queue or -1 if not found.
-+ */
-+int oxnassata_get_port_no(struct request_queue* q)
-+{
-+    struct ata_port* ap = 0;
-+    struct scsi_device* sdev = 0;
-+    
-+    /* check port 0 */
-+    ap = ox800sata_driver.ap[0];
-+    if (ap)
-+        shost_for_each_device(sdev, ap->scsi_host) {
-+            if (sdev->request_queue == q) {
-+                DPRINTK("Queue %p on port 0\n", q);
-+                return 0;
-+            }
-+        }
-+    
-+    /* check port 1 */
-+    ap = ox800sata_driver.ap[1];
-+    if (ap)
-+        shost_for_each_device(sdev, ap->scsi_host) {
-+            if (sdev->request_queue == q) {
-+                DPRINTK("Queue %p on port 1\n", q);
-+                return 1;
-+            }
-+        }
-+
-+    /* not found */
-+    return -1;  
-+}
-+
-+/**
-+ * @return true if all the drives attached to the internal SATA ports use the
-+ * same LBA size.
-+ */
-+int oxnassata_LBA_schemes_compatible( void )
-+{
-+    unsigned long flags0 ;
-+    unsigned long flags1 ;
-+    struct ata_port* ap ;
-+    
-+    /* check port 0 */
-+    ap = ox800sata_driver.ap[0];
-+    if (ap)
-+        flags0 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
-+    else
-+        return 0;
-+    
-+    /* check port 1 */
-+    ap = ox800sata_driver.ap[1];
-+    if (ap)
-+        flags1 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
-+    else
-+        return 0;
-+
-+    /* compare */
-+    return (flags0 == flags1);  
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800sata_device_init);
-+module_exit(ox800sata_device_exit);
-+
-+EXPORT_SYMBOL( oxnassata_RAID_faults );
-+EXPORT_SYMBOL( oxnassata_get_port_no );
-+EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
-diff -Nurd linux-2.6.24/drivers/ata/ox810sata.c linux-2.6.24-oxe810/drivers/ata/ox810sata.c
---- linux-2.6.24/drivers/ata/ox810sata.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/ox810sata.c	2008-06-11 17:50:32.000000000 +0200
-@@ -0,0 +1,2423 @@
-+/**************************************************************************
-+ *
-+ *  Copyright (c) 2007 Oxford Semiconductor Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, 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.
-+ *
-+ *  Module Name:
-+ *      ox810sata.c
-+ *
-+ *  Abstract:
-+ *      A driver to interface the 934 based sata core present in the ox810
-+ *      with libata and scsi
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/module.h>
-+#include <linux/leds.h>
-+
-+#include <scsi/scsi_host.h>
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_device.h>
-+#include <asm/io.h>
-+
-+#include <linux/platform_device.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/ox810sata.h>
-+
-+#include <linux/proc_fs.h>
-+
-+/***************************************************************************
-+* DEBUG CONTROL
-+***************************************************************************/
-+//#define SATA_DEBUG
-+//#define SATA_DUMP_REGS
-+//#define SATA_TF_DUMP
-+//#define DEBUG_EOT_FAILURE
-+#define ERROR_INJECTION
-+
-+#define CRAZY_DUMP_DEBUG
-+#if 0
-+typedef struct {
-+    u32 a;
-+    u32 d;
-+    u32 w;
-+} regaccess;
-+static u32 regindex = 0;
-+static regaccess regarray[1024];
-+#endif
-+
-+#if 0
-+    #ifdef writel
-+    #undef writel
-+    #endif
-+    #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;} 
-+    //#define writel(vv,aa) {regarray[regindex].a=(aa); regarray[regindex].d=(vv); regarray[regindex].w=1; ++regindex; regindex &= 1023;*((volatile u32*)(aa)) = (vv);} 
-+#endif
-+
-+#if 0
-+    #ifdef readl
-+    #undef readl
-+    #endif
-+    static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
-+    //static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));regarray[regindex].a=a; regarray[regindex].d=v; regarray[regindex].w=0; ++regindex; regindex &= 1023;return v;}
-+    #define readl(a) (myreadl(a))
-+#endif
-+
-+
-+#include <linux/libata.h>
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+
-+#define DRIVER_AUTHOR   "Oxford Semiconductor Ltd."
-+#define DRIVER_DESC     "934 SATA core controler"
-+#define DRIVER_NAME     "oxnassata"
-+
-+#define SATA_ABORT_WAIT_MS 5000
-+#define SATA_SRST_WAIT_MS  5000
-+
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+static int  ox810sata_init_one(struct platform_device *);
-+static int  ox810sata_remove_one(struct platform_device *);
-+
-+static void ox810sata_dev_config(struct ata_port *, struct ata_device *);
-+static void ox810sata_set_piomode(struct ata_port *, struct ata_device *);
-+static void ox810sata_set_dmamode(struct ata_port *, struct ata_device *);
-+static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
-+static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-+static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
-+static u8 ox810sata_check_status(struct ata_port *ap);
-+static inline u8 ox810sata_check_altstatus(struct ata_port *ap);
-+static void ox810sata_dev_select(struct ata_port *ap, unsigned int device);
-+static void ox810sata_phy_reset(struct ata_port *ap);
-+static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc);
-+static void ox810sata_bmdma_start(struct ata_queued_cmd *qc);
-+static u8 ox810sata_bmdma_status(struct ata_port *ap);
-+static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap);
-+static void ox810sata_qc_free(struct ata_queued_cmd *qc);
-+static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc);
-+static void ox810sata_eng_timeout(struct ata_port *ap);
-+static irqreturn_t ox810sata_irq_handler(int, void *);
-+static void ox810sata_eng_timeout(struct ata_port *ap);
-+static void ox810sata_irq_clear(struct ata_port *);
-+static int  ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-+static int  ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
-+static int ox810sata_port_start(struct ata_port *ap);
-+static void ox810sata_port_stop(struct ata_port *ap);
-+static void ox810sata_host_stop(struct ata_host *host_set);
-+static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device);
-+static u32* ox810sata_get_io_base(struct ata_port* ap);
-+static u8 ox810sata_irq_on(struct ata_port *ap);
-+static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc);
-+static void CrazyDumpDebug( void );
-+static void ox810sata_spot_the_end(struct work_struct *work);
-+static void ox810sata_timeout_cleanup(struct ata_port *ap);
-+static void ox810sata_error_handler(struct ata_port *ap);
-+static void ox810sata_reset_core(void);
-+static int ox810sata_prereset(struct ata_link *link, unsigned long deadline);
-+static int ox810sata_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline);
-+static void ox810sata_postreset(struct ata_link *link, unsigned int *classes);
-+static void ox810sata_pio_start(struct work_struct *work);
-+static void ox810sata_pio_task(struct work_struct *work);
-+static void ox810sata_post_reset_init(struct ata_port* ap);
-+static u32 inline __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg);
-+static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
-+#ifdef ERROR_INJECTION
-+static int ox810sata_error_inject_show(char *page, char **start, off_t off, int count, int *eof, void *data);
-+static int ox810sata_error_inject_store(struct file *file,const char __user *buffer,unsigned long count,void *data);
-+#endif
-+
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef struct
-+{
-+    struct kobject kobj;
-+    struct platform_driver driver;
-+    struct ata_port* ap[2];
-+    u32 error_inject;
-+    struct workqueue_struct* spot_the_end_q;
-+    u32 hw_raid_active;
-+    struct ata_port* active_port;
-+} ox810sata_driver_t;
-+
-+/**
-+ * Struct to hold per-port private (specific to this driver) data (still 
-+ * un-researched).
-+ */
-+typedef struct
-+{
-+    oxnas_dma_channel_t* DmaChannel;
-+	oxnas_dma_sg_entry_t* sg_entries;
-+    struct spot_the_end_work_s  {
-+        struct work_struct worker;
-+        struct ata_port* ap;
-+    } spot_the_end_work;
-+    u32 ErrorsWithNoCommamnd;
-+    u32 int_status;
-+    u32 in_cleanup;
-+} ox810sata_private_data;
-+
-+ox810sata_driver_t ox810sata_driver = 
-+{
-+    .driver =
-+    {
-+        .driver.name = DRIVER_NAME,
-+        .driver.bus = &platform_bus_type,
-+        .probe = ox810sata_init_one, 
-+        .remove = ox810sata_remove_one,
-+    },
-+    .ap = {0,0},
-+    .error_inject = 0,
-+    .hw_raid_active = 0,
-+    .active_port = 0,
-+};
-+
-+/** If we were writing this in C++ then we would be deriving a subclass of 
-+ata_port, these would be the overridden functions*/
-+static struct ata_port_operations ox810sata_port_ops =
-+{
-+    .dev_config = ox810sata_dev_config,
-+    .set_piomode = ox810sata_set_piomode,
-+    .set_dmamode = ox810sata_set_dmamode,
-+    .tf_load = ox810sata_tf_load,
-+    .tf_read = ox810sata_tf_read,
-+    .exec_command = ox810sata_exec_command,
-+    .check_status = ox810sata_check_status,
-+    .check_altstatus = ox810sata_check_altstatus,
-+    .dev_select = ox810sata_dev_select,
-+    .phy_reset = ox810sata_phy_reset,
-+    .bmdma_setup = ox810sata_bmdma_setup,
-+    .bmdma_start = ox810sata_bmdma_start,
-+    .bmdma_stop = ox810sata_bmdma_stop,
-+    .bmdma_status = ox810sata_bmdma_status,
-+    .qc_new = ox810sata_qc_new,
-+    .qc_free = ox810sata_qc_free,
-+    .qc_prep = ata_qc_prep,
-+    .qc_issue = ox810sata_qc_issue,
-+    .eng_timeout = ox810sata_eng_timeout,
-+    .irq_handler = ox810sata_irq_handler,
-+    .irq_clear = ox810sata_irq_clear,
-+    .scr_read = ox810sata_scr_read,
-+    .scr_write = ox810sata_scr_write,
-+    .port_start = ox810sata_port_start,
-+    .port_stop = ox810sata_port_stop,
-+    .host_stop = ox810sata_host_stop,
-+    .dev_chk = ox810sata_devchk,
-+    .irq_on = ox810sata_irq_on,
-+    .pio_task = ox810sata_pio_start,
-+    .error_handler = ox810sata_error_handler,
-+    .post_internal_cmd = ox810sata_bmdma_stop,
-+};
-+
-+/** the scsi_host_template structure describes the basic capabilities of libata
-+and our 921 core to the SCSI framework, it contains the addresses of functions 
-+in the libata library that handle top level comands from the SCSI library */
-+static struct scsi_host_template ox810sata_sht = 
-+{
-+    .module             = THIS_MODULE,
-+    .name               = DRIVER_NAME,
-+    .ioctl              = ata_scsi_ioctl,
-+    .queuecommand       = ata_scsi_queuecmd,
-+/*    .eh_strategy_handler= ata_scsi_error,*/
-+    .can_queue          = ATA_DEF_QUEUE,
-+    .this_id            = ATA_SHT_THIS_ID,
-+/*    .sg_tablesize       = LIBATA_MAX_PRD,*/
-+    .sg_tablesize       = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
-+    .max_sectors        = 256,  // Use the full 28-bit SATA value
-+    .cmd_per_lun        = ATA_SHT_CMD_PER_LUN,
-+    .emulated           = ATA_SHT_EMULATED,
-+    .use_clustering     = ATA_SHT_USE_CLUSTERING,
-+    .proc_name          = DRIVER_NAME,
-+    .dma_boundary       = ~0UL, // NAS has no DMA boundary restrictions
-+    .slave_configure    = ata_scsi_slave_config,
-+    .bios_param         = ata_std_bios_param,
-+    .unchecked_isa_dma  = 0,
-+
-+};
-+
-+/** after PIO read operations, DRQ can remain set even when all the data has 
-+been read, when set, PretendDRQIsClear will mask out the DRQ bit in 
-+ox810sata_check_status operation */  
-+static char PretendDRQIsClear;
-+
-+/**
-+ * used as a store for atomic test and set operations used to coordinate so
-+ * that only one port is processing comnmands at any time */
-+static unsigned long ox810sata_command_active = 0;
-+
-+/**
-+ * A record of which drives have accumulated raid faults. A set bit indicates
-+ * a fault has occured on that drive */
-+static u32 ox810sata_accumulated_RAID_faults = 0;
-+
-+/**************************************************************************/
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(1.0);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox810sata_"
-+**************************************************************************/
-+
-+/**
-+ * Gets the base of the ox810 port associated with the ata-port as known
-+ * by lib-ata, The value returned changes to the single RAID port when
-+ * hardware RAID commands are active.
-+ * 
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static inline u32* ox810sata_get_tfio_base(struct ata_port* ap)
-+{
-+    if ((ox810sata_driver.hw_raid_active) &&
-+        (ox810sata_driver.active_port == ap)) {
-+        return (u32* )SATARAID_REGS_BASE;
-+    } else {
-+        return (u32* )ap->host->iomap;
-+    }
-+}
-+
-+/**
-+ * Gets the base address of the ata core from the ata_port structure. The value
-+ * returned will remain the same when hardware raid is active.
-+ *
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static inline u32* ox810sata_get_io_base(struct ata_port* ap)
-+{
-+    return (u32* )ap->host->iomap;
-+}
-+
-+/**
-+ * Turns on the cores clock and resets it
-+ */
-+static void ox810sata_reset_core( void ){
-+    // Enable the clock to the SATA block
-+    writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+    wmb();
-+
-+    // reset Controller, Link and PHY
-+    writel( (1UL << SYS_CTRL_RSTEN_SATA_BIT)      |
-+            (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+            (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+    wmb();
-+    udelay(50);
-+    
-+    // un-reset the PHY, then Link and Controller
-+    writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+    udelay(50);
-+    writel( (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+            (1UL << SYS_CTRL_RSTEN_SATA_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+    udelay(50);
-+}
-+
-+/**
-+ * port capabilities for the ox810 sata ports.
-+ */
-+static const struct ata_port_info ox810sata_port_info = {
-+    .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
-+    .pio_mask   = 0x1f, /* pio modes 0..4*/
-+    .mwdma_mask = 0x07, /* mwdma0-2 */
-+    .udma_mask  = 0x7f, /* udma0-5 */
-+    .port_ops   = &ox810sata_port_ops,
-+};
-+
-+/** 
-+ * The driver probe function.
-+ * Registered with the amba bus driver as a parameter of ox810sata_driver.bus
-+ * it will register the ata device with kernel first performing any 
-+ * initialisation required (if the correct device is present).
-+ * @param pdev Pointer to the 921 device structure 
-+ * @return 0 if no errors
-+ */
-+static int ox810sata_init_one(struct platform_device* pdev)
-+{
-+    u32 version;
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+    unsigned long reg;
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+    struct ata_host *host;
-+    void __iomem* iomem;
-+    const struct ata_port_info* port_info[] = { &ox810sata_port_info, NULL };
-+    struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
-+    int irq = platform_get_irq(pdev, 0);
-+    
-+    /* check resourses for sanity */
-+    if ((memres == NULL) || (irq < 0)) {
-+        return 0;
-+    }
-+    iomem = (void __iomem* ) memres->start;
-+    
-+    /* check we support this version of the core */
-+    version = readl(((u32* )iomem) + OX810SATA_VERSION);
-+    switch (version) {
-+        case OX810SATA_CORE_VERSION:
-+            printk(KERN_INFO"ox810sata: OX810 sata core.\n");   
-+            break;
-+        default:
-+            printk(KERN_ERR"ox810sata: unknown sata core (version register = 0x%08x)\n",version);     
-+            return 0;
-+            break;
-+    }
-+
-+    /* initialise a work queue to spot the end of transfers */
-+    ox810sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
-+    if (!ox810sata_driver.spot_the_end_q) {
-+        printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
-+        return -1;
-+    }
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+    /* setup path */
-+    reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+    /* enable output */
-+    writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
-+
-+    /* disk light off */
-+    writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif  /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+
-+    /* setup the probe_ent structure which is basically info about the ports 
-+    capabilities */
-+
-+    /* allocate memory and check */
-+    host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX810SATA_MAX_PORTS);
-+    if (!host) {
-+        printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
-+        destroy_workqueue(ox810sata_driver.spot_the_end_q);
-+    }
-+
-+    /* set to base of ata core */
-+    host->iomap  = iomem;
-+
-+    /* call ata_device_add and begin probing for drives*/
-+    ata_host_activate(host, irq, ox810sata_irq_handler, IRQF_SHARED, &ox810sata_sht);
-+
-+    return 0;
-+}
-+
-+/** 
-+ * Called when the amba bus tells this device to remove itself.
-+ * @param pdev pointer to the device that needs to be shutdown
-+ */
-+static int ox810sata_remove_one(struct platform_device* pdev)
-+{
-+    struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
-+    struct ata_port *ap;
-+    unsigned int i;
-+    
-+    for (i = 0; i < host_set->n_ports; i++) 
-+    {
-+        ap = host_set->ports[i];
-+        scsi_remove_host( ap->scsi_host );
-+    }
-+    
-+    /** @TODO etc. */
-+
-+    // Disable the clock to the SATA block
-+    writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+    
-+    return 0;
-+}
-+
-+/** 
-+ * module initialisation
-+ * @return success
-+ */
-+static int __init ox810sata_init( void )
-+{
-+    int ret;
-+    
-+    ret = platform_driver_register( &ox810sata_driver.driver );
-+    DPRINTK(" %i\n", ret);    
-+    
-+#ifdef ERROR_INJECTION
-+{
-+    struct proc_dir_entry *res=create_proc_entry("ox810sata_errorinject",0,NULL);
-+	if (res) {
-+		res->read_proc=ox810sata_error_inject_show;
-+        res->write_proc=ox810sata_error_inject_store;
-+		res->data=NULL;
-+	}
-+    //create_proc_read_entry("ox810sata_errorinject", 0, NULL, ox810sata_error_inject_show, NULL);
-+}   
-+#endif
-+    return ret; 
-+}
-+
-+/** 
-+ * module cleanup
-+ */
-+static void __exit ox810sata_exit( void )
-+{
-+    platform_driver_unregister( &ox810sata_driver.driver );
-+}
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox810sata_init);
-+module_exit(ox810sata_exit);
-+
-+/** 
-+ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
-+ * Typically used to apply device-specific fixups prior to issue of
-+ * SET FEATURES - XFER MODE, and prior to operation.
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_dev_config(struct ata_port *ap, struct ata_device* pdev)
-+{
-+    u32 reg;
-+    u32 *ioaddr = ox810sata_get_io_base(ap);
-+
-+    /* Set the bits to put the interface into 28 or 48-bit node */
-+    reg = readl(ioaddr + OX810SATA_DRIVE_CONTROL);
-+
-+    /* mask out the pair of bits associaed with each port */
-+    reg &= ~(3 << (ap->port_no * 2));
-+
-+    /* set the mode pair associated with each port */
-+    reg |= ((pdev->flags & ATA_DFLAG_LBA48) ? OX810SATA_DR_CON_48 :
-+                                              OX810SATA_DR_CON_28) << (ap->port_no * 2);
-+    writel(reg, ioaddr + OX810SATA_DRIVE_CONTROL);
-+
-+    /* if this is an ATA-6 disk, put the port into ATA-5 auto translate mode */
-+    if (pdev->flags & ATA_DFLAG_LBA48) {
-+        reg = readl(ioaddr + OX810SATA_PORT_CONTROL);
-+        reg |= 2;
-+        writel(reg, ioaddr + OX810SATA_PORT_CONTROL);
-+    }
-+}
-+
-+/**
-+ * nothing to do
-+ * 
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
-+{
-+}
-+
-+/** 
-+ * nothing to do
-+ * 
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
-+{
-+}
-+
-+/** 
-+ * Output the taskfile for diagnostic reasons, it will always appear in the 
-+ * debug output as if it's a task file being written.
-+ * @param tf The taskfile to output
-+ */
-+static void tfdump(const struct ata_taskfile* tf)
-+{
-+    if (tf->flags & ATA_TFLAG_LBA48) {
-+#ifdef SATA_TF_DUMP
-+    printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+    DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+        tf->command,
-+
-+        tf->hob_feature,
-+        tf->feature,
-+
-+        tf->hob_lbah,
-+        tf->hob_lbam,
-+        tf->hob_lbal,
-+        tf->lbah,
-+        tf->lbam,
-+        tf->lbal,
-+
-+        tf->hob_nsect,
-+        tf->nsect,
-+        tf->ctl,
-+        tf->device );
-+    } else {
-+#ifdef SATA_TF_DUMP
-+    printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+    DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+        tf->command,
-+
-+        tf->feature,
-+
-+        tf->device & 0x0f,        
-+        tf->lbah,
-+        tf->lbam,
-+        tf->lbal,
-+
-+        tf->nsect,
-+        tf->ctl,
-+        tf->device );
-+    }
-+}
-+
-+/** 
-+ * called to write a taskfile into the ORB registers
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+    u32 count = 0;
-+    u32 Orb1 = 0; 
-+    u32 Orb2 = 0; 
-+    u32 Orb3 = 0;
-+    u32 Orb4 = 0;
-+    u32 Command_Reg;
-+    u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+    unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-+
-+    /* wait a maximum of 10ms for the core to be idle */
-+    do {
-+        Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+        if (!(Command_Reg & CMD_CORE_BUSY)) {
-+            break;
-+		}
-+        count++;
-+		udelay(50);
-+    } while (count < 200);
-+
-+    /* if the control register has changed, write it */
-+    if (tf->ctl != ap->last_ctl) 
-+    {
-+        //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
-+        Orb4 |= (tf->ctl) << 24;
-+
-+        /* write value to register */
-+        writel(Orb4, ioaddr + OX810SATA_ORB4);
-+
-+        ap->last_ctl = tf->ctl;
-+
-+        /** @todo find a more elegant way to do this */
-+        /* if the new control value is a soft reset, command the core to send a
-+        control FIS */
-+        if (tf->ctl & ATA_SRST) {
-+            writel(CMD_WRITE_TO_ORB_REGS_NO_COMMAND, ioaddr + OX810SATA_SATA_COMMAND);
-+        }
-+    }
-+
-+    /* check if the ctl register has interrupts disabled or enabled and
-+    modify the interrupt enable registers on the ata core as required */
-+    if (tf->ctl & ATA_NIEN) {
-+        /* interrupts disabled */
-+        ox810sata_irq_clear(ap);
-+    } else {
-+        /* interrupts enabled */
-+        ox810sata_irq_on(ap);
-+    }
-+
-+    /* write 48 or 28 bit tf parameters */
-+    if (is_addr) {
-+        /* set LBA bit as it's an address */
-+        Orb1 |= (tf->device & ATA_LBA) << 24;
-+
-+        if (tf->flags & ATA_TFLAG_LBA48) {
-+            //DPRINTK(KERN_INFO" 48 bit tf load \n");
-+            Orb1 |= ATA_LBA << 24;
-+
-+            Orb2 |= (tf->hob_nsect)  << 8 ;
-+
-+            Orb3 |= (tf->hob_lbal)   << 24;
-+
-+            Orb4 |= (tf->hob_lbam)   << 0 ;
-+            Orb4 |= (tf->hob_lbah)   << 8 ;
-+            Orb4 |= (tf->hob_feature)<< 16;
-+        } else {
-+            Orb3 |= (tf->device & 0xf)<< 24;
-+        }
-+
-+        /* write 28-bit lba */
-+        //DPRINTK(KERN_INFO" 28 bit tf load\n");
-+        Orb2 |= (tf->nsect)      << 0 ;
-+        Orb2 |= (tf->feature)    << 16;
-+        Orb2 |= (tf->command)    << 24;
-+
-+        Orb3 |= (tf->lbal)       << 0 ;
-+        Orb3 |= (tf->lbam)       << 8 ;
-+        Orb3 |= (tf->lbah)       << 16;
-+
-+        Orb4 |= (tf->ctl)        << 24;
-+
-+        /* write values to registers */
-+        writel(Orb1, ioaddr + OX810SATA_ORB1 );
-+        writel(Orb2, ioaddr + OX810SATA_ORB2 );
-+        writel(Orb3, ioaddr + OX810SATA_ORB3 );
-+        writel(Orb4, ioaddr + OX810SATA_ORB4 );
-+    }
-+
-+    if (tf->flags & ATA_TFLAG_DEVICE) {
-+        Orb1 |= (tf->device) << 24;
-+
-+        /* write value to register */
-+        writel(Orb1, ioaddr + OX810SATA_ORB1);
-+    }
-+
-+    tfdump(tf);
-+}
-+
-+/** 
-+ * Called to read the hardware registers / DMA buffers, to
-+ * obtain the current set of taskfile register values.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to read the registers into
-+ */
-+static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+    u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+
-+    /* read the orb registers */
-+    u32 Orb1 = readl(ioaddr + OX810SATA_ORB1); 
-+    u32 Orb2 = readl(ioaddr + OX810SATA_ORB2); 
-+    u32 Orb3 = readl(ioaddr + OX810SATA_ORB3);
-+    u32 Orb4 = readl(ioaddr + OX810SATA_ORB4);
-+
-+    /* read common 28/48 bit tf parameters */
-+    tf->device  = (Orb1 >> 24);
-+    tf->nsect   = (Orb2 >> 0);
-+    tf->feature = (Orb2 >> 16);
-+    tf->command = ox810sata_check_status(ap);
-+
-+    /* read 48 or 28 bit tf parameters */
-+    if (tf->flags & ATA_TFLAG_LBA48) {
-+        //DPRINTK(KERN_INFO" 48 bit tf read \n");
-+        tf->hob_nsect = (Orb2 >> 8) ;
-+        
-+        tf->lbal      = (Orb3 >> 0) ;
-+        tf->lbam      = (Orb3 >> 8) ;
-+        tf->lbah      = (Orb3 >> 16) ;
-+        tf->hob_lbal  = (Orb3 >> 24) ;
-+        
-+        tf->hob_lbam  = (Orb4 >> 0) ;
-+        tf->hob_lbah  = (Orb4 >> 8) ;
-+        /* feature ext and control are write only */
-+    } else {
-+        /* read 28-bit lba */
-+        //DPRINTK(KERN_INFO" 28 bit tf read\n");
-+        tf->lbal      = (Orb3 >> 0) ;
-+        tf->lbam      = (Orb3 >> 8) ;
-+        tf->lbah      = (Orb3 >> 16) ;
-+    }
-+
-+    tfdump(tf);
-+}
-+
-+/** 
-+ * Causes an ATA command, previously loaded with ->tf_load(), to be
-+ * initiated in hardware. The command is written into the registers again just
-+ * to be sure. All the other registers that are in Orb2 are also written at the 
-+ * same time. The command is initiated in hardware by a poke to the COMMAND
-+ * register.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+    u32 count =0;
-+    u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+    u32 Orb2;
-+    u32 Command_Reg;
-+
-+#ifdef ERROR_INJECTION
-+    static u32 prand = 10;
-+    if (ox810sata_driver.error_inject) {
-+        u32 *portaddr = ox810sata_get_io_base(ap);
-+        prand = prand ? prand - 1 : 100;
-+        if ( prand < ox810sata_driver.error_inject) {
-+            DPRINTK("ox810sata_exec_command: error injection on\n");
-+            __ox810sata_scr_write( portaddr, 0x14 , 0xd );
-+        } else {
-+            __ox810sata_scr_write( portaddr, 0x14 , 0x1 );
-+            DPRINTK("ox810sata_exec_command: error injection off\n");
-+        }
-+    }
-+#endif
-+
-+    VPRINTK("\n");
-+    /* Wait a maximum af 10ms for the core to go idle */
-+    do {
-+        Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+        if (!(Command_Reg & CMD_CORE_BUSY)) {
-+            break;
-+		}
-+        count++;
-+        udelay(50);
-+    } while (count < 200);
-+
-+    /* write all the things in Orb 2 */
-+    Orb2  = (tf->nsect) << 0 ;
-+    if (tf->flags & ATA_TFLAG_LBA48) {
-+        Orb2 |= (tf->hob_nsect) << 8;
-+    }
-+    Orb2 |= (tf->feature) << 16;
-+    Orb2 |= (tf->command) << 24;
-+    writel(Orb2 , ioaddr + OX810SATA_ORB2);
-+    wmb();
-+
-+    do {
-+        Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+        if (!(Command_Reg & CMD_CORE_BUSY)) {
-+            break;
-+		}
-+        count++;
-+        udelay(50);
-+    } while (count < 200);
-+
-+    /* Command that the orb registers get written to drive */
-+    Command_Reg &= ~SATA_OPCODE_MASK;
-+    Command_Reg |= CMD_WRITE_TO_ORB_REGS;
-+    writel(Command_Reg , ioaddr + OX810SATA_SATA_COMMAND);
-+    wmb();
-+}
-+
-+
-+/** 
-+ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
-+ * transfers, it it sometimes necessary to mask out the DRQ bit
-+ * @param ap hardware with the registers in
-+ * @return The status register
-+ */
-+static u8 ox810sata_check_status(struct ata_port *ap)
-+{
-+    u32 Reg;
-+    u8 status;
-+    u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+
-+//    VPRINTK(KERN_INFO"ox810sata_check_status ");
-+
-+    /* read byte 3 of Orb2 register */
-+    status = readl(ioaddr + OX810SATA_ORB2) >> 24;
-+
-+    /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
-+    if ( ox810sata_driver.hw_raid_active ) {
-+        u32 Temp;
-+        ox810sata_scr_read(ox810sata_driver.ap[0], SCR_STATUS, &Temp );
-+        ox810sata_scr_read(ox810sata_driver.ap[1], SCR_STATUS, &Reg);
-+        Reg |= Temp;
-+    } else {
-+        ox810sata_scr_read(ap, SCR_STATUS, &Reg );
-+    }
-+    if (!(Reg & 0x1)) { 
-+        status |= ATA_DF;
-+        status |= ATA_ERR;
-+    }
-+    //VPRINTK("%02x\n",result);
-+
-+    return status;
-+}
-+
-+/** 
-+ * Reads the alt status ATA shadow register from hardware. 
-+ * @param ap hardware with the registers in
-+ * @return The alt status register
-+ */
-+static u8 ox810sata_check_altstatus(struct ata_port *ap)
-+{
-+    return readl(ox810sata_get_tfio_base(ap) + OX810SATA_ORB4) >> 24;
-+}
-+
-+/** 
-+ * Use the method defined in the ATA specification to make either device 0,
-+ * or device 1, active on the ATA channel. If we ever get port multipliers
-+ * to work, this will be where they would switch.
-+ *
-+ * @param ap hardware with the registers in
-+ * @param number of the device to talk to (0..)
-+ */
-+static void ox810sata_dev_select(struct ata_port *ap, unsigned int device)
-+{
-+}
-+
-+/** 
-+ * The very first step in the probe phase. Actions vary depending on the bus
-+ * type, typically. After waking up the device and probing for device presence
-+ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
-+ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
-+ * this hook.
-+ *
-+ * This should reset the SATA core and Phisical layer then jump back into the 
-+ * libata libraries for lots of other resetting
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_phy_reset(struct ata_port *ap)
-+{
-+    u32 *ioaddr = ox810sata_get_io_base(ap);
-+
-+    DPRINTK(KERN_INFO "base = %p\n", ioaddr);
-+
-+    /* turn ata core on */
-+    writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+    /* stop all the interrupts in the ata core */
-+    writel(~0, ioaddr + OX810SATA_INT_DISABLE);
-+    writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+
-+    /* get libata to perform a soft reset */
-+	ata_port_probe(ap);
-+    ata_bus_reset(ap);
-+}
-+
-+/** 
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup) 
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc)
-+{
-+    ox810sata_private_data* PrivateData ;
-+    oxnas_dma_direction_t direction; 
-+
-+#ifdef SATA_DEBUG
-+    printk(KERN_INFO"ox810sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#else // SATA_DEBUG
-+    DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#endif // SATA_DEBUG
-+
-+    qc->private_data = qc->ap->private_data;
-+    PrivateData = (ox810sata_private_data* )qc->private_data;
-+
-+	// We check for DMA completion from ISR which cannot wait for all DMA channel
-+	// housekeeping to complete, so need to wait here is case we try to reuse
-+	// channel before that housekeeping has completed
-+	while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+		printk("DMA Setup Channel still active\n");
-+	}
-+
-+    /* Do not use DMA callback */
-+	oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+    
-+    /* decide on DMA direction */
-+    direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
-+                                                   OXNAS_DMA_TO_DEVICE;
-+
-+    /* now set-up the DMA transfer */
-+    if (qc->n_elem > 1)
-+    {
-+#ifdef SATA_DEBUG
-+    u32 total=0;
-+    int i=0;
-+    struct scatterlist* sg = qc->__sg;
-+    printk("Lengths: ");
-+    do {
-+        u32 len = sg_dma_len(sg++);
-+        printk("%u ", len); 
-+        total += len;
-+    } while (++i < qc->n_elem);
-+    printk("\nTotal len = %u\n", total);
-+#endif //  SATA_DEBUG
-+        /* try and setup scatter gather controller */
-+        if (oxnas_dma_device_set_prd(
-+                PrivateData->DmaChannel,
-+                direction,
-+                qc->ap->prd,
-+                &oxnas_sata_dma_settings,
-+                OXNAS_DMA_MODE_INC,
-+				 PrivateData->sg_entries)) {
-+            printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+            return;
-+        }
-+    }
-+    else
-+    {
-+#ifdef SATA_DEBUG
-+    printk("Total len = %u\n", sg_dma_len(qc->__sg));
-+#endif //  SATA_DEBUG
-+        /* setup a single dma */
-+        oxnas_dma_device_set(   PrivateData->DmaChannel,
-+                                direction,
-+                                (unsigned char* )sg_dma_address(qc->__sg),
-+                                sg_dma_len(qc->__sg),
-+                                &oxnas_sata_dma_settings,
-+                                OXNAS_DMA_MODE_INC,
-+                                1); /* paused */
-+    }
-+}
-+
-+/** 
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup) 
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox810sata_bmdma_start(struct ata_queued_cmd *qc)
-+{
-+    ox810sata_private_data* PrivateData ;
-+    DPRINTK("\n");
-+    PrivateData = (ox810sata_private_data*)(qc->private_data);    
-+
-+	/* start DMA transfer */
-+	oxnas_dma_start(PrivateData->DmaChannel);
-+	qc->ap->ops->exec_command(qc->ap, &(qc->tf));
-+}
-+
-+
-+/**
-+ *  ata_qc_new - Request an available ATA command, for queueing
-+ *  @ap: Port associated with device @dev
-+ *  @dev: Device from whom we request an available command structure
-+ *
-+ *  LOCKING:
-+ */
-+
-+static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap)
-+{
-+    struct ata_queued_cmd *qc = NULL;
-+
-+    VPRINTK("\n");
-+	/* no command while frozen */
-+	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
-+		return NULL;
-+    
-+    /* check to see that there are no internal commands active on either port*/
-+    if ((ox810sata_driver.ap[0]) && (ox810sata_driver.ap[0]->qc_allocated))
-+        return qc;
-+    if ((ox810sata_driver.ap[1]) && (ox810sata_driver.ap[1]->qc_allocated))
-+        return qc;
-+
-+    /* check if we're not doing a command */
-+    if (test_and_set_bit(0, &ox810sata_command_active))
-+        return qc;
-+
-+    /* now set the standard bits for compatibility */
-+    set_bit(0, &ap->qc_allocated); 
-+    qc = __ata_qc_from_tag(ap, 0);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+    /* disk light on */
-+    writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
-+#endif  // CONFIG_SATA_OXNAS_DISK_LIGHT
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+    wdc_ledtrig_sata_activity();
-+#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+
-+	if (qc) {
-+        qc->tag = 0;
-+	}
-+
-+    return qc;
-+}
-+
-+
-+/**
-+ *
-+ */
-+static void ox810sata_qc_free(struct ata_queued_cmd *qc)
-+{
-+    unsigned int tag;
-+    struct ata_port *ap = qc->ap;
-+
-+    DPRINTK("\n");
-+
-+    qc->flags = 0;
-+    tag = qc->tag;
-+    if (likely(ata_tag_valid(tag))) {
-+        qc->tag = ATA_TAG_POISON;
-+        VPRINTK("clearing active bits\n");
-+        clear_bit(tag, &ap->qc_allocated);
-+        clear_bit(0, &ox810sata_command_active);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT            
-+        /* disk light off */
-+        writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif  /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+    }
-+}
-+
-+/** 
-+ * qc_issue is used to make a command active, once the hardware and S/G tables
-+ * have been prepared. IDE BMDMA drivers use the helper function
-+ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
-+ * roll their own ->qc_issue implementation, using this as the "issue new ATA
-+ * command to hardware" hook.
-+ * @param qc the queued command to issue
-+ */
-+static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc)
-+{
-+    int this_port_fail;
-+    struct bio* bio;
-+    u32 reg;
-+    ox810sata_private_data* private_data = (ox810sata_private_data*)qc->ap->private_data ;
-+    u32 raid_reg = 0; /* default to no raid */
-+    int port0fail = 0;
-+    int port1fail = 0;
-+    unsigned long flags = 0;
-+
-+    DPRINTK("\n");
-+
-+    /* get raid settings from the bio if they exist */    
-+    if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
-+        bio = qc->scsicmd->request->bio;
-+        raid_reg = bio->bi_raid ;
-+        //if (raid_reg) {printk("Hardware RAID :");tfdump(&qc->tf);}
-+        
-+    }
-+    ox810sata_driver.hw_raid_active = raid_reg;
-+    ox810sata_driver.active_port = qc->ap;
-+
-+    /* check cable is still connected */
-+	ox810sata_scr_read(qc->ap, SCR_STATUS, &reg);
-+    this_port_fail = (!(reg & 1));
-+
-+    /* check for failed ports prior to issuing raid-ed commands */ 
-+    if (raid_reg) {
-+        port0fail = (! (__ox810sata_scr_read((u32* )SATA0_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) ); 
-+        port1fail = (! (__ox810sata_scr_read((u32* )SATA1_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+        this_port_fail |= port1fail;
-+        
-+        ox810sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
-+        ox810sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
-+    }
-+    
-+    if (!this_port_fail) {
-+        /* clear phy/link errors */
-+        if (ox810sata_driver.ap[0])
-+            ox810sata_scr_write(ox810sata_driver.ap[0], SCR_ERROR, ~0);
-+        if (ox810sata_driver.ap[1])
-+            ox810sata_scr_write(ox810sata_driver.ap[1], SCR_ERROR, ~0);
-+        
-+        /* clear errors on both hosts */
-+        reg = readl((u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        reg |= OX810SATA_SCTL_CLR_ERR ;
-+        writel(reg, (u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        reg = readl((u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        reg |= OX810SATA_SCTL_CLR_ERR ;
-+        writel(reg, (u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        reg |= OX810SATA_SCTL_CLR_ERR ;
-+        writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+        
-+        /* clear all interrupt bits */
-+        writel(~0, (u32* )SATA0_REGS_BASE + OX810SATA_INT_CLEAR);
-+        writel(~0, (u32* )SATA1_REGS_BASE + OX810SATA_INT_CLEAR);
-+        writel(~0, (u32* )SATARAID_REGS_BASE + OX810SATA_INT_CLEAR);
-+        writel(~0, OX810SATA_CORE_IEC );  
-+            
-+        /* hardware RAID */
-+        if ( raid_reg ) {
-+            /* set interrupt mode for raid controller interrupts only */
-+            writel(OX810SATA_RAID_INTS_WANTED, OX810SATA_CORE_IES );  
-+
-+            /* at the moment we only do raid-1 */
-+            writel(OXNASSATA_RAID1, OX810SATA_RAID_CONTROL);
-+            writel(OXNASSATA_RAID_TWODISKS, OX810SATA_RAID_SET);
-+        } else {
-+            /* set normal interrupt scheme */
-+            writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);  
-+
-+            /* Set the RAID controller hardware to idle */
-+            writel(OXNASSATA_NOTRAID, OX810SATA_RAID_CONTROL);
-+        }
-+
-+        /* call the default, this should be changed to take advantage of orb
-+        registers, etc... */
-+        return ata_qc_issue_prot(qc);
-+    } else {
-+        /* record the error */
-+        qc->err_mask |= AC_ERR_ATA_BUS;
-+
-+        /* maybee call ata qc complete? */
-+        local_irq_save(flags);
-+        ox810sata_irq_clear(qc->ap);
-+        private_data->int_status = 0;
-+        local_irq_restore(flags);
-+        ata_qc_complete(qc);
-+    
-+        return 0;
-+    }
-+}
-+
-+/** 
-+ * This is a high level error handling function, called from the error
-+ * handling thread, when a command times out.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_eng_timeout(struct ata_port *ap)
-+{
-+    struct ata_queued_cmd *qc;
-+    ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;    
-+    DPRINTK("\n");
-+
-+    /* set the in cleanup flag */
-+    pd->in_cleanup = 1;
-+
-+    /* if we're a PIO command existing cleanup won't be called */
-+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
-+	if (qc->tf.protocol == ATA_PROT_PIO) {
-+        /* reset the core */
-+        ox810sata_timeout_cleanup(ap);
-+    }
-+
-+    /* clear the in cleanup flag */
-+    pd->in_cleanup = 0;
-+}
-+
-+/** 
-+ * irq_handler is the interrupt handling routine registered with the system,
-+ * by libata.
-+ */
-+static irqreturn_t ox810sata_irq_handler(
-+	int   irq,
-+	void *dev_instance)
-+{
-+    struct ata_port        *ap = ((struct ata_host *)dev_instance)->ports[0];
-+    ox810sata_private_data *pd;
-+    u32                    *ioaddr;
-+    u32                     int_status;
-+    u32 count ;    
-+
-+    DPRINTK("irq = %d\n", irq);
-+
-+    if (!ap || !ap->private_data)
-+        BUG();
-+
-+    /* check the ISR for the port to see if it created the interrupt */
-+    ioaddr = ox810sata_get_tfio_base(ap);
-+    int_status = readl(ioaddr + OX810SATA_INT_STATUS);
-+    if ( !(int_status & OX810SATA_INT_WANT ) ) {
-+        VPRINTK("not me!\n");
-+        return IRQ_NONE;
-+    }
-+
-+    pd = (ox810sata_private_data*)ap->private_data;
-+    while (int_status & OX810SATA_INT_MASKABLE) {
-+        /* store interrupt status for the bottom end */
-+        pd->int_status |= int_status;
-+
-+        /* Clear and mask pending interrupts */
-+        writel(int_status, ioaddr + OX810SATA_INT_CLEAR);
-+        writel(int_status, ioaddr + OX810SATA_INT_DISABLE);
-+
-+        int_status = readl(ioaddr + OX810SATA_INT_STATUS);
-+    }
-+    
-+	// Wait a short while for the DMA to finish and if it doesn't start a thread
-+	// to poll for the finish
-+    pd->spot_the_end_work.ap = ap;
-+    for (count = 0; count < 10; ++count) {
-+        if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+            ox810sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+            break;
-+        }
-+        udelay(100);
-+    } 
-+    
-+    if (count == 10) {
-+        /* Start a worker thread looking for the DMA channel to become idle */
-+        VPRINTK("queueing work \n");
-+        queue_work(ox810sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
-+    }
-+    VPRINTK("done\n");
-+    return IRQ_HANDLED;
-+}
-+
-+/**
-+ * Work for a work queue, this will check for errors then wait for the DMA to
-+ * complete. On the DMA completing it will call ata_qc_complete
-+ */
-+static void ox810sata_spot_the_end(struct work_struct *work)
-+{
-+    struct spot_the_end_work_s* stew = 
-+        container_of(work, struct spot_the_end_work_s, worker);
-+    struct ata_port* ap = stew->ap;
-+    ox810sata_private_data* PrivateData = (ox810sata_private_data* )ap->private_data;
-+    struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->link.active_tag);
-+    unsigned long flags = 0;
-+
-+    VPRINTK("\n");
-+
-+    /* If there's no command ending associated with this IRQ, ignore it. */
-+    if (qc == NULL) {
-+        DPRINTK(" qc=null\n");
-+        return;
-+    }
-+    
-+	/* The command may have aborted, this is indicated by the interrupt bit
-+	* being masked */   
-+    if (PrivateData->in_cleanup) {
-+        DPRINTK("cleanup\n");
-+        return;
-+    }
-+
-+    /* get the status before any error cleanup */
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+
-+    /* Look to see if the core is indicating an error condition after a RAID 
-+     * command */
-+    if (qc->scsicmd &&
-+        qc->scsicmd->request &&
-+        qc->scsicmd->request->bio &&
-+        qc->scsicmd->request->bio->bi_raid ) {
-+        unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX810SATA_INT_STATUS);
-+        unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX810SATA_INT_STATUS);
-+
-+        if (OX810SATA_RAW_ERROR & Port0Irq) {
-+            printk(KERN_DEBUG"disk 0 error in hw-raid\n");
-+            ox810sata_accumulated_RAID_faults |= 1;
-+        }
-+        if (OX810SATA_RAW_ERROR & Port1Irq) {
-+            printk(KERN_DEBUG"disk 1 error in hw-raid\n");
-+            ox810sata_accumulated_RAID_faults |= 2;
-+        }
-+    }
-+
-+    /* if there was an error and the command hasn't finished, then we need to
-+     * abort the command */
-+	if ((PrivateData->int_status & 0xfffe) &&
-+        !(PrivateData->int_status & 0x1) &&
-+        (qc->tf.protocol == ATA_PROT_DMA)) 
-+    {
-+        DPRINTK(" int status 0x%08x, ata%u \n",PrivateData->int_status,ap->id);
-+        local_irq_save(flags);
-+        ox810sata_irq_clear(ap);
-+        PrivateData->int_status = 0;
-+        local_irq_restore(flags);
-+        ata_qc_complete(qc);
-+        return;
-+    }
-+     
-+	if (!in_irq()) {
-+		/* wait for the DMA to finish */
-+		while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+			schedule();
-+		}
-+	}
-+
-+    if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
-+        printk(KERN_WARNING "OX810 SATA: Command already completed!\n");
-+        return;
-+    }
-+
-+    /** @debug check for any padding */
-+    if(0)
-+    {
-+        unsigned int reg;
-+        reg = readl(OX810SATA_EXCESS);
-+        if (reg) {
-+            printk("command finished with a hint of padding\n");
-+            CrazyDumpDebug();
-+        }
-+    }
-+
-+    /* tell libata we're done */
-+    DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
-+    local_irq_save(flags);
-+    ox810sata_irq_clear(ap);
-+    PrivateData->int_status = 0;
-+    local_irq_restore(flags);
-+    ata_qc_complete(qc);
-+}
-+ 
-+/** 
-+ * ox810sata_irq_clear is called during probe just before the interrupt handler is
-+ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
-+ * in the SATA core.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_irq_clear(struct ata_port* ap)
-+{
-+    u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+    //DPRINTK(KERN_INFO"ox810sata_irq_clear\n");
-+
-+    writel(~0, ioaddr + OX810SATA_INT_DISABLE);
-+    writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+}
-+
-+static inline u32 __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg) 
-+{
-+    u32 result;
-+    u32 patience;
-+
-+    /* we've got 8 other registers in before the start of the standard ones */    
-+    writel(sc_reg, core_addr + OX810SATA_LINK_RD_ADDR );
-+
-+    for (patience = 0x100000; patience > 0; --patience) {
-+        if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+            break;
-+		}
-+    }
-+
-+    result = readl(core_addr + OX810SATA_LINK_DATA);
-+
-+    //DPRINTK(KERN_INFO"ox810sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
-+    return result;
-+}
-+
-+/** 
-+ *  Read standard SATA phy registers. Currently only used if 
-+ * ->phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @return the value in the register
-+ */
-+static int ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
-+{
-+    u32* ioaddr = ox810sata_get_io_base(ap);
-+	*val = __ox810sata_scr_read(ioaddr, 0x20 + (sc_reg*4));
-+    return 0;
-+}
-+
-+static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
-+{
-+    u32 patience;
-+
-+    //DPRINTK(KERN_INFO"ox810sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
-+    writel(val, core_addr + OX810SATA_LINK_DATA );
-+    wmb();
-+    writel(sc_reg , core_addr + OX810SATA_LINK_WR_ADDR );
-+    wmb();
-+
-+    for (patience = 0x100000; patience > 0;--patience) {
-+        if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+            break;
-+		}
-+    }
-+}
-+/** 
-+ *  Write standard SATA phy registers. Currently only used if 
-+ * phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @param val the value to write into the register
-+ */
-+static int ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
-+{
-+    u32 *ioaddr = ox810sata_get_io_base(ap);
-+    __ox810sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
-+	return 0;
-+}
-+
-+/** 
-+ * port_start() is called just after the data structures for each port are
-+ * initialized. Typically this is used to alloc per-port DMA buffers, tables
-+ * rings, enable DMA engines and similar tasks.
-+ *
-+ * @return 0 = success
-+ * @param ap hardware with the registers in
-+ */
-+static int  ox810sata_port_start(struct ata_port *ap)
-+{
-+    ox810sata_private_data* pd;
-+    struct device* pdev = ap->host->dev;
-+
-+    ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
-+    if (!ap->prd) {
-+        return -ENOMEM;
-+    }
-+
-+    /* allocate port private data memory and attach to port */    
-+    if (!ap->private_data) {
-+        ap->private_data = kmalloc(sizeof(ox810sata_private_data), GFP_KERNEL);
-+    }
-+
-+    if (!ap->private_data) {
-+        return -ENOMEM;
-+    }
-+
-+	pd = (ox810sata_private_data* )ap->private_data;
-+	pd->DmaChannel = 0;
-+	pd->sg_entries = 0;
-+
-+    DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
-+
-+	// Allocate DMA SG entries
-+	if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES, 0)) {
-+		printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA SG entries\n");
-+		return -ENOMEM;
-+	}
-+
-+	// Hold on to a DMA channel for the life of the SATA driver
-+    pd->DmaChannel = oxnas_dma_request(1);
-+    
-+	if (!pd->DmaChannel) {
-+		printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA channel\n");
-+        return -ENOMEM;
-+	}
-+
-+    /* declare a work item to spot when a command finishes */
-+    INIT_WORK(&(pd->spot_the_end_work.worker), &ox810sata_spot_the_end);
-+
-+    /* initialise to zero */
-+    pd->ErrorsWithNoCommamnd = 0;
-+    pd->int_status = 0;
-+    pd->in_cleanup = 0;
-+
-+    /* store the ata_port pointer in the driver structure */
-+    if (ox810sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
-+        ox810sata_driver.ap[0] = ap;
-+    } else if (ox810sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
-+        ox810sata_driver.ap[1] = ap;
-+	}
-+
-+    // turn ata core on
-+    writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+    /* post reset init needs to be called for both ports as there's one reset
-+    for both ports*/
-+    if (ox810sata_driver.ap[0]) {
-+        ox810sata_post_reset_init(ox810sata_driver.ap[0]);
-+	}
-+    if (ox810sata_driver.ap[1]) {
-+        ox810sata_post_reset_init(ox810sata_driver.ap[1]);
-+	}
-+
-+    return 0;
-+}
-+
-+static void ox810sata_post_reset_init(struct ata_port* ap) 
-+{
-+    u32  patience;
-+    u32* ioaddr = ox810sata_get_io_base(ap);
-+    uint dev;
-+
-+    /* turn on phy error detection by removing the masks */ 
-+    writel(0x30003, ioaddr + OX810SATA_LINK_DATA );
-+    wmb();
-+    writel(0x0C, ioaddr + OX810SATA_LINK_WR_ADDR );
-+    wmb();
-+    for (patience = 0x100000; patience > 0;--patience) {
-+        if (readl(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+            break;
-+		}
-+    }
-+
-+    /* enable interrupts for ports  */
-+    VPRINTK("Enable interrupts\n");
-+    writel(~0, OX810SATA_CORE_IEC);  
-+    writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);  
-+
-+    /* go through all the devices and configure them */
-+    for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+        if (ap->link.device[dev].class == ATA_DEV_ATA) {
-+			ox810sata_phy_reset(ap);
-+            ox810sata_dev_config(ap, &(ap->link.device[dev]));
-+		}
-+    }
-+
-+    /* disable padding */
-+/*    {
-+        unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+        reg &= ~OX810SATA_DEVICE_CONTROL_PAD  ;
-+        writel(reg, OX810SATA_DEVICE_CONTROL);
-+    }*/
-+    {
-+        unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+        reg |= OX810SATA_DEVICE_CONTROL_PADPAT  ;
-+        writel(reg, OX810SATA_DEVICE_CONTROL);
-+    }
-+}
-+
-+/** 
-+ * port_stop() is called after ->host_stop(). It's sole function is to 
-+ * release DMA/memory resources, now that they are no longer actively being
-+ * used.
-+ */
-+static void ox810sata_port_stop(struct ata_port *ap)
-+{
-+    ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
-+
-+    DPRINTK("\n");
-+
-+	if (pd->DmaChannel) {
-+		oxnas_dma_free(pd->DmaChannel);
-+		pd->DmaChannel = 0;
-+	}
-+
-+	if (pd->sg_entries) {
-+		oxnas_dma_free_sg_entries(pd->sg_entries);
-+		pd->sg_entries = 0;
-+	}
-+
-+    kfree(pd);
-+}
-+
-+/** 
-+ * host_stop() is called when the rmmod or hot unplug process begins. The
-+ * hook must stop all hardware interrupts, DMA engines, etc.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_host_stop(struct ata_host *host_set)
-+{
-+    DPRINTK("\n");
-+}
-+
-+/** 
-+ * PATA device presence detection
-+ * @param ap ATA channel to examine
-+ * @param device Device to examine (starting at zero)
-+ * @return true if something found 
-+ *
-+ * This technique was originally described in
-+ * Hale Landis's ATADRVR (www.ata-atapi.com), and
-+ * later found its way into the ATA/ATAPI spec.
-+ * 
-+ * Write a pattern to the ATA shadow registers,
-+ * and if a device is present, it will respond by
-+ * correctly storing and echoing back the
-+ * ATA shadow register contents.
-+ * 
-+ * LOCKING:
-+ * caller.
-+ */
-+static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device)
-+{
-+    DPRINTK("\n");
-+
-+    return 0;       /* nothing found */
-+}
-+
-+static void ox810sata_pio_start(struct work_struct *work)
-+{
-+	struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+	ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;
-+    struct ata_queued_cmd* qc = ap->port_task_data;
-+    u32* ioaddr = ox810sata_get_io_base(ap);
-+    unsigned long flags = 0;
-+
-+    VPRINTK("\n");
-+    // We check for DMA completion from ISR which cannot wait for all DMA channel
-+	// housekeeping to complete, so need to wait here is case we try to reuse
-+	// channel before that housekeeping has completed
-+	if (oxnas_dma_is_active(pd->DmaChannel)) {
-+		printk(KERN_WARNING "PIO start Channel still active\n");
-+        /* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+        ata_port_queue_task(ap, ox810sata_pio_start, qc, ATA_SHORT_PAUSE);
-+        return;
-+	}
-+
-+	if (qc->tf.protocol != ATA_PROT_NODATA) {
-+		oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
-+										   OXNAS_DMA_FROM_DEVICE :
-+										   OXNAS_DMA_TO_DEVICE;
-+
-+		/* Do not use DMA callback */
-+		oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+		/* map memory for dma */
-+		dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+
-+		/* setup a scatter gather dma */
-+		oxnas_dma_device_set_sg(pd->DmaChannel,
-+								 direction,
-+								 qc->__sg,
-+								 qc->n_elem,
-+								 &oxnas_sata_dma_settings,
-+								 OXNAS_DMA_MODE_INC,
-+								 0);
-+
-+		oxnas_dma_start(pd->DmaChannel);
-+
-+		if (oxnas_dma_is_active(pd->DmaChannel)) {
-+			/* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+			ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+			return;
-+		}
-+
-+		/* cleanup DMA */
-+		dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+	} else {
-+        /* if the core is still busy, reschedule */
-+        if (readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+            ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+            return;
-+        }
-+	}
-+
-+    /* notify of completion */
-+    PretendDRQIsClear = 1;
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+    spin_lock_irqsave(ap->lock, flags);
-+    ap->ops->irq_on(ap);
-+    ata_qc_complete(qc);
-+    spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+/**
-+ * This is the top level of the PIO task. It is responsible for organising the
-+ * transfer of data, collecting and reacting to status changes and notification
-+ * of command completion.
-+ *
-+ */
-+static void ox810sata_pio_task(struct work_struct *work)
-+{
-+	struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+	struct ata_queued_cmd *qc = ap->port_task_data;
-+    u32* ioaddr = ox810sata_get_io_base(ap);
-+    unsigned long flags = 0;
-+    VPRINTK("\n");
-+
-+	if (qc->tf.protocol != ATA_PROT_NODATA) {
-+		ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
-+
-+        /* if the DMA is still busy and there is no error, re-schedule the task */
-+        /* try again in 1 ms */
-+		if ((oxnas_dma_is_active(pd->DmaChannel)) && 
-+            !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
-+			ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+			return;
-+		}
-+
-+		/* cleanup DMA */
-+		dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+	} else {
-+        /* if the core is still busy, reschedule */
-+        if ((readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) &&
-+            !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
-+            ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+            return;
-+        }
-+    }
-+    
-+    /* notify of completion */
-+    PretendDRQIsClear = 1;
-+    qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+    spin_lock_irqsave(ap->lock, flags);
-+    ap->ops->irq_on(ap);
-+    ata_qc_complete(qc);
-+    spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc)
-+{
-+    struct ata_port *ap = qc->ap;
-+    ox810sata_private_data* private_data = (ox810sata_private_data*)ap->private_data;
-+
-+    /* Check if DMA is in progress, if so abort */
-+	if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+		/* 
-+		 * Attempt to abort any current transfer:
-+		 *   Abort DMA transfer at the DMA controller,
-+		 */
-+		printk(KERN_ERR "ox810sata_bmdma_stop - aborting DMA\n");
-+
-+		oxnas_dma_abort(private_data->DmaChannel, 1);
-+    }
-+    
-+    /* perform core cleanups and resets as required */
-+    ox810sata_timeout_cleanup(ap);
-+}
-+
-+/**
-+ * @param ap ata port, not used
-+ */
-+static void ox810sata_timeout_cleanup(struct ata_port *ap) {
-+    u32 reg;
-+    u32 patience;
-+
-+//    CrazyDumpDebug();
-+
-+    /* Clear error bits in both ports */
-+    reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+    reg |= OX810SATA_SCTL_CLR_ERR ;
-+    writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+    reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+    reg |= OX810SATA_SCTL_CLR_ERR ;
-+    writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+    reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+    reg |= OX810SATA_SCTL_CLR_ERR ;
-+    writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+
-+    /* Test SATA core idle state */
-+    if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+        return;
-+	}
-+
-+//    CrazyDumpDebug();
-+
-+    /* abort DMA */
-+    printk(KERN_INFO"ox810sata aborting DMA.\n");
-+    reg = readl(OX810SATA_DEVICE_CONTROL);
-+    writel(reg | OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+
-+    /* wait until patience runs out for the core to go idle */
-+    patience = 50;
-+    do {
-+        /* if the core is idle, clear the abort bit and return */
-+        if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+            writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+            return;
-+        }
-+        mdelay(1);
-+    } while (--patience);
-+    writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+
-+//    CrazyDumpDebug();
-+
-+    /* command a sync escape on both ports */
-+    printk(KERN_INFO"ox810sata sending sync escapes\n");
-+
-+    /* port 0 */
-+    reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
-+    reg &= ~SATA_OPCODE_MASK;
-+    reg |= CMD_SYNC_ESCAPE;
-+    writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
-+
-+    /* wait until patience runs out for the core to go idle */
-+    patience = 50;
-+    do {
-+        /* if the core is idle, clear the abort bit and return */
-+        if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+            return;
-+        }
-+        mdelay(1);
-+    } while (--patience);
-+
-+    /* port 1 */
-+    reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
-+    reg &= ~SATA_OPCODE_MASK;
-+    reg |= CMD_SYNC_ESCAPE;
-+    writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
-+
-+    /* wait until patience runs out for the core to go idle */
-+    patience = 50;
-+    do {
-+        /* if the core is idle, clear the abort bit and return */
-+        if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+            return;
-+        }
-+        mdelay(1);
-+    } while (--patience);
-+
-+//    CrazyDumpDebug();
-+
-+    /* SATA core did not go idle, so cause a SATA core reset from the RPS */
-+        CrazyDumpDebug();
-+    printk(KERN_INFO "ox810sata core reset\n");
-+    ox810sata_reset_core();
-+
-+    /* Read SATA core idle state */
-+    if (~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) {
-+        printk(KERN_INFO"ox810sata core still busy\n");
-+        CrazyDumpDebug();
-+    }
-+
-+    /* Perform any SATA core re-initialisation after reset */
-+    /* post reset init needs to be called for both ports as there's one reset
-+    for both ports*/
-+    if (ox810sata_driver.ap[0]) {
-+        ox810sata_post_reset_init(ox810sata_driver.ap[0]);
-+	}
-+    if (ox810sata_driver.ap[1]) {
-+        ox810sata_post_reset_init(ox810sata_driver.ap[1]);
-+	}
-+}
-+
-+
-+static void ox810sata_error_handler(struct ata_port *ap)
-+{
-+	return ata_bmdma_drive_eh(ap, ox810sata_prereset, ata_std_softreset,
-+				  ox810sata_hardreset, ox810sata_postreset);
-+}
-+
-+
-+
-+/** 
-+ * bmdma_status return a made up version of a BMDMA status register
-+ *
-+ * @param ap Hardware with the registers in
-+ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
-+ */
-+static u8   ox810sata_bmdma_status(struct ata_port *ap)
-+{
-+	return ATA_DMA_INTR;
-+}
-+ 
-+/** 
-+ * turn on the interrupts from the ata drive
-+ * wait for idle, clear any pending interrupts.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox810sata_irq_on(struct ata_port *ap)
-+{
-+    u32* ioaddr = ox810sata_get_tfio_base(ap);
-+    u8 tmp;
-+
-+    //DPRINTK(KERN_INFO"ox810sata_irq_on\n");
-+
-+    /* enable End of command interrupt */
-+    writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+    writel(OX810SATA_INT_WANT, ioaddr + OX810SATA_INT_ENABLE);
-+	tmp = ata_wait_idle(ap);
-+
-+    return tmp;
-+}
-+
-+/**
-+ *	ox810_prereset - prepare for reset
-+ *	@param link  ATA link to be reset
-+ *	@param deadline  deadline jiffies for the operation
-+ *
-+ *	link is about to be reset.  Initialize it.  Failure from
-+ *	prereset makes libata abort whole reset sequence and give up
-+ *	that port, so prereset should be best-effort.  It does its
-+ *	best to prepare for reset sequence but if things go wrong, it
-+ *	should just whine, not fail.
-+ *
-+ *	LOCKING:
-+ *	Kernel thread context (may sleep)
-+ *
-+ *	RETURNS:
-+ *	0 on success, -errno otherwise.
-+ */
-+static int ox810sata_prereset(struct ata_link *link, unsigned long deadline) {
-+	struct ata_port *ap = link->ap;
-+	struct ata_eh_context *ehc = &link->eh_context;
-+	const unsigned long *timing = sata_ehc_deb_timing(ehc);
-+	ox810sata_private_data* private_data;
-+    int rc;
-+
-+    VPRINTK("\n");
-+	/* handle link resume */
-+	if ((ehc->i.flags & ATA_EHI_RESUME_LINK) && (link->flags & ATA_LFLAG_HRST_TO_RESUME))
-+		ehc->i.action |= ATA_EH_HARDRESET;
-+
-+	/* Some PMPs don't work with only SRST, force hardreset if PMP
-+	 * is supported.
-+	 */
-+	if (ap->flags & ATA_FLAG_PMP)
-+		ehc->i.action |= ATA_EH_HARDRESET;
-+
-+	/* if we're about to do hardreset, nothing more to do */
-+	if (ehc->i.action & ATA_EH_HARDRESET)
-+		return 0;
-+
-+    /* we want both ports to be idle as soft-reset requires being able to send
-+    commands. If a command is running, abort it. */
-+    private_data = (ox810sata_private_data*)ap->private_data;
-+
-+    /* Check if DMA is in progress, if so abort */
-+    if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+        /* 
-+         * Attempt to abort any current transfer:
-+         *   Abort DMA transfer at the DMA controller,
-+         */
-+        printk(KERN_ERR "aborting DMA\n");
-+        oxnas_dma_abort(private_data->DmaChannel, 1);
-+    }
-+    
-+    /* perform core cleanups and resets */
-+    ox810sata_timeout_cleanup(NULL);
-+   
-+	/* if SATA, resume link */
-+	if (ap->flags & ATA_FLAG_SATA) {
-+		rc = sata_link_resume(link, timing, deadline);
-+		/* whine about phy resume failure but proceed */
-+		if (rc && rc != -EOPNOTSUPP)
-+			ata_link_printk(link, KERN_WARNING, "failed to resume "
-+					"link for reset (errno=%d)\n", rc);
-+	}
-+    
-+	/* Wait for !BSY if the controller can wait for the first D2H
-+	 * Reg FIS and we don't know that no device is attached.
-+	 */
-+	if (!(link->flags & ATA_LFLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) {
-+		rc = ata_wait_ready(ap, deadline);
-+		if (rc && rc != -ENODEV) {
-+			ata_link_printk(link, KERN_WARNING, "device not ready "
-+					"(errno=%d), forcing hardreset\n", rc);
-+			ehc->i.action |= ATA_EH_HARDRESET;
-+		}
-+	}
-+
-+	return 0;
-+}
-+/**
-+ *	sata_std_hardreset - reset host port via SATA phy reset
-+ *	@link: link to reset
-+ *	@class: resulting class of attached device
-+ *	@deadline: deadline jiffies for the operation
-+ *
-+ *	SATA phy-reset host port using DET bits of SControl register,
-+ *	wait for !BSY and classify the attached device.
-+ *
-+ *	LOCKING:
-+ *	Kernel thread context (may sleep)
-+ *
-+ *	RETURNS:
-+ *	0 on success, -errno otherwise.
-+ */
-+static int ox810sata_hardreset(struct ata_link *link, unsigned int *class,
-+		       unsigned long deadline)
-+{
-+	struct ata_port *ap = link->ap;
-+	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-+	int rc;
-+
-+	DPRINTK("ENTER\n");
-+    
-+	/* do hardreset */
-+	rc = sata_link_hardreset(link, timing, deadline);
-+	if (rc) {
-+		ata_link_printk(link, KERN_ERR,
-+				"COMRESET failed (errno=%d)\n", rc);
-+		return rc;
-+	}
-+
-+	/* TODO: phy layer with polling, timeouts, etc. */
-+	if (ata_link_offline(link)) {
-+		*class = ATA_DEV_NONE;
-+		DPRINTK("EXIT, link offline\n");
-+		return 0;
-+	}
-+
-+	/* wait a while before checking status */
-+	ata_wait_after_reset(ap, deadline);
-+
-+	/* If PMP is supported, we have to do follow-up SRST.  Note
-+	 * that some PMPs don't send D2H Reg FIS after hardreset at
-+	 * all if the first port is empty.  Wait for it just for a
-+	 * second and request follow-up SRST.
-+	 */
-+	if (ap->flags & ATA_FLAG_PMP) {
-+		ata_wait_ready(ap, jiffies + HZ);
-+		return -EAGAIN;
-+	}
-+
-+	rc = ata_wait_ready(ap, deadline);
-+	/* link occupied, -ENODEV too is an error */
-+	if (rc) {
-+		ata_link_printk(link, KERN_ERR,
-+				"COMRESET failed (errno=%d)\n", rc);
-+		return rc;
-+	}
-+
-+	*class = ata_dev_try_classify(link->device, 1, NULL);
-+
-+	DPRINTK("EXIT, class=%u\n", *class);
-+	return 0;
-+}
-+
-+/**
-+ *	ata_std_postreset - standard postreset callback
-+ *	@link: the target ata_link
-+ *	@classes: classes of attached devices
-+ *
-+ *	This function is invoked after a successful reset.  Note that
-+ *	the device might have been reset more than once using
-+ *	different reset methods before postreset is invoked.
-+ *
-+ *	LOCKING:
-+ *	Kernel thread context (may sleep)
-+ */
-+static void ox810sata_postreset(struct ata_link *link, unsigned int *classes)
-+{
-+	struct ata_port *ap = link->ap;
-+	u32 serror;
-+    unsigned int dev;
-+
-+	DPRINTK("ENTER\n");
-+
-+    /* print link status */
-+	sata_print_link_status(link);
-+
-+	/* clear SError */
-+	if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
-+		sata_scr_write(link, SCR_ERROR, serror);
-+	link->eh_info.serror = 0;
-+    
-+    /* turn on phy error detection by removing the masks */ 
-+    __ox810sata_scr_write((u32* )SATA0_REGS_BASE , 0x0c, 0x30003 );
-+    __ox810sata_scr_write((u32* )SATA1_REGS_BASE , 0x0c, 0x30003 );
-+
-+	/* bail out if no device is present */
-+	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
-+		DPRINTK("EXIT, no device\n");
-+		return;
-+	}
-+
-+    /* go through all the devices and configure them */
-+    for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+        if (ap->link.device[dev].class == ATA_DEV_ATA) {
-+            ox810sata_dev_config(ap, &(ap->link.device[dev]));
-+		}
-+    }
-+
-+    /* disable padding */
-+    {
-+        unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+        reg &= ~OX810SATA_DEVICE_CONTROL_PAD  ;
-+        writel(reg, OX810SATA_DEVICE_CONTROL);
-+    }
-+
-+    /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+    #if 0
-+	/* set up device control */
-+	if (ap->ioaddr.ctl_addr)
-+		iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-+    #endif
-+
-+	DPRINTK("EXIT\n");
-+}
-+
-+/** 
-+ * Outputs all the registers in the SATA core for diagnosis of faults.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static void CrazyDumpDebug()
-+{
-+#ifdef CRAZY_DUMP_DEBUG
-+    u32 offset;
-+    u32 result;
-+    u32 patience;
-+    volatile u32* ioaddr;
-+
-+#if 0
-+    {
-+        u32 i ;
-+        for(i = 0;i < 1024;++i) {
-+            printk("[%08x]%s%08x\n",
-+                regarray[regindex].a,
-+                regarray[regindex].w ? "<=" : "=>",
-+                regarray[regindex].d
-+                );
-+            ++regindex;
-+            regindex &= 1023;
-+        }
-+    }
-+#endif
-+
-+    /* port 0 */
-+    ioaddr = (u32* )SATA0_REGS_BASE;
-+    printk("Port 0 High level registers\n");
-+    for(offset = 0; offset < 48;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+    }
-+
-+    printk("Port 0 link layer registers\n");
-+    for(offset = 0; offset < 16;++offset)
-+    {
-+        *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
-+        wmb();
-+    
-+        for (patience = 0x100000;patience > 0;--patience)
-+        {
-+            if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
-+                break;
-+        }
-+    
-+        result = *(ioaddr + OX810SATA_LINK_DATA);
-+        printk("[%02x] %08x\n", offset*4, result);
-+    }
-+
-+    /* port 1 */
-+    ioaddr = (u32* )SATA1_REGS_BASE;
-+    printk("Port 1 High level registers\n");
-+    for(offset = 0; offset < 48;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+    }
-+
-+    printk("Port 1 link layer registers\n");
-+    for(offset = 0; offset < 16;++offset)
-+    {
-+        *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
-+        wmb();
-+    
-+        for (patience = 0x100000;patience > 0;--patience)
-+        {
-+            if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
-+                break;
-+        }
-+    
-+        result = *(ioaddr + OX810SATA_LINK_DATA);
-+        printk("[%02x] %08x\n", offset*4, result);
-+    }
-+    
-+    /* port 14 */
-+    ioaddr = (u32* )SATARAID_REGS_BASE;
-+    printk("RAID registers\n");
-+    for(offset = 0; offset < 48;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+    }
-+
-+    /* port 15 */
-+    ioaddr = (u32* )SATACORE_REGS_BASE;
-+    printk("CORE registers\n");
-+    for(offset = 0; offset < 48;offset++)
-+    {
-+        printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+    }
-+
-+    oxnas_dma_dump_registers();
-+    
-+#endif
-+}
-+
-+/**************************************************************************
-+* DEVICE CODE
-+**************************************************************************/
-+
-+/**
-+ * Describes the identity of the SATA core and the resources it requires
-+ */ 
-+static struct resource ox810sata_port0_resources[] = {
-+	{
-+        .name       = "sata_port_0_registers",
-+		.start		= SATA0_REGS_BASE,
-+		.end		= SATA0_REGS_BASE + 0xff,
-+		.flags		= IORESOURCE_MEM,
-+	},
-+    {
-+        .name       = "sata_irq",
-+        .start      = SATA_1_INTERRUPT,
-+		.flags		= IORESOURCE_IRQ,
-+    }
-+};
-+
-+static struct resource ox810sata_port1_resources[] = {
-+	{
-+        .name       = "sata_port_1_registers",
-+		.start		= SATA1_REGS_BASE,
-+		.end		= SATA1_REGS_BASE + 0xff,
-+		.flags		= IORESOURCE_MEM,
-+	},
-+    {
-+        .name       = "sata_irq",
-+        .start      = SATA_1_INTERRUPT,
-+		.flags		= IORESOURCE_IRQ,
-+    },
-+};
-+
-+static struct platform_device ox810sata_dev0 = 
-+{
-+    .name = DRIVER_NAME,
-+    .id = 0,
-+    .num_resources = 2,
-+	.resource  = ox810sata_port0_resources,
-+    .dev.coherent_dma_mask = 0xffffffff,
-+}; 
-+
-+static struct platform_device ox810sata_dev1 = 
-+{
-+    .name = DRIVER_NAME,
-+    .id = 1,
-+    .num_resources = 2,
-+	.resource  = ox810sata_port1_resources,
-+    .dev.coherent_dma_mask = 0xffffffff,
-+}; 
-+
-+/** 
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox810sata_device_init( void )
-+{
-+    int ret;
-+
-+    /* reset the core */
-+    ox810sata_reset_core();
-+
-+    {
-+        // register the ata device for the driver to find
-+        ret = platform_device_register( &ox810sata_dev0 );
-+        DPRINTK(" %i\n", ret);
-+    }
-+    
-+#ifndef CONFIG_OX810SATA_SINGLE_SATA
-+    {
-+        // register the ata device for the driver to find
-+        ret = platform_device_register( &ox810sata_dev1 );
-+        DPRINTK(" %i\n", ret);
-+    }
-+#endif /* CONFIG_OX810_SINGLE_SATA */
-+
-+    return ret;
-+}
-+
-+/** 
-+ * module cleanup
-+ */
-+static void __exit ox810sata_device_exit(void)
-+{
-+    platform_device_unregister( &ox810sata_dev0 );
-+    platform_device_unregister( &ox810sata_dev1 );
-+}
-+
-+/**
-+ * Returns accumulated RAID faults and then clears the accumulation
-+ * @return accumulated RAID faults indicated by set bits
-+ */
-+int  oxnassata_RAID_faults( void ) {
-+    int temp = ox810sata_accumulated_RAID_faults;
-+    ox810sata_accumulated_RAID_faults = 0;
-+    return temp;
-+}
-+
-+/**
-+ * Returns ox810 port number the request queue is serviced by.
-+ *
-+ * @param queue The queue under investigation.
-+ * @return The ox810 sata port number servicing the queue or -1 if not found.
-+ */
-+int oxnassata_get_port_no(struct request_queue* q)
-+{
-+    struct ata_port* ap = 0;
-+    struct scsi_device* sdev = 0;
-+    
-+    /* check port 0 */
-+    ap = ox810sata_driver.ap[0];
-+    if (ap)
-+        shost_for_each_device(sdev, ap->scsi_host) {
-+            if (sdev->request_queue == q) {
-+                DPRINTK("Queue %p on port 0\n", q);
-+                return 0;
-+            }
-+        }
-+    
-+    /* check port 1 */
-+    ap = ox810sata_driver.ap[1];
-+    if (ap)
-+        shost_for_each_device(sdev, ap->scsi_host) {
-+            if (sdev->request_queue == q) {
-+                DPRINTK("Queue %p on port 1\n", q);
-+                return 1;
-+            }
-+        }
-+
-+    /* not found */
-+    return -1;  
-+}
-+
-+/**
-+ * @return true if all the drives attached to the internal SATA ports use the
-+ * same LBA size.
-+ */
-+int oxnassata_LBA_schemes_compatible( void )
-+{
-+    unsigned long flags0 ;
-+    unsigned long flags1 ;
-+    struct ata_port* ap ;
-+    
-+    /* check port 0 */
-+    ap = ox810sata_driver.ap[0];
-+    if (ap)
-+        flags0 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
-+    else
-+        return 0;
-+    
-+    /* check port 1 */
-+    ap = ox810sata_driver.ap[1];
-+    if (ap)
-+        flags1 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
-+    else
-+        return 0;
-+
-+    /* compare */
-+    return (flags0 == flags1);  
-+}
-+
-+EXPORT_SYMBOL( oxnassata_RAID_faults );
-+EXPORT_SYMBOL( oxnassata_get_port_no );
-+EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
-+
-+
-+#ifdef ERROR_INJECTION
-+
-+/**
-+ * @param kobj Not Used
-+ * @param attr Used to determine which file is being accessed
-+ * @param buffer Space to put the file contents
-+ * @return The number of bytes transferred or an error
-+ */
-+static int ox810sata_error_inject_show(
-+    char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+    if (page)
-+    {
-+        if ( ox810sata_driver.error_inject ) {
-+            page[0] = ox810sata_driver.error_inject + '0';
-+            page[1] = '\n';
-+            page[2] = 0;
-+            return 3;
-+        } else {
-+            strcpy(page, "off\n" );
-+            return 5;
-+        }
-+    }
-+    
-+    /* if we get here, there's been an error */
-+    return -EIO;
-+}
-+
-+
-+static int ox810sata_error_inject_store(struct file *file,
-+                                        const char __user *buffer,
-+                                        unsigned long count,
-+                                        void *data) {
-+    if (count)
-+    {
-+        if ((buffer[0] >= '0') &&
-+            (buffer[0] <= '9')) {
-+            ox810sata_driver.error_inject = buffer[0] - '0';
-+        }
-+        return count;
-+    }
-+    
-+    /* if we get here, there's been an error */
-+    return -EIO;
-+}
-+
-+#endif /* ERROR_INJECTION */
-+
-+
-+
-+/** 
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox810sata_device_init);
-+module_exit(ox810sata_device_exit);
-diff -Nurd linux-2.6.24/drivers/ata/pata_hpt366.c linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c
---- linux-2.6.24/drivers/ata/pata_hpt366.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c	2008-06-11 17:50:32.000000000 +0200
-@@ -27,7 +27,7 @@
- #include <linux/libata.h>
- 
- #define DRV_NAME	"pata_hpt366"
--#define DRV_VERSION	"0.6.1"
-+#define DRV_VERSION	"0.6.2"
- 
- struct hpt_clock {
- 	u8	xfer_speed;
-@@ -180,9 +180,9 @@
- 		if (hpt_dma_blacklisted(adev, "UDMA",  bad_ata33))
- 			mask &= ~ATA_MASK_UDMA;
- 		if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
--			mask &= ~(0x07 << ATA_SHIFT_UDMA);
-+			mask &= ~(0xF8 << ATA_SHIFT_UDMA);
- 		if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
--			mask &= ~(0x0F << ATA_SHIFT_UDMA);
-+			mask &= ~(0xF0 << ATA_SHIFT_UDMA);
- 	}
- 	return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/ata/pata_hpt37x.c linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c
---- linux-2.6.24/drivers/ata/pata_hpt37x.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c	2008-06-11 17:50:32.000000000 +0200
-@@ -24,7 +24,7 @@
- #include <linux/libata.h>
- 
- #define DRV_NAME	"pata_hpt37x"
--#define DRV_VERSION	"0.6.9"
-+#define DRV_VERSION	"0.6.11"
- 
- struct hpt_clock {
- 	u8	xfer_speed;
-@@ -281,7 +281,7 @@
- 		if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
- 			mask &= ~ATA_MASK_UDMA;
- 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
--			mask &= ~(0x1F << ATA_SHIFT_UDMA);
-+			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- 	}
- 	return ata_pci_default_filter(adev, mask);
- }
-@@ -297,7 +297,7 @@
- {
- 	if (adev->class == ATA_DEV_ATA) {
- 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
--			mask &= ~ (0x1F << ATA_SHIFT_UDMA);
-+			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- 	}
- 	return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/ata/pata_serverworks.c linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c
---- linux-2.6.24/drivers/ata/pata_serverworks.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c	2008-06-11 17:50:32.000000000 +0200
-@@ -226,7 +226,7 @@
- 
- 	for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
- 		if (!strcmp(p, model_num))
--			mask &= ~(0x1F << ATA_SHIFT_UDMA);
-+			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- 	}
- 	return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/base/firmware_class.c linux-2.6.24-oxe810/drivers/base/firmware_class.c
---- linux-2.6.24/drivers/base/firmware_class.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/base/firmware_class.c	2008-06-11 17:50:32.000000000 +0200
-@@ -292,7 +292,8 @@
- 
- static inline void fw_setup_device_id(struct device *f_dev, struct device *dev)
- {
--	snprintf(f_dev->bus_id, BUS_ID_SIZE, "firmware-%s", dev->bus_id);
-+	/* XXX warning we should watch out for name collisions */
-+	strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE);
- }
- 
- static int fw_register_device(struct device **dev_p, const char *fw_name,
-diff -Nurd linux-2.6.24/drivers/base/platform.c linux-2.6.24-oxe810/drivers/base/platform.c
---- linux-2.6.24/drivers/base/platform.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/base/platform.c	2008-06-11 17:50:32.000000000 +0200
-@@ -647,7 +647,7 @@
- 		high_totalram += high_totalram - 1;
- 		mask = (((u64)high_totalram) << 32) + 0xffffffff;
- 	}
--	return mask & *dev->dma_mask;
-+	return mask;
- }
- EXPORT_SYMBOL_GPL(dma_get_required_mask);
- #endif
-diff -Nurd linux-2.6.24/drivers/block/ub.c linux-2.6.24-oxe810/drivers/block/ub.c
---- linux-2.6.24/drivers/block/ub.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/block/ub.c	2008-06-11 17:49:32.000000000 +0200
-@@ -657,7 +657,6 @@
- 	if ((cmd = ub_get_cmd(lun)) == NULL)
- 		return -1;
- 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
--	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
- 
- 	blkdev_dequeue_request(rq);
- 
-@@ -668,6 +667,7 @@
- 	/*
- 	 * get scatterlist from block layer
- 	 */
-+	sg_init_table(&urq->sgv[0], UB_MAX_REQ_SG);
- 	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
- 	if (n_elem < 0) {
- 		/* Impossible, because blk_rq_map_sg should not hit ENOMEM. */
-diff -Nurd linux-2.6.24/drivers/char/defkeymap.c_shipped linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped
---- linux-2.6.24/drivers/char/defkeymap.c_shipped	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped	2008-06-11 17:49:52.000000000 +0200
-@@ -223,40 +223,40 @@
- };
- 
- struct kbdiacruc accent_table[MAX_DIACR] = {
--	{'`', 'A', '\300'},	{'`', 'a', '\340'},
--	{'\'', 'A', '\301'},	{'\'', 'a', '\341'},
--	{'^', 'A', '\302'},	{'^', 'a', '\342'},
--	{'~', 'A', '\303'},	{'~', 'a', '\343'},
--	{'"', 'A', '\304'},	{'"', 'a', '\344'},
--	{'O', 'A', '\305'},	{'o', 'a', '\345'},
--	{'0', 'A', '\305'},	{'0', 'a', '\345'},
--	{'A', 'A', '\305'},	{'a', 'a', '\345'},
--	{'A', 'E', '\306'},	{'a', 'e', '\346'},
--	{',', 'C', '\307'},	{',', 'c', '\347'},
--	{'`', 'E', '\310'},	{'`', 'e', '\350'},
--	{'\'', 'E', '\311'},	{'\'', 'e', '\351'},
--	{'^', 'E', '\312'},	{'^', 'e', '\352'},
--	{'"', 'E', '\313'},	{'"', 'e', '\353'},
--	{'`', 'I', '\314'},	{'`', 'i', '\354'},
--	{'\'', 'I', '\315'},	{'\'', 'i', '\355'},
--	{'^', 'I', '\316'},	{'^', 'i', '\356'},
--	{'"', 'I', '\317'},	{'"', 'i', '\357'},
--	{'-', 'D', '\320'},	{'-', 'd', '\360'},
--	{'~', 'N', '\321'},	{'~', 'n', '\361'},
--	{'`', 'O', '\322'},	{'`', 'o', '\362'},
--	{'\'', 'O', '\323'},	{'\'', 'o', '\363'},
--	{'^', 'O', '\324'},	{'^', 'o', '\364'},
--	{'~', 'O', '\325'},	{'~', 'o', '\365'},
--	{'"', 'O', '\326'},	{'"', 'o', '\366'},
--	{'/', 'O', '\330'},	{'/', 'o', '\370'},
--	{'`', 'U', '\331'},	{'`', 'u', '\371'},
--	{'\'', 'U', '\332'},	{'\'', 'u', '\372'},
--	{'^', 'U', '\333'},	{'^', 'u', '\373'},
--	{'"', 'U', '\334'},	{'"', 'u', '\374'},
--	{'\'', 'Y', '\335'},	{'\'', 'y', '\375'},
--	{'T', 'H', '\336'},	{'t', 'h', '\376'},
--	{'s', 's', '\337'},	{'"', 'y', '\377'},
--	{'s', 'z', '\337'},	{'i', 'j', '\377'},
-+	{'`', 'A', 0300},	{'`', 'a', 0340},
-+	{'\'', 'A', 0301},	{'\'', 'a', 0341},
-+	{'^', 'A', 0302},	{'^', 'a', 0342},
-+	{'~', 'A', 0303},	{'~', 'a', 0343},
-+	{'"', 'A', 0304},	{'"', 'a', 0344},
-+	{'O', 'A', 0305},	{'o', 'a', 0345},
-+	{'0', 'A', 0305},	{'0', 'a', 0345},
-+	{'A', 'A', 0305},	{'a', 'a', 0345},
-+	{'A', 'E', 0306},	{'a', 'e', 0346},
-+	{',', 'C', 0307},	{',', 'c', 0347},
-+	{'`', 'E', 0310},	{'`', 'e', 0350},
-+	{'\'', 'E', 0311},	{'\'', 'e', 0351},
-+	{'^', 'E', 0312},	{'^', 'e', 0352},
-+	{'"', 'E', 0313},	{'"', 'e', 0353},
-+	{'`', 'I', 0314},	{'`', 'i', 0354},
-+	{'\'', 'I', 0315},	{'\'', 'i', 0355},
-+	{'^', 'I', 0316},	{'^', 'i', 0356},
-+	{'"', 'I', 0317},	{'"', 'i', 0357},
-+	{'-', 'D', 0320},	{'-', 'd', 0360},
-+	{'~', 'N', 0321},	{'~', 'n', 0361},
-+	{'`', 'O', 0322},	{'`', 'o', 0362},
-+	{'\'', 'O', 0323},	{'\'', 'o', 0363},
-+	{'^', 'O', 0324},	{'^', 'o', 0364},
-+	{'~', 'O', 0325},	{'~', 'o', 0365},
-+	{'"', 'O', 0326},	{'"', 'o', 0366},
-+	{'/', 'O', 0330},	{'/', 'o', 0370},
-+	{'`', 'U', 0331},	{'`', 'u', 0371},
-+	{'\'', 'U', 0332},	{'\'', 'u', 0372},
-+	{'^', 'U', 0333},	{'^', 'u', 0373},
-+	{'"', 'U', 0334},	{'"', 'u', 0374},
-+	{'\'', 'Y', 0335},	{'\'', 'y', 0375},
-+	{'T', 'H', 0336},	{'t', 'h', 0376},
-+	{'s', 's', 0337},	{'"', 'y', 0377},
-+	{'s', 'z', 0337},	{'i', 'j', 0377},
- };
- 
- unsigned int accent_table_size = 68;
-diff -Nurd linux-2.6.24/drivers/char/drm/drm_stub.c linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c
---- linux-2.6.24/drivers/char/drm/drm_stub.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c	2008-06-11 17:49:50.000000000 +0200
-@@ -218,6 +218,7 @@
- 	if (ret)
- 		goto err_g1;
- 
-+	pci_set_master(pdev);
- 	if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
- 		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
- 		goto err_g2;
-diff -Nurd linux-2.6.24/drivers/char/drm/drm_vm.c linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c
---- linux-2.6.24/drivers/char/drm/drm_vm.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c	2008-06-11 17:49:50.000000000 +0200
-@@ -506,6 +506,7 @@
- 	vma->vm_ops = &drm_vm_dma_ops;
- 
- 	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
-+	vma->vm_flags |= VM_DONTEXPAND;
- 
- 	vma->vm_file = filp;	/* Needed for drm_vm_open() */
- 	drm_vm_open_locked(vma);
-@@ -655,6 +656,7 @@
- 		return -EINVAL;	/* This should never happen. */
- 	}
- 	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
-+	vma->vm_flags |= VM_DONTEXPAND;
- 
- 	vma->vm_file = filp;	/* Needed for drm_vm_open() */
- 	drm_vm_open_locked(vma);
-diff -Nurd linux-2.6.24/drivers/char/mspec.c linux-2.6.24-oxe810/drivers/char/mspec.c
---- linux-2.6.24/drivers/char/mspec.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/mspec.c	2008-06-11 17:49:52.000000000 +0200
-@@ -283,7 +283,7 @@
- 	vdata->refcnt = ATOMIC_INIT(1);
- 	vma->vm_private_data = vdata;
- 
--	vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP);
-+	vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
- 	if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
- 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- 	vma->vm_ops = &mspec_vm_ops;
-diff -Nurd linux-2.6.24/drivers/char/vt.c linux-2.6.24-oxe810/drivers/char/vt.c
---- linux-2.6.24/drivers/char/vt.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/vt.c	2008-06-11 17:49:52.000000000 +0200
-@@ -702,6 +702,7 @@
- 	if (is_switch) {
- 		set_leds();
- 		compute_shiftstate();
-+		notify_update(vc);
- 	}
- }
- 
-diff -Nurd linux-2.6.24/drivers/dma/Kconfig linux-2.6.24-oxe810/drivers/dma/Kconfig
---- linux-2.6.24/drivers/dma/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/Kconfig	2008-06-11 17:49:45.000000000 +0200
-@@ -4,7 +4,7 @@
- 
- menuconfig DMADEVICES
- 	bool "DMA Engine support"
--	depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
-+	depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || ARCH_OXNAS
- 	help
- 	  DMA engines can do asynchronous data transfers without
- 	  involving the host CPU.  Currently, this framework can be
-@@ -36,6 +36,14 @@
- 	help
- 	  Enable support for the Intel(R) IOP Series RAID engines.
- 
-+config OXNAS_ADMA
-+        tristate "Oxford Semiconductor ADAM support"
-+        depends on ARCH_OXNAS
-+	select ASYNC_CORE
-+	select DMA_ENGINE
-+        help
-+          Enable support for the Oxford Semiconductor async. DMA engine
-+
- config DMA_ENGINE
- 	bool
- 
-diff -Nurd linux-2.6.24/drivers/dma/Makefile linux-2.6.24-oxe810/drivers/dma/Makefile
---- linux-2.6.24/drivers/dma/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/Makefile	2008-06-11 17:49:45.000000000 +0200
-@@ -3,3 +3,4 @@
- obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
- ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
- obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
-+obj-$(CONFIG_OXNAS_ADMA) += oxnas_adma.o
-diff -Nurd linux-2.6.24/drivers/dma/ioat_dma.c linux-2.6.24-oxe810/drivers/dma/ioat_dma.c
---- linux-2.6.24/drivers/dma/ioat_dma.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/ioat_dma.c	2008-06-11 17:49:45.000000000 +0200
-@@ -726,6 +726,7 @@
- 
- 	if (new) {
- 		new->len = len;
-+		new->async_tx.ack = 0;
- 		return &new->async_tx;
- 	} else
- 		return NULL;
-@@ -749,6 +750,7 @@
- 
- 	if (new) {
- 		new->len = len;
-+		new->async_tx.ack = 0;
- 		return &new->async_tx;
- 	} else
- 		return NULL;
-diff -Nurd linux-2.6.24/drivers/dma/oxnas_adma.c linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c
---- linux-2.6.24/drivers/dma/oxnas_adma.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c	2008-06-11 17:49:45.000000000 +0200
-@@ -0,0 +1,272 @@
-+/*
-+ * drivers/dma/oxnas_adma.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/dmaengine.h>
-+#include <linux/platform_device.h>
-+#include <asm/dma.h>
-+
-+/* MODULE API */
-+MODULE_VERSION("1.0");
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Oxford Semiconductor Ltd.");
-+
-+typedef struct oxnas_adma_device {
-+	struct dma_device common;
-+	struct platform_device *platform_device;
-+} oxnas_adma_device_t;
-+
-+typedef struct oxnas_adma_channel {
-+	struct dma_chan common;
-+	oxnas_dma_channel_t *oxnas_channel;
-+	/* Need a queue for pending descriptors */
-+	/* May need a queue for completed descriptors that haven't been acked yet */
-+} oxnas_adma_channel_t;
-+
-+typedef struct oxnas_adma_desc {
-+	struct dma_async_tx_descriptor async_desc;
-+	size_t len;
-+	dma_addr_t src_adr;
-+	dma_addr_t dst_adr;
-+} oxnas_adma_desc_t;
-+
-+static int __devexit oxnas_adma_remove(struct platform_device *dev)
-+{
-+	oxnas_adma_device_t *oxnas_adma_device = platform_get_drvdata(dev);
-+	struct dma_device *dma_device = &oxnas_adma_device->common;
-+	struct dma_chan *channel, *_channel;
-+
-+	dma_async_device_unregister(dma_device);
-+
-+	list_for_each_entry_safe(channel, _channel, &dma_device->channels, device_node) {
-+		list_del(&channel->device_node);
-+		kfree(channel);
-+	}
-+	kfree(oxnas_adma_device);
-+
-+	return 0;
-+}
-+
-+static void oxnas_adma_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-+{
-+	oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+	desc->src_adr = addr;
-+}
-+
-+static void oxnas_adm_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-+{
-+	oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+	desc->dst_adr = addr;
-+}
-+
-+static void oxnas_dma_callback(
-+	oxnas_dma_channel_t *channel,
-+	oxnas_callback_arg_t arg,
-+	oxnas_dma_callback_status_t status,
-+	u16 checksum,
-+	int interrupt_count)
-+{
-+	oxnas_adma_desc_t *desc = (oxnas_adma_desc_t*)arg;
-+
-+	/* Use cookies to record that this descriptor's transfer has completed */
-+
-+	/* Store the completion status with the descriptor */
-+
-+	/* If there is a queued descriptor, start its transfer now - if that's
-+	   possible from a DMA callback - with the callback arg updated */
-+}
-+
-+static dma_cookie_t oxnas_adma_submit_tx(struct dma_async_tx_descriptor *tx)
-+{
-+	oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+	oxnas_adma_channel_t *channel = container_of(tx->chan, oxnas_adma_channel_t, common);
-+	dma_cookie_t cookie;
-+
-+	if (oxnas_dma_set(channel->oxnas_channel,
-+					  (unsigned char*)desc->src_adr,
-+					  desc->len,
-+					  (unsigned char*)desc->dst_adr,
-+					  OXNAS_DMA_MODE_INC,
-+					  OXNAS_DMA_MODE_INC,
-+					  0, 0)) {
-+		return -1;
-+	}
-+
-+	/* Allocate a cookie for this descriptor */
-+	cookie = -1;
-+
-+	/* Be careful to syn. properly with DMA callback here */
-+	if (oxnas_dma_is_active(channel->oxnas_channel)) {
-+		/* Queue the new descriptor to be started when current transfer completes */
-+	} else {
-+		/* Start the new transfer */
-+		oxnas_dma_set_callback(channel->oxnas_channel, oxnas_dma_callback, desc)
-+		oxnas_dma_start(channel->oxnas_channel);
-+	}
-+
-+	return cookie;
-+}
-+
-+/** Allocate a DMA channel and prepare it for memory to memory transfers. Could
-+ *  preallocate descriptors here
-+ */
-+static int oxnas_adma_alloc_chan_resources(struct dma_chan *chan)
-+{
-+	oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+
-+	channel->oxnas_channel = oxnas_dma_request(0);
-+	if (!channel->oxnas_channel) {
-+		return 0;
-+	}
-+
-+	/* Pretend we've allocated one descriptor */
-+	return 1;
-+}
-+
-+static void oxnas_adma_free_chan_resources(struct dma_chan *chan)
-+{
-+	oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+	oxnas_dma_free(channel->oxnas_channel);
-+
-+	/* May need to free leftover descriptors here as well */
-+}
-+
-+/** Poll for the DMA channel's active status. There can be multiple transfers
-+ *  queued with the DMA channel identified by cookies, so should be checking
-+ *  lists containing all pending transfers and all completed transfers that have
-+ *  not yet been polled for completion
-+ */
-+static enum dma_status oxnas_adma_is_tx_complete(
-+	struct dma_chan *chan,
-+	dma_cookie_t     cookie,
-+	dma_cookie_t    *last,
-+	dma_cookie_t    *used)
-+{
-+	oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+
-+	/* Use cookies to report completion status */
-+
-+	return oxnas_dma_is_active(channel->oxnas_channel) ? DMA_IN_PROGRESS : DMA_SUCCESS;
-+}
-+
-+/** To push outstanding transfers to h/w. This should use the list of pending
-+ *  transfers identified by cookies to select the next transfer and pass this to
-+ *  the hardware
-+ */
-+static void oxnas_adma_issue_pending(struct dma_chan *chan)
-+{
-+	/* If there isn't a transfer in progress and one is queued start it now,
-+	   being careful to sync. with DMA callback function */
-+}
-+
-+static void oxnas_adma_dependency_added(struct dma_chan *chan)
-+{
-+	/* What is supposed to happen here? */
-+}
-+
-+/** Allocate descriptors capable of mapping the requested length of memory */
-+static struct dma_async_tx_descriptor *oxnas_adma_prep_dma_memcpy(struct dma_chan *chan, size_t len, int int_en)
-+{
-+	oxnas_adma_desc_t *desc = kzalloc(sizeof(oxnas_adma_desc_t), GFP_KERNEL);
-+	if (unlikely(!desc)) {
-+		return NULL;
-+	}
-+
-+	desc->async_desc.tx_set_src  = oxnas_adma_set_src;
-+	desc->async_desc.tx_set_dest = oxnas_adm_set_dest;
-+	desc->async_desc.tx_submit   = oxnas_adma_submit_tx;
-+	desc->len = len;
-+
-+	return &desc->async_desc;
-+}
-+
-+static int enumerate_dma_channels(struct dma_device *dma_device)
-+{
-+	int i;
-+
-+	dma_device->chancnt = 3;
-+
-+	for (i = 0; i < dma_device->chancnt; i++) {
-+		oxnas_adma_channel_t *channel = kzalloc(sizeof(oxnas_adma_channel_t), GFP_KERNEL);
-+		if (!channel) {
-+			dma_device->chancnt = i;
-+			break;
-+		}
-+
-+		channel->common.device = dma_device;
-+		list_add_tail(&channel->common.device_node, &dma_device->channels);
-+	}
-+
-+	return dma_device->chancnt;
-+}
-+
-+static int __devinit oxnas_adma_probe(struct platform_device *platform_device)
-+{
-+	oxnas_adma_device_t *oxnas_adma_device;
-+	struct dma_device *dma_device;
-+
-+	oxnas_adma_device = kzalloc(sizeof(oxnas_adma_device_t), GFP_KERNEL);
-+	if (!oxnas_adma_device) {
-+		return -ENOMEM;
-+	}
-+
-+	oxnas_adma_device->platform_device = platform_device;
-+	dma_device = &oxnas_adma_device->common;
-+
-+	platform_set_drvdata(platform_device, oxnas_adma_device);
-+
-+	INIT_LIST_HEAD(&dma_device->channels);
-+	enumerate_dma_channels(dma_device);
-+
-+	dma_cap_set(DMA_MEMCPY, dma_device->cap_mask);
-+	dma_device->device_alloc_chan_resources = oxnas_adma_alloc_chan_resources;
-+	dma_device->device_free_chan_resources = oxnas_adma_free_chan_resources;
-+	dma_device->device_is_tx_complete = oxnas_adma_is_tx_complete;
-+	dma_device->device_issue_pending = oxnas_adma_issue_pending;
-+	dma_device->device_dependency_added = oxnas_adma_dependency_added;
-+	dma_device->dev = &platform_device->dev;
-+	dma_device->device_prep_dma_memcpy = oxnas_adma_prep_dma_memcpy;
-+
-+	dma_async_device_register(dma_device);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver oxnas_adma_driver = {
-+	.probe		= oxnas_adma_probe,
-+	.remove		= oxnas_adma_remove,
-+	.driver		= {
-+		.owner	= THIS_MODULE,
-+		.name	= "oxnas-adma",
-+	},
-+};
-+
-+static int __init oxnas_adma_init_module(void)
-+{
-+	return platform_driver_register(&oxnas_adma_driver);
-+}
-+
-+module_init(oxnas_adma_init_module);
-+
-+static void __exit oxnas_adma_exit_module(void)
-+{
-+	platform_driver_unregister(&oxnas_adma_driver);
-+	return;
-+}
-+
-+module_exit(oxnas_adma_exit_module);
-diff -Nurd linux-2.6.24/drivers/firmware/dmi_scan.c linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c
---- linux-2.6.24/drivers/firmware/dmi_scan.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c	2008-06-11 17:49:40.000000000 +0200
-@@ -469,12 +469,3 @@
- 
- 	return year;
- }
--
--/**
-- *	dmi_get_slot - return dmi_ident[slot]
-- *	@slot:	index into dmi_ident[]
-- */
--char *dmi_get_slot(int slot)
--{
--	return(dmi_ident[slot]);
--}
-diff -Nurd linux-2.6.24/drivers/i2c/algos/Kconfig linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig
---- linux-2.6.24/drivers/i2c/algos/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig	2008-06-11 17:50:33.000000000 +0200
-@@ -34,6 +34,10 @@
- 	  This support is also available as a module.  If so, the module 
- 	  will be called i2c-algo-pca.
- 
-+config I2C_ALGOOXSEMI
-+	tristate "OXNAS I2C interface"
-+	depends on I2C
-+
- config I2C_ALGO_SGI
- 	tristate "I2C SGI interfaces"
- 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-diff -Nurd linux-2.6.24/drivers/i2c/algos/Makefile linux-2.6.24-oxe810/drivers/i2c/algos/Makefile
---- linux-2.6.24/drivers/i2c/algos/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/Makefile	2008-06-11 17:50:34.000000000 +0200
-@@ -5,6 +5,7 @@
- obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
- obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
- obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
-+obj-$(CONFIG_I2C_ALGOOXSEMI)	+= i2c-algo-oxnas.o
- obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
- 
- ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
-diff -Nurd linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c
---- linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c	2008-06-11 17:50:33.000000000 +0200
-@@ -0,0 +1,858 @@
-+/*
-+ * i2c-algo-oxnas.c i2x driver algorithms for MPCoxnas 
-+ * Copyright (c) 1999 Dan Malek (dmalek at jlc.net).
-+ *
-+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+// XXX todo
-+// timeout sleep?
-+
-+
-+/* $Id: i2c-algo-oxnas.c,v 1.15 2004/11/20 08:02:24 khali Exp $ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include "linux/i2c.h"
-+#include "linux/i2c-algo-oxnas.h"
-+#include <asm/bitops.h>
-+
-+
-+
-+#define OXNAS_MAX_READ	513
-+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */ //NOTE
-+static wait_queue_head_t iic_wait;
-+
-+int oxnas_debug = 1;
-+int oxnas_scan  = 1;
-+
-+static inline  void oxnas_iic_algo_dump_reg( void )
-+{
-+      i2c_registers_oxnas_t* i2c = (i2c_registers_oxnas_t*) I2C_BASE; // SERIAL_MASTER_CONTROL_BASE;
-+                                                                                                        
-+      printk( KERN_INFO "\n\n ==================================================================" );
-+      printk( KERN_INFO "    i2c->SerialControlRegister;                == 0x%08x @ %p\n", i2c->SerialControlRegister                 , &(i2c->SerialControlRegister                ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x00;  */
-+      printk( KERN_INFO "    i2c->SerialAddressRegister;                == 0x%08x @ %p\n", i2c->SerialAddressRegister                 , &(i2c->SerialAddressRegister                ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x04;  */
-+      printk( KERN_INFO "    i2c->SerialSWControlOutRegister;           == 0x%08x @ %p\n", i2c->SerialSWControlOutRegister            , &(i2c->SerialSWControlOutRegister           ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x08;  */
-+      printk( KERN_INFO "    i2c->SerialSWControlInRegister;            == 0x%08x @ %p\n", i2c->SerialSWControlInRegister             , &(i2c->SerialSWControlInRegister            ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x0C;  */
-+      printk( KERN_INFO "    i2c->SerialInterruptStatusRegister;        == 0x%08x @ %p\n", i2c->SerialInterruptStatusRegister         , &(i2c->SerialInterruptStatusRegister        ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x10;  */
-+      printk( KERN_INFO "    i2c->SerialInterruptEnableRegister;        == 0x%08x @ %p\n", i2c->SerialInterruptEnableRegister         , &(i2c->SerialInterruptEnableRegister        ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x14;  */
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->SerialReadData1Register;              == 0x%08x @ %p\n", i2c->SerialReadData1Register               , &(i2c->SerialReadData1Register              ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x20;  */
-+      printk( KERN_INFO "    i2c->SerialReadData2Register;              == 0x%08x @ %p\n", i2c->SerialReadData2Register               , &(i2c->SerialReadData2Register              ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x24;  */
-+      printk( KERN_INFO "    i2c->SerialReadData3Register;              == 0x%08x @ %p\n", i2c->SerialReadData3Register               , &(i2c->SerialReadData3Register              ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x28;  */
-+      printk( KERN_INFO "    i2c->SerialReadData4Register;              == 0x%08x @ %p\n", i2c->SerialReadData4Register               , &(i2c->SerialReadData4Register              ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x2C;  */
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->SerialWriteData1Register;             == 0x%08x @ %p\n", i2c->SerialWriteData1Register              , &(i2c->SerialWriteData1Register             ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x40;  */
-+      printk( KERN_INFO "    i2c->SerialWriteData2Register;             == 0x%08x @ %p\n", i2c->SerialWriteData2Register              , &(i2c->SerialWriteData2Register             ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x44;  */
-+      printk( KERN_INFO "    i2c->SerialWriteData3Register;             == 0x%08x @ %p\n", i2c->SerialWriteData3Register              , &(i2c->SerialWriteData3Register             ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x48;  */
-+      printk( KERN_INFO "    i2c->SerialWriteData4Register;             == 0x%08x @ %p\n", i2c->SerialWriteData4Register              , &(i2c->SerialWriteData4Register             ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x4C;  */
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->GenericSerialControlRegister;         == 0x%08x @ %p\n", i2c->GenericSerialControlRegister          , &(i2c->GenericSerialControlRegister         ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x80;  */        
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->GenericSerialInterruptStatusRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptStatusRegister  , &(i2c->GenericSerialInterruptStatusRegister ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x90;  */
-+      printk( KERN_INFO "    i2c->GenericSerialInterruptEnableRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptEnableRegister  , &(i2c->GenericSerialInterruptEnableRegister ) );      /* SERIAL_MASTER_CONTROL_BASE + 0x94;  */
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->GenericSerialReadData1Register;       == 0x%08x @ %p\n", i2c->GenericSerialReadData1Register        , &(i2c->GenericSerialReadData1Register       ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xA0;  */
-+      printk( KERN_INFO "    i2c->GenericSerialReadData2Register;       == 0x%08x @ %p\n", i2c->GenericSerialReadData2Register        , &(i2c->GenericSerialReadData2Register       ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xA4;  */
-+      printk( KERN_INFO "    i2c->GenericSerialReadData3Register;       == 0x%08x @ %p\n", i2c->GenericSerialReadData3Register        , &(i2c->GenericSerialReadData3Register       ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xA8;  */
-+      printk( KERN_INFO "    i2c->GenericSerialReadData4Register;       == 0x%08x @ %p\n", i2c->GenericSerialReadData4Register        , &(i2c->GenericSerialReadData4Register       ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xAC;  */
-+      printk( KERN_INFO "\n" );      /* PAD REGISTER PACKING ***/
-+      printk( KERN_INFO "    i2c->GenericSerialWriteData1Register;      == 0x%08x @ %p\n", i2c->GenericSerialWriteData1Register       , &(i2c->GenericSerialWriteData1Register      ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xC0;  */
-+      printk( KERN_INFO "    i2c->GenericSerialWriteData2Register;      == 0x%08x @ %p\n", i2c->GenericSerialWriteData2Register       , &(i2c->GenericSerialWriteData2Register      ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xC4;  */
-+      printk( KERN_INFO "    i2c->GenericSerialWriteData3Register;      == 0x%08x @ %p\n", i2c->GenericSerialWriteData3Register       , &(i2c->GenericSerialWriteData3Register      ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xC8;  */
-+      printk( KERN_INFO "    i2c->GenericSerialWriteData4Register;      == 0x%08x @ %p\n", i2c->GenericSerialWriteData4Register       , &(i2c->GenericSerialWriteData4Register      ) );      /* SERIAL_MASTER_CONTROL_BASE + 0xCC;  */
-+      printk( KERN_INFO "\n\n =================================================================="  );
-+
-+	
-+}
-+
-+static inline int oxnas_iic_algo_bus_reset( volatile struct i2c_algo_oxnas_data* oxnas )
-+{
-+	/* perform a bus reset to clean up */
-+	
-+	unsigned long flags, tmo;
-+	volatile i2c_registers_oxnas_t *pI2C = (i2c_registers_oxnas_t *) oxnas;
-+	
-+	local_irq_save(flags);
-+	oxnas->iTransferInProgress_ = 1;
-+	
-+        pI2C->SerialControlRegister = 
-+		(I2C_SCR_RESET << I2C_SCR_TRANSACTION_TYPE_BIT     ) |
-+		(I2C_SCR_RESET << I2C_SCR_TRANSACTION_PROGRESS_BIT );
-+		
-+	/* Wait for IIC transfer */
-+	tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+		
-+	// Flag that the transfer has finished
-+	oxnas->iTransferInProgress_ = 0;
-+
-+	local_irq_restore(flags);
-+	
-+	return (tmo < 1*HZ);
-+}
-+
-+
-+static  void
-+oxnas_iic_algo_interrupt(void *dev_id, struct pt_regs *regs)
-+{
-+	volatile i2c_registers_oxnas_t *i2cReg = (i2c_registers_oxnas_t *)dev_id;
-+	if (oxnas_debug)
-+		printk("oxnas_iic_algo_interrupt(dev_id=%p)\n", dev_id);
-+
-+	/* Clear interrupt.
-+	*/
-+	i2cReg->SerialInterruptStatusRegister &= ~(1UL <<  I2C_ISR_INTERRUPT_STATUS_BIT);
-+
-+	/* Get 'me going again.
-+	*/
-+	wake_up_interruptible(&iic_wait);
-+}
-+
-+static void
-+oxnas_iic_algo_init(struct i2c_algo_oxnas_data *oxnas)
-+{
-+	u32 temp;
-+	volatile i2c_registers_oxnas_t*	i2c = oxnas->i2c;
-+
-+	if (oxnas_debug) printk(KERN_INFO "oxnas_iic_algo_init()\n");
-+
-+	/* Initialize 
-+	 * Set up the IIC parameters 
-+	 */
-+	temp   = i2c->SerialControlRegister & I2C_SCR_READ_MASK;
-+	temp >>= I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_BIT;
-+	temp  &= ~(0xffffffff << ( I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_NUM_BITS ));
-+	oxnas->iMaxAutoIncTransfer_ = temp;
-+
-+        // Initialise the Serial controller(s)
-+        {
-+		// syslib::Lock lock(mutex);
-+		
-+		// TODO: Ensure the Serial block is properly reset
-+		// BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
-+		// blockResetRegister.ResetSerial();
-+		// blockResetRegister.CommitWrites();
-+		// blockResetRegister.Release();
-+		
-+		// TODO: Enable the clock to the Serial block
-+		// ClockStartRegister& clockStartRegister = ClockStartRegister::Acquire();
-+		// clockStartRegister.RefreshReadData();
-+		// clockStartRegister.StartSerialClock();
-+		// clockStartRegister.CommitWrites();
-+		// clockStartRegister.Release();
-+		
-+		// TODO: Set the Serial clock rate
-+		// SerialClockSelectRegister& serialClockSelectRegister = SerialClockSelectRegister::GetInstance();
-+		// serialClockSelectRegister.SetClockRate(SerialClockSelectRegister::PLL_DIV_32768);
-+		// serialClockSelectRegister.CommitWrites();
-+		
-+		// Disable the Serial Interrupt
-+		if (oxnas_debug) printk(KERN_INFO "    - Disabling pre existing i2c interrupt\n");
-+		i2c->SerialInterruptEnableRegister &= ~(1UL <<  I2C_IER_SERIAL_ENABLE_BIT);
-+		
-+		// Disable the Generic serial Interrupt
-+		if (oxnas_debug) printk(KERN_INFO "    - Disabling pre existing gen serial interrupt\n");
-+		i2c->SerialInterruptEnableRegister &= ~(1UL <<  I2C_IER_GEN_ENABLE_BIT);
-+				
-+		// Clear any pending Serial interrupts
-+		if ( i2c->SerialInterruptStatusRegister | (1UL <<  I2C_ISR_INTERRUPT_STATUS_BIT) )
-+		{
-+			// Yes, so clear the interrupt
-+			if (oxnas_debug) printk(KERN_INFO "    - Clearing pre existing i2c interrupt\n");
-+			*( &(i2c->SerialInterruptStatusRegister) ) |= (1UL <<  I2C_ISR_INTERRUPT_STATUS_BIT);
-+		}
-+		
-+		// Clear any pending Generic serial interrupts
-+		if (  i2c->SerialInterruptStatusRegister | (1UL <<  I2C_ISR_GEN_INTERRUPT_STATUS_BIT) )
-+		{
-+			// Yes, so clear the interrupt
-+			if (oxnas_debug) printk(KERN_INFO "    - Clearing pre existing generic serial interrupt\n");
-+			*( &(i2c->SerialInterruptStatusRegister) ) |= (1UL <<  I2C_ISR_GEN_INTERRUPT_STATUS_BIT);
-+		}
-+		
-+				
-+		// Initialise the generic serial hardware, which shares reset,
-+		// clock and interrupt hardware with the Serial controller(s)
-+		// TODO: GenericSerialHelper::Init();
-+		
-+	}
-+	
-+	init_waitqueue_head(&iic_wait);
-+
-+	/* Install interrupt handler.
-+	*/
-+	if (oxnas_debug) {
-+		printk ("%s[%d] Install ISR for IRQ %d\n",
-+			__func__,__LINE__, I2C_INTERRUPT  );
-+	}
-+	
-+	(*oxnas->setisr)( (int) I2C_INTERRUPT, &oxnas_iic_algo_interrupt, (void *)i2c);
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+}
-+
-+
-+static int
-+oxnas_iic_algo_shutdown(struct i2c_algo_oxnas_data *oxnas)
-+{
-+	volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+
-+	if (oxnas_debug) printk("oxnas_iic_algo_shutdown()\n");
-+
-+	/* Shut down IIC.
-+	*/
-+        // TODO: syslib::Lock lock(mutex);
-+
-+	// TODO: Reset Serial block to ensure there are no actve transfers
-+	// BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
-+	// blockResetRegister.ResetSerial();
-+	// blockResetRegister.CommitWrites();
-+	// blockResetRegister.Release();
-+	
-+	// Disable the Serial Interrupt
-+	if (oxnas_debug) printk(KERN_INFO "    - Disabling pre existing i2c interrupt\n");
-+	i2c->SerialInterruptEnableRegister &= ~(1UL <<  I2C_IER_SERIAL_ENABLE_BIT);
-+	
-+	// Disable the Generic serial Interrupt
-+	if (oxnas_debug) printk(KERN_INFO "    - Disabling pre existing gen serial interrupt\n");
-+	i2c->SerialInterruptEnableRegister &= ~(1UL <<  I2C_IER_GEN_ENABLE_BIT);
-+			
-+
-+	// Shutdown the generic serial hardware, which shares reset, clock and
-+	// interrupt hardware with the Serial controller(s)
-+	// TODO: GenericSerialHelper::Shutdown();
-+	
-+	// TODO: Disable the clock to the Serial block
-+	// ClockStopRegister& clockStopRegister = ClockStopRegister::Acquire();
-+	// clockStopRegister.RefreshReadData();
-+	// clockStopRegister.StopSerialClock();
-+	// clockStopRegister.CommitWrites();
-+	// clockStopRegister.Release();
-+	
-+	(*oxnas->clearisr)( (int) I2C_INTERRUPT, (void *)i2c);
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+
-+	return(0);
-+}
-+
-+
-+#define BD_SC_NAK		((ushort)0x0004) /* NAK - did not respond */
-+#define BD_SC_OV			((ushort)0x0002) /* OV - receive overrun */
-+#define OXNAS_CR_CLOSE_RXBD	((ushort)0x0007)
-+
-+static void force_close(struct i2c_algo_oxnas_data *oxnas)
-+{	
-+	volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+	
-+	if (oxnas_debug) printk("force_close()\n");
-+
-+	*( &(i2c->SerialControlRegister) ) |= (1UL <<  I2C_SCR_ABORT_BIT);
-+	
-+	/* perform a bus reset to clean up */
-+	oxnas_iic_algo_bus_reset(oxnas);
-+	
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+}
-+
-+
-+/* Read from IIC...
-+ * abyte = address byte, with r/w flag already set
-+ */
-+static int
-+oxnas_iic_algo_read(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *readBuffer, int readBufferLength)
-+{
-+	volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+	const unsigned char* pData;
-+	unsigned long flags, tmo, temp, bytesTransfered;
-+	
-+
-+	if (oxnas_debug) printk("oxnas_iic_algo_read(abyte=0x%x)\n", abyte);
-+	
-+	if (readBufferLength >= oxnas->iMaxAutoIncTransfer_ ) {
-+		if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", readBufferLength, oxnas->iMaxAutoIncTransfer_ );
-+		return -EINVAL;
-+	}
-+
-+
-+	if( 1 /*TODO: Split into multipacks. */ ) 
-+	{
-+		
-+		local_irq_save(flags);
-+		
-+		/* QUESTION: Does this get locked by the parent? it should be!! */
-+		oxnas->iTransferInProgress_  = 1;
-+		oxnas->iError_               = 0;
-+	
-+		// Set up the 7-bit slave address 
-+		i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+	
-+		// Setup the control register
-+		temp = ( I2C_SCR_READ       << I2C_SCR_READ_WRITE_BIT            ) |
-+                       ( I2C_SCR_NORMAL     << I2C_SCR_TRANSACTION_TYPE_BIT      ) |
-+                       ( I2C_SCR_SEVEN_BIT  << I2C_SCR_ADDRESS_MODE_BIT	         ) |
-+                       ( 0                  << I2C_SCR_SCCB_MODE_ENABLE_BIT      ) |
-+                       ( 1                  << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |       
-+		       ( 1		    << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+		       ( 1		    << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+		       ( 0 		    << I2C_SCR_HIGH_SPEED_DRIVE_BIT      ) |
-+                       ( readBufferLength   << I2C_SCR_BYTES_TO_TRANSFER_BIT     );
-+		       
-+		temp &= I2C_SCR_WRITE_MASK;		       
-+		i2c->SerialControlRegister = temp;
-+		
-+		/* Enable some interupts */
-+		*( &(i2c->SerialInterruptEnableRegister) ) |= (1UL <<  I2C_IER_SERIAL_ENABLE_BIT);
-+		
-+		/* Begin transmission */
-+		*( &(i2c->SerialControlRegister) ) |= (1UL <<  I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+		/* Wait for IIC transfer */
-+		tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+	
-+		/* Woken. Copy data out of special registers. */
-+
-+		temp = i2c->SerialControlRegister;
-+
-+		// How many bytes were read from the slave?
-+		bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) & 
-+				  ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+
-+		// Did the transfer fail
-+		if ( temp | (1UL <<  I2C_SCR_TRANSACTION_STATUS_BIT)  )
-+		{
-+			// Yes, so remember the error
-+			oxnas->iError_    = 1;
-+			readBufferLength  = 0;
-+		}
-+		else if (readBuffer)
-+		{
-+			if (bytesTransfered > readBufferLength)
-+			{
-+				// More bytes were read than we have buffer space to
-+				// store them
-+				oxnas->iError_ = 1;
-+			}
-+			else
-+			{
-+				// Copy the received data into the buffer that was provided by the
-+				// original caller to the Read() or ReadImmediate() method
-+				if (bytesTransfered > 0)
-+				{
-+					int i=0;
-+					temp = i2c->SerialReadData1Register;
-+					pData = (const unsigned char*) (&temp);
-+					readBuffer[i++] = *pData++;
-+					if (bytesTransfered > 1)
-+					{
-+						readBuffer[i++] = *pData++;
-+						if (bytesTransfered > 2)
-+						{
-+							readBuffer[i++] = *pData++;
-+							if (bytesTransfered > 3)
-+							{
-+								readBuffer[i++] = *pData++;
-+							}
-+						}
-+					}
-+			
-+					if (bytesTransfered > 4)
-+					{
-+						temp = i2c->SerialReadData2Register;
-+						pData = (const unsigned char*) (&temp);
-+						readBuffer[i++] = *pData++;
-+						if (bytesTransfered > 5)
-+						{
-+							readBuffer[i++] = *pData++;
-+							if (bytesTransfered > 6)
-+							{
-+								readBuffer[i++] = *pData++;
-+								if (bytesTransfered > 7)
-+								{
-+									readBuffer[i++] = *pData++;
-+								}
-+							}
-+						}
-+					}
-+			
-+					if (bytesTransfered > 8)
-+					{
-+						temp = i2c->SerialReadData3Register;
-+						pData = (const unsigned char*) (&temp);
-+						if (bytesTransfered > 9)
-+						{
-+							readBuffer[i++] = *pData++;
-+							if (bytesTransfered > 10)
-+							{
-+								readBuffer[i++] = *pData++;
-+								if (bytesTransfered > 11)
-+								{
-+									readBuffer[i++] = *pData++;
-+								}
-+							}
-+						}
-+					}
-+					
-+					if (bytesTransfered > 12)
-+					{
-+						temp = i2c->SerialReadData4Register;
-+						pData = (const unsigned char*) (&temp);
-+						if (bytesTransfered > 13)
-+						{
-+							readBuffer[i++] = *pData++;
-+							if (bytesTransfered > 14)
-+							{
-+								readBuffer[i++] = *pData++;
-+								if (bytesTransfered > 15)
-+								{
-+									readBuffer[i++] = *pData++;
-+								}
-+							}
-+						}
-+					}
-+				}
-+			}
-+		}
-+            
-+
-+		// Flag that the transfer has finished
-+		oxnas->iTransferInProgress_ = 0;
-+	
-+		local_irq_restore(flags);
-+	}
-+	
-+	/* IDEA:  busy wait for small transfers, its faster  time_after(jiffies, tmo) */
-+
-+	if (signal_pending(current) || !tmo){
-+		force_close(oxnas);
-+		if(oxnas_debug) 
-+			printk("IIC read: timeout!\n");
-+		return -EIO;
-+	}
-+	
-+	if ( i2c->SerialControlRegister | (1UL <<  I2C_SCR_TRANSACTION_STATUS_BIT) ) {
-+		if (oxnas_debug)
-+			printk("IIC read; no ack\n");
-+		return -EREMOTEIO;
-+	}
-+
-+	if (bytesTransfered > readBufferLength) {
-+		if (oxnas_debug)
-+			printk("IIC read; Overrun\n");
-+		return -EREMOTEIO;;
-+	}
-+
-+	if (oxnas_debug) printk("read %u bytes\n", readBufferLength);
-+
-+	if (bytesTransfered < readBufferLength) {
-+		if (oxnas_debug)
-+			printk("IIC read; short, wanted %lu got %ld\n",
-+			       bytesTransfered, readBufferLength);
-+		return 0;
-+	}
-+
-+	return bytesTransfered;
-+}
-+
-+
-+static void LoadWriteRegisters(
-+	volatile i2c_registers_oxnas_t *i2c, 
-+	char *data,
-+	int length )
-+{
-+	// Copy the data to be transmited into the write registers
-+	u32 temp;
-+	if (length > 0)
-+	{
-+		int i=0;
-+		unsigned char* pData = (unsigned char*) &temp;
-+		*pData++ = (data[i++]);
-+		if (length > 1)
-+		{
-+			*pData++ = (data[i++]);
-+			if (length > 2)
-+			{
-+				*pData++ = (data[i++]);
-+				if (length > 3)
-+				{
-+					*pData++ = (data[i++]);
-+				}
-+			}
-+		}
-+		i2c->SerialWriteData1Register = temp;
-+		
-+		if (length > 4)
-+		{
-+			pData = (unsigned char*) (&temp);
-+			*pData++ = (data[i++]);
-+			if (length > 5)
-+			{
-+				*pData++ = (data[i++]);
-+				if (length > 6)
-+				{
-+					*pData++ = (data[i++]);
-+					if (length > 7)
-+					{
-+						*pData++ = (data[i++]);
-+					}
-+				}
-+			}
-+			i2c->SerialWriteData2Register = temp;
-+		}
-+		
-+		if (length > 8)
-+		{
-+			pData = (unsigned char*) (&temp);
-+			*pData++ = (data[i++]);
-+			if (length > 9)
-+			{
-+				*pData++ = (data[i++]);
-+				if (length > 10)
-+				{
-+					*pData++ = (data[i++]);
-+					if (length > 11)	
-+					{
-+						*pData++ = (data[i++]);
-+					}
-+				}
-+			}
-+			i2c->SerialWriteData3Register = temp;
-+		}
-+		
-+		if (length > 12)
-+		{
-+			pData = (unsigned char*) (&temp);
-+			*pData++ = (data[i++]);	
-+			if (length > 13)
-+			{	
-+				*pData++ = (data[i++]);
-+				if (length > 14)
-+				{
-+					*pData++ = (data[i++]);
-+					if (length > 15)
-+					{
-+						*pData++ = (data[i++]);
-+					}	
-+				}
-+			}
-+			i2c->SerialWriteData4Register = temp;
-+		}
-+	}
-+}
-+
-+
-+/* Write to IIC...
-+ * addr = address byte, with r/w flag already set
-+ */
-+static int
-+oxnas_iic_algo_write(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *buf,int count)
-+{
-+	volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+	unsigned long flags, tmo, bytesTransfered, temp;
-+
-+	if (oxnas_debug) printk("oxnas_iic_algo_write(abyte=0x%x)\n", abyte);
-+
-+	if (count >= oxnas->iMaxAutoIncTransfer_ ) {
-+		if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", count, oxnas->iMaxAutoIncTransfer_ );
-+		return -EINVAL;
-+	}
-+
-+	if( 1 /* TODO: Split longer messages */ )
-+	{
-+		LoadWriteRegisters( i2c, buf, count );
-+		
-+		local_irq_save(flags);
-+		
-+		/* QUESTION: Does this get locked by the parent? it should be!! */
-+		oxnas->iTransferInProgress_ = 1;
-+		oxnas->iError_              = 0;
-+	
-+		// Set up the 7-bit slave address 
-+		i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+	
-+		// Setup the control register
-+		temp = ( I2C_SCR_WRITE      << I2C_SCR_READ_WRITE_BIT            ) |
-+                       ( I2C_SCR_NORMAL     << I2C_SCR_TRANSACTION_TYPE_BIT      ) |
-+                       ( I2C_SCR_SEVEN_BIT  << I2C_SCR_ADDRESS_MODE_BIT	         ) |
-+                       ( 0                  << I2C_SCR_SCCB_MODE_ENABLE_BIT      ) |
-+                       ( 1                  << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |       
-+		       ( 1		    << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+		       ( 1		    << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+		       ( 0 		    << I2C_SCR_HIGH_SPEED_DRIVE_BIT      ) |
-+                       ( count              << I2C_SCR_BYTES_TO_TRANSFER_BIT     );
-+		       
-+		temp &= I2C_SCR_WRITE_MASK;		       
-+		i2c->SerialControlRegister = temp;
-+		
-+		/* Enable some interupts */
-+		*( &(i2c->SerialInterruptEnableRegister) ) |= (1UL <<  I2C_IER_SERIAL_ENABLE_BIT);
-+		
-+		/* Begin transmission */
-+		*( &i2c->SerialControlRegister ) |= (1UL <<  I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+		/* Begin transmission */
-+		
-+		/* Wait for IIC transfer */
-+		tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+		local_irq_restore(flags);
-+	} 		
-+
-+	/* IDEA:  busy wait for small transfers, its faster  time_after(jiffies, tmo) */
-+	
-+	
-+	if (signal_pending(current) || !tmo){
-+		force_close(oxnas);
-+		if(oxnas_debug) 
-+			printk("IIC read: timeout!\n");
-+		return -EIO;
-+	}
-+	
-+	if ( i2c->SerialControlRegister | (1UL <<  I2C_SCR_TRANSACTION_STATUS_BIT)) {
-+		if (oxnas_debug)
-+			printk("IIC read; no ack\n");
-+		return -EREMOTEIO;
-+	}
-+
-+	// How many bytes were read from the slave?
-+	bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) & 
-+			  ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+
-+	if (bytesTransfered > count) {
-+		if (oxnas_debug)
-+			printk("IIC read; Overrun\n");
-+		return -EREMOTEIO;;
-+	}
-+
-+	if (oxnas_debug) printk("read %lu bytes\n", bytesTransfered);
-+
-+	if (bytesTransfered < count) {
-+		if (oxnas_debug)
-+			printk("IIC read; short, wanted %u got %lu\n",
-+			       count, bytesTransfered);
-+		return 0;
-+	}
-+
-+	return bytesTransfered;
-+}
-+
-+/* See if an IIC address exists..
-+ * addr = 7 bit address, unshifted
-+ */
-+static int
-+oxnas_iic_algo_tryaddress(struct i2c_algo_oxnas_data *oxnas, int addr)
-+{
-+	volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+	unsigned long flags, length, tmo, temp, bytesTransfered;
-+
-+	if (oxnas_debug) printk("oxnas_iic_algo_tryaddress(oxnas=%p/%p,addr=%d)\n", oxnas, i2c, addr);
-+
-+	/* do a simple read */
-+	length = 2;
-+	
-+	{
-+		local_irq_save(flags);
-+		
-+		/* QUESTION: Does this get locked by the parent? it should be!! */
-+		oxnas->iTransferInProgress_ = 1;
-+		oxnas->iError_              = 0;
-+	
-+		// Set up the 7-bit slave address 
-+		i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((addr) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+	
-+		// Setup the control register
-+		temp = ( I2C_SCR_WRITE      << I2C_SCR_READ_WRITE_BIT            ) |
-+                       ( I2C_SCR_NORMAL     << I2C_SCR_TRANSACTION_TYPE_BIT      ) |
-+                       ( I2C_SCR_SEVEN_BIT  << I2C_SCR_ADDRESS_MODE_BIT	         ) |
-+                       ( 0                  << I2C_SCR_SCCB_MODE_ENABLE_BIT      ) |
-+                       ( 1                  << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |       
-+		       ( 1		    << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+		       ( 1		    << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+		       ( 0 		    << I2C_SCR_HIGH_SPEED_DRIVE_BIT      ) |
-+                       ( length             << I2C_SCR_BYTES_TO_TRANSFER_BIT     );
-+		       
-+		temp &= I2C_SCR_WRITE_MASK;		       
-+		i2c->SerialControlRegister = temp;
-+		
-+		/* Enable some interupts */
-+		*( &(i2c->SerialInterruptEnableRegister) ) |= (1UL <<  I2C_IER_SERIAL_ENABLE_BIT);
-+		
-+		/* Begin transmission */
-+		*( &i2c->SerialControlRegister ) |= (1UL <<  I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+		/* Begin transmission */
-+		
-+		/* Wait for IIC transfer */
-+		tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+		local_irq_restore(flags);
-+	}
-+	
-+	/* IDEA:  busy wait for small transfers, its faster  time_after(jiffies, tmo) */
-+	
-+	
-+	if (signal_pending(current) || !tmo){
-+		force_close(oxnas);
-+		if(oxnas_debug) 
-+			printk("$rIIC test_addr: timeout!\n");
-+		return -EIO;
-+	}
-+	
-+	if ( i2c->SerialControlRegister | (1UL <<  I2C_SCR_TRANSACTION_STATUS_BIT)) {
-+		if (oxnas_debug)
-+			printk("$rIIC test_addr; no ack\n");
-+		return -EREMOTEIO;
-+	}
-+
-+	// How many bytes were read from the slave?
-+	bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) & 
-+			  ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+			  
-+	if (bytesTransfered > 2) {
-+		if (oxnas_debug)
-+			printk("$rIIC test_addr; Overrun\n");
-+		return -EREMOTEIO;;
-+	}
-+
-+	if (oxnas_debug) printk("$rtest_addr %lu bytes\n", bytesTransfered);
-+
-+	if (bytesTransfered < 2) {
-+		if (oxnas_debug)
-+			printk("$rIIC test_addr; short, wanted %d got %lu\n",
-+			       2, bytesTransfered);
-+		return 0;
-+	}
-+	printk("$GIIC found @ test_addr (oxnas=%p,addr=%d)\n", oxnas, addr);
-+	return 1;
-+}
-+
-+static int oxnas_xfer(
-+	struct  i2c_adapter *adap,
-+	struct  i2c_msg msgs[], 
-+	int 	num)
-+{
-+	struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+	struct i2c_msg 		   *pmsg;
-+	int i, ret;
-+	u_char addr;
-+    
-+	if (oxnas_debug > 1) printk("oxnas_xfer()\n");
-+	for (i = 0; i < num; i++) {
-+		pmsg = &msgs[i];
-+
-+		if (oxnas_debug)
-+			printk("i2c-algo-oxnas.o: "
-+			       "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
-+			       i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
-+
-+		addr = pmsg->addr << 1;
-+		if (pmsg->flags & I2C_M_RD )
-+			addr |= 1;
-+		if (pmsg->flags & I2C_M_REV_DIR_ADDR )
-+			addr ^= 1;
-+    
-+		if (!(pmsg->flags & I2C_M_NOSTART)) {
-+		}
-+		if (pmsg->flags & I2C_M_RD ) {
-+			/* read bytes into buffer*/
-+			ret = oxnas_iic_algo_read(oxnas, addr, pmsg->buf, pmsg->len);
-+			if (oxnas_debug)
-+				printk("i2c-algo-oxnas.o: read %d bytes\n", ret);
-+			if (ret < pmsg->len ) {
-+				return (ret<0)? ret : -EREMOTEIO;
-+			}
-+		} else {
-+			/* write bytes from buffer */
-+			ret = oxnas_iic_algo_write(oxnas, addr, pmsg->buf, pmsg->len);
-+			if (oxnas_debug)
-+				printk("i2c-algo-oxnas.o: wrote %d\n", ret);
-+			if (ret < pmsg->len ) {
-+				return (ret<0) ? ret : -EREMOTEIO;
-+			}
-+		}
-+	}
-+	return (num);
-+}
-+
-+static u32 oxnas_func(struct i2c_adapter *adap)
-+{
-+	if (oxnas_debug > 1) printk("oxnas_func(I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING)\n");
-+	
-+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-+	       I2C_FUNC_PROTOCOL_MANGLING; 
-+}
-+
-+/* -----exported algorithm data: -------------------------------------	*/
-+
-+static struct i2c_algorithm oxnas_algo = {
-+	.name		= "Oxnas algorithm",
-+	.id		= I2C_ALGO_OCP,
-+	.master_xfer	= oxnas_xfer,
-+	.functionality	= oxnas_func,
-+};
-+
-+/* 
-+ * registering functions to load algorithms at runtime 
-+ */
-+int i2c_oxnas_algo_add_bus(struct i2c_adapter *adap)
-+{
-+	int i;
-+	struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+
-+	if (oxnas_debug) printk("i2c_oxnas_algo_add_bus: hw routines for %s registered.\n", adap->name);
-+
-+	/* register new adapter to i2c module... */
-+
-+	adap->id |= oxnas_algo.id;
-+	adap->algo = &oxnas_algo;
-+
-+	oxnas_iic_algo_init(oxnas);
-+	i2c_add_adapter(adap);
-+	
-+	/* scan bus */
-+	if ( oxnas_scan ) {
-+		if (oxnas_debug) printk(KERN_INFO " i2c_oxnas_algo_add_bus: scanning bus %s...\n", adap->name);
-+		for (i = 0; i < 128; i++) {
-+			if (oxnas_debug) printk(KERN_INFO "   scanning addr %d...\n", i);
-+			if (oxnas_iic_algo_tryaddress(oxnas, i)) {
-+				printk("(%02x)",i<<1); 
-+			}
-+		}
-+		printk("\n");
-+	}
-+	
-+	return 0; 
-+}
-+
-+
-+int i2c_oxnas_algo_del_bus(struct i2c_adapter *adap)
-+{
-+	struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+
-+	oxnas_iic_algo_shutdown(oxnas);
-+
-+	return i2c_del_adapter(adap);
-+}
-+
-+EXPORT_SYMBOL(i2c_oxnas_algo_add_bus);
-+EXPORT_SYMBOL(i2c_oxnas_algo_del_bus);
-+
-+MODULE_AUTHOR("Chris FOrd <....>");
-+MODULE_DESCRIPTION("I2C-Bus oxnas algorithm");
-+MODULE_LICENSE("GPL");
-+
-diff -Nurd linux-2.6.24/drivers/i2c/busses/Kconfig linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig
---- linux-2.6.24/drivers/i2c/busses/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig	2008-06-11 17:50:33.000000000 +0200
-@@ -321,6 +321,15 @@
- 	  This driver can also be built as a module.  If so, the module
- 	  will be called i2c-nforce2.
- 
-+config I2C_OXNAS_BITBASH
-+	tristate "OXNAS bitbashed I2C interface"
-+	depends on I2C_ALGOBIT
-+	help
-+	  Say Y here if you want to use I2C GPIO bit-bash interface
-+
-+	  This driver can also be built as a module.  If so, the module
-+	  will be called i2c-oxnas-bitbash.
-+
- config I2C_OCORES
- 	tristate "OpenCores I2C Controller"
- 	depends on EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/i2c/busses/Makefile linux-2.6.24-oxe810/drivers/i2c/busses/Makefile
---- linux-2.6.24/drivers/i2c/busses/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/Makefile	2008-06-11 17:50:33.000000000 +0200
-@@ -28,6 +28,7 @@
- obj-$(CONFIG_I2C_OCORES)	+= i2c-ocores.o
- obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o
- obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
-+obj-$(CONFIG_I2C_OXNAS_BITBASH) 	+= i2c-oxnas-bitbash.o
- obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
- obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
- obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
-diff -Nurd linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c
---- linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c	2008-06-11 17:50:33.000000000 +0200
-@@ -0,0 +1,158 @@
-+/*
-+ * drivers/i2c/busses/i2c_oxnas_bitbash.c
-+ *
-+ * Copyright (C) 2006-2008 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+#define I2C_OXNAS_BITBASH_I2C_SDA_OUT   (1UL << (CONFIG_OXNAS_I2C_SDA))
-+#define I2C_OXNAS_BITBASH_I2C_SCL_OUT   (1UL << (CONFIG_OXNAS_I2C_SCL))
-+#define	I2C_OXNAS_BB_PULSEWIDTH (40)
-+#define OPEN_COLLECTOR_CLOCK    1
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static void i2c_oxnas_bitbash_setsda(void *data,int state)
-+{
-+	if (state) {
-+		// tristae as input to set line on bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+	} else {
-+		// tristate as output (with latch to zero) to assert zero on the bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_CLEAR);
-+		writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+	}
-+}
-+
-+static void i2c_oxnas_bitbash_setscl(void *data,int state)
-+{
-+#if OPEN_COLLECTOR_CLOCK
-+	if (state) {
-+		// tristae as input to set line on bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+	} else {
-+		// tristate as output (with latch to zero) to assert zero on the bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+	}
-+#else // driven clock
-+	if (state) {
-+		// tristae as input to set line on bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_SET);
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+	} else {
-+		// tristate as output (with latch to zero) to assert zero on the bus
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
-+		writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+	}
-+
-+#endif
-+}
-+
-+static int i2c_oxnas_bitbash_getsda(void *data)
-+{
-+	return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SDA_OUT) != 0);
-+}
-+
-+static int i2c_oxnas_bitbash_getscl(void *data)
-+{
-+	return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SCL_OUT) != 0);
-+}
-+
-+static struct i2c_algo_bit_data bit_i2c_oxnas_bitbash_data = {
-+	.setsda    = i2c_oxnas_bitbash_setsda,
-+	.setscl    = i2c_oxnas_bitbash_setscl,
-+	.getsda    = i2c_oxnas_bitbash_getsda,
-+	.getscl    = i2c_oxnas_bitbash_getscl,
-+	.udelay    = I2C_OXNAS_BB_PULSEWIDTH,
-+	.timeout   = HZ
-+};
-+
-+static struct i2c_adapter oxnas_i2c_bitbash_adapter = {
-+	.owner		= THIS_MODULE,
-+	.name		= "i2c_oxnas_bitbash adapter driver",
-+	.id		    = I2C_HW_B_OXNAS,
-+	.algo_data	= &bit_i2c_oxnas_bitbash_data,
-+};
-+
-+static int __init i2c_oxnas_bitbash_init(void)
-+{
-+    unsigned long flags;
-+    unsigned long mask = I2C_OXNAS_BITBASH_I2C_SDA_OUT | I2C_OXNAS_BITBASH_I2C_SCL_OUT;
-+	int ret = 0;
-+
-+	/* Dedicate the GPIO over to i2c.
-+     * NOTE: This may be confusing, but we are not using the i2c core here we
-+     * are using bit-bashed GPIO, so we must disable the primary, secondary and
-+     * tertiary functions of the relevant GPIO pins
-+     */
-+    spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  & ~mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+	i2c_oxnas_bitbash_setsda(NULL, 1);
-+	i2c_oxnas_bitbash_setscl(NULL, 1);
-+	ret = i2c_bit_add_bus(&oxnas_i2c_bitbash_adapter);
-+	if (!ret) {
-+#if defined(CONFIG_OXNAS_RTC) || defined(CONFIG_OXNAS_RTC_MODULE)
-+		/* Register the ST MT4100 RTC */
-+		struct i2c_board_info rtc_info  = {
-+			.driver_name   = "rtc-ds1307",
-+			.type          = "m41t00",
-+			.flags         = 0,
-+			.addr          = 0x68,
-+			.platform_data = NULL,
-+			.irq           = 0
-+		};
-+
-+		struct i2c_client *client = i2c_new_device(&oxnas_i2c_bitbash_adapter, &rtc_info);
-+		if (!client) {
-+			printk(KERN_WARNING "OXNAS bit-bash I2C driver failed to register RTC device\n");
-+			ret = -EIO;
-+		}
-+#endif // CONFIG_OXNAS_RTC || CONFIG_OXNAS_RTC_MODULE
-+	}
-+
-+	printk(KERN_INFO "OXNAS bit-bash I2C driver initialisation %s\n", ret ? "failed": "OK");
-+	return ret;
-+}
-+
-+static void __exit i2c_oxnas_bitbash_exit(void)
-+{
-+	i2c_oxnas_bitbash_setsda(NULL, 1);
-+	i2c_oxnas_bitbash_setscl(NULL, 1);
-+	i2c_del_adapter(&oxnas_i2c_bitbash_adapter);
-+}
-+
-+MODULE_AUTHOR("Brian Clarke");
-+MODULE_DESCRIPTION("OXNAS bit-bash I2C bus driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION("v2.0");
-+
-+module_init (i2c_oxnas_bitbash_init);
-+module_exit (i2c_oxnas_bitbash_exit);
-+
-diff -Nurd linux-2.6.24/drivers/leds/Kconfig linux-2.6.24-oxe810/drivers/leds/Kconfig
---- linux-2.6.24/drivers/leds/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/leds/Kconfig	2008-06-11 17:50:12.000000000 +0200
-@@ -62,6 +62,20 @@
- 	  This option enables support for LEDs connected to GPIO lines
- 	  on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
- 
-+config WDC_LEDS_OXNAS800
-+	tristate "LED Support for WDC OXNAS800 GPIO LEDs"
-+	depends on LEDS_CLASS && ARCH_OXNAS
-+	help
-+	  This option enables support for LEDs connected to GPIO lines on
-+	  Oxford Semiconductor NAS800 in the Western Digital My Book NAS.
-+
-+config OXNAS_WD810_LEDS
-+	tristate "LED Support for 810 based WD NAS"
-+	depends on LEDS_CLASS && ARCH_OXNAS
-+	help
-+	  This option enables support for LEDs connected to GPIO lines on the
-+	  Oxford Semiconductor OX810 in the Western Digital NAS
-+
- config LEDS_AMS_DELTA
- 	tristate "LED Support for the Amstrad Delta (E3)"
- 	depends on LEDS_CLASS && MACH_AMS_DELTA
-@@ -137,6 +151,13 @@
- 	  This allows LEDs to be controlled by IDE disk activity.
- 	  If unsure, say Y.
- 
-+config WDC_LEDS_TRIGGER_SATA_DISK
-+	bool "WDC LED SATA Disk Trigger"
-+	depends on LEDS_TRIGGERS
-+	help
-+	  This allows WDC LEDs to be controlled by SATA disk activity.
-+	  If unsure, say Y.
-+
- config LEDS_TRIGGER_HEARTBEAT
- 	tristate "LED Heartbeat Trigger"
- 	depends on LEDS_TRIGGERS
-diff -Nurd linux-2.6.24/drivers/macintosh/smu.c linux-2.6.24-oxe810/drivers/macintosh/smu.c
---- linux-2.6.24/drivers/macintosh/smu.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/macintosh/smu.c	2008-06-11 17:49:30.000000000 +0200
-@@ -85,6 +85,7 @@
- 	u32			cmd_buf_abs;	/* command buffer absolute */
- 	struct list_head	cmd_list;
- 	struct smu_cmd		*cmd_cur;	/* pending command */
-+	int			broken_nap;
- 	struct list_head	cmd_i2c_list;
- 	struct smu_i2c_cmd	*cmd_i2c_cur;	/* pending i2c command */
- 	struct timer_list	i2c_timer;
-@@ -135,6 +136,19 @@
- 	fend = faddr + smu->cmd_buf->length + 2;
- 	flush_inval_dcache_range(faddr, fend);
- 
-+
-+	/* We also disable NAP mode for the duration of the command
-+	 * on U3 based machines.
-+	 * This is slightly racy as it can be written back to 1 by a sysctl
-+	 * but that never happens in practice. There seem to be an issue with
-+	 * U3 based machines such as the iMac G5 where napping for the
-+	 * whole duration of the command prevents the SMU from fetching it
-+	 * from memory. This might be related to the strange i2c based
-+	 * mechanism the SMU uses to access memory.
-+	 */
-+	if (smu->broken_nap)
-+		powersave_nap = 0;
-+
- 	/* This isn't exactly a DMA mapping here, I suspect
- 	 * the SMU is actually communicating with us via i2c to the
- 	 * northbridge or the CPU to access RAM.
-@@ -211,6 +225,10 @@
- 	misc = cmd->misc;
- 	mb();
- 	cmd->status = rc;
-+
-+	/* Re-enable NAP mode */
-+	if (smu->broken_nap)
-+		powersave_nap = 1;
-  bail:
- 	/* Start next command if any */
- 	smu_start_cmd();
-@@ -461,7 +479,7 @@
-         if (np == NULL)
- 		return -ENODEV;
- 
--	printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR);
-+	printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR);
- 
- 	if (smu_cmdbuf_abs == 0) {
- 		printk(KERN_ERR "SMU: Command buffer not allocated !\n");
-@@ -533,6 +551,11 @@
- 		goto fail;
- 	}
- 
-+	/* U3 has an issue with NAP mode when issuing SMU commands */
-+	smu->broken_nap = pmac_get_uninorth_variant() < 4;
-+	if (smu->broken_nap)
-+		printk(KERN_INFO "SMU: using NAP mode workaround\n");
-+
- 	sys_ctrler = SYS_CTRLER_SMU;
- 	return 0;
- 
-diff -Nurd linux-2.6.24/drivers/md/Kconfig linux-2.6.24-oxe810/drivers/md/Kconfig
---- linux-2.6.24/drivers/md/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/Kconfig	2008-06-11 17:50:20.000000000 +0200
-@@ -229,6 +229,22 @@
- 
- 	  If unsure, say N.
- 
-+config DM_OX_CRYPT
-+	tristate "OX800 Hardware Cryptograpy target support"
-+	depends on BLK_DEV_DM && EXPERIMENTAL && CRYPTO_OXAESLRW
-+	---help---
-+      Based on dm-crypt by Fruhwirth & Saout it has been modified
-+      to work with the LRW-AES core in the OX800 NAS chip from
-+      Oxford Semiconductor Ltd.
-+      
-+	  This device-mapper target allows you to create a device that
-+	  transparently encrypts the data on it.
-+      
-+	  To compile this code as a module, choose M here: the module will
-+	  be called dm-ox-crypt.
-+
-+	  If unsure, say N.
-+
- config DM_SNAPSHOT
-        tristate "Snapshot target (EXPERIMENTAL)"
-        depends on BLK_DEV_DM && EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/md/Makefile linux-2.6.24-oxe810/drivers/md/Makefile
---- linux-2.6.24/drivers/md/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/Makefile	2008-06-11 17:50:20.000000000 +0200
-@@ -33,6 +33,7 @@
- obj-$(CONFIG_BLK_DEV_MD)	+= md-mod.o
- obj-$(CONFIG_BLK_DEV_DM)	+= dm-mod.o
- obj-$(CONFIG_DM_CRYPT)		+= dm-crypt.o
-+obj-$(CONFIG_DM_OX_CRYPT)   += dm-ox-crypt.o
- obj-$(CONFIG_DM_DELAY)		+= dm-delay.o
- obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
- obj-$(CONFIG_DM_MULTIPATH_EMC)	+= dm-emc.o
-diff -Nurd linux-2.6.24/drivers/md/dm-ox-crypt.c linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c
---- linux-2.6.24/drivers/md/dm-ox-crypt.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c	2008-06-11 17:50:20.000000000 +0200
-@@ -0,0 +1,791 @@
-+/* linux/drivers/md/dm-ox-crypt.c
-+ *
-+ * OX800 DPE core compatable device encryption 
-+ */
-+
-+/*
-+ * Copyright (C) 2003 Christophe Saout <christophe at saout.de>
-+ * Copyright (C) 2004 Clemens Fruhwirth <clemens at endorphin.org>
-+ *
-+ * This file is released under the GPL.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/bio.h>
-+#include <linux/blkdev.h>
-+#include <linux/mempool.h>
-+#include <linux/slab.h>
-+#include <linux/crypto.h>
-+#include <linux/workqueue.h>
-+#include <asm/atomic.h>
-+#include <asm/scatterlist.h>
-+#include <asm/page.h>
-+#include <asm/arch/cipher.h>
-+
-+#include "dm.h"
-+
-+#define DM_MSG_PREFIX "ox-crypt: "
-+
-+/*
-+ * per bio private data
-+ */
-+struct oxcrypt_io {
-+	struct dm_target *target;
-+	struct bio *bio;
-+	struct bio *first_clone;
-+	struct work_struct work;
-+	atomic_t pending;
-+	int error;
-+};
-+
-+/*
-+ * context holding the current state of a multi-part conversion
-+ */
-+struct convert_context {
-+	struct bio *bio_in;
-+	struct bio *bio_out;
-+	unsigned int offset_in;
-+	unsigned int offset_out;
-+	unsigned int idx_in;
-+	unsigned int idx_out;
-+	sector_t sector;
-+	int write;
-+};
-+
-+struct oxcrypt_config;
-+
-+struct oxcrypt_iv_operations {
-+	int (*ctr)(struct oxcrypt_config *cc, struct dm_target *ti,
-+	           const char *opts);
-+	void (*dtr)(struct oxcrypt_config *cc);
-+	const char *(*status)(struct oxcrypt_config *cc);
-+	int (*generator)(struct oxcrypt_config *cc, u8 *iv, sector_t sector);
-+};
-+
-+/*
-+ * Crypt: maps a linear range of a block device
-+ * and encrypts / decrypts at the same time.
-+ */
-+
-+struct oxcrypt_config {
-+	struct dm_dev *dev;
-+	sector_t start;
-+
-+	/*
-+	 * pool for per bio private data and
-+	 * for encryption buffer pages
-+	 */
-+	mempool_t *io_pool;
-+	mempool_t *page_pool;
-+
-+	/*
-+	 * crypto related data
-+	 */
-+	struct oxcrypt_iv_operations *iv_gen_ops;
-+	void *iv_gen_private;
-+	sector_t iv_offset;
-+	unsigned int iv_size;
-+
-+	struct crypto_tfm *tfm;
-+	u8 key[OX800DPE_KEYSIZE]; /* size of key is fixed by hardware */
-+    u8 iv_key[OX800DPE_KEYSIZE];
-+};
-+
-+#define MIN_IOS        256
-+#define MIN_POOL_PAGES 32
-+#define MIN_BIO_PAGES  8
-+
-+static struct kmem_cache *_oxcrypt_io_pool;
-+
-+/*
-+ * Mempool alloc and free functions for the page
-+ */
-+static void *mempool_alloc_page(gfp_t gfp_mask, void *data)
-+{
-+	return alloc_page(gfp_mask);
-+}
-+
-+static void mempool_free_page(void *page, void *data)
-+{
-+	__free_page(page);
-+}
-+
-+
-+/*
-+ * Different IV generation algorithms:
-+ *
-+ * oxsemi:
-+ *        Uses the 32 sector number and a reproducable hash of target device
-+ *        properties to generate bits 35-32
-+ *
-+ */
-+
-+static int oxcrypt_iv_oxsemi_gen(struct oxcrypt_config *cc, u8 *iv, sector_t sector)
-+{
-+	*((u32* )iv) = cpu_to_le32(sector & 0xffffffff);
-+    *( ((u32* )iv) + 1) = 0; /** @todo bits 35 - 32 */
-+
-+	return 0;
-+}
-+
-+static struct oxcrypt_iv_operations oxcrypt_iv_oxsemi_ops = {
-+	.generator = oxcrypt_iv_oxsemi_gen
-+};
-+
-+
-+/*static inline*/ int
-+oxcrypt_convert_scatterlist(struct oxcrypt_config *cc, struct scatterlist *out,
-+                          struct scatterlist *in, unsigned int length,
-+                          int write, sector_t sector)
-+{
-+	u8 iv[OX800DPE_KEYSIZE];
-+	int r = 0;
-+
-+	if (cc->iv_gen_ops) { /* probably no need to check this */
-+        u8* pri = cc->key;
-+        u8* twe = cc->iv_key;
-+
-+		r = cc->iv_gen_ops->generator(cc, iv, sector);
-+		if (r < 0)
-+			return r;
-+
-+		if (write)
-+			r = ox800_aeslrw_encrypt(in, out, 1, iv, pri, twe);
-+		else
-+			r = ox800_aeslrw_decrypt(in, out, 1, iv, pri, twe);
-+	} else {
-+        BUG();
-+	}
-+
-+    //printk("back\n");
-+    if (r < 0) {
-+        printk(KERN_ERR"oxcrypt_convert_scatterlist: core driver returned error %d\n",r);
-+    }
-+    
-+	return r;
-+}
-+
-+static void
-+oxcrypt_convert_init(struct oxcrypt_config *cc, struct convert_context *ctx,
-+                   struct bio *bio_out, struct bio *bio_in,
-+                   sector_t sector, int write)
-+{
-+	ctx->bio_in = bio_in;
-+	ctx->bio_out = bio_out;
-+	ctx->offset_in = 0;
-+	ctx->offset_out = 0;
-+	ctx->idx_in = bio_in ? bio_in->bi_idx : 0;
-+	ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
-+	ctx->sector = sector + cc->iv_offset;
-+	ctx->write = write;
-+}
-+
-+/**
-+ * Encrypt / decrypt data from one bio to another one (can be the same one)
-+ *
-+ * @todo This only goes atr one sector at a time, could it be made to this in
-+ * a scatter gather list of multiple sectors? 
-+ */
-+static int oxcrypt_convert(struct oxcrypt_config *cc,
-+                         struct convert_context *ctx)
-+{
-+	int r = 0;
-+    struct bio_vec *bv_in ;
-+    struct bio_vec *bv_out ;
-+    struct scatterlist sg_in;
-+    struct scatterlist sg_out;
-+    
-+    //printk("oxcrypt_convert config %p context %p \n", cc, ctx);
-+
-+	while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
-+	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
-+
-+        bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
-+        bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-+        
-+        sg_in.page = bv_in->bv_page;
-+        sg_in.offset = bv_in->bv_offset + ctx->offset_in;
-+        sg_in.length = 1 << SECTOR_SHIFT;
-+        
-+        sg_out.page = bv_out->bv_page;
-+        sg_out.offset = bv_out->bv_offset + ctx->offset_out;
-+        sg_out.length = 1 << SECTOR_SHIFT;
-+        
-+		ctx->offset_in += sg_in.length;
-+		if (ctx->offset_in >= bv_in->bv_len) {
-+			ctx->offset_in = 0;
-+			ctx->idx_in++;
-+		}
-+
-+		ctx->offset_out += sg_out.length;
-+		if (ctx->offset_out >= bv_out->bv_len) {
-+			ctx->offset_out = 0;
-+			ctx->idx_out++;
-+		}
-+
-+		r = oxcrypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
-+		                              ctx->write, ctx->sector);
-+		if (r < 0)
-+			break;
-+
-+		ctx->sector++;
-+	}
-+
-+	return r;
-+}
-+
-+/*
-+ * Generate a new unfragmented bio with the given size
-+ * This should never violate the device limitations
-+ * May return a smaller bio when running out of pages
-+ */
-+static struct bio *
-+oxcrypt_alloc_buffer(struct oxcrypt_config *cc, unsigned int size,
-+                   struct bio *base_bio, unsigned int *bio_vec_idx)
-+{
-+	struct bio *bio;
-+	unsigned int nr_iovecs = dm_div_up(size, PAGE_SIZE);
-+	int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
-+	unsigned long flags = current->flags;
-+	unsigned int i;
-+
-+	/*
-+	 * Tell VM to act less aggressively and fail earlier.
-+	 * This is not necessary but increases throughput.
-+	 * FIXME: Is this really intelligent?
-+	 */
-+	current->flags &= ~PF_MEMALLOC;
-+
-+	if (base_bio)
-+		bio = bio_clone(base_bio, GFP_NOIO);
-+	else
-+		bio = bio_alloc(GFP_NOIO, nr_iovecs);
-+	if (!bio) {
-+		if (flags & PF_MEMALLOC)
-+			current->flags |= PF_MEMALLOC;
-+		return NULL;
-+	}
-+
-+	/* if the last bio was not complete, continue where that one ended */
-+	bio->bi_idx = *bio_vec_idx;
-+	bio->bi_vcnt = *bio_vec_idx;
-+	bio->bi_size = 0;
-+	bio->bi_flags &= ~(1 << BIO_SEG_VALID);
-+
-+	/* bio->bi_idx pages have already been allocated */
-+	size -= bio->bi_idx * PAGE_SIZE;
-+
-+	for(i = bio->bi_idx; i < nr_iovecs; i++) {
-+		struct bio_vec *bv = bio_iovec_idx(bio, i);
-+
-+		bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
-+		if (!bv->bv_page)
-+			break;
-+
-+		/*
-+		 * if additional pages cannot be allocated without waiting,
-+		 * return a partially allocated bio, the caller will then try
-+		 * to allocate additional bios while submitting this partial bio
-+		 */
-+		if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
-+			gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
-+
-+		bv->bv_offset = 0;
-+		if (size > PAGE_SIZE)
-+			bv->bv_len = PAGE_SIZE;
-+		else
-+			bv->bv_len = size;
-+
-+		bio->bi_size += bv->bv_len;
-+		bio->bi_vcnt++;
-+		size -= bv->bv_len;
-+	}
-+
-+	if (flags & PF_MEMALLOC)
-+		current->flags |= PF_MEMALLOC;
-+
-+	if (!bio->bi_size) {
-+		bio_put(bio);
-+		return NULL;
-+	}
-+
-+	/*
-+	 * Remember the last bio_vec allocated to be able
-+	 * to correctly continue after the splitting.
-+	 */
-+	*bio_vec_idx = bio->bi_vcnt;
-+
-+	return bio;
-+}
-+
-+static void oxcrypt_free_buffer_pages(struct oxcrypt_config *cc,
-+                                    struct bio *bio, unsigned int bytes)
-+{
-+	unsigned int i, start, end;
-+	struct bio_vec *bv;
-+
-+	/*
-+	 * This is ugly, but Jens Axboe thinks that using bi_idx in the
-+	 * endio function is too dangerous at the moment, so I calculate the
-+	 * correct position using bi_vcnt and bi_size.
-+	 * The bv_offset and bv_len fields might already be modified but we
-+	 * know that we always allocated whole pages.
-+	 * A fix to the bi_idx issue in the kernel is in the works, so
-+	 * we will hopefully be able to revert to the cleaner solution soon.
-+	 */
-+	i = bio->bi_vcnt - 1;
-+	bv = bio_iovec_idx(bio, i);
-+	end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
-+	start = end - bytes;
-+
-+	start >>= PAGE_SHIFT;
-+	if (!bio->bi_size)
-+		end = bio->bi_vcnt;
-+	else
-+		end >>= PAGE_SHIFT;
-+
-+	for(i = start; i < end; i++) {
-+		bv = bio_iovec_idx(bio, i);
-+		BUG_ON(!bv->bv_page);
-+		mempool_free(bv->bv_page, cc->page_pool);
-+		bv->bv_page = NULL;
-+	}
-+}
-+
-+/*
-+ * One of the bios was finished. Check for completion of
-+ * the whole request and correctly clean up the buffer.
-+ */
-+static void dec_pending(struct oxcrypt_io *io, int error)
-+{
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+
-+	if (error < 0)
-+		io->error = error;
-+
-+	if (!atomic_dec_and_test(&io->pending))
-+		return;
-+
-+	if (io->first_clone)
-+		bio_put(io->first_clone);
-+
-+	bio_endio(io->bio, io->bio->bi_size, io->error);
-+
-+	mempool_free(io, cc->io_pool);
-+}
-+
-+/*
-+ * kcryptd:
-+ *
-+ * Needed because it would be very unwise to do decryption in an
-+ * interrupt context, so bios returning from read requests get
-+ * queued here.
-+ */
-+static struct workqueue_struct *_kcryptd_workqueue;
-+
-+static void kcryptd_do_work(struct work_struct *work)
-+{
-+	struct oxcrypt_io *io = container_of(work, struct oxcrypt_io, work);
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+	struct convert_context ctx;
-+	int r;
-+
-+	oxcrypt_convert_init(cc, &ctx, io->bio, io->bio,
-+	                   io->bio->bi_sector - io->target->begin, 0);
-+
-+    /* printk("kcryptd_do_work %d sectors\n", ctx.bio_in->bi_vcnt ); */
-+	r = oxcrypt_convert(cc, &ctx);
-+
-+	dec_pending(io, r);
-+}
-+
-+static void kcryptd_queue_io(struct oxcrypt_io *io)
-+{
-+	INIT_WORK(&io->work, kcryptd_do_work);
-+	queue_work(_kcryptd_workqueue, &io->work);
-+}
-+
-+/*
-+ * Decode key from its hex representation
-+ */
-+static int oxcrypt_decode_key(u8 *key, char *hex, unsigned int size)
-+{
-+	char buffer[3];
-+	char *endp;
-+	unsigned int i;
-+
-+	buffer[2] = '\0';
-+
-+	for(i = 0; i < size; i++) {
-+		buffer[0] = *hex++;
-+		buffer[1] = *hex++;
-+        key[i] = (u8)simple_strtoul(buffer, &endp, 16);
-+
-+		if (endp != &buffer[2])
-+			return -EINVAL;
-+	}
-+
-+	if (*hex != '\0')
-+		return -EINVAL;
-+
-+    /*
-+    printk(KERN_INFO"key ="); 
-+    for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+        printk("%02x", key[i]);
-+    printk("\n");
-+    */
-+    
-+	return 0;
-+}
-+
-+/*
-+ * Encode key into its hex representation
-+ */
-+static void oxcrypt_encode_key(char *hex, u8 *key, unsigned int size)
-+{
-+	unsigned int i;
-+
-+	for(i = 0; i < size; i++) {
-+		sprintf(hex, "%02x", *key);
-+		hex += 2;
-+		key++;
-+	}
-+}
-+
-+/*
-+ * Construct an encryption mapping, much simpler:
-+ * <key> <iv-key> <iv_offset> <dev_path> <start>
-+ */
-+static int oxcrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
-+{
-+	struct oxcrypt_config *cc;
-+	unsigned long long tmpll;
-+
-+	if (argc != 5) {
-+		ti->error = DM_MSG_PREFIX "Not enough arguments";
-+		return -EINVAL;
-+	}
-+
-+	cc = kmalloc(sizeof(*cc) , GFP_KERNEL);
-+	if (cc == NULL) {
-+		ti->error =
-+			DM_MSG_PREFIX "Cannot allocate transparent encryption context";
-+		return -ENOMEM;
-+	}
-+
-+    memset( cc, 0, sizeof(*cc) );
-+
-+	if (oxcrypt_decode_key(cc->key, argv[0], OX800DPE_KEYSIZE) < 0) {
-+		ti->error = DM_MSG_PREFIX "Error decoding key";
-+		goto bad1;
-+	}
-+
-+	if (oxcrypt_decode_key(cc->iv_key, argv[1], OX800DPE_KEYSIZE) < 0) {
-+		ti->error = DM_MSG_PREFIX "Error decoding iv key";
-+		goto bad1;
-+	}
-+    
-+    /*
-+     * Force the ivmode to the ox-semi version
-+     */
-+	cc->iv_gen_ops = &oxcrypt_iv_oxsemi_ops;
-+
-+	cc->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
-+				     mempool_free_slab, _oxcrypt_io_pool);
-+	if (!cc->io_pool) {
-+		ti->error = DM_MSG_PREFIX "Cannot allocate crypt io mempool";
-+		goto bad3;
-+	}
-+
-+	cc->page_pool = mempool_create(MIN_POOL_PAGES, mempool_alloc_page,
-+				       mempool_free_page, NULL);
-+	if (!cc->page_pool) {
-+		ti->error = DM_MSG_PREFIX "Cannot allocate page mempool";
-+		goto bad4;
-+	}
-+
-+	if (sscanf(argv[2], "%llu", &tmpll) != 1) {
-+		ti->error = DM_MSG_PREFIX "Invalid iv_offset sector";
-+		goto bad5;
-+	}
-+	cc->iv_offset = tmpll;
-+
-+	if (sscanf(argv[4], "%llu", &tmpll) != 1) {
-+		ti->error = DM_MSG_PREFIX "Invalid device sector";
-+		goto bad5;
-+	}
-+	cc->start = tmpll;
-+
-+	if (dm_get_device(ti, argv[3], cc->start, ti->len,
-+	                  dm_table_get_mode(ti->table), &cc->dev)) {
-+		ti->error = DM_MSG_PREFIX "Device lookup failed";
-+		goto bad5;
-+	}
-+
-+
-+	ti->private = cc;
-+
-+	return 0;
-+
-+bad5:
-+	mempool_destroy(cc->page_pool);
-+bad4:
-+	mempool_destroy(cc->io_pool);
-+bad3:
-+	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
-+		cc->iv_gen_ops->dtr(cc);
-+bad1:
-+	kfree(cc);
-+	return -EINVAL;
-+}
-+
-+static void oxcrypt_dtr(struct dm_target *ti)
-+{
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+
-+	mempool_destroy(cc->page_pool);
-+	mempool_destroy(cc->io_pool);
-+
-+	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
-+		cc->iv_gen_ops->dtr(cc);
-+	dm_put_device(ti, cc->dev);
-+    
-+	kfree(cc);
-+}
-+
-+static int oxcrypt_endio(struct bio *bio, unsigned int done, int error)
-+{
-+	struct oxcrypt_io *io = (struct oxcrypt_io *) bio->bi_private;
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+
-+	if (bio_data_dir(bio) == WRITE) {
-+		/*
-+		 * free the processed pages, even if
-+		 * it's only a partially completed write
-+		 */
-+		oxcrypt_free_buffer_pages(cc, bio, done);
-+	}
-+
-+	if (bio->bi_size)
-+		return 1;
-+
-+	bio_put(bio);
-+
-+	/*
-+	 * successful reads are decrypted by the worker thread
-+	 */
-+	if ((bio_data_dir(bio) == READ)
-+	    && bio_flagged(bio, BIO_UPTODATE)) {
-+		kcryptd_queue_io(io);
-+		return 0;
-+	}
-+
-+	dec_pending(io, error);
-+	return error;
-+}
-+
-+static struct bio *
-+oxcrypt_clone(struct oxcrypt_config *cc, struct oxcrypt_io *io, struct bio *bio,
-+            sector_t sector, unsigned int *bvec_idx,
-+            struct convert_context *ctx)
-+{
-+	struct bio *clone;
-+
-+	if (bio_data_dir(bio) == WRITE) {
-+		clone = oxcrypt_alloc_buffer(cc, bio->bi_size,
-+                                 io->first_clone, bvec_idx);
-+		if (clone) {
-+			ctx->bio_out = clone;
-+			if (oxcrypt_convert(cc, ctx) < 0) {
-+				oxcrypt_free_buffer_pages(cc, clone,
-+				                        clone->bi_size);
-+				bio_put(clone);
-+				return NULL;
-+			}
-+		}
-+	} else {
-+		/*
-+		 * The block layer might modify the bvec array, so always
-+		 * copy the required bvecs because we need the original
-+		 * one in order to decrypt the whole bio data *afterwards*.
-+		 */
-+		clone = bio_alloc(GFP_NOIO, bio_segments(bio));
-+		if (clone) {
-+			clone->bi_idx = 0;
-+			clone->bi_vcnt = bio_segments(bio);
-+			clone->bi_size = bio->bi_size;
-+			memcpy(clone->bi_io_vec, bio_iovec(bio),
-+			       sizeof(struct bio_vec) * clone->bi_vcnt);
-+		}
-+	}
-+
-+	if (!clone)
-+		return NULL;
-+
-+	clone->bi_private = io;
-+	clone->bi_end_io = oxcrypt_endio;
-+	clone->bi_bdev = cc->dev->bdev;
-+	clone->bi_sector = cc->start + sector;
-+	clone->bi_rw = bio->bi_rw;
-+
-+	return clone;
-+}
-+
-+static int oxcrypt_map(struct dm_target *ti, struct bio *bio,
-+		     union map_info *map_context)
-+{
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+	struct oxcrypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
-+	struct convert_context ctx;
-+	struct bio *clone;
-+	unsigned int remaining = bio->bi_size;
-+	sector_t sector = bio->bi_sector - ti->begin;
-+	unsigned int bvec_idx = 0;
-+
-+	io->target = ti;
-+	io->bio = bio;
-+	io->first_clone = NULL;
-+	io->error = 0;
-+	atomic_set(&io->pending, 1); /* hold a reference */
-+
-+	if (bio_data_dir(bio) == WRITE)
-+		oxcrypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
-+
-+	/*
-+	 * The allocated buffers can be smaller than the whole bio,
-+	 * so repeat the whole process until all the data can be handled.
-+	 */
-+	while (remaining) {
-+		clone = oxcrypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
-+		if (!clone)
-+			goto cleanup;
-+
-+		if (!io->first_clone) {
-+			/*
-+			 * hold a reference to the first clone, because it
-+			 * holds the bio_vec array and that can't be freed
-+			 * before all other clones are released
-+			 */
-+			bio_get(clone);
-+			io->first_clone = clone;
-+		}
-+		atomic_inc(&io->pending);
-+
-+		remaining -= clone->bi_size;
-+		sector += bio_sectors(clone);
-+
-+		generic_make_request(clone);
-+
-+		/* out of memory -> run queues */
-+		if (remaining)
-+			congestion_wait(bio_data_dir(clone), HZ/100);
-+	}
-+
-+	/* drop reference, clones could have returned before we reach this */
-+	dec_pending(io, 0);
-+	return 0;
-+
-+cleanup:
-+	if (io->first_clone) {
-+		dec_pending(io, -ENOMEM);
-+		return 0;
-+	}
-+
-+	/* if no bio has been dispatched yet, we can directly return the error */
-+	mempool_free(io, cc->io_pool);
-+	return -ENOMEM;
-+}
-+
-+static int oxcrypt_status(struct dm_target *ti, status_type_t type,
-+			char *result, unsigned int maxlen)
-+{
-+	struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+	char buffer[32];
-+	const char *cipher;
-+	const char *chainmode = NULL;
-+	unsigned int sz = 0;
-+
-+	switch (type) {
-+	case STATUSTYPE_INFO:
-+		result[0] = '\0';
-+		break;
-+
-+	case STATUSTYPE_TABLE:
-+		cipher = "AES";
-+
-+		chainmode = "ecb";
-+
-+        DMEMIT("%s-%s ", cipher, chainmode);
-+
-+        oxcrypt_encode_key(result + sz, cc->key, OX800DPE_KEYSIZE);
-+        sz += OX800DPE_KEYSIZE << 1;
-+
-+		format_dev_t(buffer, cc->dev->bdev->bd_dev);
-+		DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
-+            buffer, (unsigned long long)cc->start);
-+		break;
-+	}
-+	return 0;
-+}
-+
-+static struct target_type oxcrypt_target = {
-+	.name   = "ox-crypt",
-+	.version= {1, 1, 0},
-+	.module = THIS_MODULE,
-+	.ctr    = oxcrypt_ctr,
-+	.dtr    = oxcrypt_dtr,
-+	.map    = oxcrypt_map,
-+	.status = oxcrypt_status,
-+};
-+
-+static int __init dm_oxcrypt_init(void)
-+{
-+	int r;
-+
-+	_oxcrypt_io_pool = kmem_cache_create("dm-ox-oxcrypt_io",
-+	                                   sizeof(struct oxcrypt_io),
-+	                                   0, 0, NULL);
-+	if (!_oxcrypt_io_pool)
-+		return -ENOMEM;
-+
-+	_kcryptd_workqueue = create_workqueue("kcryptd");
-+	if (!_kcryptd_workqueue) {
-+		r = -ENOMEM;
-+		DMERR("couldn't create kcryptd");
-+		goto bad1;
-+	}
-+
-+	r = dm_register_target(&oxcrypt_target);
-+	if (r < 0) {
-+		DMERR("register failed %d", r);
-+		goto bad2;
-+	}
-+
-+	return 0;
-+
-+bad2:
-+	destroy_workqueue(_kcryptd_workqueue);
-+bad1:
-+	kmem_cache_destroy(_oxcrypt_io_pool);
-+	return r;
-+}
-+
-+static void __exit dm_oxcrypt_exit(void)
-+{
-+	int r = dm_unregister_target(&oxcrypt_target);
-+
-+	if (r < 0)
-+		DMERR("unregister failed %d", r);
-+
-+	destroy_workqueue(_kcryptd_workqueue);
-+	kmem_cache_destroy(_oxcrypt_io_pool);
-+}
-+
-+module_init(dm_oxcrypt_init);
-+module_exit(dm_oxcrypt_exit);
-+
-+MODULE_AUTHOR("Oxford Semiconductor based on work of Christophe Saout");
-+MODULE_DESCRIPTION(DM_NAME " target for hardware encryption / decryption");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/drivers/md/raid1.c linux-2.6.24-oxe810/drivers/md/raid1.c
---- linux-2.6.24/drivers/md/raid1.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/raid1.c	2008-06-11 17:50:20.000000000 +0200
-@@ -34,6 +34,12 @@
- #include "dm-bio-list.h"
- #include <linux/raid/raid1.h>
- #include <linux/raid/bitmap.h>
-+#ifdef CONFIG_SATA_OX800
-+#include <asm/arch/sata.h>
-+#endif
-+#ifdef CONFIG_SATA_OX810
-+#include <asm/arch/ox810sata.h>
-+#endif
- 
- #define DEBUG 0
- #if DEBUG
-@@ -67,6 +73,79 @@
- 	return r1_bio;
- }
- 
-+/**
-+ * Assesses if the current raid configuration is suitable for implementation
-+ * by the raid HW, if so, will enable it 
-+ */
-+static void raid1_hw_raidable(mddev_t *mddev)
-+{
-+    mdk_rdev_t *rdev0;
-+    mdk_rdev_t *rdev1;
-+    conf_t *conf = mddev_to_conf(mddev);
-+
-+    /*default to SW RAID */
-+    conf->hw_raid1_settings = 0;
-+
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+    /* if this drive is suitable for HW raid then enable it */
-+    if (mddev->raid_disks != 2) {
-+        printk(KERN_NOTICE"raid1 not hw raidable %d disks (needs to be 2)\n",mddev->raid_disks);
-+        return;
-+    }
-+    
-+    rdev0 = rcu_dereference(conf->mirrors[0].rdev);
-+    rdev1 = rcu_dereference(conf->mirrors[1].rdev);
-+    
-+    /* are there two working disks */
-+    if (!rdev0 ||
-+        !rdev1 ||
-+        test_bit(Faulty, &rdev0->flags) ||
-+        test_bit(Faulty, &rdev1->flags) ) {
-+        printk(KERN_NOTICE"raid1 not hw raidable, needs two working disks.\n");
-+        return;
-+    }
-+    
-+    if (!rdev0->bdev ||
-+        !rdev1->bdev ||
-+        !rdev0->bdev->bd_part ||
-+        !rdev1->bdev->bd_part ) {
-+        printk(KERN_NOTICE"raid1 not hw raidable, mirrors not ready\n");
-+        return;
-+	}
-+	
-+	if (rdev0->bdev->bd_part->start_sect != 
-+        rdev1->bdev->bd_part->start_sect) {
-+        printk(KERN_NOTICE"raid1 not hw raidable, partition start sectors differ %lu, %lu\n",
-+            rdev0->bdev->bd_part->start_sect,
-+            rdev1->bdev->bd_part->start_sect);
-+        return;
-+    }
-+
-+    if (!rdev0->bdev->bd_disk || 
-+		!rdev0->bdev->bd_disk->queue ||
-+		(oxnassata_get_port_no(rdev0->bdev->bd_disk->queue) < 0)) {
-+        printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 0 not on internal SATA port.\n"); 
-+        return;
-+    }
-+
-+    if (!rdev1->bdev->bd_disk || 
-+		!rdev1->bdev->bd_disk->queue ||
-+		(oxnassata_get_port_no(rdev1->bdev->bd_disk->queue) < 0)) {
-+        printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 1 not on internal SATA port.\n"); 
-+        return;
-+    }
-+
-+	/* cannot mix 28 and 48-bit LBA devices */    
-+	if (!oxnassata_LBA_schemes_compatible()) {
-+        printk(KERN_NOTICE"raid0 not hw raidable, disks need to use same LBA size (28 vs 48)\n"); 
-+		return;
-+	}
-+
-+    conf->hw_raid1_settings = OXNASSATA_RAID1;
-+    printk(KERN_NOTICE"raid1 using hardware RAID 0x%08x\n",conf->hw_raid1_settings);
-+#endif /*CONFIG_SCSI_OX800SATA*/
-+}
-+
- static void r1bio_pool_free(void *r1_bio, void *data)
- {
- 	kfree(r1_bio);
-@@ -325,9 +404,29 @@
- 		r1_bio->bios[mirror] = NULL;
- 		to_put = bio;
- 		if (!uptodate) {
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+            if ((mirror == 0) && (bio->bi_raid)) {
-+                /* command was sent to part 0 for both drives, need to find 
-+                * which drive caused the error */
-+                int device = oxnassata_RAID_faults();
-+
-+                /* it's unlikely, but both disks could fail at once */
-+                if (device & 1) md_error(r1_bio->mddev, conf->mirrors[0].rdev);
-+                if (device & 2) md_error(r1_bio->mddev, conf->mirrors[1].rdev);
-+
-+                /* an I/O failed, we can't clear the bitmap */
-+                set_bit(R1BIO_Degraded, &r1_bio->state);
-+                
-+                if (!(device & 3)) 
-+                    set_bit(R1BIO_Uptodate, &r1_bio->state);
-+            } else {
-+#endif // CONFIG_SCSI_OX800SATA
- 			md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
- 			/* an I/O failed, we can't clear the bitmap */
- 			set_bit(R1BIO_Degraded, &r1_bio->state);
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+            }
-+#endif // CONFIG_SCSI_OX800SATA
- 		} else
- 			/*
- 			 * Set R1BIO_Uptodate in our master bio, so that
-@@ -824,6 +923,53 @@
- 	}
- #endif
- 	rcu_read_lock();
-+
-+    /* start of oxsemi hw raid code */
-+    if ((rcu_dereference(conf->mirrors[0].rdev)) &&
-+        (rcu_dereference(conf->mirrors[1].rdev)) &&
-+        !test_bit(Faulty, &rcu_dereference(conf->mirrors[0].rdev)->flags) &&
-+        !test_bit(Faulty, &rcu_dereference(conf->mirrors[1].rdev)->flags) &&
-+        (conf->hw_raid1_settings) )
-+    {
-+        struct bio *mbio;
-+
-+        rdev = rcu_dereference(conf->mirrors[0].rdev);
-+        atomic_inc(&rdev->nr_pending);
-+        r1_bio->bios[0] = bio;
-+        targets++;
-+
-+        rcu_read_unlock();
-+
-+        /* do behind I/O ? */
-+        if (bitmap &&
-+            atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind &&
-+            (behind_pages = alloc_behind_pages(bio)) != NULL)
-+            set_bit(R1BIO_BehindIO, &r1_bio->state);
-+
-+        atomic_set(&r1_bio->remaining, 0);
-+        atomic_set(&r1_bio->behind_remaining, 0);
-+
-+        do_barriers = bio_barrier(bio);
-+        if (do_barriers)
-+            set_bit(R1BIO_Barrier, &r1_bio->state);
-+
-+        bio_list_init(&bl);
-+
-+        mbio = bio_clone(bio, GFP_NOIO);
-+        r1_bio->bios[0] = mbio;
-+
-+        mbio->bi_sector	= r1_bio->sector + conf->mirrors[0].rdev->data_offset;
-+        mbio->bi_bdev = conf->mirrors[0].rdev->bdev;
-+        mbio->bi_end_io	= raid1_end_write_request;
-+        mbio->bi_rw = WRITE | do_barriers | do_sync;
-+        mbio->bi_private = r1_bio;
-+        mbio->bi_raid = conf->hw_raid1_settings ;
-+
-+        atomic_inc(&r1_bio->remaining);
-+
-+        bio_list_add(&bl, mbio);
-+        /* end of hw_raid code */
-+    } else {
- 	for (i = 0;  i < disks; i++) {
- 		if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
- 		    !test_bit(Faulty, &rdev->flags)) {
-@@ -896,6 +1042,8 @@
- 
- 		bio_list_add(&bl, mbio);
- 	}
-+    }
-+    
- 	kfree(behind_pages); /* the behind pages are attached to the bios now */
- 
- 	bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
-@@ -969,6 +1117,9 @@
- 	printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
- 		"	Operation continuing on %d devices\n",
- 		bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
-+
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
- }
- 
- static void print_conf(conf_t *conf)
-@@ -1027,6 +1178,9 @@
- 		}
- 	}
- 
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
-+
- 	print_conf(conf);
- 	return 0;
- }
-@@ -1064,6 +1218,9 @@
- 			break;
- 		}
- 
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
-+
- 	print_conf(conf);
- 	return found;
- }
-@@ -1092,6 +1249,8 @@
- 		}
- 	}
- abort:
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
- 
- 	print_conf(conf);
- 	return err;
-@@ -1719,6 +1878,7 @@
- 		bio->bi_size = 0;
- 		bio->bi_end_io = NULL;
- 		bio->bi_private = NULL;
-+        bio->bi_raid = 0;
- 
- 		rdev = rcu_dereference(conf->mirrors[i].rdev);
- 		if (rdev == NULL ||
-@@ -1966,6 +2126,9 @@
- 	 */
- 	mddev->array_size = mddev->size;
- 
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
-+
- 	mddev->queue->unplug_fn = raid1_unplug;
- 	mddev->queue->backing_dev_info.congested_fn = raid1_congested;
- 	mddev->queue->backing_dev_info.congested_data = mddev;
-@@ -2035,6 +2198,9 @@
- 	}
- 	mddev->size = mddev->array_size;
- 	mddev->resync_max_sectors = sectors;
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
-+
- 	return 0;
- }
- 
-@@ -2138,6 +2304,9 @@
- 	mddev->delta_disks = 0;
- 
- 	conf->last_used = 0; /* just make sure it is in-range */
-+    /* check to see if this new configuration is supported by hardware RAID */
-+    raid1_hw_raidable(mddev);
-+
- 	lower_barrier(conf);
- 
- 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-diff -Nurd linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c
---- linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c	2008-06-11 17:48:59.000000000 +0200
-@@ -138,6 +138,10 @@
- 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
- 	},{
- 		.subvendor = 0x0070,
-+		.subdevice = 0x7809,
-+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
-+	},{
-+		.subvendor = 0x0070,
- 		.subdevice = 0x7911,
- 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1250,
- 	},{
-diff -Nurd linux-2.6.24/drivers/message/fusion/mptsas.c linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c
---- linux-2.6.24/drivers/message/fusion/mptsas.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c	2008-06-11 17:49:11.000000000 +0200
-@@ -1699,6 +1699,11 @@
- 	if (error)
- 		goto out_free_consistent;
- 
-+	if (!buffer->NumPhys) {
-+		error = -ENODEV;
-+		goto out_free_consistent;
-+	}
-+
- 	/* save config data */
- 	port_info->num_phys = buffer->NumPhys;
- 	port_info->phy_info = kcalloc(port_info->num_phys,
-diff -Nurd linux-2.6.24/drivers/net/Kconfig linux-2.6.24-oxe810/drivers/net/Kconfig
---- linux-2.6.24/drivers/net/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/Kconfig	2008-06-11 17:50:11.000000000 +0200
-@@ -2368,6 +2368,14 @@
- 	  To compile this driver as a module, choose M here.  The module
- 	  will be called atl1.
- 
-+config SYNOPSYS_GMAC
-+	tristate "Synopsys Gigabit MAC"
-+	select CRC32
-+	select MII
-+	depends on ARCH_OXNAS
-+	help
-+		Driver for the Synopsys Gigabit MAC
-+
- endif # NETDEV_1000
- 
- #
-diff -Nurd linux-2.6.24/drivers/net/bonding/bond_main.c linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c
---- linux-2.6.24/drivers/net/bonding/bond_main.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c	2008-06-11 17:50:00.000000000 +0200
-@@ -4883,14 +4883,16 @@
- 	down_write(&bonding_rwsem);
- 
- 	/* Check to see if the bond already exists. */
--	list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
--		if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
--			printk(KERN_ERR DRV_NAME
-+	if (name) {
-+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
-+			if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
-+				printk(KERN_ERR DRV_NAME
- 			       ": cannot add bond %s; it already exists\n",
--			       name);
--			res = -EPERM;
--			goto out_rtnl;
--		}
-+				       name);
-+				res = -EPERM;
-+				goto out_rtnl;
-+			}
-+	}
- 
- 	bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
- 				ether_setup);
-diff -Nurd linux-2.6.24/drivers/net/dl2k.h linux-2.6.24-oxe810/drivers/net/dl2k.h
---- linux-2.6.24/drivers/net/dl2k.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/dl2k.h	2008-06-11 17:50:11.000000000 +0200
-@@ -388,8 +388,8 @@
- 	MII_MSSR_CFG_RES = 0x4000,
- 	MII_MSSR_LOCAL_RCV_STATUS = 0x2000,
- 	MII_MSSR_REMOTE_RCVR = 0x1000,
--	MII_MSSR_LP_1000BT_HD = 0x0800,
--	MII_MSSR_LP_1000BT_FD = 0x0400,
-+	MII_MSSR_LP_1000BT_FD = 0x0800,
-+	MII_MSSR_LP_1000BT_HD = 0x0400,
- 	MII_MSSR_IDLE_ERR_COUNT = 0x00ff,
- };
- 
-diff -Nurd linux-2.6.24/drivers/net/e1000e/netdev.c linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c
---- linux-2.6.24/drivers/net/e1000e/netdev.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c	2008-06-11 17:50:07.000000000 +0200
-@@ -1686,6 +1686,9 @@
- 	else
- 		rctl |= E1000_RCTL_LPE;
- 
-+	/* Enable hardware CRC frame stripping */
-+	rctl |= E1000_RCTL_SECRC;
-+
- 	/* Setup buffer sizes */
- 	rctl &= ~E1000_RCTL_SZ_4096;
- 	rctl |= E1000_RCTL_BSEX;
-@@ -1751,9 +1754,6 @@
- 
- 		/* Enable Packet split descriptors */
- 		rctl |= E1000_RCTL_DTYP_PS;
--		
--		/* Enable hardware CRC frame stripping */
--		rctl |= E1000_RCTL_SECRC;
- 
- 		psrctl |= adapter->rx_ps_bsize0 >>
- 			E1000_PSRCTL_BSIZE0_SHIFT;
-diff -Nurd linux-2.6.24/drivers/net/forcedeth.c linux-2.6.24-oxe810/drivers/net/forcedeth.c
---- linux-2.6.24/drivers/net/forcedeth.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/forcedeth.c	2008-06-11 17:50:11.000000000 +0200
-@@ -5593,35 +5593,35 @@
- 	},
- 	{	/* MCP77 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP77 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP77 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP77 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP79 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP79 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP79 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{	/* MCP79 Ethernet Controller */
- 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
--		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- 	},
- 	{0,},
- };
-diff -Nurd linux-2.6.24/drivers/net/macb.c linux-2.6.24-oxe810/drivers/net/macb.c
---- linux-2.6.24/drivers/net/macb.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/macb.c	2008-06-11 17:50:11.000000000 +0200
-@@ -148,7 +148,7 @@
- 
- 			if (phydev->duplex)
- 				reg |= MACB_BIT(FD);
--			if (phydev->speed)
-+			if (phydev->speed == SPEED_100)
- 				reg |= MACB_BIT(SPD);
- 
- 			macb_writel(bp, NCFGR, reg);
-diff -Nurd linux-2.6.24/drivers/net/mii.c linux-2.6.24-oxe810/drivers/net/mii.c
---- linux-2.6.24/drivers/net/mii.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/mii.c	2008-06-11 17:50:11.000000000 +0200
-@@ -46,11 +46,13 @@
- 	u32 advert, bmcr, lpa, nego;
- 	u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
- 
-+	int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
- 	ecmd->supported =
- 	    (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- 	     SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- 	     SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
--	if (mii->supports_gmii)
-+	if (supports_gmii)
- 		ecmd->supported |= SUPPORTED_1000baseT_Half |
- 			SUPPORTED_1000baseT_Full;
- 
-@@ -65,7 +67,7 @@
- 
- 	ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
- 	advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
--	if (mii->supports_gmii)
-+	if (supports_gmii)
- 		advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- 
- 	if (advert & ADVERTISE_10HALF)
-@@ -83,7 +85,7 @@
- 
- 	bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
- 	lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
--	if (mii->supports_gmii) {
-+	if (supports_gmii) {
- 		bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- 		lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
- 	}
-@@ -132,6 +134,8 @@
- {
- 	struct net_device *dev = mii->dev;
- 
-+	int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
- 	if (ecmd->speed != SPEED_10 &&
- 	    ecmd->speed != SPEED_100 &&
- 	    ecmd->speed != SPEED_1000)
-@@ -146,7 +150,7 @@
- 		return -EINVAL;
- 	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
- 		return -EINVAL;
--	if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
-+	if ((ecmd->speed == SPEED_1000) && (!supports_gmii))
- 		return -EINVAL;
- 
- 	/* ignore supported, maxtxpkt, maxrxpkt */
-@@ -166,7 +170,7 @@
- 		/* advertise only what has been requested */
- 		advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
- 		tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
--		if (mii->supports_gmii) {
-+		if (supports_gmii) {
- 			advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- 			tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
- 		}
-@@ -178,7 +182,7 @@
- 			tmp |= ADVERTISE_100HALF;
- 		if (ecmd->advertising & ADVERTISED_100baseT_Full)
- 			tmp |= ADVERTISE_100FULL;
--		if (mii->supports_gmii) {
-+		if (supports_gmii) {
- 			if (ecmd->advertising & ADVERTISED_1000baseT_Half)
- 				tmp2 |= ADVERTISE_1000HALF;
- 			if (ecmd->advertising & ADVERTISED_1000baseT_Full)
-@@ -188,7 +192,7 @@
- 			mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
- 			mii->advertising = tmp;
- 		}
--		if ((mii->supports_gmii) && (advert2 != tmp2))
-+		if (advert2 != tmp2)
- 			mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
- 
- 		/* turn on autonegotiation, and force a renegotiate */
-@@ -312,6 +316,7 @@
- 	unsigned int old_carrier, new_carrier;
- 	int advertise, lpa, media, duplex;
- 	int lpa2 = 0;
-+	int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
- 
- 	/* if forced media, go no further */
- 	if (mii->force_media)
-@@ -348,7 +353,7 @@
- 		mii->advertising = advertise;
- 	}
- 	lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
--	if (mii->supports_gmii)
-+	if (supports_gmii)
- 		lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
- 
- 	/* figure out media and duplex from advertise and LPA values */
-@@ -373,6 +378,148 @@
- 	return 0; /* duplex did not change */
- }
- 
-+
-+unsigned int mii_check_media_ex(
-+    struct mii_if_info *mii,
-+    unsigned int ok_to_print,
-+    unsigned int init_media,
-+    int *has_gigabit_changed,
-+	int *has_pause_changed,
-+	void (*link_state_change_callback)(int link_state, void* arg),
-+	void *link_state_change_arg)
-+{
-+	unsigned int old_carrier, new_carrier;
-+	int advertise, lpa;
-+	unsigned int negotiated_10_100;
-+	int advertise2 = 0, lpa2 = 0;
-+	unsigned int negotiated_1000;
-+	int duplex = 0;
-+	int using_100 = 0;
-+	int using_1000 = 0;
-+	int using_pause = 0;
-+	int duplex_changed = 0;
-+	int changed_100 = 0;
-+	int changed_1000 = 0;
-+	int changed_pause = 0;
-+	int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
-+    // Initialise user's locations for returned gigabit and pause changed values
-+	// to no-change
-+	*has_gigabit_changed = 0;
-+	*has_pause_changed = 0;
-+
-+	/* if forced media, go no further */
-+	if (mii->force_media)
-+		return 0; /* duplex did not change */
-+
-+	/* check current and old link status */
-+	old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
-+	new_carrier = (unsigned int) mii_link_ok(mii);
-+
-+	/* if carrier state did not change, this is a "bounce",
-+	 * just exit as everything is already set correctly
-+	 */
-+	if ((!init_media) && (old_carrier == new_carrier))
-+		return 0; /* duplex did not change */
-+
-+	/* no carrier, nothing much to do */
-+	if (!new_carrier) {
-+		netif_carrier_off(mii->dev);
-+		if (ok_to_print) {
-+			printk(KERN_INFO "%s: link down\n", mii->dev->name);
-+		}
-+		link_state_change_callback(0, link_state_change_arg);
-+		return 0; /* duplex did not change */
-+	}
-+
-+	/*
-+	 * we have carrier, see who's on the other end
-+	 */
-+	netif_carrier_on(mii->dev);
-+
-+	/* Get our advertise values */
-+	if ((!init_media) && (mii->advertising))
-+		advertise = mii->advertising;
-+	else {
-+		advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
-+		mii->advertising = advertise;
-+	}
-+//printk("mii_check_media_ex() MII_ADVERTISE read as 0x%08x\n", advertise);
-+	if (supports_gmii) {
-+		advertise2 = mii->mdio_read(mii->dev, mii->phy_id, MII_CTRL1000);
-+//printk("mii_check_media_ex() MII_CTRL1000 read as 0x%08x\n", advertise2);
-+	}
-+
-+	/* Get link partner advertise values */
-+	lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
-+//printk("mii_check_media_ex() MII_LPA read as 0x%08x\n", lpa);
-+	if (supports_gmii) {
-+		lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
-+//printk("mii_check_media_ex() MII_STAT1000 read as 0x%08x\n", lpa2);
-+	}
-+
-+//printk("Us pause = %d, async pause = %d\n", advertise & ADVERTISE_PAUSE_CAP, advertise & ADVERTISE_PAUSE_ASYM);
-+//printk("Link partner pause = %d, async pause = %d\n", lpa & LPA_PAUSE_CAP, lpa & LPA_PAUSE_ASYM);
-+
-+	/* Determine negotiated mode/duplex from our and link partner's advertise values */
-+	negotiated_10_100 = mii_nway_result(lpa & advertise);
-+	negotiated_1000   = mii_nway_result_1000(lpa2, advertise2);
-+
-+    /* Determine the rate we're operating at */
-+	if (negotiated_1000 & (LPA_1000FULL | LPA_1000HALF)) {
-+		using_1000 = 1;
-+		duplex = (negotiated_1000 & LPA_1000FULL) ? 1 : 0;
-+	} else {
-+		if (negotiated_10_100 & (LPA_100FULL | LPA_100HALF)) {
-+			using_100 = 1;
-+		}
-+		duplex = (negotiated_10_100 & ADVERTISE_FULL) ? 1 : 0;
-+	}
-+
-+	/* Does link partner advertise that we can send pause frames to it? */
-+	using_pause = (lpa & LPA_PAUSE_CAP) ? 1 : 0;
-+
-+	if (ok_to_print)
-+		printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, %s pause, lpa 0x%04X\n",
-+		       mii->dev->name,
-+		       using_1000 ? "1000" :
-+		       using_100 ? "100" : "10",
-+		       duplex ? "full" : "half",
-+			   using_pause ? "using" : "not using",
-+		       lpa);
-+
-+	link_state_change_callback(1, link_state_change_arg);
-+
-+    if (mii->full_duplex != duplex) {
-+        duplex_changed = 1;
-+    }
-+    if (mii->using_100 != using_100) {
-+        changed_100 = 1;
-+    }
-+    if (mii->using_1000 != using_1000) {
-+        changed_1000 = 1;
-+    }
-+    if (mii->using_pause != using_pause) {
-+        changed_pause = 1;
-+    }
-+
-+    if (init_media || changed_100 || changed_1000 || changed_pause || duplex_changed) {
-+        mii->full_duplex = duplex;
-+        mii->using_100   = using_100;
-+        mii->using_1000  = using_1000;
-+		mii->using_pause = using_pause;
-+        if (init_media || changed_1000) {
-+            *has_gigabit_changed = 1;
-+        }
-+        if (init_media || changed_pause) {
-+            *has_pause_changed = 1;
-+        }
-+        return init_media || duplex_changed;
-+    }
-+
-+	return 0; /* duplex did not change */
-+}
-+
- /**
-  * generic_mii_ioctl - main MII ioctl interface
-  * @mii_if: the MII interface
-@@ -465,6 +612,7 @@
- EXPORT_SYMBOL(mii_ethtool_sset);
- EXPORT_SYMBOL(mii_check_link);
- EXPORT_SYMBOL(mii_check_media);
-+EXPORT_SYMBOL(mii_check_media_ex);
- EXPORT_SYMBOL(mii_check_gmii_support);
- EXPORT_SYMBOL(generic_mii_ioctl);
- 
-diff -Nurd linux-2.6.24/drivers/net/niu.c linux-2.6.24-oxe810/drivers/net/niu.c
---- linux-2.6.24/drivers/net/niu.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/niu.c	2008-06-11 17:50:11.000000000 +0200
-@@ -33,8 +33,8 @@
- 
- #define DRV_MODULE_NAME		"niu"
- #define PFX DRV_MODULE_NAME	": "
--#define DRV_MODULE_VERSION	"0.6"
--#define DRV_MODULE_RELDATE	"January 5, 2008"
-+#define DRV_MODULE_VERSION	"0.7"
-+#define DRV_MODULE_RELDATE	"February 18, 2008"
- 
- static char version[] __devinitdata =
- 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-@@ -1616,12 +1616,13 @@
- 	if (index >= niu_num_alt_addr(np))
- 		return -EINVAL;
- 
--	if (np->flags & NIU_FLAGS_XMAC)
-+	if (np->flags & NIU_FLAGS_XMAC) {
- 		reg = XMAC_ADDR_CMPEN;
--	else
-+		mask = 1 << index;
-+	} else {
- 		reg = BMAC_ADDR_CMPEN;
--
--	mask = 1 << index;
-+		mask = 1 << (index + 1);
-+	}
- 
- 	val = nr64_mac(reg);
- 	if (on)
-@@ -5147,7 +5148,12 @@
- 			index++;
- 		}
- 	} else {
--		for (i = 0; i < niu_num_alt_addr(np); i++) {
-+		int alt_start;
-+		if (np->flags & NIU_FLAGS_XMAC)
-+			alt_start = 0;
-+		else
-+			alt_start = 1;
-+		for (i = alt_start; i < niu_num_alt_addr(np); i++) {
- 			err = niu_enable_alt_mac(np, i, 0);
- 			if (err)
- 				printk(KERN_WARNING PFX "%s: Error %d "
-diff -Nurd linux-2.6.24/drivers/net/niu.h linux-2.6.24-oxe810/drivers/net/niu.h
---- linux-2.6.24/drivers/net/niu.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/niu.h	2008-06-11 17:50:11.000000000 +0200
-@@ -499,7 +499,7 @@
- #define BMAC_ADDR2			0x00110UL
- #define  BMAC_ADDR2_ADDR2		0x000000000000ffffULL
- 
--#define BMAC_NUM_ALT_ADDR		7
-+#define BMAC_NUM_ALT_ADDR		6
- 
- #define BMAC_ALT_ADDR0(NUM)		(0x00118UL + (NUM)*0x18UL)
- #define  BMAC_ALT_ADDR0_ADDR0		0x000000000000ffffULL
-diff -Nurd linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c
---- linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c	2008-06-11 17:50:04.000000000 +0200
-@@ -559,8 +559,16 @@
- 
-     /* Read the station address from the CIS.  It is stored as the last
-        (fourth) string in the Version 1 Version/ID tuple. */
--    if (link->prod_id[3]) {
--	station_addr = link->prod_id[3];
-+    tuple->DesiredTuple = CISTPL_VERS_1;
-+    if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
-+	rc = -1;
-+	goto free_cfg_mem;
-+    }
-+    /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-+    if (next_tuple(link, tuple, parse) != CS_SUCCESS)
-+	first_tuple(link, tuple, parse);
-+    if (parse->version_1.ns > 3) {
-+	station_addr = parse->version_1.str + parse->version_1.ofs[3];
- 	if (cvt_ascii_address(dev, station_addr) == 0) {
- 		rc = 0;
- 		goto free_cfg_mem;
-diff -Nurd linux-2.6.24/drivers/net/sky2.c linux-2.6.24-oxe810/drivers/net/sky2.c
---- linux-2.6.24/drivers/net/sky2.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/sky2.c	2008-06-11 17:50:11.000000000 +0200
-@@ -621,6 +621,7 @@
- 	static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
- 	static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
- 
-+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- 	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
- 	/* Turn on/off phy power saving */
- 	if (onoff)
-@@ -632,7 +633,8 @@
- 		reg1 |= coma_mode[port];
- 
- 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
--	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+	sky2_pci_read32(hw, PCI_DEV_REG1);
- 
- 	udelay(100);
- }
-@@ -1412,6 +1414,7 @@
- 	imask |= portirq_msk[port];
- 	sky2_write32(hw, B0_IMSK, imask);
- 
-+	sky2_set_multicast(dev);
- 	return 0;
- 
- err_out:
-@@ -2426,6 +2429,7 @@
- 	if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
- 		u16 pci_err;
- 
-+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- 		pci_err = sky2_pci_read16(hw, PCI_STATUS);
- 		if (net_ratelimit())
- 			dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
-@@ -2433,12 +2437,14 @@
- 
- 		sky2_pci_write16(hw, PCI_STATUS,
- 				      pci_err | PCI_STATUS_ERROR_BITS);
-+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- 	}
- 
- 	if (status & Y2_IS_PCI_EXP) {
- 		/* PCI-Express uncorrectable Error occurred */
- 		u32 err;
- 
-+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- 		err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
- 		sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
- 			     0xfffffffful);
-@@ -2446,6 +2452,7 @@
- 			dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
- 
- 		sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
-+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- 	}
- 
- 	if (status & Y2_HWE_L1_MASK)
-@@ -2811,6 +2818,7 @@
- 	}
- 
- 	sky2_power_on(hw);
-+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- 
- 	for (i = 0; i < hw->ports; i++) {
- 		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-@@ -3533,8 +3541,6 @@
- 		err = sky2_up(dev);
- 		if (err)
- 			dev_close(dev);
--		else
--			sky2_set_multicast(dev);
- 	}
- 
- 	return err;
-@@ -4368,8 +4374,6 @@
- 				dev_close(dev);
- 				goto out;
- 			}
--
--			sky2_set_multicast(dev);
- 		}
- 	}
- 
-diff -Nurd linux-2.6.24/drivers/net/via-velocity.c linux-2.6.24-oxe810/drivers/net/via-velocity.c
---- linux-2.6.24/drivers/net/via-velocity.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/via-velocity.c	2008-06-11 17:50:11.000000000 +0200
-@@ -72,7 +72,6 @@
- #include <linux/mii.h>
- #include <linux/in.h>
- #include <linux/if_arp.h>
--#include <linux/if_vlan.h>
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/udp.h>
-@@ -81,170 +80,50 @@
- 
- #include "via-velocity.h"
- 
-+// Default MAC address
-+static const u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0xff };
-+static u32 mac_hi=0;
-+static u32 mac_lo=0;
- 
--static int velocity_nics = 0;
--static int msglevel = MSG_LEVEL_INFO;
--
--/**
-- *	mac_get_cam_mask	-	Read a CAM mask
-- *	@regs: register block for this velocity
-- *	@mask: buffer to store mask
-- *
-- *	Fetch the mask bits of the selected CAM and store them into the
-- *	provided mask buffer.
-- */
--
--static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
--	int i;
--
--	/* Select CAM mask */
--	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--	writeb(0, &regs->CAMADDR);
--
--	/* read mask */
--	for (i = 0; i < 8; i++)
--		*mask++ = readb(&(regs->MARCAM[i]));
--
--	/* disable CAMEN */
--	writeb(0, &regs->CAMADDR);
--
--	/* Select mar */
--	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--}
--
--
--/**
-- *	mac_set_cam_mask	-	Set a CAM mask
-- *	@regs: register block for this velocity
-- *	@mask: CAM mask to load
-- *
-- *	Store a new mask into a CAM
-- */
--
--static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
--	int i;
--	/* Select CAM mask */
--	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--	writeb(CAMADDR_CAMEN, &regs->CAMADDR);
--
--	for (i = 0; i < 8; i++) {
--		writeb(*mask++, &(regs->MARCAM[i]));
--	}
--	/* disable CAMEN */
--	writeb(0, &regs->CAMADDR);
--
--	/* Select mar */
--	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--}
--
--static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
--	int i;
--	/* Select CAM mask */
--	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--	writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
--
--	for (i = 0; i < 8; i++) {
--		writeb(*mask++, &(regs->MARCAM[i]));
--	}
--	/* disable CAMEN */
--	writeb(0, &regs->CAMADDR);
--
--	/* Select mar */
--	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--}
--
--/**
-- *	mac_set_cam	-	set CAM data
-- *	@regs: register block of this velocity
-- *	@idx: Cam index
-- *	@addr: 2 or 6 bytes of CAM data
-- *
-- *	Load an address or vlan tag into a CAM
-- */
--
--static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
--{
--	int i;
--
--	/* Select CAM mask */
--	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--	idx &= (64 - 1);
--
--	writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
--
--	for (i = 0; i < 6; i++) {
--		writeb(*addr++, &(regs->MARCAM[i]));
--	}
--	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
--
--	udelay(10);
-+#define EXTRA_RX_SKB_SPACE 32
-+#define MAX_HW_FRAGMENTS 6
-+//#define VELOCITY_ZERO_COPY_SUPPORT
-+//#define LOAD_FROM_EEPROM
- 
--	writeb(0, &regs->CAMADDR);
-+#define VELOCITY_DESC_IN_SRAM
- 
--	/* Select mar */
--	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--}
-+#ifdef VELOCITY_DESC_IN_SRAM
-+#include <asm/arch/desc_alloc.h>
-+#endif // VELOCITY_DESC_IN_SRAM
- 
--static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
--			     const u8 *addr)
-+/* Parse netdev kernel cmdline options */
-+static int __init do_setup(char *str)
- {
-+    int i;
-+    int ints[5];    // Hold arg count and four args
- 
--	/* Select CAM mask */
--	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
--
--	idx &= (64 - 1);
--
--	writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
--	writew(*((u16 *) addr), &regs->MARCAM[0]);
--
--	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
--
--	udelay(10);
--
--	writeb(0, &regs->CAMADDR);
--
--	/* Select mar */
--	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+    get_options(str, sizeof(ints)/sizeof(int), ints);
-+    for (i=1; i<=ints[0]; i++) {
-+        switch (i) {
-+            case 3:
-+                mac_hi = ints[i];
-+                break;
-+            case 4:
-+                mac_lo = ints[i];
-+                break;
-+            default:
-+                break;
-+        }
-+    }
-+    return 0;
- }
-+__setup("netdev=",do_setup);
- 
--
--/**
-- *	mac_wol_reset	-	reset WOL after exiting low power
-- *	@regs: register block of this velocity
-- *
-- *	Called after we drop out of wake on lan mode in order to
-- *	reset the Wake on lan features. This function doesn't restore
-- *	the rest of the logic from the result of sleep/wakeup
-- */
--
--static void mac_wol_reset(struct mac_regs __iomem * regs)
--{
--
--	/* Turn off SWPTAG right after leaving power mode */
--	BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
--	/* clear sticky bits */
--	BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
--
--	BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
--	BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
--	/* disable force PME-enable */
--	writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
--	/* disable power-event config bit */
--	writew(0xFFFF, &regs->WOLCRClr);
--	/* clear power status */
--	writew(0xFFFF, &regs->WOLSRClr);
--}
-+static int velocity_nics = 0;
-+static int msglevel = MSG_LEVEL_INFO;
- 
- static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
--static const struct ethtool_ops velocity_ethtool_ops;
-+static struct ethtool_ops velocity_ethtool_ops;
- 
- /*
-     Define module options
-@@ -269,6 +148,15 @@
- #define TX_DESC_DEF     64
- VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
- 
-+#define VLAN_ID_MIN     0
-+#define VLAN_ID_MAX     4095
-+#define VLAN_ID_DEF     0
-+/* VID_setting[] is used for setting the VID of NIC.
-+   0: default VID.
-+   1-4094: other VIDs.
-+*/
-+VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
-+
- #define RX_THRESH_MIN   0
- #define RX_THRESH_MAX   3
- #define RX_THRESH_DEF   0
-@@ -282,7 +170,8 @@
- 
- #define DMA_LENGTH_MIN  0
- #define DMA_LENGTH_MAX  7
--#define DMA_LENGTH_DEF  0
-+#define DMA_LENGTH_100M_DEF  6
-+#define DMA_LENGTH_1000M_DEF 6
- 
- /* DMA_length[] is used for controlling the DMA length
-    0: 8 DWORDs
-@@ -294,7 +183,15 @@
-    6: SF(flush till emply)
-    7: SF(flush till emply)
- */
--VELOCITY_PARAM(DMA_length, "DMA length");
-+VELOCITY_PARAM(DMA_length_100M,  "DMA length 100M");
-+VELOCITY_PARAM(DMA_length_1000M, "DMA length 1000M");
-+
-+#define TAGGING_DEF     0
-+/* enable_tagging[] is used for enabling 802.1Q VID tagging.
-+   0: disable VID seeting(default).
-+   1: enable VID setting.
-+*/
-+VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
- 
- #define IP_ALIG_DEF     0
- /* IP_byte_align[] is used for IP header DWORD byte aligned
-@@ -378,7 +275,7 @@
- static int velocity_open(struct net_device *dev);
- static int velocity_change_mtu(struct net_device *dev, int mtu);
- static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
--static int velocity_intr(int irq, void *dev_instance);
-+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);
- static void velocity_set_multi(struct net_device *dev);
- static struct net_device_stats *velocity_get_stats(struct net_device *dev);
- static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-@@ -401,25 +298,23 @@
- static u32 mii_check_media_mode(struct mac_regs __iomem * regs);
- static u32 check_connection_type(struct mac_regs __iomem * regs);
- static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
-+static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* addr);
-+static int set_mac_address(struct net_device *dev, void *p);
- 
- #ifdef CONFIG_PM
- 
- static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
- static int velocity_resume(struct pci_dev *pdev);
- 
--static DEFINE_SPINLOCK(velocity_dev_list_lock);
--static LIST_HEAD(velocity_dev_list);
--
--#endif
--
--#if defined(CONFIG_PM) && defined(CONFIG_INET)
--
- static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
- 
- static struct notifier_block velocity_inetaddr_notifier = {
-       .notifier_call	= velocity_netdev_event,
- };
- 
-+static DEFINE_SPINLOCK(velocity_dev_list_lock);
-+static LIST_HEAD(velocity_dev_list);
-+
- static void velocity_register_notifier(void)
- {
- 	register_inetaddr_notifier(&velocity_inetaddr_notifier);
-@@ -430,12 +325,12 @@
- 	unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
- }
- 
--#else
-+#else				/* CONFIG_PM */
- 
- #define velocity_register_notifier()	do {} while (0)
- #define velocity_unregister_notifier()	do {} while (0)
- 
--#endif
-+#endif				/* !CONFIG_PM */
- 
- /*
-  *	Internal board variants. At the moment we have only one
-@@ -466,7 +361,7 @@
-  *	a pointer a static string valid while the driver is loaded.
-  */
- 
--static const char __devinit *get_chip_name(enum chip_type chip_id)
-+static char __devinit *get_chip_name(enum chip_type chip_id)
- {
- 	int i;
- 	for (i = 0; chip_info_table[i].name != NULL; i++)
-@@ -557,11 +452,11 @@
- 	if (val == -1)
- 		*opt |= (def ? flag : 0);
- 	else if (val < 0 || val > 1) {
--		printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
-+		printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n", 
- 			devname, name);
- 		*opt |= (def ? flag : 0);
- 	} else {
--		printk(KERN_INFO "%s: set parameter %s to %s\n",
-+		printk(KERN_INFO "%s: set parameter %s to %s\n", 
- 			devname, name, val ? "TRUE" : "FALSE");
- 		*opt |= (val ? flag : 0);
- 	}
-@@ -581,10 +476,12 @@
- {
- 
- 	velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
--	velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
-+	velocity_set_int_opt(&opts->DMA_length_100M,  DMA_length_100M[index],  DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_100M_DEF,  "DMA_length 100M",  devname);
-+	velocity_set_int_opt(&opts->DMA_length_1000M, DMA_length_1000M[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_1000M_DEF, "DMA_length 1000M", devname);
- 	velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
- 	velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
--
-+	velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname);
-+	velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname);
- 	velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
- 	velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
- 	velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
-@@ -606,61 +503,35 @@
- static void velocity_init_cam_filter(struct velocity_info *vptr)
- {
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
--	unsigned short vid;
- 
- 	/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
- 	WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
- 	WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
- 
- 	/* Disable all CAMs */
--	memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
--	memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
--	mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
--	mac_set_cam_mask(regs, vptr->mCAMmask);
-+	memset(vptr->vCAMmask, 0, VCAM_SIZE / 8);
-+	memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
-+	mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
-+	mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
- 
- 	/* Enable first VCAM */
--	if (vptr->vlgrp) {
--		for (vid = 0; vid < VLAN_VID_MASK; vid++) {
--			if (vlan_group_get_device(vptr->vlgrp, vid)) {
--				/* If Tagging option is enabled and
--				   VLAN ID is not zero, then
--				   turn on MCFG_RTGOPT also */
--				if (vid != 0)
--					WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
-+	if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-+		/* If Tagging option is enabled and VLAN ID is not zero, then
-+		   turn on MCFG_RTGOPT also */
-+		if (vptr->options.vid != 0)
-+			WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
- 
--				mac_set_vlan_cam(regs, 0, (u8 *) &vid);
--			}
--		}
-+		mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM);
- 		vptr->vCAMmask[0] |= 1;
--		mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
-+		mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
- 	} else {
- 		u16 temp = 0;
--		mac_set_vlan_cam(regs, 0, (u8 *) &temp);
-+		mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
- 		temp = 1;
--		mac_set_vlan_cam_mask(regs, (u8 *) &temp);
-+		mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
- 	}
- }
- 
--static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
--{
--	struct velocity_info *vptr = netdev_priv(dev);
--
--        spin_lock_irq(&vptr->lock);
--	velocity_init_cam_filter(vptr);
--        spin_unlock_irq(&vptr->lock);
--}
--
--static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
--{
--	struct velocity_info *vptr = netdev_priv(dev);
--
--        spin_lock_irq(&vptr->lock);
--	vlan_group_set_device(vptr->vlgrp, vid, NULL);
--	velocity_init_cam_filter(vptr);
--        spin_unlock_irq(&vptr->lock);
--}
--
--
- /**
-  *	velocity_rx_reset	-	handle a receive reset
-  *	@vptr: velocity we are resetting
-@@ -690,6 +561,61 @@
- }
- 
- /**
-+ * Cause the eeprom to be read into the chip.
-+ * @returns Zero on success
-+ */
-+int mac_eeprom_reload(struct mac_regs __iomem *regs)
-+{
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("Before eeprom load regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+    printk("0x%02x\t", readb(&(ptr[i])));
-+    if (!((i+1) % 8)) {
-+        printk("\n0x%02x:\t", i+1);
-+    }
-+}
-+}
-+#endif
-+    BYTE_REG_BITS_ON(EECSR_RELOAD, &((regs)->EECSR));
-+    mdelay(100);
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("\nAfter eeprom load regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+    printk("0x%02x\t", readb(&(ptr[i])));
-+    if (!((i+1) % 8)) {
-+        printk("\n0x%02x:\t", i+1);
-+    }
-+}
-+}
-+#endif
-+    return BYTE_REG_BITS_IS_ON(EECSR_RELOAD, &((regs)->EECSR));
-+}
-+
-+
-+static inline void mac_set_dma_length(struct velocity_info *vptr)
-+{
-+	struct mac_regs __iomem *regs = vptr->mac_regs;
-+    int burst_size = vptr->options.DMA_length_100M;
-+
-+    if (!(vptr->mii_status & VELOCITY_LINK_FAIL) &&
-+         (vptr->options.spd_dpx == SPD_DPX_AUTO) &&
-+         (vptr->mii_status & VELOCITY_SPEED_1000)) {
-+        burst_size = vptr->options.DMA_length_1000M;
-+    }
-+
-+//printk("Setting fifo burst size to %d\n", burst_size);
-+	BYTE_REG_BITS_SET(burst_size, 0x07, &(regs->DCFG));
-+}
-+
-+/**
-  *	velocity_init_registers	-	initialise MAC registers
-  *	@vptr: velocity to init
-  *	@type: type of initialisation (hot or cold)
-@@ -698,7 +624,7 @@
-  *	hardware.
-  */
- 
--static void velocity_init_registers(struct velocity_info *vptr,
-+static void velocity_init_registers(struct velocity_info *vptr, 
- 				    enum velocity_init_type type)
- {
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -726,11 +652,12 @@
- 				netif_wake_queue(vptr->dev);
- 		}
- 
-+		mac_set_dma_length(vptr);
- 		enable_flow_control_ability(vptr);
- 
- 		mac_clear_isr(regs);
- 		writel(CR0_STOP, &regs->CR0Clr);
--		writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
-+		writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), 
- 							&regs->CR0Set);
- 
- 		break;
-@@ -743,16 +670,27 @@
- 		velocity_soft_reset(vptr);
- 		mdelay(5);
- 
-+#ifdef LOAD_FROM_EEPROM
- 		mac_eeprom_reload(regs);
-+#endif // LOAD_FROM_EEPROM
-+
- 		for (i = 0; i < 6; i++) {
- 			writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
- 		}
-+
-+        // Initialise the hardware's record of our primary MAC address
-+        hw_set_mac_address(vptr, vptr->dev->dev_addr);
-+
-+        /*
-+         *  Set LED Select bits to CASE_1
-+         */
-+        BYTE_REG_BITS_SET(CFGA_PHYLEDS1, (CFGA_PHYLEDS1 | CFGA_PHYLEDS0), &(regs->CFGA));
-+
- 		/*
- 		 *	clear Pre_ACPI bit.
- 		 */
- 		BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
- 		mac_set_rx_thresh(regs, vptr->options.rx_thresh);
--		mac_set_dma_length(regs, vptr->options.DMA_length);
- 
- 		writeb(WOLCFG_SAM | WOLCFG_SAB, &regs->WOLCFGSet);
- 		/*
-@@ -805,7 +743,9 @@
- 				netif_wake_queue(vptr->dev);
- 		}
- 
-+		mac_set_dma_length(vptr);
- 		enable_flow_control_ability(vptr);
-+
- 		mac_hw_mibs_init(regs);
- 		mac_write_int_mask(vptr->int_mask, regs);
- 		mac_clear_isr(regs);
-@@ -866,7 +806,7 @@
- 	 * can support more than MAX_UNITS.
- 	 */
- 	if (velocity_nics >= MAX_UNITS) {
--		dev_notice(&pdev->dev, "already found %d NICs.\n",
-+		dev_notice(&pdev->dev, "already found %d NICs.\n", 
- 			   velocity_nics);
- 		return -ENODEV;
- 	}
-@@ -876,15 +816,16 @@
- 		dev_err(&pdev->dev, "allocate net device failed.\n");
- 		goto out;
- 	}
--
-+	
- 	/* Chain it all together */
--
-+	
-+	SET_MODULE_OWNER(dev);
- 	SET_NETDEV_DEV(dev, &pdev->dev);
- 	vptr = netdev_priv(dev);
- 
- 
- 	if (first) {
--		printk(KERN_INFO "%s Ver. %s\n",
-+		printk(KERN_INFO "%s Ver. %s\n", 
- 			VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
- 		printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
- 		printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
-@@ -898,7 +839,7 @@
- 	dev->irq = pdev->irq;
- 
- 	ret = pci_enable_device(pdev);
--	if (ret < 0)
-+	if (ret < 0) 
- 		goto err_free_dev;
- 
- 	ret = velocity_get_pci_info(vptr, pdev);
-@@ -928,19 +869,32 @@
- 	for (i = 0; i < 6; i++)
- 		dev->dev_addr[i] = readb(&regs->PAR[i]);
- 
-+    // Tell the kernel of our MAC address
-+    if ((mac_hi==0)&&(mac_lo==0)) {
-+        memcpy(dev->dev_addr, DEFAULT_MAC_ADDRESS, dev->addr_len);
-+    } else {
-+        int i;
-+        for (i=0; i < dev->addr_len; i++) {
-+            if (i < sizeof(u32)) {
-+                dev->dev_addr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
-+            } else {
-+                dev->dev_addr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
-+            }
-+        }
-+    }
- 
- 	velocity_get_options(&vptr->options, velocity_nics, dev->name);
- 
--	/*
-+	/* 
- 	 *	Mask out the options cannot be set to the chip
- 	 */
--
-+	 
- 	vptr->options.flags &= info->flags;
- 
- 	/*
- 	 *	Enable the chip specified capbilities
- 	 */
--
-+	 
- 	vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
- 
- 	vptr->wol_opts = vptr->options.wol_opts;
-@@ -957,17 +911,14 @@
- 	dev->do_ioctl = velocity_ioctl;
- 	dev->ethtool_ops = &velocity_ethtool_ops;
- 	dev->change_mtu = velocity_change_mtu;
--
--	dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
--	dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
--
-+    dev->set_mac_address = set_mac_address;
- #ifdef  VELOCITY_ZERO_COPY_SUPPORT
- 	dev->features |= NETIF_F_SG;
- #endif
--	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER;
- 
--	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-+	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
- 		dev->features |= NETIF_F_IP_CSUM;
-+	}
- 
- 	ret = register_netdev(dev);
- 	if (ret < 0)
-@@ -978,9 +929,9 @@
- 
- 	velocity_print_info(vptr);
- 	pci_set_drvdata(pdev, dev);
--
-+	
- 	/* and leave the chip powered down */
--
-+	
- 	pci_set_power_state(pdev, PCI_D3hot);
- #ifdef CONFIG_PM
- 	{
-@@ -1019,9 +970,9 @@
- 	struct net_device *dev = vptr->dev;
- 
- 	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
--	printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
--		dev->name,
--		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-+	printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", 
-+		dev->name, 
-+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 
- 		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- }
- 
-@@ -1044,7 +995,6 @@
- 	vptr->pdev = pdev;
- 	vptr->chip_id = info->chip_id;
- 	vptr->num_txq = info->txqueue;
--	vptr->multicast_limit = MCAM_SIZE;
- 	spin_lock_init(&vptr->lock);
- 	INIT_LIST_HEAD(&vptr->list);
- }
-@@ -1061,12 +1011,12 @@
- static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
- {
- 	vptr->rev_id = pdev->revision;
--
-+		
- 	pci_set_master(pdev);
- 
- 	vptr->ioaddr = pci_resource_start(pdev, 0);
- 	vptr->memaddr = pci_resource_start(pdev, 1);
--
-+	
- 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
- 		dev_err(&pdev->dev,
- 			   "region #0 is not an I/O resource, aborting.\n");
-@@ -1105,20 +1055,25 @@
- 	u8 *pool;
- 
- 	/*
--	 *	Allocate all RD/TD rings a single pool
-+	 *	Allocate all RD/TD rings a single pool 
- 	 */
--
--	psize = vptr->options.numrx * sizeof(struct rx_desc) +
-+	 
-+	psize = vptr->options.numrx * sizeof(struct rx_desc) + 
- 		vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
- 
- 	/*
- 	 * pci_alloc_consistent() fulfills the requirement for 64 bytes
- 	 * alignment
- 	 */
--	pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
-+#ifdef VELOCITY_DESC_IN_SRAM
-+    pool = (u8*)GMAC_DESC_ALLOC_START;
-+    pool_dma = GMAC_DESC_ALLOC_START_PA;
-+#else
-+     pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
-+#endif // VELOCITY_DESC_IN_SRAM
- 
- 	if (pool == NULL) {
--		printk(KERN_ERR "%s : DMA memory allocation failed.\n",
-+		printk(KERN_ERR "%s : DMA memory allocation failed.\n", 
- 					vptr->dev->name);
- 		return -ENOMEM;
- 	}
-@@ -1130,13 +1085,15 @@
- 	vptr->rd_pool_dma = pool_dma;
- 
- 	tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
--	vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
-+	vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize, 
- 						&vptr->tx_bufs_dma);
- 
- 	if (vptr->tx_bufs == NULL) {
--		printk(KERN_ERR "%s: DMA memory allocation failed.\n",
-+		printk(KERN_ERR "%s: DMA memory allocation failed.\n", 
- 					vptr->dev->name);
-+#ifndef VELOCITY_DESC_IN_SRAM
- 		pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
-+#endif // !VELOCITY_DESC_IN_SRAM
- 		return -ENOMEM;
- 	}
- 
-@@ -1167,10 +1124,12 @@
- {
- 	int size;
- 
--	size = vptr->options.numrx * sizeof(struct rx_desc) +
-+	size = vptr->options.numrx * sizeof(struct rx_desc) + 
- 	       vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
- 
-+#ifndef VELOCITY_DESC_IN_SRAM
- 	pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
-+#endif // !VELOCITY_DESC_IN_SRAM
- 
- 	size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
- 
-@@ -1219,7 +1178,7 @@
- 				break;
- 		}
- 		done++;
--		dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
-+		dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;	
- 	} while (dirty != vptr->rd_curr);
- 
- 	if (done) {
-@@ -1241,15 +1200,14 @@
- 
- static int velocity_init_rd_ring(struct velocity_info *vptr)
- {
--	int ret;
--	int mtu = vptr->dev->mtu;
--
--	vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
-+	int ret = -ENOMEM;
-+	unsigned int rsize = sizeof(struct velocity_rd_info) * 
-+					vptr->options.numrx;
- 
--	vptr->rd_info = kcalloc(vptr->options.numrx,
--				sizeof(struct velocity_rd_info), GFP_KERNEL);
--	if (!vptr->rd_info)
--		return -ENOMEM;
-+	vptr->rd_info = kmalloc(rsize, GFP_KERNEL);
-+	if(vptr->rd_info == NULL)
-+		goto out;
-+	memset(vptr->rd_info, 0, rsize);
- 
- 	vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
- 
-@@ -1259,7 +1217,7 @@
- 			"%s: failed to allocate RX buffer.\n", vptr->dev->name);
- 		velocity_free_rd_ring(vptr);
- 	}
--
-+out:
- 	return ret;
- }
- 
-@@ -1306,26 +1264,28 @@
-  *	Returns zero on success or a negative posix errno code for
-  *	failure.
-  */
--
-+ 
- static int velocity_init_td_ring(struct velocity_info *vptr)
- {
- 	int i, j;
- 	dma_addr_t curr;
- 	struct tx_desc *td;
- 	struct velocity_td_info *td_info;
-+	unsigned int tsize = sizeof(struct velocity_td_info) * 
-+					vptr->options.numtx;
- 
- 	/* Init the TD ring entries */
- 	for (j = 0; j < vptr->num_txq; j++) {
- 		curr = vptr->td_pool_dma[j];
- 
--		vptr->td_infos[j] = kcalloc(vptr->options.numtx,
--					    sizeof(struct velocity_td_info),
--					    GFP_KERNEL);
--		if (!vptr->td_infos[j])	{
-+		vptr->td_infos[j] = kmalloc(tsize, GFP_KERNEL);
-+		if(vptr->td_infos[j] == NULL)
-+		{
- 			while(--j >= 0)
- 				kfree(vptr->td_infos[j]);
- 			return -ENOMEM;
- 		}
-+		memset(vptr->td_infos[j], 0, tsize);
- 
- 		for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
- 			td = &(vptr->td_rings[j][i]);
-@@ -1340,31 +1300,12 @@
- 	return 0;
- }
- 
--/*
-- *	FIXME: could we merge this with velocity_free_tx_buf ?
-- */
--
--static void velocity_free_td_ring_entry(struct velocity_info *vptr,
--							 int q, int n)
-+static void velocity_free_td_ring_entry(struct velocity_info *vptr, int q, int n)
- {
- 	struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
--	int i;
--
--	if (td_info == NULL)
--		return;
- 
--	if (td_info->skb) {
--		for (i = 0; i < td_info->nskb_dma; i++)
--		{
--			if (td_info->skb_dma[i]) {
--				pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
--					td_info->skb->len, PCI_DMA_TODEVICE);
--				td_info->skb_dma[i] = (dma_addr_t) NULL;
--			}
--		}
--		dev_kfree_skb(td_info->skb);
--		td_info->skb = NULL;
--	}
-+	if (td_info && td_info->skb)
-+        velocity_free_tx_buf(vptr, td_info);
- }
- 
- /**
-@@ -1374,17 +1315,16 @@
-  *	Free up the transmit ring for this particular velocity adapter.
-  *	We free the ring contents but not the ring itself.
-  */
--
-+ 
- static void velocity_free_td_ring(struct velocity_info *vptr)
- {
- 	int i, j;
- 
--	for (j = 0; j < vptr->num_txq; j++) {
-+	for (j=0; j < vptr->num_txq; j++) {
- 		if (vptr->td_infos[j] == NULL)
- 			continue;
--		for (i = 0; i < vptr->options.numtx; i++) {
-+		for (i=0; i < vptr->options.numtx; i++) {
- 			velocity_free_td_ring_entry(vptr, j, i);
--
- 		}
- 		kfree(vptr->td_infos[j]);
- 		vptr->td_infos[j] = NULL;
-@@ -1400,14 +1340,14 @@
-  *	any received packets from the receive queue. Hand the ring
-  *	slots back to the adapter for reuse.
-  */
--
-+ 
- static int velocity_rx_srv(struct velocity_info *vptr, int status)
- {
- 	struct net_device_stats *stats = &vptr->stats;
- 	int rd_curr = vptr->rd_curr;
- 	int works = 0;
- 
--	do {
-+    while (1) {
- 		struct rx_desc *rd = vptr->rd_ring + rd_curr;
- 
- 		if (!vptr->rd_info[rd_curr].skb)
-@@ -1422,15 +1362,19 @@
- 		 *	Don't drop CE or RL error frame although RXOK is off
- 		 */
- 		if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
--			if (velocity_receive_frame(vptr, rd_curr) < 0)
--				stats->rx_dropped++;
-+			if (velocity_receive_frame(vptr, rd_curr) < 0) {
-+                /* velocity_receive_frame() has already recorded the type of */
-+                /* so just inc overall rx error count */
-+                ++stats->rx_errors;
-+            }
- 		} else {
- 			if (rd->rdesc0.RSR & RSR_CRC)
- 				stats->rx_crc_errors++;
- 			if (rd->rdesc0.RSR & RSR_FAE)
- 				stats->rx_frame_errors++;
- 
--			stats->rx_dropped++;
-+            /* We've had an error of some sort so inc. overall rx error count */
-+            ++stats->rx_errors;
- 		}
- 
- 		rd->inten = 1;
-@@ -1440,7 +1384,9 @@
- 		rd_curr++;
- 		if (rd_curr >= vptr->options.numrx)
- 			rd_curr = 0;
--	} while (++works <= 15);
-+
-+        ++works;
-+    }
- 
- 	vptr->rd_curr = rd_curr;
- 
-@@ -1461,14 +1407,14 @@
-  *	Process the status bits for the received packet and determine
-  *	if the checksum was computed and verified by the hardware
-  */
--
-+ 
- static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
- {
- 	skb->ip_summed = CHECKSUM_NONE;
- 
- 	if (rd->rdesc1.CSM & CSM_IPKT) {
- 		if (rd->rdesc1.CSM & CSM_IPOK) {
--			if ((rd->rdesc1.CSM & CSM_TCPKT) ||
-+			if ((rd->rdesc1.CSM & CSM_TCPKT) || 
- 					(rd->rdesc1.CSM & CSM_UDPKT)) {
- 				if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
- 					return;
-@@ -1499,20 +1445,19 @@
- 	if (pkt_size < rx_copybreak) {
- 		struct sk_buff *new_skb;
- 
--		new_skb = dev_alloc_skb(pkt_size + 2);
-+        /* Always realign IP header to quad boundary if copying anyway */
-+		new_skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
- 		if (new_skb) {
- 			new_skb->dev = vptr->dev;
- 			new_skb->ip_summed = rx_skb[0]->ip_summed;
- 
--			if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
--				skb_reserve(new_skb, 2);
-+			skb_reserve(new_skb, NET_IP_ALIGN);
- 
--			skb_copy_from_linear_data(rx_skb[0], new_skb->data,
--						  pkt_size);
-+			memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
- 			*rx_skb = new_skb;
- 			ret = 0;
- 		}
--
-+		
- 	}
- 	return ret;
- }
-@@ -1529,13 +1474,10 @@
- static inline void velocity_iph_realign(struct velocity_info *vptr,
- 					struct sk_buff *skb, int pkt_size)
- {
--	/* FIXME - memmove ? */
- 	if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
--		int i;
--
--		for (i = pkt_size; i >= 0; i--)
--			*(skb->data + i + 2) = *(skb->data + i);
--		skb_reserve(skb, 2);
-+//printk("velocity_iph_realign()\n");
-+        memmove(skb->data + NET_IP_ALIGN, skb->data, pkt_size);
-+		skb_reserve(skb, NET_IP_ALIGN);
- 	}
- }
- 
-@@ -1543,11 +1485,11 @@
-  *	velocity_receive_frame	-	received packet processor
-  *	@vptr: velocity we are handling
-  *	@idx: ring index
-- *
-+ *	
-  *	A packet has arrived. We process the packet and if appropriate
-  *	pass the frame up the network stack
-  */
--
-+ 
- static int velocity_receive_frame(struct velocity_info *vptr, int idx)
- {
- 	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
-@@ -1558,7 +1500,7 @@
- 	struct sk_buff *skb;
- 
- 	if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
--		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
-+		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multple RDs.\n", vptr->dev->name);
- 		stats->rx_length_errors++;
- 		return -EINVAL;
- 	}
-@@ -1567,6 +1509,7 @@
- 		vptr->stats.multicast++;
- 
- 	skb = rd_info->skb;
-+	skb->dev = vptr->dev;
- 
- 	pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
- 				    vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
-@@ -1574,7 +1517,6 @@
- 	/*
- 	 *	Drop frame not meeting IEEE 802.3
- 	 */
--
- 	if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
- 		if (rd->rdesc0.RSR & RSR_RL) {
- 			stats->rx_length_errors++;
-@@ -1596,9 +1538,11 @@
- 		   PCI_DMA_FROMDEVICE);
- 
- 	skb_put(skb, pkt_len - 4);
--	skb->protocol = eth_type_trans(skb, vptr->dev);
-+	skb->protocol = eth_type_trans(skb, skb->dev);	
- 
- 	stats->rx_bytes += pkt_len;
-+    ++stats->rx_packets;
-+
- 	netif_rx(skb);
- 
- 	return 0;
-@@ -1614,7 +1558,7 @@
-  *	requires *64* byte alignment of the buffer which makes life
-  *	less fun than would be ideal.
-  */
--
-+ 
- static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
- {
- 	struct rx_desc *rd = &(vptr->rd_ring[idx]);
-@@ -1631,11 +1575,10 @@
- 	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
- 	rd_info->skb->dev = vptr->dev;
- 	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
--
-+	
- 	/*
- 	 *	Fill in the descriptor to match
-- 	 */
--
-+ 	 */	
- 	*((u32 *) & (rd->rdesc0)) = 0;
- 	rd->len = cpu_to_le32(vptr->rx_buf_sz);
- 	rd->inten = 1;
-@@ -1651,9 +1594,9 @@
-  *
-  *	Scan the queues looking for transmitted packets that
-  *	we can complete and clean up. Update any statistics as
-- *	necessary/
-+ *	neccessary/
-  */
--
-+ 
- static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
- {
- 	struct tx_desc *td;
-@@ -1665,7 +1608,7 @@
- 	struct net_device_stats *stats = &vptr->stats;
- 
- 	for (qnum = 0; qnum < vptr->num_txq; qnum++) {
--		for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
-+		for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0; 
- 			idx = (idx + 1) % vptr->options.numtx) {
- 
- 			/*
-@@ -1677,8 +1620,7 @@
- 			if (td->tdesc0.owner == OWNED_BY_NIC)
- 				break;
- 
--			if ((works++ > 15))
--				break;
-+            ++works;
- 
- 			if (td->tdesc0.TSR & TSR0_TERR) {
- 				stats->tx_errors++;
-@@ -1730,7 +1672,7 @@
- 	if (vptr->mii_status & VELOCITY_LINK_FAIL) {
- 		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
- 	} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
--		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
-+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name);
- 
- 		if (vptr->mii_status & VELOCITY_SPEED_1000)
- 			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
-@@ -1765,17 +1707,48 @@
- }
- 
- /**
-+ *	velocity_update_hw_mibs	-	fetch MIB counters from chip
-+ *	@vptr: velocity to update
-+ *
-+ *	The velocity hardware keeps certain counters in the hardware
-+ * 	side. We need to read these when the user asks for statistics
-+ *	or when they overflow (causing an interrupt). The read of the
-+ *	statistic clears it, so we keep running master counters in user
-+ *	space.
-+ */
-+static void velocity_update_hw_mibs(struct velocity_info *vptr)
-+{
-+	int i;
-+
-+	/* Toggle flush to update MIB SRAM from fast counters */
-+	BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
-+	while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
-+
-+	/* Toggle MIBINI to begin MIB SRAM read out. Datasheet says always reads as
-+       zero, so no point polling for it to return to zero after setting */
-+	BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
-+
-+	for (i=0; i < HW_MIB_SIZE; ++i) {
-+		/* Read MIB, preserving both index and count */
-+		u32 mib = readl(&(vptr->mac_regs->MIBData));
-+		int index = (mib & 0xff000000) >> 24;
-+		u32 count =  mib & 0x00ffffff;
-+		vptr->mib_counter[index] += count;
-+	}
-+}
-+
-+/**
-  *	velocity_error	-	handle error from controller
-  *	@vptr: velocity
-  *	@status: card status
-  *
-  *	Process an error report from the hardware and attempt to recover
-- *	the card itself. At the moment we cannot recover from some
-+ *	the card itself. At the moment we cannot recover from some 
-  *	theoretically impossible errors but this could be fixed using
-  *	the pci_device_failed logic to bounce the hardware
-  *
-  */
--
-+ 
- static void velocity_error(struct velocity_info *vptr, int status)
- {
- 
-@@ -1786,7 +1759,7 @@
- 		BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
- 		writew(TRDCSR_RUN, &regs->TDCSRClr);
- 		netif_stop_queue(vptr->dev);
--
-+		
- 		/* FIXME: port over the pci_device_failed code and use it
- 		   here */
- 	}
-@@ -1799,7 +1772,7 @@
- 			vptr->mii_status = check_connection_type(regs);
- 
- 			/*
--			 *	If it is a 3119, disable frame bursting in
-+			 *	If it is a 3119, disable frame bursting in 
- 			 *	halfduplex mode and enable it in fullduplex
- 			 *	 mode
- 			 */
-@@ -1832,13 +1805,15 @@
- 		}
- 
- 		velocity_print_link_status(vptr);
-+
-+		mac_set_dma_length(vptr);
- 		enable_flow_control_ability(vptr);
- 
- 		/*
--		 *	Re-enable auto-polling because SRCI will disable
-+		 *	Re-enable auto-polling because SRCI will disable 
- 		 *	auto-polling
- 		 */
--
-+		 
- 		enable_mii_autopoll(regs);
- 
- 		if (vptr->mii_status & VELOCITY_LINK_FAIL)
-@@ -1846,9 +1821,11 @@
- 		else
- 			netif_wake_queue(vptr->dev);
- 
--	};
-+	}
-+
- 	if (status & ISR_MIBFI)
- 		velocity_update_hw_mibs(vptr);
-+
- 	if (status & ISR_LSTEI)
- 		mac_rx_queue_wake(vptr->mac_regs);
- }
-@@ -1858,29 +1835,35 @@
-  *	@vptr: velocity
-  *	@tdinfo: buffer
-  *
-- *	Release an transmit buffer. If the buffer was preallocated then
-+ *	Release a transmit buffer. If the buffer was preallocated then
-  *	recycle it, if not then unmap the buffer.
-  */
--
- static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
- {
- 	struct sk_buff *skb = tdinfo->skb;
- 	int i;
- 
--	/*
--	 *	Don't unmap the pre-allocated tx_bufs
--	 */
--	if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
-+	/* Don't unmap the pre-allocated tx_bufs */
-+	if (tdinfo->skb_dma[0] && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
-+        if (tdinfo->nskb_dma == 1) {
-+            /* Either no fragments originally, or was linearized because too
-+               many fragments */
-+            pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb->len, PCI_DMA_TODEVICE);
-+            tdinfo->skb_dma[0] = 0;
-+        } else {
-+            /* Unmap the head buffer */
-+            pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb_headlen(skb), PCI_DMA_TODEVICE);
-+            tdinfo->skb_dma[0] = 0;
- 
--		for (i = 0; i < tdinfo->nskb_dma; i++) {
--#ifdef VELOCITY_ZERO_COPY_SUPPORT
--			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], td->tdesc1.len, PCI_DMA_TODEVICE);
--#else
--			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE);
--#endif
--			tdinfo->skb_dma[i] = 0;
--		}
-+            /* Unmap the fragment buffers */
-+            for (i=0; i < tdinfo->nskb_dma-1; ++i) {
-+                pci_unmap_page(vptr->pdev, tdinfo->skb_dma[i+1],
-+                    skb_shinfo(skb)->frags[i].size, PCI_DMA_TODEVICE);
-+                tdinfo->skb_dma[i+1] = 0;
-+            }
-+        }
- 	}
-+
- 	dev_kfree_skb_irq(skb);
- 	tdinfo->skb = NULL;
- }
-@@ -1895,12 +1878,14 @@
-  *	All the ring allocation and set up is done on open for this
-  *	adapter to minimise memory usage when inactive
-  */
--
-+ 
- static int velocity_open(struct net_device *dev)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
- 	int ret;
- 
-+    vptr->rx_buf_sz = dev->mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
-+
- 	ret = velocity_init_rings(vptr);
- 	if (ret < 0)
- 		goto out;
-@@ -1912,13 +1897,13 @@
- 	ret = velocity_init_td_ring(vptr);
- 	if (ret < 0)
- 		goto err_free_rd_ring;
--
--	/* Ensure chip is running */
-+	
-+	/* Ensure chip is running */	
- 	pci_set_power_state(vptr->pdev, PCI_D0);
--
-+	
- 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
- 
--	ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
-+	ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ,
- 			  dev->name, dev);
- 	if (ret < 0) {
- 		/* Power down the chip */
-@@ -1941,7 +1926,7 @@
- 	goto out;
- }
- 
--/**
-+/** 
-  *	velocity_change_mtu	-	MTU change callback
-  *	@dev: network device
-  *	@new_mtu: desired MTU
-@@ -1950,7 +1935,7 @@
-  *	this interface. It gets called on a change by the network layer.
-  *	Return zero for success or negative posix error code.
-  */
--
-+ 
- static int velocity_change_mtu(struct net_device *dev, int new_mtu)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
-@@ -1959,16 +1944,11 @@
- 	int ret = 0;
- 
- 	if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
--		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
-+		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n", 
- 				vptr->dev->name);
- 		return -EINVAL;
- 	}
- 
--	if (!netif_running(dev)) {
--		dev->mtu = new_mtu;
--		return 0;
--	}
--
- 	if (new_mtu != oldmtu) {
- 		spin_lock_irqsave(&vptr->lock, flags);
- 
-@@ -1978,7 +1958,7 @@
- 		velocity_free_td_ring(vptr);
- 		velocity_free_rd_ring(vptr);
- 
--		dev->mtu = new_mtu;
-+		dev->mtu = new_mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
- 
- 		ret = velocity_init_rd_ring(vptr);
- 		if (ret < 0)
-@@ -2006,7 +1986,7 @@
-  *	Shuts down the internal operations of the velocity and
-  *	disables interrupts, autopolling, transmit and receive
-  */
--
-+ 
- static void velocity_shutdown(struct velocity_info *vptr)
- {
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -2037,10 +2017,10 @@
- 		velocity_get_ip(vptr);
- 	if (dev->irq != 0)
- 		free_irq(dev->irq, dev);
--
-+		
- 	/* Power down the chip */
- 	pci_set_power_state(vptr->pdev, PCI_D3hot);
--
-+	
- 	/* Free the resources */
- 	velocity_free_td_ring(vptr);
- 	velocity_free_rd_ring(vptr);
-@@ -2058,7 +2038,7 @@
-  *	Called by the networ layer to request a packet is queued to
-  *	the velocity. Returns zero on success.
-  */
--
-+ 
- static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
-@@ -2067,16 +2047,22 @@
- 	struct velocity_td_info *tdinfo;
- 	unsigned long flags;
- 	int index;
--
--	int pktlen = skb->len;
--
-+	int pktlen;
-+printk("Tx");
- #ifdef VELOCITY_ZERO_COPY_SUPPORT
--	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
--		kfree_skb(skb);
--		return 0;
-+	if (skb_shinfo(skb)->nr_frags > MAX_HW_FRAGMENTS) {
-+//printk("Too many fragments (%d), linearizing\n", skb_shinfo(skb)->nr_frags);
-+        if (__skb_linearize(skb, GFP_ATOMIC)) {
-+//printk("Linearization failed, dropping Tx packet\n");
-+            kfree_skb(skb);
-+            return 0;
-+        }
- 	}
- #endif
- 
-+    // Get packet length after any linearization has occured
-+    pktlen = skb->len;
-+
- 	spin_lock_irqsave(&vptr->lock, flags);
- 
- 	index = vptr->td_curr[qnum];
-@@ -2088,19 +2074,28 @@
- 	td_ptr->td_buf[0].queue = 0;
- 
- 	/*
--	 *	Pad short frames.
-+	 *	Pad short frames. 
- 	 */
- 	if (pktlen < ETH_ZLEN) {
--		/* Cannot occur until ZC support */
-+        int pad_required = ETH_ZLEN - skb->len;
-+printk("Padding short Tx frame\n");
- 		pktlen = ETH_ZLEN;
--		skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
--		memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
- 		tdinfo->skb = skb;
--		tdinfo->skb_dma[0] = tdinfo->buf_dma;
-+
-+        if (skb_tailroom(skb) >= pad_required) {
-+//printk("Using short frame\n");
-+			tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
-+        } else { 
-+//printk("Copying short frame\n");
-+            memcpy(tdinfo->buf, skb->data, skb->len);
-+            memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
-+            tdinfo->skb_dma[0] = tdinfo->buf_dma;
-+        }
-+
- 		td_ptr->tdesc0.pktsize = pktlen;
- 		td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- 		td_ptr->td_buf[0].pa_high = 0;
--		td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+		td_ptr->td_buf[0].bufsize = pktlen;
- 		tdinfo->nskb_dma = 1;
- 		td_ptr->tdesc1.CMDZ = 2;
- 	} else
-@@ -2108,41 +2103,46 @@
- 	if (skb_shinfo(skb)->nr_frags > 0) {
- 		int nfrags = skb_shinfo(skb)->nr_frags;
- 		tdinfo->skb = skb;
--		if (nfrags > 6) {
--			skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
--			tdinfo->skb_dma[0] = tdinfo->buf_dma;
--			td_ptr->tdesc0.pktsize =
-+        td_ptr->tdesc0.pktsize = pktlen;
-+
-+		if (nfrags > MAX_HW_FRAGMENTS) {
-+//printk("Using linearized skb\n");
-+            /* SKB has already been linearized above, so use direct from skb */
-+			tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
- 			td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- 			td_ptr->td_buf[0].pa_high = 0;
--			td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+			td_ptr->td_buf[0].bufsize = pktlen;
- 			tdinfo->nskb_dma = 1;
- 			td_ptr->tdesc1.CMDZ = 2;
- 		} else {
- 			int i = 0;
--			tdinfo->nskb_dma = 0;
--			tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data, skb->len - skb->data_len, PCI_DMA_TODEVICE);
- 
--			td_ptr->tdesc0.pktsize = pktlen;
-+			tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE);
- 
--			/* FIXME: support 48bit DMA later */
--			td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
--			td_ptr->td_buf[i].pa_high = 0;
--			td_ptr->td_buf[i].bufsize = skb->len->skb->data_len;
-+			td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
-+			td_ptr->td_buf[0].pa_high = 0;
-+			td_ptr->td_buf[0].bufsize = skb_headlen(skb);
- 
--			for (i = 0; i < nfrags; i++) {
-+			for (i=0; i < nfrags; ++i) {
- 				skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
--				void *addr = ((void *) page_address(frag->page + frag->page_offset));
- 
--				tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
-+                tdinfo->skb_dma[i+1] = pci_map_page(vptr->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE);
- 
--				td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
--				td_ptr->td_buf[i + 1].pa_high = 0;
--				td_ptr->td_buf[i + 1].bufsize = frag->size;
-+                td_ptr->td_buf[i+1].pa_low = cpu_to_le32(tdinfo->skb_dma[i+1]);
-+                td_ptr->td_buf[i+1].pa_high = 0;
-+                td_ptr->td_buf[i+1].bufsize = frag->size;
- 			}
--			tdinfo->nskb_dma = i - 1;
--			td_ptr->tdesc1.CMDZ = i;
--		}
- 
-+			tdinfo->nskb_dma = nfrags+1;
-+			td_ptr->tdesc1.CMDZ = nfrags+2;
-+
-+//printk("Num frags = %d\n", nfrags);
-+//printk("skb: 0x%08lx:0x%08x, %d\n", (unsigned long)skb->data, tdinfo->skb_dma[0], skb_headlen(skb));
-+//for (i=0; i < nfrags; ++i) {
-+//    skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+//    printk("frag: 0x%08lx:0x%08x, %d\n", (unsigned long)page_address(frag->page) + frag->page_offset, tdinfo->skb_dma[i+1], frag->size);
-+//}
-+		}
- 	} else
- #endif
- 	{
-@@ -2155,13 +2155,18 @@
- 		td_ptr->tdesc0.pktsize = pktlen;
- 		td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- 		td_ptr->td_buf[0].pa_high = 0;
--		td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+		td_ptr->td_buf[0].bufsize = pktlen;
- 		tdinfo->nskb_dma = 1;
- 		td_ptr->tdesc1.CMDZ = 2;
-+printk("0x%08x:%u\n", td_ptr->td_buf[0].pa_low, td_ptr->td_buf[0].bufsize);
-+printk("TdInd0=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[0]));
-+printk("TdInd1=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[1]));
-+printk("TdInd2=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[2]));
-+printk("TdInd3=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[3]));
- 	}
- 
--	if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
--		td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);
-+	if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-+		td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
- 		td_ptr->tdesc1.pqinf.priority = 0;
- 		td_ptr->tdesc1.pqinf.CFI = 0;
- 		td_ptr->tdesc1.TCR |= TCR0_VETAG;
-@@ -2170,21 +2175,23 @@
- 	/*
- 	 *	Handle hardware checksum
- 	 */
--	if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
--				 && (skb->ip_summed == CHECKSUM_PARTIAL)) {
--		const struct iphdr *ip = ip_hdr(skb);
-+	if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) &&
-+        (skb->ip_summed == CHECKSUM_HW)) {
-+		struct iphdr *ip = skb->nh.iph;
-+
- 		if (ip->protocol == IPPROTO_TCP)
- 			td_ptr->tdesc1.TCR |= TCR0_TCPCK;
- 		else if (ip->protocol == IPPROTO_UDP)
- 			td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
-+
- 		td_ptr->tdesc1.TCR |= TCR0_IPCK;
- 	}
- 	{
--
- 		int prev = index - 1;
- 
- 		if (prev < 0)
- 			prev = vptr->options.numtx - 1;
-+
- 		td_ptr->tdesc0.owner = OWNED_BY_NIC;
- 		vptr->td_used[qnum]++;
- 		vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
-@@ -2196,8 +2203,10 @@
- 		td_ptr->td_buf[0].queue = 1;
- 		mac_tx_queue_wake(vptr->mac_regs, qnum);
- 	}
-+
- 	dev->trans_start = jiffies;
- 	spin_unlock_irqrestore(&vptr->lock, flags);
-+printk("xT\n");
- 	return 0;
- }
- 
-@@ -2205,57 +2214,55 @@
-  *	velocity_intr		-	interrupt callback
-  *	@irq: interrupt number
-  *	@dev_instance: interrupting device
-+ *	@pt_regs: CPU register state at interrupt
-  *
-  *	Called whenever an interrupt is generated by the velocity
-  *	adapter IRQ line. We may not be the source of the interrupt
-  *	and need to identify initially if we are, and if not exit as
-  *	efficiently as possible.
-  */
--
--static int velocity_intr(int irq, void *dev_instance)
-+ 
-+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
- {
- 	struct net_device *dev = dev_instance;
- 	struct velocity_info *vptr = netdev_priv(dev);
- 	u32 isr_status;
- 	int max_count = 0;
- 
--
-+printk("I");
- 	spin_lock(&vptr->lock);
- 	isr_status = mac_read_isr(vptr->mac_regs);
-+printk("0x%08x ", isr_status);
- 
--	/* Not us ? */
--	if (isr_status == 0) {
-+	if (!isr_status) {
- 		spin_unlock(&vptr->lock);
-+printk("N ");
- 		return IRQ_NONE;
- 	}
- 
- 	mac_disable_int(vptr->mac_regs);
- 
--	/*
--	 *	Keep processing the ISR until we have completed
--	 *	processing and the isr_status becomes zero
--	 */
--
--	while (isr_status != 0) {
-+	/* Process all pending interrupts */
-+	while (isr_status) {
-+        /* Ack all pending interrupt sources */
- 		mac_write_isr(vptr->mac_regs, isr_status);
--		if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
--			velocity_error(vptr, isr_status);
--		if (isr_status & (ISR_PRXI | ISR_PPRXI))
-+
-+		velocity_error(vptr, isr_status);
-+		if (isr_status & (ISR_PRXI | ISR_PPRXI)) {
-+printk("R");
- 			max_count += velocity_rx_srv(vptr, isr_status);
--		if (isr_status & (ISR_PTXI | ISR_PPTXI))
-+		}
-+		if (isr_status & (ISR_PTXI | ISR_PPTXI)) {
-+printk("T");
- 			max_count += velocity_tx_srv(vptr, isr_status);
--		isr_status = mac_read_isr(vptr->mac_regs);
--		if (max_count > vptr->options.int_works)
--		{
--			printk(KERN_WARNING "%s: excessive work at interrupt.\n",
--				dev->name);
--			max_count = 0;
- 		}
-+		isr_status = mac_read_isr(vptr->mac_regs);
- 	}
-+
- 	spin_unlock(&vptr->lock);
-+printk("i");
- 	mac_enable_int(vptr->mac_regs);
- 	return IRQ_HANDLED;
--
- }
- 
- 
-@@ -2267,41 +2274,70 @@
-  *	for a velocity adapter. Reload the CAMs with the new address
-  *	filter ruleset.
-  */
-+static void clear_all_multicast(struct velocity_info *vptr)
-+{
-+	struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+    /* Do not allow any multicast packets through the multicast hash table */
-+    writel(0x0, &regs->MARCAM[0]);
-+    writel(0x0, &regs->MARCAM[4]);
-+}
-+
-+static void set_all_multicast(struct velocity_info *vptr)
-+{
-+	struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+    /* Allow all multicast packets through the multicast hash table */
-+    writel(0xffffffff, &regs->MARCAM[0]);
-+    writel(0xffffffff, &regs->MARCAM[4]);
-+}
- 
- static void velocity_set_multi(struct net_device *dev)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
--	u8 rx_mode;
--	int i;
- 	struct dev_mc_list *mclist;
-+	int i;
-+	u8 rx_mode = RCR_AB;    /* Always enable broadcast packet reception */
- 
--	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
--		writel(0xffffffff, &regs->MARCAM[0]);
--		writel(0xffffffff, &regs->MARCAM[4]);
--		rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
--	} else if ((dev->mc_count > vptr->multicast_limit)
--		   || (dev->flags & IFF_ALLMULTI)) {
--		writel(0xffffffff, &regs->MARCAM[0]);
--		writel(0xffffffff, &regs->MARCAM[4]);
--		rx_mode = (RCR_AM | RCR_AB);
--	} else {
--		int offset = MCAM_SIZE - vptr->multicast_limit;
--		mac_get_cam_mask(regs, vptr->mCAMmask);
-+    /* Clear out the multicast hash table */
-+    clear_all_multicast(vptr);
- 
-+    /* Disable all multicast CAM entries */
-+	memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
-+    mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
-+
-+	if (dev->flags & IFF_PROMISC) {
-+        /* Enable promiscuous mode */
-+		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
-+
-+        set_all_multicast(vptr);
-+		rx_mode |= (RCR_PROM | RCR_AM);
-+	} else if ((dev->mc_count > MCAM_SIZE) ||
-+               (dev->flags & IFF_ALLMULTI)) {
-+        /* ALL_MULTI or too many entries for perfect filtering, so allow all
-+         * multicast packets through hash table */
-+        set_all_multicast(vptr);
-+		rx_mode |= RCR_AM;
-+	} else {
-+        /* Write a CAM entry for each multicast address */
- 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
--			mac_set_cam(regs, i + offset, mclist->dmi_addr);
--			vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
-+			mac_set_cam(regs, i, mclist->dmi_addr, VELOCITY_MULTICAST_CAM);
-+			vptr->mCAMmask[i / 8] |= 1 << (i & 7);
- 		}
- 
--		mac_set_cam_mask(regs, vptr->mCAMmask);
--		rx_mode = (RCR_AM | RCR_AB);
-+        /* Enable those multicast CAM entries just written */
-+		mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
-+
-+        /* Enable multicast perfect matching */
-+		rx_mode |= (RCR_AM | RCR_AP);
- 	}
-+
-+    /* Allow large packets if indicated by MTU */
- 	if (dev->mtu > 1500)
- 		rx_mode |= RCR_AL;
- 
--	BYTE_REG_BITS_ON(rx_mode, &regs->RCR);
--
-+	BYTE_REG_BITS_SET(rx_mode, RCR_AM | RCR_AB | RCR_PROM | RCR_AL | RCR_AP, &regs->RCR);
- }
- 
- /**
-@@ -2314,36 +2350,32 @@
-  *	the hardware into the counters before letting the network
-  *	layer display them.
-  */
--
-+ 
- static struct net_device_stats *velocity_get_stats(struct net_device *dev)
- {
--	struct velocity_info *vptr = netdev_priv(dev);
--
--	/* If the hardware is down, don't touch MII */
--	if(!netif_running(dev))
--		return &vptr->stats;
--
--	spin_lock_irq(&vptr->lock);
--	velocity_update_hw_mibs(vptr);
--	spin_unlock_irq(&vptr->lock);
-+	struct velocity_info *vptr = dev->priv;
- 
--	vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
--	vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
--	vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
-+#if 0
-+    /* Only access the MIBs if the hardware is up */
-+    if (netif_running(dev)) {
-+        int i;
- 
--//  unsigned long   rx_dropped;     /* no space in linux buffers    */
--	vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
--	/* detailed rx_errors: */
--//  unsigned long   rx_length_errors;
--//  unsigned long   rx_over_errors;     /* receiver ring buff overflow  */
--	vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
--//  unsigned long   rx_frame_errors;    /* recv'd frame alignment error */
--//  unsigned long   rx_fifo_errors;     /* recv'r fifo overrun      */
--//  unsigned long   rx_missed_errors;   /* receiver missed packet   */
-+        /* Transfer from fast counters to MIB SRAM, locking against
-+           simulatanous access by ISR due to MIB high threshold being
-+           exceeded */
-+        spin_lock_irq(&vptr->lock);
-+        velocity_update_hw_mibs(vptr);
-+        spin_unlock_irq(&vptr->lock);
- 
--	/* detailed tx_errors */
--//  unsigned long   tx_fifo_errors;
-+        /* Print MIB statistics */
-+        printk("MIBs:\n");
-+        for (i=0; i < HW_MIB_SIZE; ++i) {
-+            printk("%02d: %08d\n", i, vptr->mib_counter[i]);
-+        }
-+    }
-+#endif
- 
-+    /* Return only the statistics gathered by the driver, not MIBs */
- 	return &vptr->stats;
- }
- 
-@@ -2357,7 +2389,7 @@
-  *	Called when the user issues an ioctl request to the network
-  *	device in question. The velocity interface supports MII.
-  */
--
-+ 
- static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
-@@ -2365,10 +2397,10 @@
- 
- 	/* If we are asked for information and the device is power
- 	   saving then we need to bring the device back up to talk to it */
--
-+	   	
- 	if (!netif_running(dev))
- 		pci_set_power_state(vptr->pdev, PCI_D0);
--
-+		
- 	switch (cmd) {
- 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
- 	case SIOCGMIIREG:	/* Read MII PHY register. */
-@@ -2381,8 +2413,8 @@
- 	}
- 	if (!netif_running(dev))
- 		pci_set_power_state(vptr->pdev, PCI_D3hot);
--
--
-+		
-+		
- 	return ret;
- }
- 
-@@ -2390,7 +2422,7 @@
-  *	Definition for our device driver. The PCI layer interface
-  *	uses this to handle all our card discover and plugging
-  */
--
-+ 
- static struct pci_driver velocity_driver = {
-       .name	= VELOCITY_NAME,
-       .id_table	= velocity_id_table,
-@@ -2410,13 +2442,13 @@
-  *	the probe functions for each velocity adapter installed
-  *	in the system.
-  */
--
-+ 
- static int __init velocity_init_module(void)
- {
- 	int ret;
- 
- 	velocity_register_notifier();
--	ret = pci_register_driver(&velocity_driver);
-+	ret = pci_module_init(&velocity_driver);
- 	if (ret < 0)
- 		velocity_unregister_notifier();
- 	return ret;
-@@ -2426,11 +2458,11 @@
-  *	velocity_cleanup	-	module unload
-  *
-  *	When the velocity hardware is unloaded this function is called.
-- *	It will clean up the notifiers and the unregister the PCI
-+ *	It will clean up the notifiers and the unregister the PCI 
-  *	driver interface for this hardware. This in turn cleans up
-  *	all discovered interfaces before returning from the function
-  */
--
-+ 
- static void __exit velocity_cleanup_module(void)
- {
- 	velocity_unregister_notifier();
-@@ -2444,8 +2476,8 @@
- /*
-  * MII access , media link mode setting functions
-  */
--
--
-+ 
-+ 
- /**
-  *	mii_init	-	set up MII
-  *	@vptr: velocity adapter
-@@ -2453,7 +2485,7 @@
-  *
-  *	Set up the PHY for the current link state.
-  */
--
-+ 
- static void mii_init(struct velocity_info *vptr, u32 mii_status)
- {
- 	u16 BMCR;
-@@ -2466,7 +2498,7 @@
- 		MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- 		/*
- 		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
--		 *	off it in NWay-forced half mode for NWay-forced v.s.
-+		 *	off it in NWay-forced half mode for NWay-forced v.s. 
- 		 *	legacy-forced issue.
- 		 */
- 		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-@@ -2486,7 +2518,7 @@
- 		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- 		/*
- 		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
--		 *	off it in NWay-forced half mode for NWay-forced v.s.
-+		 *	off it in NWay-forced half mode for NWay-forced v.s. 
- 		 *	legacy-forced issue
- 		 */
- 		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-@@ -2498,11 +2530,11 @@
- 	case PHYID_MARVELL_1000:
- 	case PHYID_MARVELL_1000S:
- 		/*
--		 *	Assert CRS on Transmit
-+		 *	Assert CRS on Transmit 
- 		 */
- 		MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
- 		/*
--		 *	Reset to hardware default
-+		 *	Reset to hardware default 
- 		 */
- 		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- 		break;
-@@ -2522,7 +2554,7 @@
-  *
-  *	Turn off the autopoll and wait for it to disable on the chip
-  */
--
-+ 
- static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs)
- {
- 	u16 ww;
-@@ -2576,7 +2608,7 @@
-  *	Perform a single read of an MII 16bit register. Returns zero
-  *	on success or -ETIMEDOUT if the PHY did not respond.
-  */
--
-+ 
- static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
- {
- 	u16 ww;
-@@ -2612,7 +2644,7 @@
-  *	Perform a single write to an MII 16bit register. Returns zero
-  *	on success or -ETIMEDOUT if the PHY did not respond.
-  */
--
-+ 
- static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
- {
- 	u16 ww;
-@@ -2651,7 +2683,7 @@
-  *	mii_status accordingly. The requested link state information
-  *	is also returned.
-  */
--
-+ 
- static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
- {
- 	u32 status = 0;
-@@ -2683,7 +2715,7 @@
-  *
-  *	Enable autonegotation on this interface
-  */
--
-+ 
- static void mii_set_auto_on(struct velocity_info *vptr)
- {
- 	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
-@@ -2707,7 +2739,7 @@
-  *	Set up the flow control on this interface according to
-  *	the supplied user/eeprom options.
-  */
--
-+ 
- static void set_mii_flow_control(struct velocity_info *vptr)
- {
- 	/*Enable or Disable PAUSE in ANAR */
-@@ -2744,7 +2776,7 @@
-  *	PHY and also velocity hardware setup accordingly. In particular
-  *	we need to set up CD polling and frame bursting.
-  */
--
-+ 
- static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
- {
- 	u32 curr_status;
-@@ -2854,7 +2886,7 @@
-  *	Check the current MII status and determine the link status
-  *	accordingly
-  */
--
-+ 
- static u32 mii_check_media_mode(struct mac_regs __iomem * regs)
- {
- 	u32 status = 0;
-@@ -2986,14 +3018,14 @@
-  *	Called before an ethtool operation. We need to make sure the
-  *	chip is out of D3 state before we poke at it.
-  */
--
-+ 
- static int velocity_ethtool_up(struct net_device *dev)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
- 	if (!netif_running(dev))
- 		pci_set_power_state(vptr->pdev, PCI_D0);
- 	return 0;
--}
-+}	
- 
- /**
-  *	velocity_ethtool_down	-	post hook for ethtool
-@@ -3002,7 +3034,7 @@
-  *	Called after an ethtool operation. Restore the chip back to D3
-  *	state if it isn't running.
-  */
--
-+ 
- static void velocity_ethtool_down(struct net_device *dev)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
-@@ -3040,7 +3072,21 @@
- 		cmd->duplex = DUPLEX_FULL;
- 	else
- 		cmd->duplex = DUPLEX_HALF;
--
-+		
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("Regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+    printk("0x%02x\t", readb(&(ptr[i])));
-+    if (!((i+1) % 8)) {
-+        printk("\n0x%02x:\t", i+1);
-+    }
-+}
-+}
-+#endif
- 	return 0;
- }
- 
-@@ -3050,7 +3096,7 @@
- 	u32 curr_status;
- 	u32 new_status = 0;
- 	int ret = 0;
--
-+	
- 	curr_status = check_connection_type(vptr->mac_regs);
- 	curr_status &= (~VELOCITY_LINK_FAIL);
- 
-@@ -3061,8 +3107,10 @@
- 
- 	if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE)))
- 		ret = -EINVAL;
--	else
-+	else {
- 		velocity_set_media_mode(vptr, new_status);
-+		mac_set_dma_length(vptr);
-+    }
- 
- 	return ret;
- }
-@@ -3139,7 +3187,7 @@
- 	 msglevel = value;
- }
- 
--static const struct ethtool_ops velocity_ethtool_ops = {
-+static struct ethtool_ops velocity_ethtool_ops = {
- 	.get_settings	=	velocity_get_settings,
- 	.set_settings	=	velocity_set_settings,
- 	.get_drvinfo	=	velocity_get_drvinfo,
-@@ -3162,7 +3210,7 @@
-  *	are used by tools like kudzu to interrogate the link state of the
-  *	hardware
-  */
--
-+ 
- static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
- 	struct velocity_info *vptr = netdev_priv(dev);
-@@ -3170,7 +3218,7 @@
- 	unsigned long flags;
- 	struct mii_ioctl_data *miidata = if_mii(ifr);
- 	int err;
--
-+	
- 	switch (cmd) {
- 	case SIOCGMIIPHY:
- 		miidata->phy_id = readb(&regs->MIIADR) & 0x1f;
-@@ -3197,11 +3245,36 @@
- 	return 0;
- }
- 
-+static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* p)
-+{
-+    struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+    int i;
-+    for (i = 0; i < 6; i++) {
-+        writeb(p[i], &(regs->PAR[i]));
-+    }
-+}
-+
-+static int set_mac_address(struct net_device *dev, void *p)
-+{
-+    struct sockaddr *addr = p;
-+    struct velocity_info *vptr = dev->priv;
-+
-+    if (!is_valid_ether_addr(addr->sa_data)) {
-+        return -EADDRNOTAVAIL;
-+    }
-+
-+    memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+    hw_set_mac_address(vptr, addr->sa_data);
-+
-+    return 0;
-+}
-+
- #ifdef CONFIG_PM
- 
- /**
-  *	velocity_save_context	-	save registers
-- *	@vptr: velocity
-+ *	@vptr: velocity 
-  *	@context: buffer for stored context
-  *
-  *	Retrieve the current configuration from the velocity hardware
-@@ -3209,7 +3282,7 @@
-  *	restore functions. This allows us to save things we need across
-  *	power down states
-  */
--
-+ 
- static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
- {
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -3229,13 +3302,13 @@
- 
- /**
-  *	velocity_restore_context	-	restore registers
-- *	@vptr: velocity
-+ *	@vptr: velocity 
-  *	@context: buffer for stored context
-  *
-- *	Reload the register configuration from the velocity context
-+ *	Reload the register configuration from the velocity context 
-  *	created by velocity_save_context.
-  */
--
-+ 
- static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
- {
- 	struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -3301,7 +3374,7 @@
- 	}
- 	/*	Finally, invert the result once to get the correct data */
- 	crc = ~crc;
--	return bitrev32(crc) >> 16;
-+	return bitreverse(crc) >> 16;
- }
- 
- /**
-@@ -3461,8 +3534,6 @@
- 	return 0;
- }
- 
--#ifdef CONFIG_INET
--
- static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
- {
- 	struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
-@@ -3483,6 +3554,4 @@
- 	}
- 	return NOTIFY_DONE;
- }
--
--#endif
- #endif
-diff -Nurd linux-2.6.24/drivers/net/via-velocity.h linux-2.6.24-oxe810/drivers/net/via-velocity.h
---- linux-2.6.24/drivers/net/via-velocity.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/via-velocity.h	2008-06-11 17:50:11.000000000 +0200
-@@ -25,8 +25,6 @@
- #ifndef VELOCITY_H
- #define VELOCITY_H
- 
--#define VELOCITY_TX_CSUM_SUPPORT
--
- #define VELOCITY_NAME          "via-velocity"
- #define VELOCITY_FULL_DRV_NAM  "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"
- #define VELOCITY_VERSION       "1.14"
-@@ -35,6 +33,8 @@
- 
- #define PKT_BUF_SZ          1540
- 
-+#define PKT_BUF_SZ          ETH_ZLEN
-+
- #define MAX_UNITS           8
- #define OPTION_DEFAULT      { [0 ... MAX_UNITS-1] = -1}
- 
-@@ -716,6 +716,8 @@
- /*
-  *	Bits in the CFGA register
-  */
-+#define CFGA_PHYLEDS1       0x20
-+#define CFGA_PHYLEDS0       0x10
- 
- #define CFGA_PMHCTG         0x08
- #define CFGA_GPIO1PD        0x04
-@@ -766,6 +768,7 @@
- #define DCFG_XMRM           0x4000
- #define DCFG_XMRL           0x2000
- #define DCFG_PERDIS         0x1000
-+#define DCFG_MRDPL          0x0800
- #define DCFG_MRWAIT         0x0400
- #define DCFG_MWWAIT         0x0200
- #define DCFG_LATMEN         0x0100
-@@ -1173,7 +1176,7 @@
- 
- struct velocity_info_tbl {
- 	enum chip_type chip_id;
--	const char *name;
-+	char *name;
- 	int txqueue;
- 	u32 flags;
- };
-@@ -1194,8 +1197,12 @@
- #define mac_disable_int(regs)       	writel(CR0_GINTMSK1,&((regs)->CR0Clr))
- #define mac_enable_int(regs)    	writel(CR0_GINTMSK1,&((regs)->CR0Set))
- 
--#define mac_set_dma_length(regs, n) {\
--	BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\
-+#define mac_hw_mibs_read(regs, MIBs) {\
-+	int i;\
-+	BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\
-+	for (i=0;i<HW_MIB_SIZE;i++) {\
-+		(MIBs)[i]=readl(&((regs)->MIBData));\
-+	}\
- }
- 
- #define mac_set_rx_thresh(regs, n) {\
-@@ -1218,17 +1225,184 @@
- 	writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\
- }
- 
--static inline void mac_eeprom_reload(struct mac_regs __iomem * regs) {
--	int i=0;
-+enum velocity_cam_type {
-+	VELOCITY_VLAN_ID_CAM = 0,
-+	VELOCITY_MULTICAST_CAM
-+};
- 
--	BYTE_REG_BITS_ON(EECSR_RELOAD,&(regs->EECSR));
--	do {
--		udelay(10);
--		if (i++>0x1000)
--			break;
--	} while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&(regs->EECSR)));
-+/**
-+ *	mac_get_cam_mask	-	Read a CAM mask
-+ *	@regs: register block for this velocity
-+ *	@mask: buffer to store mask
-+ *	@cam_type: CAM to fetch
-+ *
-+ *	Fetch the mask bits of the selected CAM and store them into the
-+ *	provided mask buffer.
-+ */
-+
-+static inline void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-+{
-+	int i;
-+	/* Select CAM mask */
-+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		writeb(CAMADDR_VCAMSL, &regs->CAMADDR);
-+	else
-+		writeb(0, &regs->CAMADDR);
-+
-+	/* read mask */
-+	for (i = 0; i < 8; i++)
-+		*mask++ = readb(&(regs->MARCAM[i]));
-+
-+	/* disable CAMEN */
-+	writeb(0, &regs->CAMADDR);
-+
-+	/* Select mar */
-+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+
-+}
-+
-+/**
-+ *	mac_set_cam_mask	-	Set a CAM mask
-+ *	@regs: register block for this velocity
-+ *	@mask: CAM mask to load
-+ *	@cam_type: CAM to store
-+ *
-+ *	Store a new mask into a CAM
-+ */
-+
-+static inline void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-+{
-+	int i;
-+	/* Select CAM mask */
-+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
-+	else
-+		writeb(CAMADDR_CAMEN, &regs->CAMADDR);
-+
-+	for (i = 0; i < 8; i++) {
-+		writeb(*mask++, &(regs->MARCAM[i]));
-+	}
-+	/* disable CAMEN */
-+	writeb(0, &regs->CAMADDR);
-+
-+	/* Select mar */
-+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
- }
- 
-+/**
-+ *	mac_set_cam	-	set CAM data
-+ *	@regs: register block of this velocity
-+ *	@idx: Cam index
-+ *	@addr: 2 or 6 bytes of CAM data
-+ *	@cam_type: CAM to load
-+ *
-+ *	Load an address or vlan tag into a CAM
-+ */
-+
-+static inline void mac_set_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-+{
-+	int i;
-+
-+	/* Select CAM mask */
-+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+
-+	idx &= (64 - 1);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
-+	else
-+		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		writew(*((u16 *) addr), &regs->MARCAM[0]);
-+	else {
-+		for (i = 0; i < 6; i++) {
-+			writeb(*addr++, &(regs->MARCAM[i]));
-+		}
-+	}
-+	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
-+
-+	udelay(10);
-+
-+	writeb(0, &regs->CAMADDR);
-+
-+	/* Select mar */
-+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+}
-+
-+/**
-+ *	mac_get_cam	-	fetch CAM data
-+ *	@regs: register block of this velocity
-+ *	@idx: Cam index
-+ *	@addr: buffer to hold up to 6 bytes of CAM data
-+ *	@cam_type: CAM to load
-+ *
-+ *	Load an address or vlan tag from a CAM into the buffer provided by
-+ *	the caller. VLAN tags are 2 bytes the address cam entries are 6.
-+ */
-+
-+static inline void mac_get_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-+{
-+	int i;
-+
-+	/* Select CAM mask */
-+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+
-+	idx &= (64 - 1);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
-+	else
-+		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
-+
-+	BYTE_REG_BITS_ON(CAMCR_CAMRD, &regs->CAMCR);
-+
-+	udelay(10);
-+
-+	if (cam_type == VELOCITY_VLAN_ID_CAM)
-+		*((u16 *) addr) = readw(&(regs->MARCAM[0]));
-+	else
-+		for (i = 0; i < 6; i++, addr++)
-+			*((u8 *) addr) = readb(&(regs->MARCAM[i]));
-+
-+	writeb(0, &regs->CAMADDR);
-+
-+	/* Select mar */
-+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-+}
-+
-+/**
-+ *	mac_wol_reset	-	reset WOL after exiting low power
-+ *	@regs: register block of this velocity
-+ *
-+ *	Called after we drop out of wake on lan mode in order to
-+ *	reset the Wake on lan features. This function doesn't restore
-+ *	the rest of the logic from the result of sleep/wakeup
-+ */
-+
-+static inline void mac_wol_reset(struct mac_regs __iomem * regs)
-+{
-+
-+	/* Turn off SWPTAG right after leaving power mode */
-+	BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
-+	/* clear sticky bits */
-+	BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
-+
-+	BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
-+	BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
-+	/* disable force PME-enable */
-+	writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
-+	/* disable power-event config bit */
-+	writew(0xFFFF, &regs->WOLCRClr);
-+	/* clear power status */
-+	writew(0xFFFF, &regs->WOLSRClr);
-+}
-+
-+
- /*
-  * Header for WOL definitions. Used to compute hashes
-  */
-@@ -1515,8 +1689,9 @@
- 	int numrx;			/* Number of RX descriptors */
- 	int numtx;			/* Number of TX descriptors */
- 	enum speed_opt spd_dpx;		/* Media link mode */
--
--	int DMA_length;			/* DMA length */
-+	int vid;			/* vlan id */
-+	int DMA_length_100M;	/* DMA length at 100Mb/s */
-+	int DMA_length_1000M;	/* DMA length at 1Gb/s */
- 	int rx_thresh;			/* RX_THRESH */
- 	int flow_cntl;
- 	int wol_opts;			/* Wake on lan options */
-@@ -1541,7 +1716,6 @@
- 	dma_addr_t tx_bufs_dma;
- 	u8 *tx_bufs;
- 
--	struct vlan_group    *vlgrp;
- 	u8 ip_addr[4];
- 	enum chip_type chip_id;
- 
-@@ -1578,7 +1752,6 @@
- 	int rx_buf_sz;
- 	u32 mii_status;
- 	u32 phy_id;
--	int multicast_limit;
- 
- 	u8 vCAMmask[(VCAM_SIZE / 8)];
- 	u8 mCAMmask[(MCAM_SIZE / 8)];
-@@ -1623,32 +1796,6 @@
- }
- 
- /**
-- *	velocity_update_hw_mibs	-	fetch MIB counters from chip
-- *	@vptr: velocity to update
-- *
-- *	The velocity hardware keeps certain counters in the hardware
-- * 	side. We need to read these when the user asks for statistics
-- *	or when they overflow (causing an interrupt). The read of the
-- *	statistic clears it, so we keep running master counters in user
-- *	space.
-- */
--
--static inline void velocity_update_hw_mibs(struct velocity_info *vptr)
--{
--	u32 tmp;
--	int i;
--	BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
--
--	while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
--
--	BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
--	for (i = 0; i < HW_MIB_SIZE; i++) {
--		tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL;
--		vptr->mib_counter[i] += tmp;
--	}
--}
--
--/**
-  *	init_flow_control_register 	-	set up flow control
-  *	@vptr: velocity to configure
-  *
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c
---- linux-2.6.24/drivers/net/wireless/b43/dma.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c	2008-06-11 17:49:58.000000000 +0200
-@@ -165,7 +165,7 @@
- 	addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
- 	addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
- 	    >> SSB_DMA_TRANSLATION_SHIFT;
--	addrhi |= ssb_dma_translation(ring->dev->dev);
-+	addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
- 	if (slot == ring->nr_slots - 1)
- 		ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
- 	if (start)
-@@ -426,9 +426,21 @@
- static int alloc_ringmemory(struct b43_dmaring *ring)
- {
- 	struct device *dev = ring->dev->dev->dev;
-+	gfp_t flags = GFP_KERNEL;
- 
-+	/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
-+	 * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
-+	 * has shown that 4K is sufficient for the latter as long as the buffer
-+	 * does not cross an 8K boundary.
-+	 *
-+	 * For unknown reasons - possibly a hardware error - the BCM4311 rev
-+	 * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
-+	 * which accounts for the GFP_DMA flag below.
-+	 */
-+	if (ring->dma64)
-+		flags |= GFP_DMA;
- 	ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
--					    &(ring->dmabase), GFP_KERNEL);
-+					    &(ring->dmabase), flags);
- 	if (!ring->descbase) {
- 		b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
- 		return -ENOMEM;
-@@ -483,7 +495,7 @@
- 	return 0;
- }
- 
--/* Reset the RX DMA channel */
-+/* Reset the TX DMA channel */
- int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
- {
- 	int i;
-@@ -647,7 +659,7 @@
- 			b43_dma_write(ring, B43_DMA64_TXRINGHI,
- 				      ((ringbase >> 32) &
- 				       ~SSB_DMA_TRANSLATION_MASK)
--				      | trans);
-+				      | (trans << 1));
- 		} else {
- 			u32 ringbase = (u32) (ring->dmabase);
- 
-@@ -680,8 +692,9 @@
- 			b43_dma_write(ring, B43_DMA64_RXRINGHI,
- 				      ((ringbase >> 32) &
- 				       ~SSB_DMA_TRANSLATION_MASK)
--				      | trans);
--			b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
-+				      | (trans << 1));
-+			b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
-+				      sizeof(struct b43_dmadesc64));
- 		} else {
- 			u32 ringbase = (u32) (ring->dmabase);
- 
-@@ -695,11 +708,12 @@
- 			b43_dma_write(ring, B43_DMA32_RXRING,
- 				      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
- 				      | trans);
--			b43_dma_write(ring, B43_DMA32_RXINDEX, 200);
-+			b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
-+				      sizeof(struct b43_dmadesc32));
- 		}
- 	}
- 
--      out:
-+out:
- 	return err;
- }
- 
-@@ -1106,7 +1120,7 @@
- {
- 	const struct b43_dma_ops *ops = ring->ops;
- 	u8 *header;
--	int slot;
-+	int slot, old_top_slot, old_used_slots;
- 	int err;
- 	struct b43_dmadesc_generic *desc;
- 	struct b43_dmadesc_meta *meta;
-@@ -1116,20 +1130,31 @@
- #define SLOTS_PER_PACKET  2
- 	B43_WARN_ON(skb_shinfo(skb)->nr_frags);
- 
-+	old_top_slot = ring->current_slot;
-+	old_used_slots = ring->used_slots;
-+
- 	/* Get a slot for the header. */
- 	slot = request_slot(ring);
- 	desc = ops->idx2desc(ring, slot, &meta_hdr);
- 	memset(meta_hdr, 0, sizeof(*meta_hdr));
- 
- 	header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]);
--	b43_generate_txhdr(ring->dev, header,
-+	err = b43_generate_txhdr(ring->dev, header,
- 			   skb->data, skb->len, ctl,
- 			   generate_cookie(ring, slot));
-+	if (unlikely(err)) {
-+		ring->current_slot = old_top_slot;
-+		ring->used_slots = old_used_slots;
-+		return err;
-+	}
- 
- 	meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
- 					   sizeof(struct b43_txhdr_fw4), 1);
--	if (dma_mapping_error(meta_hdr->dmaaddr))
-+	if (dma_mapping_error(meta_hdr->dmaaddr)) {
-+		ring->current_slot = old_top_slot;
-+		ring->used_slots = old_used_slots;
- 		return -EIO;
-+	}
- 	ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
- 			     sizeof(struct b43_txhdr_fw4), 1, 0, 0);
- 
-@@ -1147,6 +1172,8 @@
- 	if (dma_mapping_error(meta->dmaaddr)) {
- 		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
- 		if (!bounce_skb) {
-+			ring->current_slot = old_top_slot;
-+			ring->used_slots = old_used_slots;
- 			err = -ENOMEM;
- 			goto out_unmap_hdr;
- 		}
-@@ -1157,6 +1184,8 @@
- 		meta->skb = skb;
- 		meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- 		if (dma_mapping_error(meta->dmaaddr)) {
-+			ring->current_slot = old_top_slot;
-+			ring->used_slots = old_used_slots;
- 			err = -EIO;
- 			goto out_free_bounce;
- 		}
-@@ -1219,6 +1248,13 @@
- 	B43_WARN_ON(ring->stopped);
- 
- 	err = dma_tx_fragment(ring, skb, ctl);
-+	if (unlikely(err == -ENOKEY)) {
-+		/* Drop this packet, as we don't have the encryption key
-+		 * anymore and must not transmit it unencrypted. */
-+		dev_kfree_skb_any(skb);
-+		err = 0;
-+		goto out_unlock;
-+	}
- 	if (unlikely(err)) {
- 		b43err(dev->wl, "DMA tx mapping failure\n");
- 		goto out_unlock;
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c
---- linux-2.6.24/drivers/net/wireless/b43/main.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c	2008-06-11 17:49:58.000000000 +0200
-@@ -101,6 +101,7 @@
- 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
- 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
- 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
-+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
- 	SSB_DEVTABLE_END
- };
- 
-@@ -1800,6 +1801,18 @@
- 		err = -EOPNOTSUPP;
- 		goto out;
- 	}
-+	if (fwrev > 351) {
-+		b43err(dev->wl, "YOUR FIRMWARE IS TOO NEW. Please downgrade your "
-+		       "firmware.\n");
-+		b43err(dev->wl, "Use this firmware tarball: "
-+		       "http://downloads.openwrt.org/sources/broadcom-wl-4.80.53.0.tar.bz2\n");
-+		b43err(dev->wl, "Use this b43-fwcutter tarball: "
-+		       "http://bu3sch.de/b43/fwcutter/b43-fwcutter-009.tar.bz2\n");
-+		b43err(dev->wl, "Read, understand and _do_ what this message says, please.\n");
-+		b43_write32(dev, B43_MMIO_MACCTL, 0);
-+		err = -EOPNOTSUPP;
-+		goto out;
-+	}
- 	b43dbg(dev->wl, "Loading firmware version %u.%u "
- 	       "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
- 	       fwrev, fwpatch,
-@@ -3067,7 +3080,7 @@
- 			unsupported = 1;
- 		break;
- 	case B43_PHYTYPE_G:
--		if (phy_rev > 8)
-+		if (phy_rev > 9)
- 			unsupported = 1;
- 		break;
- 	default:
-@@ -3395,8 +3408,6 @@
- 	b43_bluetooth_coext_enable(dev);
- 
- 	ssb_bus_powerup(bus, 1);	/* Enable dynamic PCTL */
--	memset(wl->bssid, 0, ETH_ALEN);
--	memset(wl->mac_addr, 0, ETH_ALEN);
- 	b43_upload_card_macaddress(dev);
- 	b43_security_init(dev);
- 	b43_rng_init(wl);
-@@ -3493,6 +3504,13 @@
- 	int did_init = 0;
- 	int err = 0;
- 
-+	/* Kill all old instance specific information to make sure
-+	 * the card won't use it in the short timeframe between start
-+	 * and mac80211 reconfiguring it. */
-+	memset(wl->bssid, 0, ETH_ALEN);
-+	memset(wl->mac_addr, 0, ETH_ALEN);
-+	wl->filter_flags = 0;
-+
- 	/* First register RFkill.
- 	 * LEDs that are registered later depend on it. */
- 	b43_rfkill_init(dev);
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c
---- linux-2.6.24/drivers/net/wireless/b43/xmit.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c	2008-06-11 17:49:58.000000000 +0200
-@@ -177,7 +177,7 @@
- 	return 0;
- }
- 
--static void generate_txhdr_fw4(struct b43_wldev *dev,
-+static int generate_txhdr_fw4(struct b43_wldev *dev,
- 			       struct b43_txhdr_fw4 *txhdr,
- 			       const unsigned char *fragment_data,
- 			       unsigned int fragment_len,
-@@ -235,7 +235,15 @@
- 
- 		B43_WARN_ON(key_idx >= dev->max_nr_keys);
- 		key = &(dev->key[key_idx]);
--		B43_WARN_ON(!key->keyconf);
-+
-+		if (unlikely(!key->keyconf)) {
-+			/* This key is invalid. This might only happen
-+			 * in a short timeframe after machine resume before
-+			 * we were able to reconfigure keys.
-+			 * Drop this packet completely. Do not transmit it
-+			 * unencrypted to avoid leaking information. */
-+			return -ENOKEY;
-+		}
- 
- 		/* Hardware appends ICV. */
- 		plcp_fragment_len += txctl->icv_len;
-@@ -352,16 +360,18 @@
- 	txhdr->mac_ctl = cpu_to_le32(mac_ctl);
- 	txhdr->phy_ctl = cpu_to_le16(phy_ctl);
- 	txhdr->extra_ft = extra_ft;
-+
-+	return 0;
- }
- 
--void b43_generate_txhdr(struct b43_wldev *dev,
-+int b43_generate_txhdr(struct b43_wldev *dev,
- 			u8 * txhdr,
- 			const unsigned char *fragment_data,
- 			unsigned int fragment_len,
- 			const struct ieee80211_tx_control *txctl, u16 cookie)
- {
--	generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
--			   fragment_data, fragment_len, txctl, cookie);
-+	return generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
-+				  fragment_data, fragment_len, txctl, cookie);
- }
- 
- static s8 b43_rssi_postprocess(struct b43_wldev *dev,
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h
---- linux-2.6.24/drivers/net/wireless/b43/xmit.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h	2008-06-11 17:49:58.000000000 +0200
-@@ -82,7 +82,7 @@
- #define  B43_TX4_PHY_ANT1		0x0100	/* Use antenna 1 */
- #define  B43_TX4_PHY_ANTLAST	0x0300	/* Use last used antenna */
- 
--void b43_generate_txhdr(struct b43_wldev *dev,
-+int b43_generate_txhdr(struct b43_wldev *dev,
- 			u8 * txhdr,
- 			const unsigned char *fragment_data,
- 			unsigned int fragment_len,
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/dma.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c	2008-06-11 17:49:57.000000000 +0200
-@@ -1164,7 +1164,7 @@
- {
- 	const struct b43legacy_dma_ops *ops = ring->ops;
- 	u8 *header;
--	int slot;
-+	int slot, old_top_slot, old_used_slots;
- 	int err;
- 	struct b43legacy_dmadesc_generic *desc;
- 	struct b43legacy_dmadesc_meta *meta;
-@@ -1174,6 +1174,9 @@
- #define SLOTS_PER_PACKET  2
- 	B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
- 
-+	old_top_slot = ring->current_slot;
-+	old_used_slots = ring->used_slots;
-+
- 	/* Get a slot for the header. */
- 	slot = request_slot(ring);
- 	desc = ops->idx2desc(ring, slot, &meta_hdr);
-@@ -1181,9 +1184,14 @@
- 
- 	header = &(ring->txhdr_cache[slot * sizeof(
- 			       struct b43legacy_txhdr_fw3)]);
--	b43legacy_generate_txhdr(ring->dev, header,
-+	err = b43legacy_generate_txhdr(ring->dev, header,
- 				 skb->data, skb->len, ctl,
- 				 generate_cookie(ring, slot));
-+	if (unlikely(err)) {
-+		ring->current_slot = old_top_slot;
-+		ring->used_slots = old_used_slots;
-+		return err;
-+	}
- 
- 	meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
- 				       sizeof(struct b43legacy_txhdr_fw3), 1);
-@@ -1206,6 +1214,8 @@
- 	if (dma_mapping_error(meta->dmaaddr)) {
- 		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
- 		if (!bounce_skb) {
-+			ring->current_slot = old_top_slot;
-+			ring->used_slots = old_used_slots;
- 			err = -ENOMEM;
- 			goto out_unmap_hdr;
- 		}
-@@ -1216,6 +1226,8 @@
- 		meta->skb = skb;
- 		meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- 		if (dma_mapping_error(meta->dmaaddr)) {
-+			ring->current_slot = old_top_slot;
-+			ring->used_slots = old_used_slots;
- 			err = -EIO;
- 			goto out_free_bounce;
- 		}
-@@ -1282,6 +1294,13 @@
- 	B43legacy_BUG_ON(ring->stopped);
- 
- 	err = dma_tx_fragment(ring, skb, ctl);
-+	if (unlikely(err == -ENOKEY)) {
-+		/* Drop this packet, as we don't have the encryption key
-+		 * anymore and must not transmit it unencrypted. */
-+		dev_kfree_skb_any(skb);
-+		err = 0;
-+		goto out_unlock;
-+	}
- 	if (unlikely(err)) {
- 		b43legacyerr(dev->wl, "DMA tx mapping failure\n");
- 		goto out_unlock;
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/main.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c	2008-06-11 17:49:57.000000000 +0200
-@@ -3215,8 +3215,6 @@
- 	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4);
- 
- 	ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
--	memset(wl->bssid, 0, ETH_ALEN);
--	memset(wl->mac_addr, 0, ETH_ALEN);
- 	b43legacy_upload_card_macaddress(dev);
- 	b43legacy_security_init(dev);
- 	b43legacy_rng_init(wl);
-@@ -3311,6 +3309,13 @@
- 	int did_init = 0;
- 	int err = 0;
- 
-+	/* Kill all old instance specific information to make sure
-+	 * the card won't use it in the short timeframe between start
-+	 * and mac80211 reconfiguring it. */
-+	memset(wl->bssid, 0, ETH_ALEN);
-+	memset(wl->mac_addr, 0, ETH_ALEN);
-+	wl->filter_flags = 0;
-+
- 	mutex_lock(&wl->mutex);
- 
- 	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/pio.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/pio.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c	2008-06-11 17:49:57.000000000 +0200
-@@ -181,7 +181,7 @@
- 	struct b43legacy_txhdr_fw3 txhdr_fw3;
- };
- 
--static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
-+static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
- 				  struct sk_buff *skb,
- 				  struct b43legacy_pio_txpacket *packet,
- 				  size_t txhdr_size)
-@@ -189,14 +189,17 @@
- 	union txhdr_union txhdr_data;
- 	u8 *txhdr = NULL;
- 	unsigned int octets;
-+	int err;
- 
- 	txhdr = (u8 *)(&txhdr_data.txhdr_fw3);
- 
- 	B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
--	b43legacy_generate_txhdr(queue->dev,
-+	err = b43legacy_generate_txhdr(queue->dev,
- 				 txhdr, skb->data, skb->len,
- 				 &packet->txstat.control,
- 				 generate_cookie(queue, packet));
-+	if (err)
-+		return err;
- 
- 	tx_start(queue);
- 	octets = skb->len + txhdr_size;
-@@ -204,6 +207,8 @@
- 		octets--;
- 	tx_data(queue, txhdr, (u8 *)skb->data, octets);
- 	tx_complete(queue, skb);
-+
-+	return 0;
- }
- 
- static void free_txpacket(struct b43legacy_pio_txpacket *packet,
-@@ -226,6 +231,7 @@
- 	struct b43legacy_pioqueue *queue = packet->queue;
- 	struct sk_buff *skb = packet->skb;
- 	u16 octets;
-+	int err;
- 
- 	octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3);
- 	if (queue->tx_devq_size < octets) {
-@@ -247,8 +253,14 @@
- 	if (queue->tx_devq_used + octets > queue->tx_devq_size)
- 		return -EBUSY;
- 	/* Now poke the device. */
--	pio_tx_write_fragment(queue, skb, packet,
-+	err = pio_tx_write_fragment(queue, skb, packet,
- 			      sizeof(struct b43legacy_txhdr_fw3));
-+	if (unlikely(err == -ENOKEY)) {
-+		/* Drop this packet, as we don't have the encryption key
-+		 * anymore and must not transmit it unencrypted. */
-+		free_txpacket(packet, 1);
-+		return 0;
-+	}
- 
- 	/* Account for the packet size.
- 	 * (We must not overflow the device TX queue)
-@@ -486,6 +498,9 @@
- 	queue = parse_cookie(dev, status->cookie, &packet);
- 	B43legacy_WARN_ON(!queue);
- 
-+	if (!packet->skb)
-+		return;
-+
- 	queue->tx_devq_packets--;
- 	queue->tx_devq_used -= (packet->skb->len +
- 				sizeof(struct b43legacy_txhdr_fw3));
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c	2008-06-11 17:49:57.000000000 +0200
-@@ -181,7 +181,7 @@
- 	return 0;
- }
- 
--static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
-+static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
- 			       struct b43legacy_txhdr_fw3 *txhdr,
- 			       const unsigned char *fragment_data,
- 			       unsigned int fragment_len,
-@@ -252,6 +252,13 @@
- 			iv_len = min((size_t)txctl->iv_len,
- 				     ARRAY_SIZE(txhdr->iv));
- 			memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
-+		} else {
-+			/* This key is invalid. This might only happen
-+			 * in a short timeframe after machine resume before
-+			 * we were able to reconfigure keys.
-+			 * Drop this packet completely. Do not transmit it
-+			 * unencrypted to avoid leaking information. */
-+			return -ENOKEY;
- 		}
- 	}
- 	b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
-@@ -344,16 +351,18 @@
- 	/* Apply the bitfields */
- 	txhdr->mac_ctl = cpu_to_le32(mac_ctl);
- 	txhdr->phy_ctl = cpu_to_le16(phy_ctl);
-+
-+	return 0;
- }
- 
--void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
-+int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
- 			      u8 *txhdr,
- 			      const unsigned char *fragment_data,
- 			      unsigned int fragment_len,
- 			      const struct ieee80211_tx_control *txctl,
- 			      u16 cookie)
- {
--	generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
-+	return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
- 			   fragment_data, fragment_len,
- 			   txctl, cookie);
- }
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h
---- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h	2008-06-11 17:49:57.000000000 +0200
-@@ -76,7 +76,7 @@
- 
- 
- 
--void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
-+int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
- 			      u8 *txhdr,
- 			      const unsigned char *fragment_data,
- 			      unsigned int fragment_len,
-diff -Nurd linux-2.6.24/drivers/pci/hotplug/fakephp.c linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c
---- linux-2.6.24/drivers/pci/hotplug/fakephp.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c	2008-06-11 17:49:28.000000000 +0200
-@@ -39,6 +39,7 @@
- #include <linux/init.h>
- #include <linux/string.h>
- #include <linux/slab.h>
-+#include <linux/workqueue.h>
- #include "../pci.h"
- 
- #if !defined(MODULE)
-@@ -63,10 +64,16 @@
- 	struct list_head node;
- 	struct hotplug_slot *slot;
- 	struct pci_dev *dev;
-+	struct work_struct remove_work;
-+	unsigned long removed;
- };
- 
- static int debug;
- static LIST_HEAD(slot_list);
-+static struct workqueue_struct *dummyphp_wq;
-+
-+static void pci_rescan_worker(struct work_struct *work);
-+static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
- 
- static int enable_slot (struct hotplug_slot *slot);
- static int disable_slot (struct hotplug_slot *slot);
-@@ -109,7 +116,7 @@
- 	slot->name = &dev->dev.bus_id[0];
- 	dbg("slot->name = %s\n", slot->name);
- 
--	dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
-+	dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
- 	if (!dslot)
- 		goto error_info;
- 
-@@ -164,6 +171,14 @@
- 		err("Problem unregistering a slot %s\n", dslot->slot->name);
- }
- 
-+/* called from the single-threaded workqueue handler to remove a slot */
-+static void remove_slot_worker(struct work_struct *work)
-+{
-+	struct dummy_slot *dslot =
-+		container_of(work, struct dummy_slot, remove_work);
-+	remove_slot(dslot);
-+}
-+
- /**
-  * pci_rescan_slot - Rescan slot
-  * @temp: Device template. Should be set: bus and devfn.
-@@ -267,11 +282,17 @@
- 	pci_rescan_buses(&pci_root_buses);
- }
- 
-+/* called from the single-threaded workqueue handler to rescan all pci buses */
-+static void pci_rescan_worker(struct work_struct *work)
-+{
-+	pci_rescan();
-+}
- 
- static int enable_slot(struct hotplug_slot *hotplug_slot)
- {
- 	/* mis-use enable_slot for rescanning of the pci bus */
--	pci_rescan();
-+	cancel_work_sync(&pci_rescan_work);
-+	queue_work(dummyphp_wq, &pci_rescan_work);
- 	return -ENODEV;
- }
- 
-@@ -306,6 +327,10 @@
- 		err("Can't remove PCI devices with other PCI devices behind it yet.\n");
- 		return -ENODEV;
- 	}
-+	if (test_and_set_bit(0, &dslot->removed)) {
-+		dbg("Slot already scheduled for removal\n");
-+		return -ENODEV;
-+	}
- 	/* search for subfunctions and disable them first */
- 	if (!(dslot->dev->devfn & 7)) {
- 		for (func = 1; func < 8; func++) {
-@@ -328,8 +353,9 @@
- 	/* remove the device from the pci core */
- 	pci_remove_bus_device(dslot->dev);
- 
--	/* blow away this sysfs entry and other parts. */
--	remove_slot(dslot);
-+	/* queue work item to blow away this sysfs entry and other parts. */
-+	INIT_WORK(&dslot->remove_work, remove_slot_worker);
-+	queue_work(dummyphp_wq, &dslot->remove_work);
- 
- 	return 0;
- }
-@@ -340,6 +366,7 @@
- 	struct list_head *next;
- 	struct dummy_slot *dslot;
- 
-+	destroy_workqueue(dummyphp_wq);
- 	list_for_each_safe (tmp, next, &slot_list) {
- 		dslot = list_entry (tmp, struct dummy_slot, node);
- 		remove_slot(dslot);
-@@ -351,6 +378,10 @@
- {
- 	info(DRIVER_DESC "\n");
- 
-+	dummyphp_wq = create_singlethread_workqueue(MY_NAME);
-+	if (!dummyphp_wq)
-+		return -ENOMEM;
-+
- 	return pci_scan_buses();
- }
- 
-diff -Nurd linux-2.6.24/drivers/pci/probe.c linux-2.6.24-oxe810/drivers/pci/probe.c
---- linux-2.6.24/drivers/pci/probe.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/pci/probe.c	2008-06-11 17:49:28.000000000 +0200
-@@ -991,8 +991,18 @@
- 	for (func = 0; func < 8; func++, devfn++) {
- 		struct pci_dev *dev;
- 
--		dev = pci_scan_single_device(bus, devfn);
--		if (dev) {
-+#ifdef CONFIG_PCI_OXNAS_CARDBUS
-+        // printk(KERN_INFO "pci_scan_slot %u\n", PCI_SLOT(devfn) ); 
-+        scan_all_fns = 1;
-+        if (  PCI_SLOT(devfn) == 5 ) 
-+            dev = pci_scan_single_device(bus, devfn);
-+        else
-+            dev = 0;
-+#else  /* ifndef CONFIG_OXNAS_CARDBUS */
-+        dev = pci_scan_single_device(bus, devfn);
-+#endif /* CONFIG_OXNAS_CARDBUS */
-+
-+        if (dev) {
- 			nr++;
- 
- 			/*
-diff -Nurd linux-2.6.24/drivers/rtc/rtc-ds1307.c linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c
---- linux-2.6.24/drivers/rtc/rtc-ds1307.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c	2008-06-11 17:49:41.000000000 +0200
-@@ -17,7 +17,7 @@
- #include <linux/rtc.h>
- #include <linux/bcd.h>
- 
--
-+#define ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
- 
- /* We can't determine type by probing, but if we expect pre-Linux code
-  * to have set the chip up as a clock (turning on the oscillator and
-@@ -445,6 +445,7 @@
- 		break;
- 	}
- 
-+#ifndef ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
- 	tmp = ds1307->regs[DS1307_REG_SECS];
- 	tmp = BCD2BIN(tmp & 0x7f);
- 	if (tmp > 60)
-@@ -460,6 +461,7 @@
- 	tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
- 	if (tmp == 0 || tmp > 12)
- 		goto exit_bad;
-+#endif // !ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
- 
- 	tmp = ds1307->regs[DS1307_REG_HOUR];
- 	switch (ds1307->type) {
-diff -Nurd linux-2.6.24/drivers/s390/char/defkeymap.c linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c
---- linux-2.6.24/drivers/s390/char/defkeymap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c	2008-06-11 17:49:17.000000000 +0200
-@@ -151,8 +151,8 @@
- };
- 
- struct kbdiacruc accent_table[MAX_DIACR] = {
--	{'^', 'c', '\003'},	{'^', 'd', '\004'},
--	{'^', 'z', '\032'},	{'^', '\012', '\000'},
-+	{'^', 'c', 0003},	{'^', 'd', 0004},
-+	{'^', 'z', 0032},	{'^', 0012, 0000},
- };
- 
- unsigned int accent_table_size = 4;
-diff -Nurd linux-2.6.24/drivers/scsi/Kconfig linux-2.6.24-oxe810/drivers/scsi/Kconfig
---- linux-2.6.24/drivers/scsi/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/Kconfig	2008-06-11 17:50:29.000000000 +0200
-@@ -556,6 +556,15 @@
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called arcmsr (modprobe arcmsr).
- 
-+config SCSI_SATA_DISK_DETECTION_TENACITY
-+    int "The number of attempts to detect a disk."
-+    default 1
-+	depends on SCSI_SATA
-+	help
-+	  Sets the number of times taken to repeat a 700 ms process of detecting a disk. Some disks will not respond to detection until they have spun-up and they won't spin-up untill they receive some communication from the host.
-+
-+	  If unsure, use 1.
-+
- config SCSI_ARCMSR_AER
- 	bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)"
- 	depends on SCSI_ARCMSR && PCIEAER
-diff -Nurd linux-2.6.24/drivers/scsi/advansys.c linux-2.6.24-oxe810/drivers/scsi/advansys.c
---- linux-2.6.24/drivers/scsi/advansys.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/advansys.c	2008-06-11 17:50:28.000000000 +0200
-@@ -566,7 +566,7 @@
- 	ASC_SCSI_BIT_ID_TYPE unit_not_ready;
- 	ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
- 	ASC_SCSI_BIT_ID_TYPE start_motor;
--	uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8);
-+	uchar *overrun_buf;
- 	dma_addr_t overrun_dma;
- 	uchar scsi_reset_wait;
- 	uchar chip_no;
-@@ -6439,7 +6439,7 @@
- 			i += 2;
- 			len += 2;
- 		} else {
--			unsigned char off = buf[i] * 2;
-+			unsigned int off = buf[i] * 2;
- 			unsigned short word = (buf[off + 1] << 8) | buf[off];
- 			AdvWriteWordAutoIncLram(iop_base, word);
- 			len += 2;
-@@ -13833,6 +13833,12 @@
- 	 */
- 	if (ASC_NARROW_BOARD(boardp)) {
- 		ASC_DBG(2, "AscInitAsc1000Driver()\n");
-+
-+		asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
-+		if (!asc_dvc_varp->overrun_buf) {
-+			ret = -ENOMEM;
-+			goto err_free_wide_mem;
-+		}
- 		warn_code = AscInitAsc1000Driver(asc_dvc_varp);
- 
- 		if (warn_code || asc_dvc_varp->err_code) {
-@@ -13840,8 +13846,10 @@
- 					"warn 0x%x, error 0x%x\n",
- 					asc_dvc_varp->init_state, warn_code,
- 					asc_dvc_varp->err_code);
--			if (asc_dvc_varp->err_code)
-+			if (asc_dvc_varp->err_code) {
- 				ret = -ENODEV;
-+				kfree(asc_dvc_varp->overrun_buf);
-+			}
- 		}
- 	} else {
- 		if (advansys_wide_init_chip(shost))
-@@ -13894,6 +13902,7 @@
- 		dma_unmap_single(board->dev,
- 					board->dvc_var.asc_dvc_var.overrun_dma,
- 					ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
-+		kfree(board->dvc_var.asc_dvc_var.overrun_buf);
- 	} else {
- 		iounmap(board->ioremap_addr);
- 		advansys_wide_free_mem(board);
-diff -Nurd linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c
---- linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c	2008-06-11 17:50:27.000000000 +0200
-@@ -458,13 +458,19 @@
- 		tc_abort = le16_to_cpu(tc_abort);
- 
- 		list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
--			struct sas_task *task = ascb->uldd_task;
-+			struct sas_task *task = a->uldd_task;
- 
--			if (task && a->tc_index == tc_abort) {
-+			if (a->tc_index != tc_abort)
-+				continue;
-+
-+			if (task) {
- 				failed_dev = task->dev;
- 				sas_task_abort(task);
--				break;
-+			} else {
-+				ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
-+					    a->scb->header.opcode);
- 			}
-+			break;
- 		}
- 
- 		if (!failed_dev) {
-@@ -478,7 +484,7 @@
- 		 * that the EH will wake up and do something.
- 		 */
- 		list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
--			struct sas_task *task = ascb->uldd_task;
-+			struct sas_task *task = a->uldd_task;
- 
- 			if (task &&
- 			    task->dev == failed_dev &&
-diff -Nurd linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c
---- linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c	2008-06-11 17:50:28.000000000 +0200
-@@ -1380,17 +1380,16 @@
- 	switch(controlcode) {
- 
- 	case ARCMSR_MESSAGE_READ_RQBUFFER: {
--		unsigned long *ver_addr;
--		dma_addr_t buf_handle;
-+		unsigned char *ver_addr;
- 		uint8_t *pQbuffer, *ptmpQbuffer;
- 		int32_t allxfer_len = 0;
- 
--		ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
-+		ver_addr = kmalloc(1032, GFP_ATOMIC);
- 		if (!ver_addr) {
- 			retvalue = ARCMSR_MESSAGE_FAIL;
- 			goto message_out;
- 		}
--		ptmpQbuffer = (uint8_t *) ver_addr;
-+		ptmpQbuffer = ver_addr;
- 		while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
- 			&& (allxfer_len < 1031)) {
- 			pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
-@@ -1419,25 +1418,24 @@
- 			}
- 			arcmsr_iop_message_read(acb);
- 		}
--		memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
-+		memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
- 		pcmdmessagefld->cmdmessage.Length = allxfer_len;
- 		pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
--		pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
-+		kfree(ver_addr);
- 		}
- 		break;
- 
- 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
--		unsigned long *ver_addr;
--		dma_addr_t buf_handle;
-+		unsigned char *ver_addr;
- 		int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
- 		uint8_t *pQbuffer, *ptmpuserbuffer;
- 
--		ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
-+		ver_addr = kmalloc(1032, GFP_ATOMIC);
- 		if (!ver_addr) {
- 			retvalue = ARCMSR_MESSAGE_FAIL;
- 			goto message_out;
- 		}
--		ptmpuserbuffer = (uint8_t *)ver_addr;
-+		ptmpuserbuffer = ver_addr;
- 		user_len = pcmdmessagefld->cmdmessage.Length;
- 		memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
- 		wqbuf_lastindex = acb->wqbuf_lastindex;
-@@ -1483,7 +1481,7 @@
- 				retvalue = ARCMSR_MESSAGE_FAIL;
- 			}
- 			}
--			pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
-+			kfree(ver_addr);
- 		}
- 		break;
- 
-diff -Nurd linux-2.6.24/drivers/scsi/gdth.c linux-2.6.24-oxe810/drivers/scsi/gdth.c
---- linux-2.6.24/drivers/scsi/gdth.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth.c	2008-06-11 17:50:29.000000000 +0200
-@@ -160,7 +160,7 @@
- static void gdth_clear_events(void);
- 
- static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
--                                    char *buffer, ushort count, int to_buffer);
-+                                    char *buffer, ushort count);
- static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
- static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
- 
-@@ -183,7 +183,6 @@
-                       unsigned int cmd, unsigned long arg);
- 
- static void gdth_flush(gdth_ha_str *ha);
--static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
- static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
- static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
- 				struct gdth_cmndinfo *cmndinfo);
-@@ -418,12 +417,6 @@
- #include "gdth_proc.h"
- #include "gdth_proc.c"
- 
--/* notifier block to get a notify on system shutdown/halt/reboot */
--static struct notifier_block gdth_notifier = {
--    gdth_halt, NULL, 0
--};
--static int notifier_disabled = 0;
--
- static gdth_ha_str *gdth_find_ha(int hanum)
- {
- 	gdth_ha_str *ha;
-@@ -446,8 +439,8 @@
- 	for (i=0; i<GDTH_MAXCMDS; ++i) {
- 		if (ha->cmndinfo[i].index == 0) {
- 			priv = &ha->cmndinfo[i];
--			priv->index = i+1;
- 			memset(priv, 0, sizeof(*priv));
-+			priv->index = i+1;
- 			break;
- 		}
- 	}
-@@ -494,7 +487,6 @@
-     gdth_ha_str *ha = shost_priv(sdev->host);
-     Scsi_Cmnd *scp;
-     struct gdth_cmndinfo cmndinfo;
--    struct scatterlist one_sg;
-     DECLARE_COMPLETION_ONSTACK(wait);
-     int rval;
- 
-@@ -508,13 +500,10 @@
-     /* use request field to save the ptr. to completion struct. */
-     scp->request = (struct request *)&wait;
-     scp->timeout_per_command = timeout*HZ;
--    sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
--    gdth_set_sglist(scp, &one_sg);
--    gdth_set_sg_count(scp, 1);
--    gdth_set_bufflen(scp, sizeof(*gdtcmd));
-     scp->cmd_len = 12;
-     memcpy(scp->cmnd, cmnd, 12);
-     cmndinfo.priority = IOCTL_PRI;
-+    cmndinfo.internal_cmd_str = gdtcmd;
-     cmndinfo.internal_command = 1;
- 
-     TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
-@@ -2355,7 +2344,7 @@
-  * buffers, kmap_atomic() as needed.
-  */
- static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
--                                    char *buffer, ushort count, int to_buffer)
-+                                    char *buffer, ushort count)
- {
-     ushort cpcount,i, max_sg = gdth_sg_count(scp);
-     ushort cpsum,cpnow;
-@@ -2381,10 +2370,7 @@
-             }
-             local_irq_save(flags);
-             address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
--            if (to_buffer)
--                memcpy(buffer, address, cpnow);
--            else
--                memcpy(address, buffer, cpnow);
-+            memcpy(address, buffer, cpnow);
-             flush_dcache_page(sg_page(sl));
-             kunmap_atomic(address, KM_BIO_SRC_IRQ);
-             local_irq_restore(flags);
-@@ -2438,7 +2424,7 @@
-         strcpy(inq.vendor,ha->oem_name);
-         sprintf(inq.product,"Host Drive  #%02d",t);
-         strcpy(inq.revision,"   ");
--        gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0);
-+        gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
-         break;
- 
-       case REQUEST_SENSE:
-@@ -2448,7 +2434,7 @@
-         sd.key       = NO_SENSE;
-         sd.info      = 0;
-         sd.add_length= 0;
--        gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0);
-+        gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
-         break;
- 
-       case MODE_SENSE:
-@@ -2460,7 +2446,7 @@
-         mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
-         mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
-         mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
--        gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0);
-+        gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
-         break;
- 
-       case READ_CAPACITY:
-@@ -2470,7 +2456,7 @@
-         else
-             rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
-         rdc.block_length  = cpu_to_be32(SECTOR_SIZE);
--        gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0);
-+        gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
-         break;
- 
-       case SERVICE_ACTION_IN:
-@@ -2482,7 +2468,7 @@
-             rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
-             rdc16.block_length  = cpu_to_be32(SECTOR_SIZE);
-             gdth_copy_internal_data(ha, scp, (char*)&rdc16,
--                                                 sizeof(gdth_rdcap16_data), 0);
-+                                                 sizeof(gdth_rdcap16_data));
-         } else { 
-             scp->result = DID_ABORT << 16;
-         }
-@@ -2852,6 +2838,7 @@
- static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
- {
-     register gdth_cmd_str *cmdp;
-+    struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
-     int cmd_index;
- 
-     cmdp= ha->pccb;
-@@ -2860,7 +2847,7 @@
-     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
-         return 0;
- 
--    gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1);
-+    *cmdp = *cmndinfo->internal_cmd_str;
-     cmdp->RequestBuffer = scp;
- 
-     /* search free command index */
-@@ -3793,6 +3780,8 @@
-     gdth_ha_str *ha;
-     ulong flags;
- 
-+    BUG_ON(list_empty(&gdth_instances));
-+
-     ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
-     spin_lock_irqsave(&ha->smp_lock, flags);
- 
-@@ -4668,45 +4657,6 @@
-     }
- }
- 
--/* shutdown routine */
--static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
--{
--    gdth_ha_str *ha;
--#ifndef __alpha__
--    gdth_cmd_str    gdtcmd;
--    char            cmnd[MAX_COMMAND_SIZE];   
--#endif
--
--    if (notifier_disabled)
--        return NOTIFY_OK;
--
--    TRACE2(("gdth_halt() event %d\n",(int)event));
--    if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
--        return NOTIFY_DONE;
--
--    notifier_disabled = 1;
--    printk("GDT-HA: Flushing all host drives .. ");
--    list_for_each_entry(ha, &gdth_instances, list) {
--        gdth_flush(ha);
--
--#ifndef __alpha__
--        /* controller reset */
--        memset(cmnd, 0xff, MAX_COMMAND_SIZE);
--        gdtcmd.BoardNode = LOCALBOARD;
--        gdtcmd.Service = CACHESERVICE;
--        gdtcmd.OpCode = GDT_RESET;
--        TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum));
--        gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL);
--#endif
--    }
--    printk("Done.\n");
--
--#ifdef GDTH_STATISTICS
--    del_timer(&gdth_timer);
--#endif
--    return NOTIFY_OK;
--}
--
- /* configure lun */
- static int gdth_slave_configure(struct scsi_device *sdev)
- {
-@@ -4838,6 +4788,9 @@
- 	if (error)
- 		goto out_free_coal_stat;
- 	list_add_tail(&ha->list, &gdth_instances);
-+
-+	scsi_scan_host(shp);
-+
- 	return 0;
- 
-  out_free_coal_stat:
-@@ -4965,6 +4918,9 @@
- 	if (error)
- 		goto out_free_coal_stat;
- 	list_add_tail(&ha->list, &gdth_instances);
-+
-+	scsi_scan_host(shp);
-+
- 	return 0;
- 
-  out_free_ccb_phys:
-@@ -5102,6 +5058,9 @@
- 	if (error)
- 		goto out_free_coal_stat;
- 	list_add_tail(&ha->list, &gdth_instances);
-+
-+	scsi_scan_host(shp);
-+
- 	return 0;
- 
-  out_free_coal_stat:
-@@ -5132,13 +5091,13 @@
- 
- 	scsi_remove_host(shp);
- 
-+	gdth_flush(ha);
-+
- 	if (ha->sdev) {
- 		scsi_free_host_dev(ha->sdev);
- 		ha->sdev = NULL;
- 	}
- 
--	gdth_flush(ha);
--
- 	if (shp->irq)
- 		free_irq(shp->irq,ha);
- 
-@@ -5164,6 +5123,24 @@
- 	scsi_host_put(shp);
- }
- 
-+static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
-+{
-+	gdth_ha_str *ha;
-+
-+	TRACE2(("gdth_halt() event %d\n", (int)event));
-+	if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
-+		return NOTIFY_DONE;
-+
-+	list_for_each_entry(ha, &gdth_instances, list)
-+		gdth_flush(ha);
-+
-+	return NOTIFY_OK;
-+}
-+
-+static struct notifier_block gdth_notifier = {
-+    gdth_halt, NULL, 0
-+};
-+
- static int __init gdth_init(void)
- {
- 	if (disable) {
-@@ -5226,7 +5203,6 @@
- 	add_timer(&gdth_timer);
- #endif
- 	major = register_chrdev(0,"gdth", &gdth_fops);
--	notifier_disabled = 0;
- 	register_reboot_notifier(&gdth_notifier);
- 	gdth_polling = FALSE;
- 	return 0;
-@@ -5236,14 +5212,15 @@
- {
- 	gdth_ha_str *ha;
- 
--	list_for_each_entry(ha, &gdth_instances, list)
--		gdth_remove_one(ha);
-+	unregister_chrdev(major, "gdth");
-+	unregister_reboot_notifier(&gdth_notifier);
- 
- #ifdef GDTH_STATISTICS
--	del_timer(&gdth_timer);
-+	del_timer_sync(&gdth_timer);
- #endif
--	unregister_chrdev(major,"gdth");
--	unregister_reboot_notifier(&gdth_notifier);
-+
-+	list_for_each_entry(ha, &gdth_instances, list)
-+		gdth_remove_one(ha);
- }
- 
- module_init(gdth_init);
-diff -Nurd linux-2.6.24/drivers/scsi/gdth.h linux-2.6.24-oxe810/drivers/scsi/gdth.h
---- linux-2.6.24/drivers/scsi/gdth.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth.h	2008-06-11 17:50:29.000000000 +0200
-@@ -915,6 +915,7 @@
-     struct gdth_cmndinfo {                      /* per-command private info */
-         int index;
-         int internal_command;                   /* don't call scsi_done */
-+        gdth_cmd_str *internal_cmd_str;         /* crier for internal messages*/
-         dma_addr_t sense_paddr;                 /* sense dma-addr */
-         unchar priority;
-         int timeout;
-diff -Nurd linux-2.6.24/drivers/scsi/gdth_proc.c linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c
---- linux-2.6.24/drivers/scsi/gdth_proc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c	2008-06-11 17:50:29.000000000 +0200
-@@ -694,15 +694,13 @@
- {
-     ulong flags;
- 
--    spin_lock_irqsave(&ha->smp_lock, flags);
--
-     if (buf == ha->pscratch) {
-+	spin_lock_irqsave(&ha->smp_lock, flags);
-         ha->scratch_busy = FALSE;
-+	spin_unlock_irqrestore(&ha->smp_lock, flags);
-     } else {
-         pci_free_consistent(ha->pdev, size, buf, paddr);
-     }
--
--    spin_unlock_irqrestore(&ha->smp_lock, flags);
- }
- 
- #ifdef GDTH_IOCTL_PROC
-diff -Nurd linux-2.6.24/drivers/scsi/ips.c linux-2.6.24-oxe810/drivers/scsi/ips.c
---- linux-2.6.24/drivers/scsi/ips.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/ips.c	2008-06-11 17:50:29.000000000 +0200
-@@ -1580,7 +1580,7 @@
- 	METHOD_TRACE("ips_make_passthru", 1);
- 
-         scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
--                length += sg[i].length;
-+		length += sg->length;
- 
- 	if (length < sizeof (ips_passthru_t)) {
- 		/* wrong size */
-@@ -6842,13 +6842,10 @@
- 	if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
- 		IPS_PRINTK(KERN_WARNING, ha->pcidev,
- 			   "Unable to install interrupt handler\n");
--		scsi_host_put(sh);
--		return -1;
-+		goto err_out_sh;
- 	}
- 
- 	kfree(oldha);
--	ips_sh[index] = sh;
--	ips_ha[index] = ha;
- 
- 	/* Store away needed values for later use */
- 	sh->io_port = ha->io_addr;
-@@ -6867,10 +6864,21 @@
- 	sh->max_channel = ha->nbus - 1;
- 	sh->can_queue = ha->max_cmds - 1;
- 
--	scsi_add_host(sh, NULL);
-+	if (scsi_add_host(sh, &ha->pcidev->dev))
-+		goto err_out;
-+
-+	ips_sh[index] = sh;
-+	ips_ha[index] = ha;
-+
- 	scsi_scan_host(sh);
- 
- 	return 0;
-+
-+err_out:
-+	free_irq(ha->pcidev->irq, ha);
-+err_out_sh:
-+	scsi_host_put(sh);
-+	return -1;
- }
- 
- /*---------------------------------------------------------------------------*/
-diff -Nurd linux-2.6.24/drivers/scsi/scsi_lib.c linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c
---- linux-2.6.24/drivers/scsi/scsi_lib.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c	2008-06-11 17:50:29.000000000 +0200
-@@ -298,7 +298,6 @@
- 		page = sg_page(sg);
- 		off = sg->offset;
- 		len = sg->length;
-- 		data_len += len;
- 
- 		while (len > 0 && data_len > 0) {
- 			/*
-diff -Nurd linux-2.6.24/drivers/scsi/sd.c linux-2.6.24-oxe810/drivers/scsi/sd.c
---- linux-2.6.24/drivers/scsi/sd.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/sd.c	2008-06-11 17:50:29.000000000 +0200
-@@ -907,6 +907,7 @@
-  	unsigned int xfer_size = SCpnt->request_bufflen;
-  	unsigned int good_bytes = result ? 0 : xfer_size;
-  	u64 start_lba = SCpnt->request->sector;
-+	u64 end_lba = SCpnt->request->sector + (xfer_size / 512);
-  	u64 bad_lba;
- 	struct scsi_sense_hdr sshdr;
- 	int sense_valid = 0;
-@@ -945,26 +946,23 @@
- 			goto out;
- 		if (xfer_size <= SCpnt->device->sector_size)
- 			goto out;
--		switch (SCpnt->device->sector_size) {
--		case 256:
-+		if (SCpnt->device->sector_size < 512) {
-+			/* only legitimate sector_size here is 256 */
- 			start_lba <<= 1;
--			break;
--		case 512:
--			break;
--		case 1024:
--			start_lba >>= 1;
--			break;
--		case 2048:
--			start_lba >>= 2;
--			break;
--		case 4096:
--			start_lba >>= 3;
--			break;
--		default:
--			/* Print something here with limiting frequency. */
--			goto out;
--			break;
-+			end_lba <<= 1;
-+		} else {
-+			/* be careful ... don't want any overflows */
-+			u64 factor = SCpnt->device->sector_size / 512;
-+			do_div(start_lba, factor);
-+			do_div(end_lba, factor);
- 		}
-+
-+		if (bad_lba < start_lba  || bad_lba >= end_lba)
-+			/* the bad lba was reported incorrectly, we have
-+			 * no idea where the error is
-+			 */
-+			goto out;
-+
- 		/* This computation should always be done in terms of
- 		 * the resolution of the device's medium.
- 		 */
-diff -Nurd linux-2.6.24/drivers/serial/8250.c linux-2.6.24-oxe810/drivers/serial/8250.c
---- linux-2.6.24/drivers/serial/8250.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/serial/8250.c	2008-06-11 17:48:56.000000000 +0200
-@@ -2153,7 +2153,37 @@
- 		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
- 	}
- 
--	serial_dl_write(up, quot);
-+    if ((up->port.type == PORT_16550A) &&
-+        (serial_in(up, UART_XON_CHAR)  == 0x11) &&
-+        (serial_in(up, UART_XOFF_CHAR) == 0x13))
-+    {
-+        /* We should now be dealing with an extended 16550A-type UART from
-+         * the Oxsemi 0x800 */
-+
-+        /* Calculate values for DLM,DLL,DLF divisor registers from clock
-+         * frequency in Hz and Baud rate in bits per second, and program them
-+         * into the UART */
-+        u32  tmp;
-+        u8 lcr, dlm, dll, dlf;
-+
-+        tmp = port->uartclk / baud;
-+        tmp = (tmp + 1) / 2;
-+        dlm = tmp >> (8 + 3);
-+        dll = (tmp >> 3) & 0xFF;
-+        dlf = (tmp & 7) << 5;
-+
-+        lcr = serial_in(up, UART_LSR);  /* Store LCR */
-+
-+        serial_outp(up, UART_LCR, 0x80); /* Enable access to DLM DLL */ 
-+        serial_outp(up, UART_DLL, dll);  /* LS of divisor */
-+        serial_outp(up, UART_DLM, dlm);  /* MS of divisor */
-+        serial_outp(up, UART_DLF, dlf);  /* Set non-standard fractional divisor */
-+        serial_outp(up, UART_LCR, lcr);  /* Restore LCR */
-+
-+        printk(KERN_INFO "Using fractional divider baud %d, clock %d dlf %02x\n", baud, port->uartclk, dlf);
-+    } else {
-+        serial_dl_write(up, quot);
-+    }
- 
- 	/*
- 	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
-@@ -2519,7 +2549,11 @@
- static int __init serial8250_console_setup(struct console *co, char *options)
- {
- 	struct uart_port *port;
--	int baud = 9600;
-+#if defined (CONFIG_ARCH_OXNAS)
-+   int baud = 115200;
-+#else
-+    int baud = 9600;
-+#endif // defined (CONFIG_ARCH_OXNAS)
- 	int bits = 8;
- 	int parity = 'n';
- 	int flow = 'n';
-diff -Nurd linux-2.6.24/drivers/spi/atmel_spi.c linux-2.6.24-oxe810/drivers/spi/atmel_spi.c
---- linux-2.6.24/drivers/spi/atmel_spi.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/spi/atmel_spi.c	2008-06-11 17:49:13.000000000 +0200
-@@ -85,6 +85,16 @@
- 	unsigned gpio = (unsigned) spi->controller_data;
- 	unsigned active = spi->mode & SPI_CS_HIGH;
- 	u32 mr;
-+	int i;
-+	u32 csr;
-+	u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
-+
-+	/* Make sure clock polarity is correct */
-+	for (i = 0; i < spi->master->num_chipselect; i++) {
-+		csr = spi_readl(as, CSR0 + 4 * i);
-+		if ((csr ^ cpol) & SPI_BIT(CPOL))
-+			spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
-+	}
- 
- 	mr = spi_readl(as, MR);
- 	mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
-diff -Nurd linux-2.6.24/drivers/spi/pxa2xx_spi.c linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c
---- linux-2.6.24/drivers/spi/pxa2xx_spi.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c	2008-06-11 17:49:13.000000000 +0200
-@@ -48,13 +48,19 @@
- #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
- #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
- 
--/* for testing SSCR1 changes that require SSP restart, basically
-- * everything except the service and interrupt enables */
--#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \
-+/*
-+ * for testing SSCR1 changes that require SSP restart, basically
-+ * everything except the service and interrupt enables, the pxa270 developer
-+ * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this
-+ * list, but the PXA255 dev man says all bits without really meaning the
-+ * service and interrupt enables
-+ */
-+#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
- 				| SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
--				| SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \
--				| SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \
--				| SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
-+				| SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
-+				| SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
-+				| SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
-+				| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
- 
- #define DEFINE_SSP_REG(reg, off) \
- static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
-@@ -961,9 +967,6 @@
- 		if (drv_data->ssp_type == PXA25x_SSP)
- 			DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN;
- 
--		/* Fix me, need to handle cs polarity */
--		drv_data->cs_control(PXA2XX_CS_ASSERT);
--
- 		/* Clear status and start DMA engine */
- 		cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1;
- 		write_SSSR(drv_data->clear_sr, reg);
-@@ -973,9 +976,6 @@
- 		/* Ensure we have the correct interrupt handler	*/
- 		drv_data->transfer_handler = interrupt_transfer;
- 
--		/* Fix me, need to handle cs polarity */
--		drv_data->cs_control(PXA2XX_CS_ASSERT);
--
- 		/* Clear status  */
- 		cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
- 		write_SSSR(drv_data->clear_sr, reg);
-@@ -986,16 +986,29 @@
- 		|| (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
- 			(cr1 & SSCR1_CHANGE_MASK)) {
- 
-+		/* stop the SSP, and update the other bits */
- 		write_SSCR0(cr0 & ~SSCR0_SSE, reg);
- 		if (drv_data->ssp_type != PXA25x_SSP)
- 			write_SSTO(chip->timeout, reg);
--		write_SSCR1(cr1, reg);
-+		/* first set CR1 without interrupt and service enables */
-+		write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
-+		/* restart the SSP */
- 		write_SSCR0(cr0, reg);
-+
- 	} else {
- 		if (drv_data->ssp_type != PXA25x_SSP)
- 			write_SSTO(chip->timeout, reg);
--		write_SSCR1(cr1, reg);
- 	}
-+
-+	/* FIXME, need to handle cs polarity,
-+	 * this driver uses struct pxa2xx_spi_chip.cs_control to
-+	 * specify a CS handling function, and it ignores most
-+	 * struct spi_device.mode[s], including SPI_CS_HIGH */
-+	drv_data->cs_control(PXA2XX_CS_ASSERT);
-+
-+	/* after chip select, release the data by enabling service
-+	 * requests and interrupts, without changing any mode bits */
-+	write_SSCR1(cr1, reg);
- }
- 
- static void pump_messages(struct work_struct *work)
-diff -Nurd linux-2.6.24/drivers/usb/Kconfig linux-2.6.24-oxe810/drivers/usb/Kconfig
---- linux-2.6.24/drivers/usb/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/Kconfig	2008-06-11 17:50:19.000000000 +0200
-@@ -36,6 +36,7 @@
- 	default y if ARCH_EP93XX
- 	default y if ARCH_AT91
- 	default y if ARCH_PNX4008
-+	default y if ARCH_OXNAS
- 	# PPC:
- 	default y if STB03xxx
- 	default y if PPC_MPC52xx
-@@ -49,6 +50,7 @@
- 	boolean
- 	default y if PPC_83xx
- 	default y if SOC_AU1200
-+	default y if ARCH_OXNAS
- 	default PCI
- 
- # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
-diff -Nurd linux-2.6.24/drivers/usb/class/usblp.c linux-2.6.24-oxe810/drivers/usb/class/usblp.c
---- linux-2.6.24/drivers/usb/class/usblp.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/class/usblp.c	2008-06-11 17:50:16.000000000 +0200
-@@ -428,6 +428,7 @@
- 	usblp->rcomplete = 0;
- 
- 	if (handle_bidir(usblp) < 0) {
-+		usb_autopm_put_interface(intf);
- 		usblp->used = 0;
- 		file->private_data = NULL;
- 		retval = -EIO;
-diff -Nurd linux-2.6.24/drivers/usb/core/driver.c linux-2.6.24-oxe810/drivers/usb/core/driver.c
---- linux-2.6.24/drivers/usb/core/driver.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/driver.c	2008-06-11 17:50:16.000000000 +0200
-@@ -534,8 +534,8 @@
- 	   id->driver_info is the way to create an entry that
- 	   indicates that the driver want to examine every
- 	   device and interface. */
--	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
--	       id->driver_info; id++) {
-+	for (; id->idVendor || id->idProduct || id->bDeviceClass ||
-+	       id->bInterfaceClass || id->driver_info; id++) {
- 		if (usb_match_one_id(interface, id))
- 			return id;
- 	}
-diff -Nurd linux-2.6.24/drivers/usb/core/hcd.h linux-2.6.24-oxe810/drivers/usb/core/hcd.h
---- linux-2.6.24/drivers/usb/core/hcd.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/hcd.h	2008-06-11 17:50:16.000000000 +0200
-@@ -312,7 +312,9 @@
- #define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
- #define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)
- 
--
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+#define ResetHubTT                 (0x2308)             
-+#endif
- /*-------------------------------------------------------------------------*/
- 
- /*
-@@ -359,6 +361,11 @@
- 
- /*-------------------------------------------------------------------------*/
- 
-+extern int usb_register_root_hub (struct usb_device *usb_dev,
-+		struct device *parent_dev);
-+
-+extern void usb_hcd_release (struct usb_bus *);
-+
- extern void usb_set_device_state(struct usb_device *udev,
- 		enum usb_device_state new_state);
- 
-diff -Nurd linux-2.6.24/drivers/usb/core/hub.c linux-2.6.24-oxe810/drivers/usb/core/hub.c
---- linux-2.6.24/drivers/usb/core/hub.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/hub.c	2008-06-11 17:50:16.000000000 +0200
-@@ -2946,7 +2946,7 @@
- 		if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
- 			len = le16_to_cpu(udev->config[index].desc.wTotalLength);
- 	}
--	buf = kmalloc (len, GFP_KERNEL);
-+	buf = kmalloc(len, GFP_NOIO);
- 	if (buf == NULL) {
- 		dev_err(&udev->dev, "no mem to re-read configs after reset\n");
- 		/* assume the worst */
-diff -Nurd linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c
---- linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c	2008-06-11 17:50:17.000000000 +0200
-@@ -776,7 +776,7 @@
- 		VDBG("%s, bad params\n", __FUNCTION__);
- 		return -EINVAL;
- 	}
--	if (!_ep || (!ep->desc && ep_index(ep))) {
-+	if (unlikely(!_ep || !ep->desc)) {
- 		VDBG("%s, bad ep\n", __FUNCTION__);
- 		return -EINVAL;
- 	}
-diff -Nurd linux-2.6.24/drivers/usb/host/Kconfig linux-2.6.24-oxe810/drivers/usb/host/Kconfig
---- linux-2.6.24/drivers/usb/host/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/Kconfig	2008-06-11 17:50:19.000000000 +0200
-@@ -41,6 +41,7 @@
- config USB_EHCI_ROOT_HUB_TT
- 	bool "Root Hub Transaction Translators (EXPERIMENTAL)"
- 	depends on USB_EHCI_HCD && EXPERIMENTAL
-+	default y if ARCH_OXNAS
- 	---help---
- 	  Some EHCI chips have vendor-specific extensions to integrate
- 	  transaction translators, so that no OHCI or UHCI companion
-diff -Nurd linux-2.6.24/drivers/usb/host/Makefile linux-2.6.24-oxe810/drivers/usb/host/Makefile
---- linux-2.6.24/drivers/usb/host/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/Makefile	2008-06-11 17:50:19.000000000 +0200
-@@ -3,7 +3,11 @@
- #
- 
- ifeq ($(CONFIG_USB_DEBUG),y)
--	EXTRA_CFLAGS		+= -DDEBUG
-+	EXTRA_CFLAGS		+= -DDEBUG 
-+endif
-+
-+ifeq ($(CONFIG_EHCI_VERBOSE_DEBUG),y)
-+	EXTRA_CFLAGS	 	+= -DEHCI_VERBOSE_DEBUG
- endif
- 
- obj-$(CONFIG_PCI)		+= pci-quirks.o
-@@ -16,4 +20,3 @@
- obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
- obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
- obj-$(CONFIG_USB_R8A66597_HCD)	+= r8a66597-hcd.o
--
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-dbg.c linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c
---- linux-2.6.24/drivers/usb/host/ehci-dbg.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c	2008-06-11 17:50:19.000000000 +0200
-@@ -28,11 +28,11 @@
- 	dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
- 
- #ifdef EHCI_VERBOSE_DEBUG
--#	define vdbg dbg
--#	define ehci_vdbg ehci_dbg
-+	#define vdbg dbg
-+	#define ehci_vdbg ehci_dbg
- #else
--#	define vdbg(fmt,args...) do { } while (0)
--#	define ehci_vdbg(ehci, fmt, args...) do { } while (0)
-+	#define vdbg(fmt,args...) do { } while (0)
-+	#define ehci_vdbg(ehci, fmt, args...) do { } while (0)
- #endif
- 
- #ifdef	DEBUG
-@@ -242,6 +242,10 @@
- 		);
- }
- 
-+#define PORT_SPD_HIGH    (2 << 26)
-+#define PORT_SPD_FULL    (1 << 26)
-+
-+
- static int
- dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
- {
-@@ -256,7 +260,7 @@
- 	}
- 
- 	return scnprintf (buf, len,
--		"%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
-+		"%s%sport %d status %06x%s%s sig=%s %s%s%s%s%s%s%s%s%s %s",
- 		label, label [0] ? " " : "", port, status,
- 		(status & PORT_POWER) ? " POWER" : "",
- 		(status & PORT_OWNER) ? " OWNER" : "",
-@@ -269,7 +273,9 @@
- 		(status & PORT_PEC) ? " PEC" : "",
- 		(status & PORT_PE) ? " PE" : "",
- 		(status & PORT_CSC) ? " CSC" : "",
--		(status & PORT_CONNECT) ? " CONNECT" : "");
-+		(status & PORT_CONNECT) ? " CONNECT" : "",
-+		(status & PORT_SPD_HIGH) ? ((status & PORT_SPD_FULL) ? "??" : "HIGH" ) : (status & PORT_SPD_FULL) ? "LOW" : "FULL"
-+	    );
- }
- 
- #else
-@@ -783,13 +789,38 @@
- 	size -= temp;
- 	next += temp;
- #endif
--
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+        long unsigned tt_status =readl((u32)ehci->regs +TT_STATUS);
-+        temp = scnprintf (next, size,
-+                "tt status %08lx \n",
-+                tt_status);
-+        size -= temp;
-+        next += temp;
-+#endif
- done:
- 	spin_unlock_irqrestore (&ehci->lock, flags);
- 
- 	return PAGE_SIZE - size;
- }
- static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+static ssize_t
-+reset_tt (struct class_device *class_dev, const char *buf, size_t len)
-+{
-+        struct usb_bus          *bus;
-+        struct usb_hcd          *hcd;
-+        struct ehci_hcd         *ehci;
-+ 
-+        bus = class_get_devdata(class_dev);
-+        hcd = bus->hcpriv;
-+        ehci = hcd_to_ehci (hcd);
-+
-+       *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
-+        return len;
-+}
-+
-+static CLASS_DEVICE_ATTR (tt_reset, S_IWUGO, NULL, reset_tt );
-+#endif
- 
- static inline void create_debug_files (struct ehci_hcd *ehci)
- {
-@@ -799,6 +830,9 @@
- 	retval = class_device_create_file(cldev, &class_device_attr_async);
- 	retval = class_device_create_file(cldev, &class_device_attr_periodic);
- 	retval = class_device_create_file(cldev, &class_device_attr_registers);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT	
-+        class_device_create_file(cldev, &class_device_attr_tt_reset);
-+#endif        
- }
- 
- static inline void remove_debug_files (struct ehci_hcd *ehci)
-@@ -808,6 +842,9 @@
- 	class_device_remove_file(cldev, &class_device_attr_async);
- 	class_device_remove_file(cldev, &class_device_attr_periodic);
- 	class_device_remove_file(cldev, &class_device_attr_registers);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT	
-+        class_device_remove_file(cldev, &class_device_attr_tt_reset);
-+#endif        
- }
- 
- #endif /* STUB_DEBUG_FILES */
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hcd.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c
---- linux-2.6.24/drivers/usb/host/ehci-hcd.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c	2008-06-11 17:50:19.000000000 +0200
-@@ -197,7 +197,7 @@
- 	u32 __iomem	*reg_ptr;
- 	u32		tmp;
- 
--	reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
-+	reg_ptr = (u32 __iomem *)&ehci->regs->usbmode;
- 	tmp = ehci_readl(ehci, reg_ptr);
- 	tmp |= USBMODE_CM_HC;
- 	/* The default byte access to MMR space is LE after
-@@ -207,6 +207,20 @@
- 	if (ehci_big_endian_mmio(ehci))
- 		tmp |= USBMODE_BE;
- 	ehci_writel(ehci, tmp, reg_ptr);
-+
-+#ifdef CONFIG_ARCH_OXNAS
-+	reg_ptr = (u32 __iomem *)&ehci->regs->txfilltuning;
-+	tmp = ehci_readl(ehci, reg_ptr);
-+	tmp &= ~0x00ff0000;
-+	tmp |= 0x00200000; /* set burst pre load count to 16 */
-+	tmp |= 0x16; /* set sheduler overhead to 3 * 1.267us */
-+	ehci_writel(ehci, tmp, reg_ptr);
-+
-+	reg_ptr = (u32 __iomem *)&ehci->regs->txttfilltuning;
-+	tmp = readl (reg_ptr);
-+	tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
-+	writel (tmp, reg_ptr);
-+#endif // CONFIG_ARCH_OXNAS
- }
- 
- /* reset a non-running (STS_HALT == 1) controller */
-@@ -225,9 +239,17 @@
- 
- 	if (retval)
- 		return retval;
-+	if (ehci->is_tdi_rh_tt)
-+		tdi_reset(ehci); /* set TDI EHCI internal registers */
-+#ifdef CONFIG_ARCH_OXNAS
-+	command=readl(&ehci->regs->port_status[1]);
-+	command |=0xc0000000; /* force use of serial PHY on 1st full speed port */
-+	writel(command,&ehci->regs->port_status[1]); 
- 
--	if (ehci_is_TDI(ehci))
--		tdi_reset (ehci);
-+	command=readl(&ehci->regs->port_status[2]);
-+	command |=0xc0000000; /* force use of serial PHY on 2nd full speed port */
-+	writel(command,&ehci->regs->port_status[2]); 
-+#endif // CONFIG_ARCH_OXNAS
- 
- 	return retval;
- }
-@@ -939,10 +961,15 @@
- MODULE_AUTHOR (DRIVER_AUTHOR);
- MODULE_LICENSE ("GPL");
- 
-+#ifdef CONFIG_ARCH_OXNAS
-+#include "ehci-oxnas.c"
-+#define	PLATFORM_DRIVER		ehci_hcd_oxnas_driver
-+#else // CONFIG_ARCH_OXNAS
- #ifdef CONFIG_PCI
- #include "ehci-pci.c"
- #define	PCI_DRIVER		ehci_pci_driver
--#endif
-+#endif // CONFIG_PCI
-+#endif // CONFIG_ARCH_OXNAS
- 
- #ifdef CONFIG_USB_EHCI_FSL
- #include "ehci-fsl.c"
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hub.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c
---- linux-2.6.24/drivers/usb/host/ehci-hub.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c	2008-06-11 17:50:19.000000000 +0200
-@@ -769,6 +769,11 @@
- 		dbg_port (ehci, "GetStatus", wIndex + 1, temp);
- 		put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
- 		break;
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+        case ResetHubTT :
-+                *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
-+                break;
-+#endif                
- 	case SetHubFeature:
- 		switch (wValue) {
- 		case C_HUB_LOCAL_POWER:
-@@ -825,6 +830,23 @@
- 				temp |= PORT_RESET;
- 				temp &= ~PORT_PE;
- 
-+#if defined(CONFIG_USB_EHCI_ROOT_HUB_TT) & defined (CONFIG_ARCH_OXNAS) & 0 
-+		printk(KERN_ERR "port using status raw %lx\n",temp);
-+		temp &= 0x0fffffffL; /* remove default data source */
-+		if (temp & (1 << 27 ))
-+		{ 
-+			/* set the input to the UTMI input */
-+			temp |= 0x20000000L;
-+			printk(KERN_ERR "port using UTMI %d\n",wIndex);
-+		}
-+		else
-+		{
-+			/* set the input to the serial PHY input */
-+			temp |= 0xE0000000L; 
-+			printk(KERN_ERR "port using serial PHY %d\n",wIndex);
-+		}
-+		writel(temp, &ehci->regs->port_status [wIndex]);
-+#endif	
- 				/*
- 				 * caller must wait, then call GetPortStatus
- 				 * usb 2.0 spec says 50 ms resets on root
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-oxnas.c linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c
---- linux-2.6.24/drivers/usb/host/ehci-oxnas.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c	2008-06-11 17:50:19.000000000 +0200
-@@ -0,0 +1,307 @@
-+/*
-+ * EHCI HCD (Host Controller Driver) for USB.
-+ *
-+ * (C) Copyright 2005 John Larkworthy <john.larkworthy at oxsemi.com>
-+ * 
-+ * OXNAS Bus Glue
-+ *
-+ * Written by John Larkworthy 
-+ *
-+ * This file is licenced under the GPL.
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <asm/hardware.h>
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+int usb_patch = 1;
-+
-+module_param(usb_patch, int, 1);
-+MODULE_PARM_DESC (usb_patch, "use usb hw patch");
-+
-+/* called during probe() after chip reset completes */
-+static int ehci_oxnas_setup(struct usb_hcd *hcd)
-+{
-+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
-+	int temp;
-+	int retval;
-+
-+	ehci->caps = hcd->regs;
-+	ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
-+	dbg_hcs_params(ehci, "reset");
-+	dbg_hcc_params(ehci, "reset");
-+
-+	/* cache this readonly data; minimize chip reads */
-+	ehci->hcs_params = readl(&ehci->caps->hcs_params);
-+
-+	retval = ehci_halt(ehci);
-+	if (retval)
-+			return retval;
-+
-+	/* data structure init */
-+	retval = ehci_init(hcd);
-+	if (retval)
-+		return retval;
-+
-+	if (ehci_is_TDI(ehci))
-+		ehci_reset(ehci);
-+
-+	/* at least the Genesys GL880S needs fixup here */
-+	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
-+	temp &= 0x0f;
-+	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
-+		ehci_dbg(ehci, "bogus port configuration: "
-+			"cc=%d x pcc=%d < ports=%d\n",
-+			HCS_N_CC(ehci->hcs_params),
-+			HCS_N_PCC(ehci->hcs_params),
-+			HCS_N_PORTS(ehci->hcs_params));
-+	}
-+
-+	ehci_port_power(ehci, 0);
-+
-+	return retval;
-+}
-+
-+static const struct hc_driver ehci_oxnas_driver = {
-+	.description =		hcd_name,
-+	.product_desc =		"OXNAS EHCI Host Controller",
-+	.hcd_priv_size =	sizeof(struct ehci_hcd),
-+
-+	/*
-+	 * generic hardware linkage
-+	 */
-+	.irq =   ehci_irq,
-+	.flags = HCD_MEMORY | HCD_USB2,
-+
-+	/*
-+	 * basic lifecycle operations
-+	 */
-+	.reset =   ehci_oxnas_setup,
-+	.start =   ehci_run,
-+#ifdef	CONFIG_PM
-+	.suspend = ehci_suspend,
-+	.resume =  ehci_resume,
-+#endif
-+	.stop =	   ehci_stop,
-+	.shutdown = ehci_shutdown,
-+
-+	/*
-+	 * managing i/o requests and associated device resources
-+	 */
-+	.urb_enqueue =		ehci_urb_enqueue,
-+	.urb_dequeue =		ehci_urb_dequeue,
-+	.endpoint_disable =	ehci_endpoint_disable,
-+
-+	/*
-+	 * scheduling support
-+	 */
-+	.get_frame_number =	ehci_get_frame,
-+
-+	/*
-+	 * root hub support
-+	 */
-+	.hub_status_data =	ehci_hub_status_data,
-+	.hub_control =		ehci_hub_control,
-+	.bus_suspend =		ehci_bus_suspend,
-+	.bus_resume =		ehci_bus_resume,
-+};
-+
-+static int start_oxnas_usb_ehci(struct platform_device *dev)
-+{
-+    unsigned long flags;
-+    unsigned long input_polarity = 0;
-+    unsigned long output_polarity = 0;
-+    unsigned long power_switch_mask = 0;
-+    unsigned long power_monitor_mask = 0;
-+    unsigned long power_lines_mask = 0;
-+
-+	if (usb_disabled())
-+		return -ENODEV;
-+
-+	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
-+		hcd_name,
-+		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
-+		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
-+
-+#ifdef CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
-+    power_switch_mask  |= (1UL << USBA_POWO_GPIO);
-+    power_monitor_mask |= (1UL << USBA_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
-+
-+#ifdef CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
-+    power_switch_mask  |= (1UL << USBB_POWO_GPIO);
-+    power_monitor_mask |= (1UL << USBB_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
-+
-+#ifdef CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
-+    power_switch_mask  |= (1UL << USBC_POWO_GPIO);
-+    power_monitor_mask |= (1UL << USBC_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
-+
-+    power_lines_mask = power_switch_mask | power_monitor_mask;
-+
-+    // Configure USB power monitoring input and switch output GPIOs
-+#ifdef CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+    input_polarity = ((1UL << SYS_CTRL_USBHSMPH_IP_POL_A_BIT) |
-+                      (1UL << SYS_CTRL_USBHSMPH_IP_POL_B_BIT) |
-+                      (1UL << SYS_CTRL_USBHSMPH_IP_POL_C_BIT));
-+#endif // CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+
-+#ifdef CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+    output_polarity = ((1UL << SYS_CTRL_USBHSMPH_OP_POL_A_BIT) |
-+                       (1UL << SYS_CTRL_USBHSMPH_OP_POL_B_BIT) |
-+                       (1UL << SYS_CTRL_USBHSMPH_OP_POL_C_BIT));
-+#endif // CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+
-+    // Enable primary function on USB power monitor and switch lines
-+    spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+    writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |  power_lines_mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0)  & ~power_lines_mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~power_lines_mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+    // Enable GPIO output on USB power switch output GPIOs
-+    writel(power_switch_mask, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+    // Enable GPIO input on USB power monitoring input GPIOs
-+    writel(power_monitor_mask, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+
-+    // Set the polarity of the USB power switch output and monitoring
-+    // inputs in system control
-+    if (usb_patch) {
-+        writel(input_polarity | output_polarity| (1<<6) , SYS_CTRL_USBHSMPH_CTRL);
-+    } 
-+    else {
-+            writel(input_polarity | output_polarity, SYS_CTRL_USBHSMPH_CTRL);
-+    }
-+    
-+    // Ensure the USB block is properly reset
-+    writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+    writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Force the high speed clock to be generated all the time, via serial
-+    // programming of the USB HS PHY
-+    writel((2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+           (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+    writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
-+           (2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+           (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+    writel((0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) | 
-+           (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+    writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
-+           (0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+           (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+    // Enable the clock to the USB block
-+    writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Ensure reset and clock operations are complete
-+    wmb();
-+
-+	return 0;
-+}
-+
-+static void stop_oxnas_usb_ehci(struct platform_device *dev)
-+{
-+	// put usb core into reset
-+    writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+    // Disable the clock to the USB block
-+    writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+}
-+
-+/**
-+ * usb_hcd_oxnas_probe - initialize OXNAS-based HCD
-+ * Context: !in_interrupt()
-+ *
-+ * Allocates basic resources for this USB host controller.
-+ *
-+ */
-+static int usb_hcd_oxnas_probe(const struct hc_driver *driver, struct platform_device *dev)
-+{
-+	int retval;
-+	unsigned long ehci_id;
-+	struct usb_hcd *hcd = 0;
-+	struct ehci_hcd *ehci;
-+
-+	if (dev->num_resources != 2) {
-+		pr_debug("wrong number of resources %d, expected %d", dev->num_resources, 2);
-+	}
-+
-+	start_oxnas_usb_ehci(dev);
-+
-+	if (((ehci_id = readl(USB_BASE)) & 0x2f) != 0x05) {
-+		pr_debug("wrong chip ID found %lx", ehci_id);
-+		return -ENODEV;
-+	}
-+
-+	hcd = usb_create_hcd(driver, &dev->dev, "usb");
-+	if (!hcd) {
-+		pr_debug("usb_create_hcd() failed");
-+		retval = -ENOMEM;
-+	}
-+	hcd->regs = (void *)(USB_BASE + 0x100); /* adjust to point at cap length register */
-+
-+	printk(DRIVER_INFO "@%p Device ID register %lx\n", (void *)USB_BASE, *(unsigned long *)USB_BASE);
-+
-+	/* OXNAS device has a transaction translator */
-+	ehci = hcd_to_ehci(hcd);
-+	ehci->is_tdi_rh_tt = 1;
-+
-+	/* Finished initialisation and register */
-+	if ((retval = usb_add_hcd(hcd, dev->resource[1].start, 0))) {
-+		pr_debug("usb_add_hcd() failed");
-+		stop_oxnas_usb_ehci(dev);
-+		usb_put_hcd(hcd);
-+		return retval;
-+	}
-+	return 0;
-+}
-+
-+/**
-+ * usb_hcd_oxnas_remove - shutdown processing for OXNAS-based HCD
-+ * @dev: USB Host Controller being removed
-+ * Context: !in_interrupt()
-+ *
-+ * Reverses the effect of usb_hcd_oxnas_probe(), first invoking
-+ * the HCD's stop() method.  It is always called from a thread
-+ * context, normally "rmmod", "apmd", or something similar.
-+ *
-+ */
-+static void usb_hcd_oxnas_remove(struct usb_hcd *hcd, struct platform_device *dev)
-+{
-+	usb_remove_hcd(hcd);
-+	usb_put_hcd(hcd);
-+	stop_oxnas_usb_ehci(dev);
-+}
-+
-+static int ehci_hcd_oxnas_drv_probe(struct platform_device *dev)
-+{
-+	if (usb_disabled())
-+		return -ENODEV;
-+
-+	return usb_hcd_oxnas_probe(&ehci_oxnas_driver, dev);
-+}
-+
-+static int ehci_hcd_oxnas_drv_remove(struct platform_device *dev)
-+{
-+	usb_hcd_oxnas_remove(platform_get_drvdata(dev), dev);
-+	return 0;
-+}
-+
-+MODULE_ALIAS("oxnas-ehci");
-+
-+static struct platform_driver ehci_hcd_oxnas_driver = {
-+	.probe = ehci_hcd_oxnas_drv_probe,
-+	.remove = ehci_hcd_oxnas_drv_remove,
-+	.shutdown = usb_hcd_platform_shutdown,
-+	.driver = {
-+		.name = "oxnas-ehci",
-+	},
-+};
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-q.c linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c
---- linux-2.6.24/drivers/usb/host/ehci-q.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c	2008-06-11 17:50:19.000000000 +0200
-@@ -315,10 +315,10 @@
- 			if (likely (last->urb != urb)) {
- 				ehci_urb_done(ehci, last->urb, last_status);
- 				count++;
-+				last_status = -EINPROGRESS;
- 			}
- 			ehci_qtd_free (ehci, last);
- 			last = NULL;
--			last_status = -EINPROGRESS;
- 		}
- 
- 		/* ignore urbs submitted during completions we reported */
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-sched.c linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c
---- linux-2.6.24/drivers/usb/host/ehci-sched.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c	2008-06-11 17:50:19.000000000 +0200
-@@ -2109,6 +2109,7 @@
- {
- 	unsigned	frame, clock, now_uframe, mod;
- 	unsigned	modified;
-+	u8		uncompleted_td = 0;
- 
- 	mod = ehci->periodic_size << 3;
- 
-@@ -2188,8 +2189,10 @@
- 					q = *q_p;
- 					break;
- 				}
--				if (uf != 8)
-+				if (uf != 8){
-+					uncompleted_td = 1;
- 					break;
-+				}
- 
- 				/* this one's ready ... HC won't cache the
- 				 * pointer for much longer, if at all.
-@@ -2214,6 +2217,7 @@
- 				*q_p = q.sitd->sitd_next;
- 				*hw_p = q.sitd->hw_next;
- 				type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
-+				uncompleted_td = 1;
- 				wmb();
- 				modified = sitd_complete (ehci, q.sitd);
- 				q = *q_p;
-@@ -2239,6 +2243,12 @@
- 		// don't exceed periodic_size msec (default 1.024 sec).
- 
- 		// FIXME:  likewise assumes HC doesn't halt mid-scan
-+		
-+		/* We must stat the next scan cycle at the first
-+		 * uncompleted TD so that TDs are not lost.
-+		 */
-+		 if ((!uncompleted_td) && (ehci_to_hcd(ehci)->state == HC_STATE_RUNNING))
-+		 	ehci->next_uframe = now_uframe;
- 
- 		if (now_uframe == clock) {
- 			unsigned	now;
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci.h linux-2.6.24-oxe810/drivers/usb/host/ehci.h
---- linux-2.6.24/drivers/usb/host/ehci.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci.h	2008-06-11 17:50:19.000000000 +0200
-@@ -262,14 +262,22 @@
- 	/* ASYNCLISTADDR: offset 0x18 */
- 	u32		async_next;	/* address of next async queue head */
- 
--	u32		reserved [9];
-+	u32 ttctrl;
-+	u32 burstsize;
-+	u32 txfilltuning;
-+	u32 txttfilltuning;
-+	u32 reserved_1;
-+	u32 ulpi_viewport;
-+	u32 reserved_2;
-+	u32 endpknack;
-+	u32 endptnalek;
- 
- 	/* CONFIGFLAG: offset 0x40 */
- 	u32		configured_flag;
- #define FLAG_CF		(1<<0)		/* true: we'll support "high speed" */
- 
- 	/* PORTSC: offset 0x44 */
--	u32		port_status [0];	/* up to N_PORTS */
-+	u32		port_status [8];	/* up to N_PORTS, max 8 */
- /* 31:23 reserved */
- #define PORT_WKOC_E	(1<<22)		/* wake on overcurrent (enable) */
- #define PORT_WKDISC_E	(1<<21)		/* wake on disconnect (enable) */
-@@ -294,14 +302,22 @@
- #define PORT_CSC	(1<<1)		/* connect status change */
- #define PORT_CONNECT	(1<<0)		/* device connected */
- #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC)
--} __attribute__ ((packed));
- 
--#define USBMODE		0x68		/* USB Device mode */
-+	u32 otgsc;
-+	u32 usbmode;
- #define USBMODE_SDIS	(1<<3)		/* Stream disable */
--#define USBMODE_BE	(1<<2)		/* BE/LE endianness select */
-+#define USBMODE_BE		(1<<2)		/* BE/LE endianness select */
- #define USBMODE_CM_HC	(3<<0)		/* host controller mode */
- #define USBMODE_CM_IDLE	(0<<0)		/* idle state */
- 
-+	u32 endptsetupstack;
-+	u32 endptprime;
-+	u32 endptflush;
-+	u32 endptstat;
-+	u32 endptcomplete;
-+	u32 endptctrl[8];
-+} __attribute__ ((packed));
-+
- /* Appendix C, Debug port ... intended for use with special "debug devices"
-  * that can help if there's no serial console.  (nonstandard enumeration.)
-  */
-@@ -682,6 +698,11 @@
- 	}
- 	return (1<<USB_PORT_FEAT_HIGHSPEED);
- }
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+/* TDI transaction translator status register and busy bit */
-+#define TT_BUSY 0x1
-+#define TT_STATUS  (0x15c-0x140)
-+#endif
- 
- #else
- 
-diff -Nurd linux-2.6.24/drivers/usb/misc/usbtest.c linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c
---- linux-2.6.24/drivers/usb/misc/usbtest.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c	2008-06-11 17:50:18.000000000 +0200
-@@ -993,6 +993,7 @@
- 
- 		u->context = &context;
- 		u->complete = ctrl_complete;
-+		u->transfer_flags |= URB_NO_SETUP_DMA_MAP;
- 	}
- 
- 	/* queue the urbs */
-@@ -1151,6 +1152,7 @@
- 		dbg ("ep %02x couldn't get halt status, %d", ep, retval);
- 		return retval;
- 	}
-+	le16_to_cpus(&status);
- 	if (status != 1) {
- 		dbg ("ep %02x bogus status: %04x != 1", ep, status);
- 		return -EINVAL;
-@@ -1207,7 +1209,7 @@
- 	int		retval = 0;
- 	struct urb	*urb;
- 
--	urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 512);
-+	urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 256);
- 	if (urb == NULL)
- 		return -ENOMEM;
- 
-@@ -2100,6 +2102,10 @@
- 	/* EZ-USB devices which download firmware to replace (or in our
- 	 * case augment) the default device implementation.
- 	 */
-+	/* generic EZ-USB FX controller */
-+	{ USB_DEVICE (0x0547, 0x2131),
-+		.driver_info = (unsigned long) &ez1_info,
-+		},
- 
- 	/* generic EZ-USB FX controller */
- 	{ USB_DEVICE (0x0547, 0x2235),
-diff -Nurd linux-2.6.24/drivers/usb/serial/cp2101.c linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c
---- linux-2.6.24/drivers/usb/serial/cp2101.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c	2008-06-11 17:50:15.000000000 +0200
-@@ -59,6 +59,7 @@
- 	{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
- 	{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
- 	{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
-+	{ USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
- 	{ USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
- 	{ USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
- 	{ USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
-@@ -76,8 +77,13 @@
- 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
- 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
- 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
-+	{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
-+	{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
-+	{ USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
-+	{ USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
- 	{ USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
- 	{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
-+	{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
- 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
- 	{ } /* Terminating Entry */
- };
-diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.c linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c
---- linux-2.6.24/drivers/usb/serial/ftdi_sio.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c	2008-06-11 17:50:15.000000000 +0200
-@@ -310,6 +310,7 @@
- };
- 
- static int   ftdi_olimex_probe		(struct usb_serial *serial);
-+static int   ftdi_mtxorb_hack_setup	(struct usb_serial *serial);
- static void  ftdi_USB_UIRT_setup	(struct ftdi_private *priv);
- static void  ftdi_HE_TIRA1_setup	(struct ftdi_private *priv);
- 
-@@ -317,6 +318,10 @@
- 	.probe	= ftdi_olimex_probe,
- };
- 
-+static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
-+	.probe  = ftdi_mtxorb_hack_setup,
-+};
-+
- static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
- 	.port_probe = ftdi_USB_UIRT_setup,
- };
-@@ -379,6 +384,8 @@
- 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
-+	{ USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID),
-+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- 	{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
-@@ -471,30 +478,29 @@
- 	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
- 	/*
--	 * These will probably use user-space drivers.  Uncomment them if
--	 * you need them or use the user-specified vendor/product module
--	 * parameters (see ftdi_sio.h for the numbers).  Make a fuss if
--	 * you think the driver should recognize any of them by default.
-+	 * Due to many user requests for multiple ELV devices we enable
-+	 * them by default.
- 	 */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
--	/* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
- 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
- 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
- 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
-@@ -545,6 +551,7 @@
- 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) },
- 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
- 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
- 	{ USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
-@@ -569,6 +576,7 @@
- 	{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
- 	{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
- 	{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
- 		.driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
- 	{ },					/* Optional parameter entry */
-@@ -1299,6 +1307,23 @@
- 	}
- 
- 	return 0;
-+}
-+
-+/*
-+ * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
-+ * We have to correct it if we want to read from it.
-+ */
-+static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
-+{
-+	struct usb_host_endpoint *ep = serial->dev->ep_in[1];
-+	struct usb_endpoint_descriptor *ep_desc = &ep->desc;
-+
-+	if (ep->enabled && ep_desc->wMaxPacketSize == 0) {
-+		ep_desc->wMaxPacketSize = 0x40;
-+		info("Fixing invalid wMaxPacketSize on read pipe");
-+	}
-+
-+	return 0;
- }
- 
- /* ftdi_shutdown is called from usbserial:usb_serial_disconnect
-diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.h linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h
---- linux-2.6.24/drivers/usb/serial/ftdi_sio.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h	2008-06-11 17:50:15.000000000 +0200
-@@ -98,6 +98,13 @@
- #define FTDI_MTXORB_5_PID      0xFA05  /* Matrix Orbital Product Id */
- #define FTDI_MTXORB_6_PID      0xFA06  /* Matrix Orbital Product Id */
- 
-+/*
-+ * The following are the values for the Matrix Orbital VK204-25-USB
-+ * display, which use the FT232RL.
-+ */
-+#define MTXORB_VK_VID		0x1b3d
-+#define MTXORB_VK_PID		0x0158
-+
- /* Interbiometrics USB I/O Board */
- /* Developed for Interbiometrics by Rudolf Gugler */
- #define INTERBIOMETRICS_VID              0x1209
-@@ -245,6 +252,7 @@
- #define FTDI_ELV_WS300PC_PID	0xE0F6	/* PC-Wetterstation (WS 300 PC) */
- #define FTDI_ELV_FHZ1300PC_PID	0xE0E8	/* FHZ 1300 PC */
- #define FTDI_ELV_WS500_PID	0xE0E9	/* PC-Wetterstation (WS 500) */
-+#define FTDI_ELV_EM1010PC_PID	0xE0EF	/* Engery monitor EM 1010 PC */
- 
- /*
-  * Definitions for ID TECH (www.idt-net.com) devices
-@@ -278,6 +286,7 @@
- #define FTDI_ATIK_ATK16C_PID	0xDF32	/* ATIK ATK-16C Colour Camera */
- #define FTDI_ATIK_ATK16HR_PID	0xDF31	/* ATIK ATK-16HR Grayscale Camera */
- #define FTDI_ATIK_ATK16HRC_PID	0xDF33	/* ATIK ATK-16HRC Colour Camera */
-+#define FTDI_ATIK_ATK16IC_PID   0xDF35  /* ATIK ATK-16IC Grayscale Camera */
- 
- /*
-  * Protego product ids
-@@ -534,6 +543,8 @@
- #define OLIMEX_VID			0x15BA
- #define OLIMEX_ARM_USB_OCD_PID		0x0003
- 
-+/* www.elsterelectricity.com Elster Unicom III Optical Probe */
-+#define FTDI_ELSTER_UNICOM_PID		0xE700 /* Product Id */
- 
- /*
-  * The Mobility Lab (TML)
-diff -Nurd linux-2.6.24/drivers/usb/serial/keyspan.c linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c
---- linux-2.6.24/drivers/usb/serial/keyspan.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c	2008-06-11 17:50:15.000000000 +0200
-@@ -838,7 +838,7 @@
- 
- 	port = (struct usb_serial_port *) urb->context;
- 	tty = port->tty;
--	if (urb->actual_length) {
-+	if (tty && urb->actual_length) {
- 		/* 0x80 bit is error flag */
- 		if ((data[0] & 0x80) == 0) {
- 			/* no error on any byte */
-diff -Nurd linux-2.6.24/drivers/usb/serial/kobil_sct.c linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c
---- linux-2.6.24/drivers/usb/serial/kobil_sct.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c	2008-06-11 17:50:15.000000000 +0200
-@@ -114,6 +114,7 @@
- 	.usb_driver = 		&kobil_driver,
- 	.id_table =		id_table,
- 	.num_interrupt_in =	NUM_DONT_CARE,
-+	.num_interrupt_out = 	NUM_DONT_CARE,
- 	.num_bulk_in =		0,
- 	.num_bulk_out =		0,
- 	.num_ports =		1,
-diff -Nurd linux-2.6.24/drivers/usb/serial/option.c linux-2.6.24-oxe810/drivers/usb/serial/option.c
---- linux-2.6.24/drivers/usb/serial/option.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/option.c	2008-06-11 17:50:15.000000000 +0200
-@@ -180,6 +180,7 @@
- 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8117) },	/* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
- 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) },	/* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
- 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8128) },	/* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
-+	{ USB_DEVICE(DELL_VENDOR_ID, 0x8136) },	/* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
- 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8137) },	/* Dell Wireless HSDPA 5520 */
- 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
- 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
-diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.c linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c
---- linux-2.6.24/drivers/usb/serial/pl2303.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c	2008-06-11 17:50:15.000000000 +0200
-@@ -65,6 +65,7 @@
- 	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
- 	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
- 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
-+	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
- 	{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
- 	{ USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
- 	{ USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
-@@ -84,9 +85,10 @@
- 	{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
- 	{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
- 	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
--	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
- 	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
- 	{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
-+	{ USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
-+	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
- 	{ }					/* Terminating entry */
- };
- 
-diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.h linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h
---- linux-2.6.24/drivers/usb/serial/pl2303.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h	2008-06-11 17:50:15.000000000 +0200
-@@ -35,6 +35,7 @@
- 
- #define RATOC_VENDOR_ID		0x0584
- #define RATOC_PRODUCT_ID	0xb000
-+#define RATOC_PRODUCT_ID_USB60F	0xb020
- 
- #define TRIPP_VENDOR_ID		0x2478
- #define TRIPP_PRODUCT_ID	0x2008
-@@ -96,10 +97,6 @@
- #define ALCOR_VENDOR_ID		0x058F
- #define ALCOR_PRODUCT_ID	0x9720
- 
--/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
--#define HUAWEI_VENDOR_ID	0x12d1
--#define HUAWEI_PRODUCT_ID	0x1001
--
- /* Willcom WS002IN Data Driver (by NetIndex Inc.) */
- #define WS002IN_VENDOR_ID	0x11f6
- #define WS002IN_PRODUCT_ID	0x2001
-@@ -107,3 +104,11 @@
- /* Corega CG-USBRS232R Serial Adapter */
- #define COREGA_VENDOR_ID	0x07aa
- #define COREGA_PRODUCT_ID	0x002a
-+
-+/* HL HL-340 (ID: 4348:5523) */
-+#define HL340_VENDOR_ID		0x4348
-+#define HL340_PRODUCT_ID	0x5523
-+
-+/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
-+#define YCCABLE_VENDOR_ID	0x05ad
-+#define YCCABLE_PRODUCT_ID	0x0fba
-diff -Nurd linux-2.6.24/drivers/usb/serial/sierra.c linux-2.6.24-oxe810/drivers/usb/serial/sierra.c
---- linux-2.6.24/drivers/usb/serial/sierra.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/sierra.c	2008-06-11 17:50:15.000000000 +0200
-@@ -104,6 +104,7 @@
- 	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */
- 	{ USB_DEVICE(0x1199, 0x0021) },	/* Sierra Wireless AirCard 597E */
- 	{ USB_DEVICE(0x1199, 0x0120) },	/* Sierra Wireless USB Dongle 595U */
-+	{ USB_DEVICE(0x1199, 0x0023) },	/* Sierra Wireless AirCard */
- 
- 	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */
- 	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 */
-@@ -117,9 +118,15 @@
- 	{ USB_DEVICE(0x1199, 0x6851) },	/* Sierra Wireless AirCard 881 */
- 	{ USB_DEVICE(0x1199, 0x6852) },	/* Sierra Wireless AirCard 880 E */
- 	{ USB_DEVICE(0x1199, 0x6853) },	/* Sierra Wireless AirCard 881 E */
-+	{ USB_DEVICE(0x1199, 0x6855) },	/* Sierra Wireless AirCard 880 U */
-+	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */
-+
-+	{ USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
-+	{ USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
- 
- 	{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
- 	{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
-+	{ USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */
- 
- 	{ USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
- 	{ }
-@@ -129,6 +136,7 @@
- static struct usb_device_id id_table_1port [] = {
- 	{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
- 	{ USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */
-+	{ USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600/ZTE MF330 */
- 	{ }
- };
- 
-@@ -142,6 +150,7 @@
- 	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */
- 	{ USB_DEVICE(0x1199, 0x0021) },	/* Sierra Wireless AirCard 597E */
- 	{ USB_DEVICE(0x1199, 0x0120) },	/* Sierra Wireless USB Dongle 595U*/
-+	{ USB_DEVICE(0x1199, 0x0023) },	/* Sierra Wireless AirCard */
- 
- 	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */
- 	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 */
-@@ -155,6 +164,10 @@
- 	{ USB_DEVICE(0x1199, 0x6851) },	/* Sierra Wireless AirCard 881 */
- 	{ USB_DEVICE(0x1199, 0x6852) },	/* Sierra Wireless AirCard 880E */
- 	{ USB_DEVICE(0x1199, 0x6853) },	/* Sierra Wireless AirCard 881E */
-+	{ USB_DEVICE(0x1199, 0x6855) },	/* Sierra Wireless AirCard 880 U */
-+	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881U */
-+	{ USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
-+	{ USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
- 	{ }
- };
- 
-diff -Nurd linux-2.6.24/drivers/usb/storage/protocol.c linux-2.6.24-oxe810/drivers/usb/storage/protocol.c
---- linux-2.6.24/drivers/usb/storage/protocol.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/storage/protocol.c	2008-06-11 17:50:16.000000000 +0200
-@@ -194,7 +194,7 @@
- 		 * and the starting offset within the page, and update
- 		 * the *offset and *index values for the next loop. */
- 		cnt = 0;
--		while (cnt < buflen) {
-+		while (cnt < buflen && sg) {
- 			struct page *page = sg_page(sg) +
- 					((sg->offset + *offset) >> PAGE_SHIFT);
- 			unsigned int poff =
-@@ -249,7 +249,8 @@
- 	unsigned int offset = 0;
- 	struct scatterlist *sg = NULL;
- 
--	usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
-+	buflen = min(buflen, srb->request_bufflen);
-+	buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
- 			TO_XFER_BUF);
- 	if (buflen < srb->request_bufflen)
- 		srb->resid = srb->request_bufflen - buflen;
-diff -Nurd linux-2.6.24/drivers/usb/storage/unusual_devs.h linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h
---- linux-2.6.24/drivers/usb/storage/unusual_devs.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h	2008-06-11 17:50:16.000000000 +0200
-@@ -86,6 +86,14 @@
- 		US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
- #endif
- 
-+/* Reported by Grant Grundler <grundler at parisc-linux.org>
-+ * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware.
-+ */
-+UNUSUAL_DEV(  0x03f0, 0x4002, 0x0001, 0x0001,
-+		"HP",
-+		"PhotoSmart R707",
-+		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY),
-+
- /* Reported by Sebastian Kapfer <sebastian_kapfer at gmx.net>
-  * and Olaf Hering <olh at suse.de> (different bcd's, same vendor/product)
-  * for USB floppies that need the SINGLE_LUN enforcement.
-diff -Nurd linux-2.6.24/fs/adfs/file.c linux-2.6.24-oxe810/fs/adfs/file.c
---- linux-2.6.24/fs/adfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/adfs/file.c	2008-06-11 17:47:02.000000000 +0200
-@@ -33,6 +33,7 @@
- 	.fsync		= file_fsync,
- 	.write		= do_sync_write,
- 	.aio_write	= generic_file_aio_write,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/affs/file.c linux-2.6.24-oxe810/fs/affs/file.c
---- linux-2.6.24/fs/affs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/affs/file.c	2008-06-11 17:46:52.000000000 +0200
-@@ -35,6 +35,7 @@
- 	.open		= affs_file_open,
- 	.release	= affs_file_release,
- 	.fsync		= file_fsync,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/afs/file.c linux-2.6.24-oxe810/fs/afs/file.c
---- linux-2.6.24/fs/afs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/afs/file.c	2008-06-11 17:46:51.000000000 +0200
-@@ -32,6 +32,7 @@
- 	.aio_read	= generic_file_aio_read,
- 	.aio_write	= afs_file_write,
- 	.mmap		= generic_file_readonly_mmap,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- 	.fsync		= afs_fsync,
- 	.lock		= afs_lock,
-diff -Nurd linux-2.6.24/fs/aio.c linux-2.6.24-oxe810/fs/aio.c
---- linux-2.6.24/fs/aio.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/aio.c	2008-06-11 17:47:10.000000000 +0200
-@@ -997,6 +997,14 @@
- 	/* everything turned out well, dispose of the aiocb. */
- 	ret = __aio_put_req(ctx, iocb);
- 
-+	/*
-+	 * We have to order our ring_info tail store above and test
-+	 * of the wait list below outside the wait lock.  This is
-+	 * like in wake_up_bit() where clearing a bit has to be
-+	 * ordered with the unlocked test.
-+	 */
-+	smp_mb();
-+
- 	if (waitqueue_active(&ctx->wait))
- 		wake_up(&ctx->wait);
- 
-diff -Nurd linux-2.6.24/fs/bio.c linux-2.6.24-oxe810/fs/bio.c
---- linux-2.6.24/fs/bio.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/bio.c	2008-06-11 17:47:10.000000000 +0200
-@@ -133,6 +133,7 @@
- 	memset(bio, 0, sizeof(*bio));
- 	bio->bi_flags = 1 << BIO_UPTODATE;
- 	atomic_set(&bio->bi_cnt, 1);
-+	bio->bi_raid = 0;
- }
- 
- /**
-@@ -260,6 +261,7 @@
- 	bio->bi_vcnt = bio_src->bi_vcnt;
- 	bio->bi_size = bio_src->bi_size;
- 	bio->bi_idx = bio_src->bi_idx;
-+    bio->bi_raid = bio_src->bi_raid;
- 	bio_phys_segments(q, bio);
- 	bio_hw_segments(q, bio);
- }
-diff -Nurd linux-2.6.24/fs/coda/file.c linux-2.6.24-oxe810/fs/coda/file.c
---- linux-2.6.24/fs/coda/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/coda/file.c	2008-06-11 17:47:09.000000000 +0200
-@@ -238,6 +238,7 @@
- 	.open		= coda_open,
- 	.release	= coda_release,
- 	.fsync		= coda_fsync,
-+	.sendfile	= coda_file_sendfile,
- 	.splice_read	= coda_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/ecryptfs/file.c linux-2.6.24-oxe810/fs/ecryptfs/file.c
---- linux-2.6.24/fs/ecryptfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ecryptfs/file.c	2008-06-11 17:46:59.000000000 +0200
-@@ -292,6 +292,7 @@
- 	.release = ecryptfs_release,
- 	.fsync = ecryptfs_fsync,
- 	.fasync = ecryptfs_fasync,
-+ 	.sendfile = ecryptfs_sendfile,
- 	.splice_read = generic_file_splice_read,
- };
- 
-@@ -309,6 +310,7 @@
- 	.release = ecryptfs_release,
- 	.fsync = ecryptfs_fsync,
- 	.fasync = ecryptfs_fasync,
-+ 	.sendfile = ecryptfs_sendfile,
- 	.splice_read = generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/ecryptfs/mmap.c linux-2.6.24-oxe810/fs/ecryptfs/mmap.c
---- linux-2.6.24/fs/ecryptfs/mmap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ecryptfs/mmap.c	2008-06-11 17:46:59.000000000 +0200
-@@ -263,52 +263,102 @@
- 	return 0;
- }
- 
--/* This function must zero any hole we create */
-+/**
-+ * ecryptfs_prepare_write
-+ * @file: The eCryptfs file
-+ * @page: The eCryptfs page
-+ * @from: The start byte from which we will write
-+ * @to: The end byte to which we will write
-+ *
-+ * This function must zero any hole we create
-+ *
-+ * Returns zero on success; non-zero otherwise
-+ */
- static int ecryptfs_prepare_write(struct file *file, struct page *page,
- 				  unsigned from, unsigned to)
- {
--	int rc = 0;
- 	loff_t prev_page_end_size;
-+	int rc = 0;
- 
- 	if (!PageUptodate(page)) {
--		rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
--						      PAGE_CACHE_SIZE,
--						      page->mapping->host);
--		if (rc) {
--			printk(KERN_ERR "%s: Error attemping to read lower "
--			       "page segment; rc = [%d]\n", __FUNCTION__, rc);
--			ClearPageUptodate(page);
--			goto out;
--		} else
-+		struct ecryptfs_crypt_stat *crypt_stat =
-+			&ecryptfs_inode_to_private(
-+				file->f_path.dentry->d_inode)->crypt_stat;
-+
-+		if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
-+		    || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
-+			rc = ecryptfs_read_lower_page_segment(
-+				page, page->index, 0, PAGE_CACHE_SIZE,
-+				page->mapping->host);
-+			if (rc) {
-+				printk(KERN_ERR "%s: Error attemping to read "
-+				       "lower page segment; rc = [%d]\n",
-+				       __FUNCTION__, rc);
-+				ClearPageUptodate(page);
-+				goto out;
-+			} else
-+				SetPageUptodate(page);
-+		} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
-+			if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
-+				rc = ecryptfs_copy_up_encrypted_with_header(
-+					page, crypt_stat);
-+				if (rc) {
-+					printk(KERN_ERR "%s: Error attempting "
-+					       "to copy the encrypted content "
-+					       "from the lower file whilst "
-+					       "inserting the metadata from "
-+					       "the xattr into the header; rc "
-+					       "= [%d]\n", __FUNCTION__, rc);
-+					ClearPageUptodate(page);
-+					goto out;
-+				}
-+				SetPageUptodate(page);
-+			} else {
-+				rc = ecryptfs_read_lower_page_segment(
-+					page, page->index, 0, PAGE_CACHE_SIZE,
-+					page->mapping->host);
-+				if (rc) {
-+					printk(KERN_ERR "%s: Error reading "
-+					       "page; rc = [%d]\n",
-+					       __FUNCTION__, rc);
-+					ClearPageUptodate(page);
-+					goto out;
-+				}
-+				SetPageUptodate(page);
-+			}
-+		} else {
-+			rc = ecryptfs_decrypt_page(page);
-+			if (rc) {
-+				printk(KERN_ERR "%s: Error decrypting page "
-+				       "at index [%ld]; rc = [%d]\n",
-+				       __FUNCTION__, page->index, rc);
-+				ClearPageUptodate(page);
-+				goto out;
-+			}
- 			SetPageUptodate(page);
-+		}
- 	}
--
- 	prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
--
--	/*
--	 * If creating a page or more of holes, zero them out via truncate.
--	 * Note, this will increase i_size.
--	 */
-+	/* If creating a page or more of holes, zero them out via truncate.
-+	 * Note, this will increase i_size. */
- 	if (page->index != 0) {
- 		if (prev_page_end_size > i_size_read(page->mapping->host)) {
- 			rc = ecryptfs_truncate(file->f_path.dentry,
- 					       prev_page_end_size);
- 			if (rc) {
--				printk(KERN_ERR "Error on attempt to "
-+				printk(KERN_ERR "%s: Error on attempt to "
- 				       "truncate to (higher) offset [%lld];"
--				       " rc = [%d]\n", prev_page_end_size, rc);
-+				       " rc = [%d]\n", __FUNCTION__,
-+				       prev_page_end_size, rc);
- 				goto out;
- 			}
- 		}
- 	}
--	/*
--	 * Writing to a new page, and creating a small hole from start of page?
--	 * Zero it out.
--	 */
--	if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
--	    (from != 0)) {
-+	/* Writing to a new page, and creating a small hole from start
-+	 * of page?  Zero it out. */
-+	if ((i_size_read(page->mapping->host) == prev_page_end_size)
-+	    && (from != 0))
- 		zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
--	}
- out:
- 	return rc;
- }
-diff -Nurd linux-2.6.24/fs/eventpoll.c linux-2.6.24-oxe810/fs/eventpoll.c
---- linux-2.6.24/fs/eventpoll.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/eventpoll.c	2008-06-11 17:47:10.000000000 +0200
-@@ -353,7 +353,7 @@
- 	spin_unlock_irqrestore(&psw->lock, flags);
- 
- 	/* Do really wake up now */
--	wake_up(wq);
-+	wake_up_nested(wq, 1 + wake_nests);
- 
- 	/* Remove the current task from the list */
- 	spin_lock_irqsave(&psw->lock, flags);
-diff -Nurd linux-2.6.24/fs/ext2/file.c linux-2.6.24-oxe810/fs/ext2/file.c
---- linux-2.6.24/fs/ext2/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext2/file.c	2008-06-11 17:47:06.000000000 +0200
-@@ -56,6 +56,7 @@
- 	.open		= generic_file_open,
- 	.release	= ext2_release_file,
- 	.fsync		= ext2_sync_file,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- 	.splice_write	= generic_file_splice_write,
- };
-@@ -73,6 +74,7 @@
- 	.open		= generic_file_open,
- 	.release	= ext2_release_file,
- 	.fsync		= ext2_sync_file,
-+	.sendfile	= xip_file_sendfile,
- };
- #endif
- 
-diff -Nurd linux-2.6.24/fs/ext3/file.c linux-2.6.24-oxe810/fs/ext3/file.c
---- linux-2.6.24/fs/ext3/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext3/file.c	2008-06-11 17:47:06.000000000 +0200
-@@ -120,6 +120,7 @@
- 	.open		= generic_file_open,
- 	.release	= ext3_release_file,
- 	.fsync		= ext3_sync_file,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- 	.splice_write	= generic_file_splice_write,
- };
-diff -Nurd linux-2.6.24/fs/ext3/ialloc.c linux-2.6.24-oxe810/fs/ext3/ialloc.c
---- linux-2.6.24/fs/ext3/ialloc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext3/ialloc.c	2008-06-11 17:47:06.000000000 +0200
-@@ -543,7 +543,16 @@
- 		percpu_counter_inc(&sbi->s_dirs_counter);
- 	sb->s_dirt = 1;
- 
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+	if (dir->i_mode & S_ISUID) {
-+		inode->i_uid = dir->i_uid;
-+		if (S_ISDIR(mode))
-+			mode |= S_ISUID;
-+	} else
-+#else // CONFIG_OXNAS_SUID_INHERIT
- 	inode->i_uid = current->fsuid;
-+#endif // CONFIG_OXNAS_SUID_INHERIT
-+
- 	if (test_opt (sb, GRPID))
- 		inode->i_gid = dir->i_gid;
- 	else if (dir->i_mode & S_ISGID) {
-diff -Nurd linux-2.6.24/fs/ext4/file.c linux-2.6.24-oxe810/fs/ext4/file.c
---- linux-2.6.24/fs/ext4/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext4/file.c	2008-06-11 17:47:07.000000000 +0200
-@@ -120,7 +120,8 @@
- 	.open		= generic_file_open,
- 	.release	= ext4_release_file,
- 	.fsync		= ext4_sync_file,
--	.splice_read	= generic_file_splice_read,
-+	.sendfile	= generic_file_sendfile,
-+ 	.splice_read	= generic_file_splice_read,
- 	.splice_write	= generic_file_splice_write,
- };
- 
-diff -Nurd linux-2.6.24/fs/fat/file.c linux-2.6.24-oxe810/fs/fat/file.c
---- linux-2.6.24/fs/fat/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fat/file.c	2008-06-11 17:47:05.000000000 +0200
-@@ -134,6 +134,7 @@
- 	.release	= fat_file_release,
- 	.ioctl		= fat_generic_ioctl,
- 	.fsync		= file_fsync,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/fuse/dir.c linux-2.6.24-oxe810/fs/fuse/dir.c
---- linux-2.6.24/fs/fuse/dir.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fuse/dir.c	2008-06-11 17:47:00.000000000 +0200
-@@ -905,7 +905,7 @@
- 	}
- 
- 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
--		int err = generic_permission(inode, mask, NULL);
-+		err = generic_permission(inode, mask, NULL);
- 
- 		/* If permission is denied, try to refresh file
- 		   attributes.  This is also needed, because the root
-diff -Nurd linux-2.6.24/fs/fuse/file.c linux-2.6.24-oxe810/fs/fuse/file.c
---- linux-2.6.24/fs/fuse/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fuse/file.c	2008-06-11 17:47:00.000000000 +0200
-@@ -920,6 +920,7 @@
- 	.fsync		= fuse_fsync,
- 	.lock		= fuse_file_lock,
- 	.flock		= fuse_file_flock,
-+    .sendfile   = generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/gfs2/ops_file.c linux-2.6.24-oxe810/fs/gfs2/ops_file.c
---- linux-2.6.24/fs/gfs2/ops_file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/gfs2/ops_file.c	2008-06-11 17:47:09.000000000 +0200
-@@ -662,6 +662,7 @@
- 	.release	= gfs2_close,
- 	.fsync		= gfs2_fsync,
- 	.lock		= gfs2_lock,
-+	.sendfile	= generic_file_sendfile,
- 	.flock		= gfs2_flock,
- 	.splice_read	= generic_file_splice_read,
- 	.splice_write	= generic_file_splice_write,
-diff -Nurd linux-2.6.24/fs/hpfs/file.c linux-2.6.24-oxe810/fs/hpfs/file.c
---- linux-2.6.24/fs/hpfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/hpfs/file.c	2008-06-11 17:46:57.000000000 +0200
-@@ -137,6 +137,7 @@
- 	.mmap		= generic_file_mmap,
- 	.release	= hpfs_file_release,
- 	.fsync		= hpfs_file_fsync,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/inotify_user.c linux-2.6.24-oxe810/fs/inotify_user.c
---- linux-2.6.24/fs/inotify_user.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/inotify_user.c	2008-06-11 17:47:10.000000000 +0200
-@@ -269,7 +269,7 @@
- 	/* we can safely put the watch as we don't reference it while
- 	 * generating the event
- 	 */
--	if (mask & IN_IGNORED || mask & IN_ONESHOT)
-+	if (mask & IN_IGNORED || w->mask & IN_ONESHOT)
- 		put_inotify_watch(w); /* final put */
- 
- 	/* coalescing: drop this event if it is a dupe of the previous */
-diff -Nurd linux-2.6.24/fs/isofs/compress.c linux-2.6.24-oxe810/fs/isofs/compress.c
---- linux-2.6.24/fs/isofs/compress.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/isofs/compress.c	2008-06-11 17:46:52.000000000 +0200
-@@ -72,6 +72,17 @@
- 	offset = index & ~zisofs_block_page_mask;
- 	blockindex = offset >> zisofs_block_page_shift;
- 	maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-+
-+	/*
-+	 * If this page is wholly outside i_size we just return zero;
-+	 * do_generic_file_read() will handle this for us
-+	 */
-+	if (page->index >= maxpage) {
-+		SetPageUptodate(page);
-+		unlock_page(page);
-+		return 0;
-+	}
-+
- 	maxpage = min(zisofs_block_pages, maxpage-offset);
- 
- 	for ( i = 0 ; i < maxpage ; i++, offset++ ) {
-diff -Nurd linux-2.6.24/fs/jbd/recovery.c linux-2.6.24-oxe810/fs/jbd/recovery.c
---- linux-2.6.24/fs/jbd/recovery.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jbd/recovery.c	2008-06-11 17:47:07.000000000 +0200
-@@ -478,7 +478,7 @@
- 					memcpy(nbh->b_data, obh->b_data,
- 							journal->j_blocksize);
- 					if (flags & JFS_FLAG_ESCAPE) {
--						*((__be32 *)bh->b_data) =
-+						*((__be32 *)nbh->b_data) =
- 						cpu_to_be32(JFS_MAGIC_NUMBER);
- 					}
- 
-diff -Nurd linux-2.6.24/fs/jbd2/recovery.c linux-2.6.24-oxe810/fs/jbd2/recovery.c
---- linux-2.6.24/fs/jbd2/recovery.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jbd2/recovery.c	2008-06-11 17:46:49.000000000 +0200
-@@ -488,7 +488,7 @@
- 					memcpy(nbh->b_data, obh->b_data,
- 							journal->j_blocksize);
- 					if (flags & JBD2_FLAG_ESCAPE) {
--						*((__be32 *)bh->b_data) =
-+						*((__be32 *)nbh->b_data) =
- 						cpu_to_be32(JBD2_MAGIC_NUMBER);
- 					}
- 
-diff -Nurd linux-2.6.24/fs/jffs2/file.c linux-2.6.24-oxe810/fs/jffs2/file.c
---- linux-2.6.24/fs/jffs2/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jffs2/file.c	2008-06-11 17:47:10.000000000 +0200
-@@ -49,7 +49,8 @@
- 	.ioctl =	jffs2_ioctl,
- 	.mmap =		generic_file_readonly_mmap,
- 	.fsync =	jffs2_fsync,
--	.splice_read =	generic_file_splice_read,
-+	.sendfile =	generic_file_sendfile,
-+  	.splice_read =	generic_file_splice_read,
- };
- 
- /* jffs2_file_inode_operations */
-diff -Nurd linux-2.6.24/fs/jfs/file.c linux-2.6.24-oxe810/fs/jfs/file.c
---- linux-2.6.24/fs/jfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jfs/file.c	2008-06-11 17:46:58.000000000 +0200
-@@ -108,6 +108,7 @@
- 	.aio_read	= generic_file_aio_read,
- 	.aio_write	= generic_file_aio_write,
- 	.mmap		= generic_file_mmap,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- 	.splice_write	= generic_file_splice_write,
- 	.fsync		= jfs_fsync,
-diff -Nurd linux-2.6.24/fs/minix/file.c linux-2.6.24-oxe810/fs/minix/file.c
---- linux-2.6.24/fs/minix/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/minix/file.c	2008-06-11 17:47:00.000000000 +0200
-@@ -23,6 +23,7 @@
- 	.aio_write	= generic_file_aio_write,
- 	.mmap		= generic_file_mmap,
- 	.fsync		= minix_sync_file,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/ncpfs/mmap.c linux-2.6.24-oxe810/fs/ncpfs/mmap.c
---- linux-2.6.24/fs/ncpfs/mmap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ncpfs/mmap.c	2008-06-11 17:47:09.000000000 +0200
-@@ -50,10 +50,6 @@
- 	pos = vmf->pgoff << PAGE_SHIFT;
- 
- 	count = PAGE_SIZE;
--	if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) {
--		WARN_ON(1); /* shouldn't happen? */
--		count = area->vm_end - (unsigned long)vmf->virtual_address;
--	}
- 	/* what we can read in one go */
- 	bufsize = NCP_SERVER(inode)->buffer_size;
- 
-diff -Nurd linux-2.6.24/fs/nfs/write.c linux-2.6.24-oxe810/fs/nfs/write.c
---- linux-2.6.24/fs/nfs/write.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/nfs/write.c	2008-06-11 17:46:59.000000000 +0200
-@@ -701,6 +701,17 @@
- }
- 
- /*
-+ * If the page cache is marked as unsafe or invalid, then we can't rely on
-+ * the PageUptodate() flag. In this case, we will need to turn off
-+ * write optimisations that depend on the page contents being correct.
-+ */
-+static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
-+{
-+	return PageUptodate(page) &&
-+		!(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA));
-+}
-+
-+/*
-  * Update and possibly write a cached page of an NFS file.
-  *
-  * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
-@@ -721,10 +732,13 @@
- 		(long long)(page_offset(page) +offset));
- 
- 	/* If we're not using byte range locks, and we know the page
--	 * is entirely in cache, it may be more efficient to avoid
--	 * fragmenting write requests.
-+	 * is up to date, it may be more efficient to extend the write
-+	 * to cover the entire page in order to avoid fragmentation
-+	 * inefficiencies.
- 	 */
--	if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
-+	if (nfs_write_pageuptodate(page, inode) &&
-+			inode->i_flock == NULL &&
-+			!(file->f_mode & O_SYNC)) {
- 		count = max(count + offset, nfs_page_length(page));
- 		offset = 0;
- 	}
-diff -Nurd linux-2.6.24/fs/nfsd/nfsfh.c linux-2.6.24-oxe810/fs/nfsd/nfsfh.c
---- linux-2.6.24/fs/nfsd/nfsfh.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/nfsd/nfsfh.c	2008-06-11 17:47:05.000000000 +0200
-@@ -231,6 +231,7 @@
- 		fhp->fh_dentry = dentry;
- 		fhp->fh_export = exp;
- 		nfsd_nr_verified++;
-+		cache_get(&exp->h);
- 	} else {
- 		/*
- 		 * just rechecking permissions
-@@ -240,6 +241,7 @@
- 		dprintk("nfsd: fh_verify - just checking\n");
- 		dentry = fhp->fh_dentry;
- 		exp = fhp->fh_export;
-+		cache_get(&exp->h);
- 		/*
- 		 * Set user creds for this exportpoint; necessary even
- 		 * in the "just checking" case because this may be a
-@@ -251,8 +253,6 @@
- 		if (error)
- 			goto out;
- 	}
--	cache_get(&exp->h);
--
- 
- 	error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
- 	if (error)
-diff -Nurd linux-2.6.24/fs/ntfs/file.c linux-2.6.24-oxe810/fs/ntfs/file.c
---- linux-2.6.24/fs/ntfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ntfs/file.c	2008-06-11 17:47:01.000000000 +0200
-@@ -2274,16 +2274,11 @@
- 						    mounted filesystem. */
- 	.mmap		= generic_file_mmap,	 /* Mmap file. */
- 	.open		= ntfs_file_open,	 /* Open file. */
--	.splice_read	= generic_file_splice_read /* Zero-copy data send with
-+	.sendfile	= generic_file_sendfile, /* Zero-copy data send with
- 						    the data source being on
- 						    the ntfs partition.  We do
- 						    not need to care about the
- 						    data destination. */
--	/*.sendpage	= ,*/			 /* Zero-copy data send with
--						    the data destination being
--						    on the ntfs partition.  We
--						    do not need to care about
--						    the data source. */
- };
- 
- const struct inode_operations ntfs_file_inode_ops = {
-diff -Nurd linux-2.6.24/fs/ocfs2/file.c linux-2.6.24-oxe810/fs/ocfs2/file.c
---- linux-2.6.24/fs/ocfs2/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ocfs2/file.c	2008-06-11 17:46:56.000000000 +0200
-@@ -2206,6 +2206,7 @@
- const struct file_operations ocfs2_fops = {
- 	.read		= do_sync_read,
- 	.write		= do_sync_write,
-+	.sendfile	= generic_file_sendfile,
- 	.mmap		= ocfs2_mmap,
- 	.fsync		= ocfs2_sync_file,
- 	.release	= ocfs2_file_release,
-diff -Nurd linux-2.6.24/fs/qnx4/file.c linux-2.6.24-oxe810/fs/qnx4/file.c
---- linux-2.6.24/fs/qnx4/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/qnx4/file.c	2008-06-11 17:46:56.000000000 +0200
-@@ -25,6 +25,7 @@
- 	.read		= do_sync_read,
- 	.aio_read	= generic_file_aio_read,
- 	.mmap		= generic_file_mmap,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- #ifdef CONFIG_QNX4FS_RW
- 	.write		= do_sync_write,
-diff -Nurd linux-2.6.24/fs/read_write.c linux-2.6.24-oxe810/fs/read_write.c
---- linux-2.6.24/fs/read_write.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/read_write.c	2008-06-11 17:47:10.000000000 +0200
-@@ -26,7 +26,8 @@
- 	.read		= do_sync_read,
- 	.aio_read	= generic_file_aio_read,
- 	.mmap		= generic_file_readonly_mmap,
--	.splice_read	= generic_file_splice_read,
-+	//.splice_read	= generic_file_splice_read,
-+	.sendfile	= generic_file_sendfile,
- };
- 
- EXPORT_SYMBOL(generic_ro_fops);
-@@ -709,7 +710,7 @@
- 	struct inode * in_inode, * out_inode;
- 	loff_t pos;
- 	ssize_t retval;
--	int fput_needed_in, fput_needed_out, fl;
-+	int fput_needed_in, fput_needed_out;
- 
- 	/*
- 	 * Get input file, and verify that it is ok..
-@@ -724,7 +725,7 @@
- 	in_inode = in_file->f_path.dentry->d_inode;
- 	if (!in_inode)
- 		goto fput_in;
--	if (!in_file->f_op || !in_file->f_op->splice_read)
-+	if (!in_file->f_op || !in_file->f_op->sendfile)
- 		goto fput_in;
- 	retval = -ESPIPE;
- 	if (!ppos)
-@@ -777,7 +778,6 @@
- 		count = max - pos;
- 	}
- 
--	fl = 0;
- #if 0
- 	/*
- 	 * We need to debate whether we can enable this or not. The
-@@ -788,7 +788,7 @@
- 	if (in_file->f_flags & O_NONBLOCK)
- 		fl = SPLICE_F_NONBLOCK;
- #endif
--	retval = do_splice_direct(in_file, ppos, out_file, count, fl);
-+	retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
- 
- 	if (retval > 0) {
- 		add_rchar(current, retval);
-diff -Nurd linux-2.6.24/fs/reiserfs/file.c linux-2.6.24-oxe810/fs/reiserfs/file.c
---- linux-2.6.24/fs/reiserfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/reiserfs/file.c	2008-06-11 17:46:50.000000000 +0200
-@@ -292,6 +292,7 @@
- 	.open = generic_file_open,
- 	.release = reiserfs_file_release,
- 	.fsync = reiserfs_sync_file,
-+	.sendfile = generic_file_sendfile,
- 	.aio_read = generic_file_aio_read,
- 	.aio_write = generic_file_aio_write,
- 	.splice_read = generic_file_splice_read,
-diff -Nurd linux-2.6.24/fs/smbfs/file.c linux-2.6.24-oxe810/fs/smbfs/file.c
---- linux-2.6.24/fs/smbfs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/smbfs/file.c	2008-06-11 17:47:00.000000000 +0200
-@@ -283,6 +283,27 @@
- 	return status;
- }
- 
-+static ssize_t
-+smb_file_sendfile(struct file *file, loff_t *ppos,
-+		  size_t count, read_actor_t actor, void *target)
-+{
-+	struct dentry *dentry = file->f_path.dentry;
-+	ssize_t status;
-+
-+	VERBOSE("file %s/%s, pos=%Ld, count=%d\n",
-+		DENTRY_PATH(dentry), *ppos, count);
-+
-+	status = smb_revalidate_inode(dentry);
-+	if (status) {
-+		PARANOIA("%s/%s validation failed, error=%Zd\n",
-+			 DENTRY_PATH(dentry), status);
-+		goto out;
-+	}
-+	status = generic_file_sendfile(file, ppos, count, actor, target);
-+out:
-+	return status;
-+}
-+
- /*
-  * This does the "real" work of the write. The generic routine has
-  * allocated the page, locked it, done all the page alignment stuff
-@@ -434,6 +455,7 @@
- 	.open		= smb_file_open,
- 	.release	= smb_file_release,
- 	.fsync		= smb_fsync,
-+	.sendfile	= smb_file_sendfile,
- 	.splice_read	= smb_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/splice.c linux-2.6.24-oxe810/fs/splice.c
---- linux-2.6.24/fs/splice.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/splice.c	2008-06-11 17:47:10.000000000 +0200
-@@ -1184,6 +1184,9 @@
- {
- 	int partial;
- 
-+	if (!access_ok(VERIFY_READ, src, n))
-+		return -EFAULT;
-+
- 	pagefault_disable();
- 	partial = __copy_from_user_inatomic(dst, src, n);
- 	pagefault_enable();
-@@ -1236,7 +1239,7 @@
- 		if (unlikely(!len))
- 			break;
- 		error = -EFAULT;
--		if (unlikely(!base))
-+		if (!access_ok(VERIFY_READ, base, len))
- 			break;
- 
- 		/*
-@@ -1391,6 +1394,11 @@
- 			error = -EFAULT;
- 			break;
- 		}
-+
-+		if (unlikely(!access_ok(VERIFY_WRITE, base, len))) {
-+			error = -EFAULT;
-+			break;
-+		}
- 
- 		sd.len = 0;
- 		sd.total_len = len;
-diff -Nurd linux-2.6.24/fs/sysv/file.c linux-2.6.24-oxe810/fs/sysv/file.c
---- linux-2.6.24/fs/sysv/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/sysv/file.c	2008-06-11 17:47:00.000000000 +0200
-@@ -27,6 +27,7 @@
- 	.aio_write	= generic_file_aio_write,
- 	.mmap		= generic_file_mmap,
- 	.fsync		= sysv_sync_file,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/udf/file.c linux-2.6.24-oxe810/fs/udf/file.c
---- linux-2.6.24/fs/udf/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/udf/file.c	2008-06-11 17:47:10.000000000 +0200
-@@ -246,6 +246,8 @@
- 	.aio_write		= udf_file_aio_write,
- 	.release		= udf_release_file,
- 	.fsync			= udf_fsync_file,
-+	.sendfile		= generic_file_sendfile,
-+	.sendfile		= generic_file_sendfile,
- 	.splice_read		= generic_file_splice_read,
- };
- 
-diff -Nurd linux-2.6.24/fs/ufs/file.c linux-2.6.24-oxe810/fs/ufs/file.c
---- linux-2.6.24/fs/ufs/file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ufs/file.c	2008-06-11 17:46:54.000000000 +0200
-@@ -63,5 +63,6 @@
- 	.mmap		= generic_file_mmap,
- 	.open           = generic_file_open,
- 	.fsync		= ufs_sync_file,
-+	.sendfile	= generic_file_sendfile,
- 	.splice_read	= generic_file_splice_read,
- };
-diff -Nurd linux-2.6.24/fs/ufs/util.h linux-2.6.24-oxe810/fs/ufs/util.h
---- linux-2.6.24/fs/ufs/util.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ufs/util.h	2008-06-11 17:46:54.000000000 +0200
-@@ -58,7 +58,7 @@
- {
- 	switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
- 	case UFS_ST_SUNOS:
--		if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
-+		if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) {
- 			usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
- 			break;
- 		}
-diff -Nurd linux-2.6.24/fs/xfs/Makefile-linux-2.6 linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6
---- linux-2.6.24/fs/xfs/Makefile-linux-2.6	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6	2008-06-11 17:46:48.000000000 +0200
-@@ -15,13 +15,20 @@
- # along with this program; if not, write the Free Software Foundation,
- # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- #
-+CONFIG_XFS_DEBUG := n
-+CONFIG_XFS_TRACE := n
- 
- EXTRA_CFLAGS +=	 -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
- 
- XFS_LINUX := linux-2.6
- 
-+ifeq ($(CONFIG_XFS_TRACE),y)
-+	EXTRA_CFLAGS += -DCONFIG_XFS_TRACE
-+endif
-+
- ifeq ($(CONFIG_XFS_DEBUG),y)
- 	EXTRA_CFLAGS += -g
-+	EXTRA_CFLAGS += -DCONFIG_XFS_DEBUG
- endif
- 
- obj-$(CONFIG_XFS_FS)		+= xfs.o
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c	2008-06-11 17:46:46.000000000 +0200
-@@ -330,20 +330,26 @@
- 
- 	ASSERT(list_empty(&bp->b_hash_list));
- 
--	if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) {
-+	if (bp->b_flags & _XBF_PAGE_CACHE) {
- 		uint		i;
- 
- 		if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
- 			free_address(bp->b_addr - bp->b_offset);
- 
- 		for (i = 0; i < bp->b_page_count; i++) {
--			struct page	*page = bp->b_pages[i];
--
--			if (bp->b_flags & _XBF_PAGE_CACHE)
--				ASSERT(!PagePrivate(page));
-+			struct page *page = bp->b_pages[i];
-+			ASSERT(!PagePrivate(page));
- 			page_cache_release(page);
- 		}
- 		_xfs_buf_free_pages(bp);
-+	} else if (bp->b_flags & _XBF_KMEM_ALLOC) {
-+		 /*
-+		  * XXX(hch): bp->b_count_desired might be incorrect (see
-+		  * xfs_buf_associate_memory for details), but fortunately
-+		  * the Linux version of kmem_free ignores the len argument..
-+		  */
-+		kmem_free(bp->b_addr, bp->b_count_desired);
-+		_xfs_buf_free_pages(bp);
- 	}
- 
- 	xfs_buf_deallocate(bp);
-@@ -766,44 +772,46 @@
- 	size_t			len,
- 	xfs_buftarg_t		*target)
- {
--	unsigned long		page_count = PAGE_ALIGN(len) >> PAGE_SHIFT;
--	int			error, i;
-+	size_t			malloc_len = len;
- 	xfs_buf_t		*bp;
-+	void			*data;
-+	int			error;
- 
- 	bp = xfs_buf_allocate(0);
- 	if (unlikely(bp == NULL))
- 		goto fail;
- 	_xfs_buf_initialize(bp, target, 0, len, 0);
- 
--	error = _xfs_buf_get_pages(bp, page_count, 0);
--	if (error)
-+ try_again:
-+	data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
-+	if (unlikely(data == NULL))
- 		goto fail_free_buf;
- 
--	for (i = 0; i < page_count; i++) {
--		bp->b_pages[i] = alloc_page(GFP_KERNEL);
--		if (!bp->b_pages[i])
--			goto fail_free_mem;
-+	/* check whether alignment matches.. */
-+	if ((__psunsigned_t)data !=
-+	    ((__psunsigned_t)data & ~target->bt_smask)) {
-+		/* .. else double the size and try again */
-+		kmem_free(data, malloc_len);
-+		malloc_len <<= 1;
-+		goto try_again;
- 	}
--	bp->b_flags |= _XBF_PAGES;
- 
--	error = _xfs_buf_map_pages(bp, XBF_MAPPED);
--	if (unlikely(error)) {
--		printk(KERN_WARNING "%s: failed to map pages\n",
--				__FUNCTION__);
-+	/* Clear the memory contents */
-+	memset(data, 0, malloc_len);
-+
-+	error = xfs_buf_associate_memory(bp, data, len);
-+	if (error)
- 		goto fail_free_mem;
--	}
-+	bp->b_flags |= _XBF_KMEM_ALLOC;
- 
- 	xfs_buf_unlock(bp);
- 
--	XB_TRACE(bp, "no_daddr", len);
-+	XB_TRACE(bp, "no_daddr", data);
- 	return bp;
--
-  fail_free_mem:
--	while (--i >= 0)
--		__free_page(bp->b_pages[i]);
--	_xfs_buf_free_pages(bp);
-+	kmem_free(data, malloc_len);
-  fail_free_buf:
--	xfs_buf_deallocate(bp);
-+	xfs_buf_free(bp);
-  fail:
- 	return NULL;
- }
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h	2008-06-11 17:46:46.000000000 +0200
-@@ -63,7 +63,7 @@
- 
- 	/* flags used only internally */
- 	_XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache		   */
--	_XBF_PAGES = (1 << 18),	    /* backed by refcounted pages	   */
-+	_XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() 		   */
- 	_XBF_RUN_QUEUES = (1 << 19),/* run block device task queue	   */
- 	_XBF_DELWRI_Q = (1 << 21),   /* buffer on delwri queue		   */
- } xfs_buf_flags_t;
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c	2008-06-11 17:46:46.000000000 +0200
-@@ -122,6 +122,28 @@
- }
- 
- STATIC ssize_t
-+xfs_file_sendfile(
-+	struct file		*filp,
-+	loff_t			*pos,
-+	size_t			count,
-+	read_actor_t		actor,
-+	void			*target)
-+{
-+	return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, 0, count, actor, target);
-+}
-+
-+STATIC ssize_t
-+xfs_file_sendfile_invis(
-+	struct file		*filp,
-+	loff_t			*pos,
-+	size_t			count,
-+	read_actor_t		actor,
-+	void			*target)
-+{
-+	return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, IO_INVIS, count, actor, target);
-+}
-+
-+STATIC ssize_t
- xfs_file_splice_read(
- 	struct file		*infilp,
- 	loff_t			*ppos,
-@@ -350,8 +372,8 @@
- 
- 		size = buf.used;
- 		de = (struct hack_dirent *)buf.dirent;
--		curr_offset = de->offset /* & 0x7fffffff */;
- 		while (size > 0) {
-+			curr_offset = de->offset /* & 0x7fffffff */;
- 			if (filldir(dirent, de->name, de->namlen,
- 					curr_offset & 0x7fffffff,
- 					de->ino, de->d_type)) {
-@@ -362,7 +384,6 @@
- 				       sizeof(u64));
- 			size -= reclen;
- 			de = (struct hack_dirent *)((char *)de + reclen);
--			curr_offset = de->offset /* & 0x7fffffff */;
- 		}
- 	}
- 
-@@ -502,8 +523,11 @@
- 	.llseek		= generic_file_llseek,
- 	.read		= do_sync_read,
- 	.write		= do_sync_write,
-+//	.readv		= xfs_file_readv,
-+//	.writev		= xfs_file_writev,
- 	.aio_read	= xfs_file_aio_read,
- 	.aio_write	= xfs_file_aio_write,
-+	.sendfile	= xfs_file_sendfile,
- 	.splice_read	= xfs_file_splice_read,
- 	.splice_write	= xfs_file_splice_write,
- 	.unlocked_ioctl	= xfs_file_ioctl,
-@@ -525,6 +549,7 @@
- 	.write		= do_sync_write,
- 	.aio_read	= xfs_file_aio_read_invis,
- 	.aio_write	= xfs_file_aio_write_invis,
-+	.sendfile	= xfs_file_sendfile_invis,
- 	.splice_read	= xfs_file_splice_read_invis,
- 	.splice_write	= xfs_file_splice_write_invis,
- 	.unlocked_ioctl	= xfs_file_ioctl_invis,
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c	2008-06-11 17:46:46.000000000 +0200
-@@ -271,6 +271,48 @@
- }
- 
- ssize_t
-+xfs_sendfile(
-+	xfs_inode_t		*ip,
-+	struct file		*filp,
-+	loff_t			*offset,
-+	int			ioflags,
-+	size_t			count,
-+	read_actor_t		actor,
-+	void			*target)
-+{
-+	bhv_vnode_t		*vp = XFS_ITOV(ip);
-+	xfs_mount_t		*mp = ip->i_mount;
-+	ssize_t			ret;
-+
-+	XFS_STATS_INC(xs_read_calls);
-+	if (XFS_FORCED_SHUTDOWN(mp))
-+		return -EIO;
-+
-+	xfs_ilock(ip, XFS_IOLOCK_SHARED);
-+
-+	if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
-+	    (!(ioflags & IO_INVIS))) {
-+		bhv_vrwlock_t locktype = VRWLOCK_READ;
-+		int error;
-+
-+		error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp,*offset, count,
-+				      FILP_DELAY_FLAG(filp), &locktype);
-+		if (error) {
-+			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-+			return -error;
-+		}
-+	}
-+	xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
-+		   (void *)(unsigned long)target, count, *offset, ioflags);
-+	ret = generic_file_sendfile(filp, offset, count, actor, target);
-+	if (ret > 0)
-+		XFS_STATS_ADD(xs_read_bytes, ret);
-+
-+	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-+	return ret;
-+}
-+
-+ssize_t
- xfs_splice_read(
- 	xfs_inode_t		*ip,
- 	struct file		*infilp,
-diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c
---- linux-2.6.24/fs/xfs/xfs_alloc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c	2008-06-11 17:46:48.000000000 +0200
-@@ -592,7 +592,7 @@
- 		if (!(args->wasfromfl)) {
- 
- 			agf = XFS_BUF_TO_AGF(args->agbp);
--			be32_add(&agf->agf_freeblks, -(args->len));
-+			be32_add_cpu(&agf->agf_freeblks, -(args->len));
- 			xfs_trans_agblocks_delta(args->tp,
- 						 -((long)(args->len)));
- 			args->pag->pagf_freeblks -= args->len;
-@@ -1720,7 +1720,7 @@
- 
- 		agf = XFS_BUF_TO_AGF(agbp);
- 		pag = &mp->m_perag[agno];
--		be32_add(&agf->agf_freeblks, len);
-+		be32_add_cpu(&agf->agf_freeblks, len);
- 		xfs_trans_agblocks_delta(tp, len);
- 		pag->pagf_freeblks += len;
- 		XFS_WANT_CORRUPTED_GOTO(
-@@ -2008,18 +2008,18 @@
- 	 * Get the block number and update the data structures.
- 	 */
- 	bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
--	be32_add(&agf->agf_flfirst, 1);
-+	be32_add_cpu(&agf->agf_flfirst, 1);
- 	xfs_trans_brelse(tp, agflbp);
- 	if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
- 		agf->agf_flfirst = 0;
- 	pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
--	be32_add(&agf->agf_flcount, -1);
-+	be32_add_cpu(&agf->agf_flcount, -1);
- 	xfs_trans_agflist_delta(tp, -1);
- 	pag->pagf_flcount--;
- 
- 	logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
- 	if (btreeblk) {
--		be32_add(&agf->agf_btreeblks, 1);
-+		be32_add_cpu(&agf->agf_btreeblks, 1);
- 		pag->pagf_btreeblks++;
- 		logflags |= XFS_AGF_BTREEBLKS;
- 	}
-@@ -2117,17 +2117,17 @@
- 			be32_to_cpu(agf->agf_seqno), &agflbp)))
- 		return error;
- 	agfl = XFS_BUF_TO_AGFL(agflbp);
--	be32_add(&agf->agf_fllast, 1);
-+	be32_add_cpu(&agf->agf_fllast, 1);
- 	if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
- 		agf->agf_fllast = 0;
- 	pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
--	be32_add(&agf->agf_flcount, 1);
-+	be32_add_cpu(&agf->agf_flcount, 1);
- 	xfs_trans_agflist_delta(tp, 1);
- 	pag->pagf_flcount++;
- 
- 	logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
- 	if (btreeblk) {
--		be32_add(&agf->agf_btreeblks, -1);
-+		be32_add_cpu(&agf->agf_btreeblks, -1);
- 		pag->pagf_btreeblks--;
- 		logflags |= XFS_AGF_BTREEBLKS;
- 	}
-diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c
---- linux-2.6.24/fs/xfs/xfs_alloc_btree.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c	2008-06-11 17:46:48.000000000 +0200
-@@ -221,7 +221,7 @@
- 			 */
- 			bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
- 			agf->agf_roots[cur->bc_btnum] = *lpp;
--			be32_add(&agf->agf_levels[cur->bc_btnum], -1);
-+			be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1);
- 			mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
- 			/*
- 			 * Put this buffer/block on the ag's freelist.
-@@ -1256,9 +1256,9 @@
- 	/*
- 	 * Bump and log left's numrecs, decrement and log right's numrecs.
- 	 */
--	be16_add(&left->bb_numrecs, 1);
-+	be16_add_cpu(&left->bb_numrecs, 1);
- 	xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
--	be16_add(&right->bb_numrecs, -1);
-+	be16_add_cpu(&right->bb_numrecs, -1);
- 	xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- 	/*
- 	 * Slide the contents of right down one entry.
-@@ -1346,7 +1346,7 @@
- 
- 		agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- 		agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
--		be32_add(&agf->agf_levels[cur->bc_btnum], 1);
-+		be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1);
- 		seqno = be32_to_cpu(agf->agf_seqno);
- 		mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
- 		xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
-@@ -1558,9 +1558,9 @@
- 	/*
- 	 * Decrement and log left's numrecs, bump and log right's numrecs.
- 	 */
--	be16_add(&left->bb_numrecs, -1);
-+	be16_add_cpu(&left->bb_numrecs, -1);
- 	xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
--	be16_add(&right->bb_numrecs, 1);
-+	be16_add_cpu(&right->bb_numrecs, 1);
- 	xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- 	/*
- 	 * Using a temporary cursor, update the parent key values of the
-@@ -1643,7 +1643,7 @@
- 	 */
- 	if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- 	    cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
--		be16_add(&right->bb_numrecs, 1);
-+		be16_add_cpu(&right->bb_numrecs, 1);
- 	i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- 	/*
- 	 * For non-leaf blocks, copy keys and addresses over to the new block.
-@@ -1689,7 +1689,7 @@
- 	 * Adjust numrecs, sibling pointers.
- 	 */
- 	lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
--	be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+	be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- 	right->bb_rightsib = left->bb_rightsib;
- 	left->bb_rightsib = cpu_to_be32(rbno);
- 	right->bb_leftsib = cpu_to_be32(lbno);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_attr_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c
---- linux-2.6.24/fs/xfs/xfs_attr_leaf.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c	2008-06-11 17:46:48.000000000 +0200
-@@ -319,7 +319,7 @@
- 	memcpy(sfe->nameval, args->name, args->namelen);
- 	memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
- 	sf->hdr.count++;
--	be16_add(&sf->hdr.totsize, size);
-+	be16_add_cpu(&sf->hdr.totsize, size);
- 	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
- 
- 	xfs_sbversion_add_attr2(mp, args->trans);
-@@ -365,7 +365,7 @@
- 	if (end != totsize)
- 		memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
- 	sf->hdr.count--;
--	be16_add(&sf->hdr.totsize, -size);
-+	be16_add_cpu(&sf->hdr.totsize, -size);
- 
- 	/*
- 	 * Fix up the start offset of the attribute fork
-@@ -1135,7 +1135,7 @@
- 		xfs_da_log_buf(args->trans, bp,
- 		    XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- 	}
--	be16_add(&hdr->count, 1);
-+	be16_add_cpu(&hdr->count, 1);
- 
- 	/*
- 	 * Allocate space for the new string (at the end of the run).
-@@ -1149,7 +1149,7 @@
- 					 mp->m_sb.sb_blocksize, NULL));
- 	ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- 	ASSERT((be16_to_cpu(map->size) & 0x3) == 0);
--	be16_add(&map->size,
-+	be16_add_cpu(&map->size,
- 		-xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
- 					  mp->m_sb.sb_blocksize, &tmp));
- 	entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) +
-@@ -1216,12 +1216,12 @@
- 	map = &hdr->freemap[0];
- 	for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
- 		if (be16_to_cpu(map->base) == tmp) {
--			be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t));
--			be16_add(&map->size,
-+			be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t));
-+			be16_add_cpu(&map->size,
- 				 -((int)sizeof(xfs_attr_leaf_entry_t)));
- 		}
- 	}
--	be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
-+	be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
- 	xfs_da_log_buf(args->trans, bp,
- 		XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
- 	return(0);
-@@ -1729,9 +1729,9 @@
- 		ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
- 		ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- 		if (be16_to_cpu(map->base) == tablesize) {
--			be16_add(&map->base,
-+			be16_add_cpu(&map->base,
- 				 -((int)sizeof(xfs_attr_leaf_entry_t)));
--			be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t));
-+			be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t));
- 		}
- 
- 		if ((be16_to_cpu(map->base) + be16_to_cpu(map->size))
-@@ -1753,19 +1753,19 @@
- 	if ((before >= 0) || (after >= 0)) {
- 		if ((before >= 0) && (after >= 0)) {
- 			map = &hdr->freemap[before];
--			be16_add(&map->size, entsize);
--			be16_add(&map->size,
-+			be16_add_cpu(&map->size, entsize);
-+			be16_add_cpu(&map->size,
- 				 be16_to_cpu(hdr->freemap[after].size));
- 			hdr->freemap[after].base = 0;
- 			hdr->freemap[after].size = 0;
- 		} else if (before >= 0) {
- 			map = &hdr->freemap[before];
--			be16_add(&map->size, entsize);
-+			be16_add_cpu(&map->size, entsize);
- 		} else {
- 			map = &hdr->freemap[after];
- 			/* both on-disk, don't endian flip twice */
- 			map->base = entry->nameidx;
--			be16_add(&map->size, entsize);
-+			be16_add_cpu(&map->size, entsize);
- 		}
- 	} else {
- 		/*
-@@ -1790,7 +1790,7 @@
- 	 * Compress the remaining entries and zero out the removed stuff.
- 	 */
- 	memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize);
--	be16_add(&hdr->usedbytes, -entsize);
-+	be16_add_cpu(&hdr->usedbytes, -entsize);
- 	xfs_da_log_buf(args->trans, bp,
- 	     XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
- 				   entsize));
-@@ -1798,7 +1798,7 @@
- 	tmp = (be16_to_cpu(hdr->count) - args->index)
- 					* sizeof(xfs_attr_leaf_entry_t);
- 	memmove((char *)entry, (char *)(entry+1), tmp);
--	be16_add(&hdr->count, -1);
-+	be16_add_cpu(&hdr->count, -1);
- 	xfs_da_log_buf(args->trans, bp,
- 	    XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- 	entry = &leaf->entries[be16_to_cpu(hdr->count)];
-@@ -2184,15 +2184,15 @@
- 		 */
- 		if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
- 			memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
--			be16_add(&hdr_s->usedbytes, -tmp);
--			be16_add(&hdr_s->count, -1);
-+			be16_add_cpu(&hdr_s->usedbytes, -tmp);
-+			be16_add_cpu(&hdr_s->count, -1);
- 			entry_d--;	/* to compensate for ++ in loop hdr */
- 			desti--;
- 			if ((start_s + i) < offset)
- 				result++;	/* insertion index adjustment */
- 		} else {
- #endif /* GROT */
--			be16_add(&hdr_d->firstused, -tmp);
-+			be16_add_cpu(&hdr_d->firstused, -tmp);
- 			/* both on-disk, don't endian flip twice */
- 			entry_d->hashval = entry_s->hashval;
- 			/* both on-disk, don't endian flip twice */
-@@ -2205,10 +2205,10 @@
- 			ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
- 							<= XFS_LBSIZE(mp));
- 			memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
--			be16_add(&hdr_s->usedbytes, -tmp);
--			be16_add(&hdr_d->usedbytes, tmp);
--			be16_add(&hdr_s->count, -1);
--			be16_add(&hdr_d->count, 1);
-+			be16_add_cpu(&hdr_s->usedbytes, -tmp);
-+			be16_add_cpu(&hdr_d->usedbytes, tmp);
-+			be16_add_cpu(&hdr_s->count, -1);
-+			be16_add_cpu(&hdr_d->count, 1);
- 			tmp = be16_to_cpu(hdr_d->count)
- 						* sizeof(xfs_attr_leaf_entry_t)
- 						+ sizeof(xfs_attr_leaf_hdr_t);
-@@ -2249,7 +2249,7 @@
- 	 * Fill in the freemap information
- 	 */
- 	hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
--	be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
-+	be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
- 			sizeof(xfs_attr_leaf_entry_t));
- 	hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused)
- 			      - be16_to_cpu(hdr_d->freemap[0].base));
-diff -Nurd linux-2.6.24/fs/xfs/xfs_bmap_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c
---- linux-2.6.24/fs/xfs/xfs_bmap_btree.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c	2008-06-11 17:46:48.000000000 +0200
-@@ -631,7 +631,7 @@
- 		memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
- 		xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
- 	}
--	be16_add(&left->bb_numrecs, numrrecs);
-+	be16_add_cpu(&left->bb_numrecs, numrrecs);
- 	left->bb_rightsib = right->bb_rightsib;
- 	xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
- 	if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
-@@ -924,7 +924,7 @@
- 		xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
- 		block = ifp->if_broot;
- 	}
--	be16_add(&block->bb_numrecs, i);
-+	be16_add_cpu(&block->bb_numrecs, i);
- 	ASSERT(block->bb_numrecs == cblock->bb_numrecs);
- 	kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- 	ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
-@@ -947,7 +947,7 @@
- 			XFS_TRANS_DQ_BCOUNT, -1L);
- 	xfs_trans_binval(cur->bc_tp, cbp);
- 	cur->bc_bufs[level - 1] = NULL;
--	be16_add(&block->bb_level, -1);
-+	be16_add_cpu(&block->bb_level, -1);
- 	xfs_trans_log_inode(cur->bc_tp, ip,
- 		XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- 	cur->bc_nlevels--;
-@@ -1401,9 +1401,9 @@
- 		key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
- 		rkp = &key;
- 	}
--	be16_add(&left->bb_numrecs, -1);
-+	be16_add_cpu(&left->bb_numrecs, -1);
- 	xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
--	be16_add(&right->bb_numrecs, 1);
-+	be16_add_cpu(&right->bb_numrecs, 1);
- #ifdef DEBUG
- 	if (level > 0)
- 		xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
-@@ -1535,7 +1535,7 @@
- 	right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
- 	if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- 	    cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
--		be16_add(&right->bb_numrecs, 1);
-+		be16_add_cpu(&right->bb_numrecs, 1);
- 	i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- 	if (level > 0) {
- 		lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
-@@ -1562,7 +1562,7 @@
- 		xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- 		*startoff = xfs_bmbt_disk_get_startoff(rrp);
- 	}
--	be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+	be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- 	right->bb_rightsib = left->bb_rightsib;
- 	left->bb_rightsib = cpu_to_be64(args.fsbno);
- 	right->bb_leftsib = cpu_to_be64(lbno);
-@@ -2241,7 +2241,7 @@
- 	bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
- 	cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
- 	*cblock = *block;
--	be16_add(&block->bb_level, 1);
-+	be16_add_cpu(&block->bb_level, 1);
- 	block->bb_numrecs = cpu_to_be16(1);
- 	cur->bc_nlevels++;
- 	cur->bc_ptrs[level + 1] = 1;
-diff -Nurd linux-2.6.24/fs/xfs/xfs_da_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c
---- linux-2.6.24/fs/xfs/xfs_da_btree.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c	2008-06-11 17:46:48.000000000 +0200
-@@ -511,12 +511,12 @@
- 		 * Move the req'd B-tree elements from high in node1 to
- 		 * low in node2.
- 		 */
--		be16_add(&node2->hdr.count, count);
-+		be16_add_cpu(&node2->hdr.count, count);
- 		tmp = count * (uint)sizeof(xfs_da_node_entry_t);
- 		btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count];
- 		btree_d = &node2->btree[0];
- 		memcpy(btree_d, btree_s, tmp);
--		be16_add(&node1->hdr.count, -count);
-+		be16_add_cpu(&node1->hdr.count, -count);
- 	} else {
- 		/*
- 		 * Move the req'd B-tree elements from low in node2 to
-@@ -527,7 +527,7 @@
- 		btree_s = &node2->btree[0];
- 		btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)];
- 		memcpy(btree_d, btree_s, tmp);
--		be16_add(&node1->hdr.count, count);
-+		be16_add_cpu(&node1->hdr.count, count);
- 		xfs_da_log_buf(tp, blk1->bp,
- 			XFS_DA_LOGRANGE(node1, btree_d, tmp));
- 
-@@ -539,7 +539,7 @@
- 		btree_s = &node2->btree[count];
- 		btree_d = &node2->btree[0];
- 		memmove(btree_d, btree_s, tmp);
--		be16_add(&node2->hdr.count, -count);
-+		be16_add_cpu(&node2->hdr.count, -count);
- 	}
- 
- 	/*
-@@ -604,7 +604,7 @@
- 	btree->before = cpu_to_be32(newblk->blkno);
- 	xfs_da_log_buf(state->args->trans, oldblk->bp,
- 		XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
--	be16_add(&node->hdr.count, 1);
-+	be16_add_cpu(&node->hdr.count, 1);
- 	xfs_da_log_buf(state->args->trans, oldblk->bp,
- 		XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
- 
-@@ -959,7 +959,7 @@
- 	memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
- 	xfs_da_log_buf(state->args->trans, drop_blk->bp,
- 	    XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
--	be16_add(&node->hdr.count, -1);
-+	be16_add_cpu(&node->hdr.count, -1);
- 	xfs_da_log_buf(state->args->trans, drop_blk->bp,
- 	    XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
- 
-@@ -1018,7 +1018,7 @@
- 	 */
- 	tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
- 	memcpy(btree, &drop_node->btree[0], tmp);
--	be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
-+	be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
- 
- 	xfs_da_log_buf(tp, save_blk->bp,
- 		XFS_DA_LOGRANGE(save_node, &save_node->hdr,
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_block.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c
---- linux-2.6.24/fs/xfs/xfs_dir2_block.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c	2008-06-11 17:46:48.000000000 +0200
-@@ -271,7 +271,7 @@
- 		}
- 		lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
- 		lfloghigh -= be32_to_cpu(btp->stale) - 1;
--		be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1));
-+		be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
- 		xfs_dir2_data_make_free(tp, bp,
- 			(xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
- 			(xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
-@@ -326,7 +326,7 @@
- 		/*
- 		 * Update the tail (entry count).
- 		 */
--		be32_add(&btp->count, 1);
-+		be32_add_cpu(&btp->count, 1);
- 		/*
- 		 * If we now need to rebuild the bestfree map, do so.
- 		 * This needs to happen before the next call to use_free.
-@@ -387,7 +387,7 @@
- 			lfloglow = MIN(mid, lfloglow);
- 			lfloghigh = MAX(highstale, lfloghigh);
- 		}
--		be32_add(&btp->stale, -1);
-+		be32_add_cpu(&btp->stale, -1);
- 	}
- 	/*
- 	 * Point to the new data entry.
-@@ -767,7 +767,7 @@
- 	/*
- 	 * Fix up the block tail.
- 	 */
--	be32_add(&btp->stale, 1);
-+	be32_add_cpu(&btp->stale, 1);
- 	xfs_dir2_block_log_tail(tp, bp);
- 	/*
- 	 * Remove the leaf entry by marking it stale.
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_data.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c
---- linux-2.6.24/fs/xfs/xfs_dir2_data.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c	2008-06-11 17:46:48.000000000 +0200
-@@ -587,7 +587,7 @@
- 		/*
- 		 * Fix up the new big freespace.
- 		 */
--		be16_add(&prevdup->length, len + be16_to_cpu(postdup->length));
-+		be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
- 		*xfs_dir2_data_unused_tag_p(prevdup) =
- 			cpu_to_be16((char *)prevdup - (char *)d);
- 		xfs_dir2_data_log_unused(tp, bp, prevdup);
-@@ -621,7 +621,7 @@
- 	 */
- 	else if (prevdup) {
- 		dfp = xfs_dir2_data_freefind(d, prevdup);
--		be16_add(&prevdup->length, len);
-+		be16_add_cpu(&prevdup->length, len);
- 		*xfs_dir2_data_unused_tag_p(prevdup) =
- 			cpu_to_be16((char *)prevdup - (char *)d);
- 		xfs_dir2_data_log_unused(tp, bp, prevdup);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c
---- linux-2.6.24/fs/xfs/xfs_dir2_leaf.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c	2008-06-11 17:46:48.000000000 +0200
-@@ -359,7 +359,7 @@
- 			bestsp--;
- 			memmove(&bestsp[0], &bestsp[1],
- 				be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
--			be32_add(&ltp->bestcount, 1);
-+			be32_add_cpu(&ltp->bestcount, 1);
- 			xfs_dir2_leaf_log_tail(tp, lbp);
- 			xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- 		}
-@@ -445,7 +445,7 @@
- 		 */
- 		lfloglow = index;
- 		lfloghigh = be16_to_cpu(leaf->hdr.count);
--		be16_add(&leaf->hdr.count, 1);
-+		be16_add_cpu(&leaf->hdr.count, 1);
- 	}
- 	/*
- 	 * There are stale entries.
-@@ -523,7 +523,7 @@
- 			lfloglow = MIN(index, lfloglow);
- 			lfloghigh = MAX(highstale, lfloghigh);
- 		}
--		be16_add(&leaf->hdr.stale, -1);
-+		be16_add_cpu(&leaf->hdr.stale, -1);
- 	}
- 	/*
- 	 * Fill in the new leaf entry.
-@@ -626,7 +626,7 @@
- 	 * Update and log the header, log the leaf entries.
- 	 */
- 	ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
--	be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
-+	be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
- 	leaf->hdr.stale = 0;
- 	xfs_dir2_leaf_log_header(args->trans, bp);
- 	if (loglow != -1)
-@@ -728,7 +728,7 @@
- 	/*
- 	 * Adjust the leaf header values.
- 	 */
--	be16_add(&leaf->hdr.count, -(from - to));
-+	be16_add_cpu(&leaf->hdr.count, -(from - to));
- 	leaf->hdr.stale = cpu_to_be16(1);
- 	/*
- 	 * Remember the low/high stale value only in the "right"
-@@ -1470,7 +1470,7 @@
- 	/*
- 	 * We just mark the leaf entry stale by putting a null in it.
- 	 */
--	be16_add(&leaf->hdr.stale, 1);
-+	be16_add_cpu(&leaf->hdr.stale, 1);
- 	xfs_dir2_leaf_log_header(tp, lbp);
- 	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- 	xfs_dir2_leaf_log_ents(tp, lbp, index, index);
-@@ -1531,7 +1531,7 @@
- 			 */
- 			memmove(&bestsp[db - i], bestsp,
- 				(be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
--			be32_add(&ltp->bestcount, -(db - i));
-+			be32_add_cpu(&ltp->bestcount, -(db - i));
- 			xfs_dir2_leaf_log_tail(tp, lbp);
- 			xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- 		} else
-@@ -1712,7 +1712,7 @@
- 	 * Eliminate the last bests entry from the table.
- 	 */
- 	bestsp = xfs_dir2_leaf_bests_p(ltp);
--	be32_add(&ltp->bestcount, -1);
-+	be32_add_cpu(&ltp->bestcount, -1);
- 	memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
- 	xfs_dir2_leaf_log_tail(tp, lbp);
- 	xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_node.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c
---- linux-2.6.24/fs/xfs/xfs_dir2_node.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c	2008-06-11 17:46:48.000000000 +0200
-@@ -254,7 +254,7 @@
- 				(be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
- 		lfloglow = index;
- 		lfloghigh = be16_to_cpu(leaf->hdr.count);
--		be16_add(&leaf->hdr.count, 1);
-+		be16_add_cpu(&leaf->hdr.count, 1);
- 	}
- 	/*
- 	 * There are stale entries.  We'll use one for the new entry.
-@@ -322,7 +322,7 @@
- 			lfloglow = MIN(index, lfloglow);
- 			lfloghigh = MAX(highstale, lfloghigh);
- 		}
--		be16_add(&leaf->hdr.stale, -1);
-+		be16_add_cpu(&leaf->hdr.stale, -1);
- 	}
- 	/*
- 	 * Insert the new entry, log everything.
-@@ -697,10 +697,10 @@
- 	/*
- 	 * Update the headers and log them.
- 	 */
--	be16_add(&leaf_s->hdr.count, -(count));
--	be16_add(&leaf_s->hdr.stale, -(stale));
--	be16_add(&leaf_d->hdr.count, count);
--	be16_add(&leaf_d->hdr.stale, stale);
-+	be16_add_cpu(&leaf_s->hdr.count, -(count));
-+	be16_add_cpu(&leaf_s->hdr.stale, -(stale));
-+	be16_add_cpu(&leaf_d->hdr.count, count);
-+	be16_add_cpu(&leaf_d->hdr.stale, stale);
- 	xfs_dir2_leaf_log_header(tp, bp_s);
- 	xfs_dir2_leaf_log_header(tp, bp_d);
- 	xfs_dir2_leafn_check(args->dp, bp_s);
-@@ -885,7 +885,7 @@
- 	 * Kill the leaf entry by marking it stale.
- 	 * Log the leaf block changes.
- 	 */
--	be16_add(&leaf->hdr.stale, 1);
-+	be16_add_cpu(&leaf->hdr.stale, 1);
- 	xfs_dir2_leaf_log_header(tp, bp);
- 	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- 	xfs_dir2_leaf_log_ents(tp, bp, index, index);
-@@ -971,7 +971,7 @@
- 			/*
- 			 * One less used entry in the free table.
- 			 */
--			be32_add(&free->hdr.nused, -1);
-+			be32_add_cpu(&free->hdr.nused, -1);
- 			xfs_dir2_free_log_header(tp, fbp);
- 			/*
- 			 * If this was the last entry in the table, we can
-@@ -1642,7 +1642,7 @@
- 		 * (this should always be true) then update the header.
- 		 */
- 		if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) {
--			be32_add(&free->hdr.nused, 1);
-+			be32_add_cpu(&free->hdr.nused, 1);
- 			xfs_dir2_free_log_header(tp, fbp);
- 		}
- 		/*
-diff -Nurd linux-2.6.24/fs/xfs/xfs_fsops.c linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c
---- linux-2.6.24/fs/xfs/xfs_fsops.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c	2008-06-11 17:46:48.000000000 +0200
-@@ -318,7 +318,7 @@
- 		}
- 		ASSERT(bp);
- 		agi = XFS_BUF_TO_AGI(bp);
--		be32_add(&agi->agi_length, new);
-+		be32_add_cpu(&agi->agi_length, new);
- 		ASSERT(nagcount == oagcount ||
- 		       be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
- 		xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
-@@ -331,7 +331,7 @@
- 		}
- 		ASSERT(bp);
- 		agf = XFS_BUF_TO_AGF(bp);
--		be32_add(&agf->agf_length, new);
-+		be32_add_cpu(&agf->agf_length, new);
- 		ASSERT(be32_to_cpu(agf->agf_length) ==
- 		       be32_to_cpu(agi->agi_length));
- 		xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c
---- linux-2.6.24/fs/xfs/xfs_ialloc.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c	2008-06-11 17:46:48.000000000 +0200
-@@ -301,8 +301,8 @@
- 		}
- 		xfs_trans_inode_alloc_buf(tp, fbuf);
- 	}
--	be32_add(&agi->agi_count, newlen);
--	be32_add(&agi->agi_freecount, newlen);
-+	be32_add_cpu(&agi->agi_count, newlen);
-+	be32_add_cpu(&agi->agi_freecount, newlen);
- 	agno = be32_to_cpu(agi->agi_seqno);
- 	down_read(&args.mp->m_peraglock);
- 	args.mp->m_perag[agno].pagi_freecount += newlen;
-@@ -885,7 +885,7 @@
- 	if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
- 			rec.ir_free)))
- 		goto error0;
--	be32_add(&agi->agi_freecount, -1);
-+	be32_add_cpu(&agi->agi_freecount, -1);
- 	xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- 	down_read(&mp->m_peraglock);
- 	mp->m_perag[tagno].pagi_freecount--;
-@@ -1065,8 +1065,8 @@
- 		 * to be freed when the transaction is committed.
- 		 */
- 		ilen = XFS_IALLOC_INODES(mp);
--		be32_add(&agi->agi_count, -ilen);
--		be32_add(&agi->agi_freecount, -(ilen - 1));
-+		be32_add_cpu(&agi->agi_count, -ilen);
-+		be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
- 		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
- 		down_read(&mp->m_peraglock);
- 		mp->m_perag[agno].pagi_freecount -= ilen - 1;
-@@ -1095,7 +1095,7 @@
- 		/* 
- 		 * Change the inode free counts and log the ag/sb changes.
- 		 */
--		be32_add(&agi->agi_freecount, 1);
-+		be32_add_cpu(&agi->agi_freecount, 1);
- 		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- 		down_read(&mp->m_peraglock);
- 		mp->m_perag[agno].pagi_freecount++;
-diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c
---- linux-2.6.24/fs/xfs/xfs_ialloc_btree.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c	2008-06-11 17:46:48.000000000 +0200
-@@ -189,7 +189,7 @@
- 			 */
- 			bno = be32_to_cpu(agi->agi_root);
- 			agi->agi_root = *pp;
--			be32_add(&agi->agi_level, -1);
-+			be32_add_cpu(&agi->agi_level, -1);
- 			/*
- 			 * Free the block.
- 			 */
-@@ -1132,7 +1132,7 @@
- 	/*
- 	 * Bump and log left's numrecs, decrement and log right's numrecs.
- 	 */
--	be16_add(&left->bb_numrecs, 1);
-+	be16_add_cpu(&left->bb_numrecs, 1);
- 	xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- #ifdef DEBUG
- 	if (level > 0)
-@@ -1140,7 +1140,7 @@
- 	else
- 		xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
- #endif
--	be16_add(&right->bb_numrecs, -1);
-+	be16_add_cpu(&right->bb_numrecs, -1);
- 	xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- 	/*
- 	 * Slide the contents of right down one entry.
-@@ -1232,7 +1232,7 @@
- 	 * Set the root data in the a.g. inode structure.
- 	 */
- 	agi->agi_root = cpu_to_be32(args.agbno);
--	be32_add(&agi->agi_level, 1);
-+	be32_add_cpu(&agi->agi_level, 1);
- 	xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp,
- 		XFS_AGI_ROOT | XFS_AGI_LEVEL);
- 	/*
-@@ -1426,9 +1426,9 @@
- 	/*
- 	 * Decrement and log left's numrecs, bump and log right's numrecs.
- 	 */
--	be16_add(&left->bb_numrecs, -1);
-+	be16_add_cpu(&left->bb_numrecs, -1);
- 	xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
--	be16_add(&right->bb_numrecs, 1);
-+	be16_add_cpu(&right->bb_numrecs, 1);
- #ifdef DEBUG
- 	if (level > 0)
- 		xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
-@@ -1529,7 +1529,7 @@
- 	 */
- 	if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- 	    cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
--		be16_add(&right->bb_numrecs, 1);
-+		be16_add_cpu(&right->bb_numrecs, 1);
- 	i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- 	/*
- 	 * For non-leaf blocks, copy keys and addresses over to the new block.
-@@ -1565,7 +1565,7 @@
- 	 * Find the left block number by looking in the buffer.
- 	 * Adjust numrecs, sibling pointers.
- 	 */
--	be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+	be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- 	right->bb_rightsib = left->bb_rightsib;
- 	left->bb_rightsib = cpu_to_be32(args.agbno);
- 	right->bb_leftsib = cpu_to_be32(lbno);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.c linux-2.6.24-oxe810/fs/xfs/xfs_inode.c
---- linux-2.6.24/fs/xfs/xfs_inode.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.c	2008-06-11 17:46:48.000000000 +0200
-@@ -1158,6 +1158,16 @@
- 	if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
- 		xfs_bump_ino_vers2(tp, ip);
- 
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+	/* Modification to propagate SUID down directory hierarchy */
-+	if (pip && XFS_INHERIT_UID(pip)) {
-+		ip->i_d.di_uid = pip->i_d.di_uid;
-+		if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
-+			ip->i_d.di_mode |= S_ISUID;
-+		}
-+	}
-+#endif // CONFIG_OXNAS_SUID_INHERIT
-+
- 	if (pip && XFS_INHERIT_GID(pip)) {
- 		ip->i_d.di_gid = pip->i_d.di_gid;
- 		if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
-diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.h linux-2.6.24-oxe810/fs/xfs/xfs_inode.h
---- linux-2.6.24/fs/xfs/xfs_inode.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.h	2008-06-11 17:46:48.000000000 +0200
-@@ -495,6 +495,11 @@
- #define XFS_INHERIT_GID(pip)	\
- 	(((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
- 	 ((pip)->i_d.di_mode & S_ISGID))
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+/* Modification to propagate SUID down directory hierarchy */
-+#define XFS_INHERIT_UID(pip)	\
-+	((pip)->i_d.di_mode & S_ISUID)
-+#endif // CONFIG_OXNAS_SUID_INHERIT
- 
- /*
-  * Flags for xfs_iget()
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log.c linux-2.6.24-oxe810/fs/xfs/xfs_log.c
---- linux-2.6.24/fs/xfs/xfs_log.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log.c	2008-06-11 17:46:48.000000000 +0200
-@@ -399,10 +399,10 @@
- {
- 	xlog_t *log = mp->m_log;
- 	xlog_in_core_t	  *iclog = (xlog_in_core_t *)iclog_hndl;
--	int	abortflg, spl;
-+	int	abortflg;
- 
- 	cb->cb_next = NULL;
--	spl = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
- 	if (!abortflg) {
- 		ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
-@@ -411,7 +411,7 @@
- 		*(iclog->ic_callback_tail) = cb;
- 		iclog->ic_callback_tail = &(cb->cb_next);
- 	}
--	LOG_UNLOCK(log, spl);
-+	spin_unlock(&log->l_icloglock);
- 	return abortflg;
- }	/* xfs_log_notify */
- 
-@@ -503,6 +503,8 @@
- 	      xfs_daddr_t	blk_offset,
- 	      int		num_bblks)
- {
-+	int		error;
-+
- 	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
- 		cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname);
- 	else {
-@@ -519,7 +521,7 @@
- 	 * just worked.
- 	 */
- 	if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
--		int		error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
-+		int	readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
- 
- 		if (readonly)
- 			mp->m_flags &= ~XFS_MOUNT_RDONLY;
-@@ -530,8 +532,8 @@
- 			mp->m_flags |= XFS_MOUNT_RDONLY;
- 		if (error) {
- 			cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
--			xlog_dealloc_log(mp->m_log);
--			return error;
-+			
-+			goto error;
- 		}
- 	}
- 
-@@ -540,6 +542,9 @@
- 
- 	/* End mounting message in xfs_log_mount_finish */
- 	return 0;
-+error:
-+	xfs_log_unmount_dealloc(mp);
-+	return error;
- }	/* xfs_log_mount */
- 
- /*
-@@ -606,7 +611,6 @@
- 	xfs_log_ticket_t tic = NULL;
- 	xfs_lsn_t	 lsn;
- 	int		 error;
--	SPLDECL(s);
- 
- 	/* the data section must be 32 bit size aligned */
- 	struct {
-@@ -659,24 +663,24 @@
- 		}
- 
- 
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		iclog = log->l_iclog;
- 		iclog->ic_refcnt++;
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		xlog_state_want_sync(log, iclog);
- 		(void) xlog_state_release_iclog(log, iclog);
- 
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
- 		      iclog->ic_state == XLOG_STATE_DIRTY)) {
- 			if (!XLOG_FORCED_SHUTDOWN(log)) {
- 				sv_wait(&iclog->ic_forcesema, PMEM,
- 					&log->l_icloglock, s);
- 			} else {
--				LOG_UNLOCK(log, s);
-+				spin_unlock(&log->l_icloglock);
- 			}
- 		} else {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 		}
- 		if (tic) {
- 			xlog_trace_loggrant(log, tic, "unmount rec");
-@@ -697,15 +701,15 @@
- 		 * a file system that went into forced_shutdown as
- 		 * the result of an unmount..
- 		 */
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		iclog = log->l_iclog;
- 		iclog->ic_refcnt++;
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 
- 		xlog_state_want_sync(log, iclog);
- 		(void) xlog_state_release_iclog(log, iclog);
- 
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 
- 		if ( ! (   iclog->ic_state == XLOG_STATE_ACTIVE
- 			|| iclog->ic_state == XLOG_STATE_DIRTY
-@@ -714,7 +718,7 @@
- 				sv_wait(&iclog->ic_forcesema, PMEM,
- 					&log->l_icloglock, s);
- 		} else {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 		}
- 	}
- 
-@@ -723,6 +727,9 @@
- 
- /*
-  * Deallocate log structures for unmount/relocation.
-+ *
-+ * We need to stop the aild from running before we destroy
-+ * and deallocate the log as the aild references the log.
-  */
- void
- xfs_log_unmount_dealloc(xfs_mount_t *mp)
-@@ -762,20 +769,18 @@
- 	xlog_ticket_t	*tic;
- 	xlog_t		*log = mp->m_log;
- 	int		need_bytes, free_bytes, cycle, bytes;
--	SPLDECL(s);
- 
- 	if (XLOG_FORCED_SHUTDOWN(log))
- 		return;
--	ASSERT(!XFS_FORCED_SHUTDOWN(mp));
- 
- 	if (tail_lsn == 0) {
- 		/* needed since sync_lsn is 64 bits */
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		tail_lsn = log->l_last_sync_lsn;
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 	}
- 
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 
- 	/* Also an invalid lsn.  1 implies that we aren't passing in a valid
- 	 * tail_lsn.
-@@ -824,7 +829,7 @@
- 			tic = tic->t_next;
- 		} while (tic != log->l_reserve_headq);
- 	}
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- }	/* xfs_log_move_tail */
- 
- /*
-@@ -836,14 +841,13 @@
- int
- xfs_log_need_covered(xfs_mount_t *mp)
- {
--	SPLDECL(s);
- 	int		needed = 0, gen;
- 	xlog_t		*log = mp->m_log;
- 
- 	if (!xfs_fs_writable(mp))
- 		return 0;
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
- 		(log->l_covered_state == XLOG_STATE_COVER_NEED2))
- 			&& !xfs_trans_first_ail(mp, &gen)
-@@ -856,7 +860,7 @@
- 		}
- 		needed = 1;
- 	}
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 	return needed;
- }
- 
-@@ -881,17 +885,16 @@
- xlog_assign_tail_lsn(xfs_mount_t *mp)
- {
- 	xfs_lsn_t tail_lsn;
--	SPLDECL(s);
- 	xlog_t	  *log = mp->m_log;
- 
- 	tail_lsn = xfs_trans_tail_ail(mp);
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	if (tail_lsn != 0) {
- 		log->l_tail_lsn = tail_lsn;
- 	} else {
- 		tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
- 	}
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 
- 	return tail_lsn;
- }	/* xlog_assign_tail_lsn */
-@@ -911,7 +914,7 @@
-  * the tail.  The details of this case are described below, but the end
-  * result is that we return the size of the log as the amount of space left.
-  */
--int
-+STATIC int
- xlog_space_left(xlog_t *log, int cycle, int bytes)
- {
- 	int free_bytes;
-@@ -1165,7 +1168,7 @@
- 	log->l_flags	   |= XLOG_ACTIVE_RECOVERY;
- 
- 	log->l_prev_block  = -1;
--	ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, 1, 0);
-+	log->l_tail_lsn	   = xlog_assign_lsn(1, 0);
- 	/* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */
- 	log->l_last_sync_lsn = log->l_tail_lsn;
- 	log->l_curr_cycle  = 1;	    /* 0 is bad since this is initial value */
-@@ -1193,8 +1196,8 @@
- 	ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- 	log->l_xbuf = bp;
- 
--	spinlock_init(&log->l_icloglock, "iclog");
--	spinlock_init(&log->l_grant_lock, "grhead_iclog");
-+	spin_lock_init(&log->l_icloglock);
-+	spin_lock_init(&log->l_grant_lock);
- 	initnsema(&log->l_flushsema, 0, "ic-flush");
- 	xlog_state_ticket_alloc(log);  /* wait until after icloglock inited */
- 
-@@ -1231,12 +1234,12 @@
- 
- 		head = &iclog->ic_header;
- 		memset(head, 0, sizeof(xlog_rec_header_t));
--		INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
--		INT_SET(head->h_version, ARCH_CONVERT,
-+		head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
-+		head->h_version = cpu_to_be32(
- 			XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
--		INT_SET(head->h_size, ARCH_CONVERT, log->l_iclog_size);
-+		head->h_size = cpu_to_be32(log->l_iclog_size);
- 		/* new fields */
--		INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
-+		head->h_fmt = cpu_to_be32(XLOG_FMT);
- 		memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
- 
- 
-@@ -1293,7 +1296,7 @@
-  * pushes on an lsn which is further along in the log once we reach the high
-  * water mark.  In this manner, we would be creating a low water mark.
-  */
--void
-+STATIC void
- xlog_grant_push_ail(xfs_mount_t	*mp,
- 		    int		need_bytes)
- {
-@@ -1305,11 +1308,10 @@
-     int		threshold_block;	/* block in lsn we'd like to be at */
-     int		threshold_cycle;	/* lsn cycle we'd like to be at */
-     int		free_threshold;
--    SPLDECL(s);
- 
-     ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
- 
--    s = GRANT_LOCK(log);
-+    spin_lock(&log->l_grant_lock);
-     free_bytes = xlog_space_left(log,
- 				 log->l_grant_reserve_cycle,
- 				 log->l_grant_reserve_bytes);
-@@ -1331,8 +1333,7 @@
- 	    threshold_block -= log->l_logBBsize;
- 	    threshold_cycle += 1;
- 	}
--	ASSIGN_ANY_LSN_HOST(threshold_lsn, threshold_cycle,
--		       threshold_block);
-+	threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block);
- 
- 	/* Don't pass in an lsn greater than the lsn of the last
- 	 * log record known to be on disk.
-@@ -1340,7 +1341,7 @@
- 	if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0)
- 	    threshold_lsn = log->l_last_sync_lsn;
-     }
--    GRANT_UNLOCK(log, s);
-+    spin_unlock(&log->l_grant_lock);
- 
-     /*
-      * Get the transaction layer to kick the dirty buffers out to
-@@ -1378,19 +1379,18 @@
-  * is added immediately before calling bwrite().
-  */
- 
--int
-+STATIC int
- xlog_sync(xlog_t		*log,
- 	  xlog_in_core_t	*iclog)
- {
- 	xfs_caddr_t	dptr;		/* pointer to byte sized element */
- 	xfs_buf_t	*bp;
--	int		i, ops;
-+	int		i;
- 	uint		count;		/* byte count of bwrite */
- 	uint		count_init;	/* initial count before roundup */
- 	int		roundoff;       /* roundoff to BB or stripe */
- 	int		split = 0;	/* split write into two regions */
- 	int		error;
--	SPLDECL(s);
- 	int		v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
- 
- 	XFS_STATS_INC(xs_log_writes);
-@@ -1415,30 +1415,24 @@
- 		 roundoff < BBTOB(1)));
- 
- 	/* move grant heads by roundoff in sync */
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	xlog_grant_add_space(log, roundoff);
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 
- 	/* put cycle number in every block */
- 	xlog_pack_data(log, iclog, roundoff); 
- 
- 	/* real byte length */
- 	if (v2) {
--		INT_SET(iclog->ic_header.h_len, 
--			ARCH_CONVERT,
--			iclog->ic_offset + roundoff);
-+		iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset + roundoff);
- 	} else {
--		INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
-+		iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset);
- 	}
- 
--	/* put ops count in correct order */
--	ops = iclog->ic_header.h_num_logops;
--	INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
--
- 	bp = iclog->ic_bp;
- 	ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
- 	XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
--	XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
-+	XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
- 
- 	XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
- 
-@@ -1450,11 +1444,13 @@
- 	} else {
- 		iclog->ic_bwritecnt = 1;
- 	}
-+
- 	XFS_BUF_SET_COUNT(bp, count);
- 	XFS_BUF_SET_FSPRIVATE(bp, iclog);	/* save for later */
- 	XFS_BUF_ZEROFLAGS(bp);
- 	XFS_BUF_BUSY(bp);
- 	XFS_BUF_ASYNC(bp);
-+
- 	/*
- 	 * Do an ordered write for the log block.
- 	 * Its unnecessary to flush the first split block in the log wrap case.
-@@ -1480,6 +1476,7 @@
- 				  XFS_BUF_ADDR(bp));
- 		return error;
- 	}
-+
- 	if (split) {
- 		bp = iclog->ic_log->l_xbuf;
- 		ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
-@@ -1501,10 +1498,10 @@
- 		 * a new cycle.  Watch out for the header magic number
- 		 * case, though.
- 		 */
--		for (i=0; i<split; i += BBSIZE) {
--			INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
--			if (INT_GET(*(uint *)dptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
--				INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
-+		for (i = 0; i < split; i += BBSIZE) {
-+			be32_add_cpu((__be32 *)dptr, 1);
-+			if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM)
-+				be32_add_cpu((__be32 *)dptr, 1);
- 			dptr += BBSIZE;
- 		}
- 
-@@ -1520,6 +1517,7 @@
- 			return error;
- 		}
- 	}
-+
- 	return 0;
- }	/* xlog_sync */
- 
-@@ -1527,7 +1525,7 @@
- /*
-  * Deallocate a log structure
-  */
--void
-+STATIC void
- xlog_dealloc_log(xlog_t *log)
- {
- 	xlog_in_core_t	*iclog, *next_iclog;
-@@ -1592,14 +1590,12 @@
- 		       int		record_cnt,
- 		       int		copy_bytes)
- {
--	SPLDECL(s);
--
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
--	iclog->ic_header.h_num_logops += record_cnt;
-+	be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt);
- 	iclog->ic_offset += copy_bytes;
- 
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- }	/* xlog_state_finish_copy */
- 
- 
-@@ -1752,7 +1748,7 @@
-  *	we don't update ic_offset until the end when we know exactly how many
-  *	bytes have been written out.
-  */
--int
-+STATIC int
- xlog_write(xfs_mount_t *	mp,
- 	   xfs_log_iovec_t	reg[],
- 	   int			nentries,
-@@ -1823,7 +1819,7 @@
- 
- 	/* start_lsn is the first lsn written to. That's all we need. */
- 	if (! *start_lsn)
--	    *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-+	    *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
- 
- 	/* This loop writes out as many regions as can fit in the amount
- 	 * of space which was allocated by xlog_state_get_iclog_space().
-@@ -1839,7 +1835,7 @@
- 	     */
- 	    if (ticket->t_flags & XLOG_TIC_INITED) {
- 		logop_head		= (xlog_op_header_t *)ptr;
--		INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
-+		logop_head->oh_tid	= cpu_to_be32(ticket->t_tid);
- 		logop_head->oh_clientid = ticket->t_clientid;
- 		logop_head->oh_len	= 0;
- 		logop_head->oh_flags    = XLOG_START_TRANS;
-@@ -1853,7 +1849,7 @@
- 
- 	    /* Copy log operation header directly into data section */
- 	    logop_head			= (xlog_op_header_t *)ptr;
--	    INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
-+	    logop_head->oh_tid		= cpu_to_be32(ticket->t_tid);
- 	    logop_head->oh_clientid	= ticket->t_clientid;
- 	    logop_head->oh_res2		= 0;
- 
-@@ -1888,13 +1884,14 @@
- 
- 	    copy_off = partial_copy_len;
- 	    if (need_copy <= iclog->ic_size - log_offset) { /*complete write */
--		INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy);
-+		copy_len = need_copy;
-+		logop_head->oh_len = cpu_to_be32(copy_len);
- 		if (partial_copy)
- 		    logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
- 		partial_copy_len = partial_copy = 0;
- 	    } else {					    /* partial write */
- 		copy_len = iclog->ic_size - log_offset;
--		INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len);
-+		logop_head->oh_len = cpu_to_be32(copy_len);
- 		logop_head->oh_flags |= XLOG_CONTINUE_TRANS;
- 		if (partial_copy)
- 			logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;
-@@ -1992,7 +1989,8 @@
- 			 * We don't need to cover the dummy.
- 			 */
- 			if (!changed &&
--			   (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) {
-+			   (be32_to_cpu(iclog->ic_header.h_num_logops) ==
-+			   		XLOG_COVER_OPS)) {
- 				changed = 1;
- 			} else {
- 				/*
-@@ -2060,7 +2058,7 @@
- 	lowest_lsn = 0;
- 	do {
- 	    if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) {
--		lsn = INT_GET(lsn_log->ic_header.h_lsn, ARCH_CONVERT);
-+		lsn = be64_to_cpu(lsn_log->ic_header.h_lsn);
- 		if ((lsn && !lowest_lsn) ||
- 		    (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) {
- 			lowest_lsn = lsn;
-@@ -2089,9 +2087,8 @@
- 	int		   funcdidcallbacks; /* flag: function did callbacks */
- 	int		   repeats;	/* for issuing console warnings if
- 					 * looping too many times */
--	SPLDECL(s);
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	first_iclog = iclog = log->l_iclog;
- 	ioerrors = 0;
- 	funcdidcallbacks = 0;
-@@ -2162,11 +2159,9 @@
- 				 */
- 
- 				lowest_lsn = xlog_get_lowest_lsn(log);
--				if (lowest_lsn && (
--					XFS_LSN_CMP(
--						lowest_lsn,
--						INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
--					)<0)) {
-+				if (lowest_lsn && 
-+				    XFS_LSN_CMP(lowest_lsn,
-+				    		be64_to_cpu(iclog->ic_header.h_lsn)) < 0) {
- 					iclog = iclog->ic_next;
- 					continue; /* Leave this iclog for
- 						   * another thread */
-@@ -2174,19 +2169,18 @@
- 
- 				iclog->ic_state = XLOG_STATE_CALLBACK;
- 
--				LOG_UNLOCK(log, s);
-+				spin_unlock(&log->l_icloglock);
- 
- 				/* l_last_sync_lsn field protected by
- 				 * GRANT_LOCK. Don't worry about iclog's lsn.
- 				 * No one else can be here except us.
- 				 */
--				s = GRANT_LOCK(log);
--				ASSERT(XFS_LSN_CMP(
--						log->l_last_sync_lsn,
--						INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
--					)<=0);
--				log->l_last_sync_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
--				GRANT_UNLOCK(log, s);
-+				spin_lock(&log->l_grant_lock);
-+				ASSERT(XFS_LSN_CMP(log->l_last_sync_lsn,
-+				       be64_to_cpu(iclog->ic_header.h_lsn)) <= 0);
-+				log->l_last_sync_lsn =
-+					be64_to_cpu(iclog->ic_header.h_lsn);
-+				spin_unlock(&log->l_grant_lock);
- 
- 				/*
- 				 * Keep processing entries in the callback list
-@@ -2195,7 +2189,7 @@
- 				 * empty and change the state to DIRTY so that
- 				 * we don't miss any more callbacks being added.
- 				 */
--				s = LOG_LOCK(log);
-+				spin_lock(&log->l_icloglock);
- 			} else {
- 				ioerrors++;
- 			}
-@@ -2204,14 +2198,14 @@
- 			while (cb) {
- 				iclog->ic_callback_tail = &(iclog->ic_callback);
- 				iclog->ic_callback = NULL;
--				LOG_UNLOCK(log, s);
-+				spin_unlock(&log->l_icloglock);
- 
- 				/* perform callbacks in the order given */
- 				for (; cb; cb = cb_next) {
- 					cb_next = cb->cb_next;
- 					cb->cb_func(cb->cb_arg, aborted);
- 				}
--				s = LOG_LOCK(log);
-+				spin_lock(&log->l_icloglock);
- 				cb = iclog->ic_callback;
- 			}
- 
-@@ -2276,7 +2270,7 @@
- 		flushcnt = log->l_flushcnt;
- 		log->l_flushcnt = 0;
- 	}
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 	while (flushcnt--)
- 		vsema(&log->l_flushsema);
- }	/* xlog_state_do_callback */
-@@ -2296,15 +2290,14 @@
-  * global state machine log lock.  Assume that the calls to cvsema won't
-  * take a long time.  At least we know it won't sleep.
-  */
--void
-+STATIC void
- xlog_state_done_syncing(
- 	xlog_in_core_t	*iclog,
- 	int		aborted)
- {
- 	xlog_t		   *log = iclog->ic_log;
--	SPLDECL(s);
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
- 	ASSERT(iclog->ic_state == XLOG_STATE_SYNCING ||
- 	       iclog->ic_state == XLOG_STATE_IOERROR);
-@@ -2320,7 +2313,7 @@
- 	 */
- 	if (iclog->ic_state != XLOG_STATE_IOERROR) {
- 		if (--iclog->ic_bwritecnt == 1) {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 			return;
- 		}
- 		iclog->ic_state = XLOG_STATE_DONE_SYNC;
-@@ -2332,7 +2325,7 @@
- 	 * I/O, the others get to wait for the result.
- 	 */
- 	sv_broadcast(&iclog->ic_writesema);
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 	xlog_state_do_callback(log, aborted, iclog);	/* also cleans log */
- }	/* xlog_state_done_syncing */
- 
-@@ -2357,7 +2350,7 @@
-  *		needs to be incremented, depending on the amount of data which
-  *		is copied.
-  */
--int
-+STATIC int
- xlog_state_get_iclog_space(xlog_t	  *log,
- 			   int		  len,
- 			   xlog_in_core_t **iclogp,
-@@ -2365,23 +2358,22 @@
- 			   int		  *continued_write,
- 			   int		  *logoffsetp)
- {
--	SPLDECL(s);
- 	int		  log_offset;
- 	xlog_rec_header_t *head;
- 	xlog_in_core_t	  *iclog;
- 	int		  error;
- 
- restart:
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	if (XLOG_FORCED_SHUTDOWN(log)) {
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		return XFS_ERROR(EIO);
- 	}
- 
- 	iclog = log->l_iclog;
- 	if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) {
- 		log->l_flushcnt++;
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
- 		XFS_STATS_INC(xs_log_noiclogs);
- 		/* Ensure that log writes happen */
-@@ -2404,8 +2396,9 @@
- 		xlog_tic_add_region(ticket,
- 				    log->l_iclog_hsize,
- 				    XLOG_REG_TYPE_LRHEADER);
--		INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
--		ASSIGN_LSN(head->h_lsn, log);
-+		head->h_cycle = cpu_to_be32(log->l_curr_cycle);
-+		head->h_lsn = cpu_to_be64(
-+			xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block));
- 		ASSERT(log->l_curr_block >= 0);
- 	}
- 
-@@ -2423,12 +2416,12 @@
- 
- 		/* If I'm the only one writing to this iclog, sync it to disk */
- 		if (iclog->ic_refcnt == 1) {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 			if ((error = xlog_state_release_iclog(log, iclog)))
- 				return error;
- 		} else {
- 			iclog->ic_refcnt--;
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 		}
- 		goto restart;
- 	}
-@@ -2449,7 +2442,7 @@
- 	*iclogp = iclog;
- 
- 	ASSERT(iclog->ic_offset <= iclog->ic_size);
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 
- 	*logoffsetp = log_offset;
- 	return 0;
-@@ -2467,7 +2460,6 @@
- {
- 	int		 free_bytes;
- 	int		 need_bytes;
--	SPLDECL(s);
- #ifdef DEBUG
- 	xfs_lsn_t	 tail_lsn;
- #endif
-@@ -2479,7 +2471,7 @@
- #endif
- 
- 	/* Is there space or do we need to sleep? */
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter");
- 
- 	/* something is already sleeping; insert new transaction at end */
-@@ -2502,7 +2494,7 @@
- 		 */
- 		xlog_trace_loggrant(log, tic,
- 				    "xlog_grant_log_space: wake 1");
--		s = GRANT_LOCK(log);
-+		spin_lock(&log->l_grant_lock);
- 	}
- 	if (tic->t_flags & XFS_LOG_PERM_RESERV)
- 		need_bytes = tic->t_unit_res*tic->t_ocnt;
-@@ -2524,14 +2516,14 @@
- 		sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
- 
- 		if (XLOG_FORCED_SHUTDOWN(log)) {
--			s = GRANT_LOCK(log);
-+			spin_lock(&log->l_grant_lock);
- 			goto error_return;
- 		}
- 
- 		xlog_trace_loggrant(log, tic,
- 				    "xlog_grant_log_space: wake 2");
- 		xlog_grant_push_ail(log->l_mp, need_bytes);
--		s = GRANT_LOCK(log);
-+		spin_lock(&log->l_grant_lock);
- 		goto redo;
- 	} else if (tic->t_flags & XLOG_TIC_IN_Q)
- 		xlog_del_ticketq(&log->l_reserve_headq, tic);
-@@ -2553,7 +2545,7 @@
- #endif
- 	xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit");
- 	xlog_verify_grant_head(log, 1);
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	return 0;
- 
-  error_return:
-@@ -2567,7 +2559,7 @@
- 	 */
- 	tic->t_curr_res = 0;
- 	tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	return XFS_ERROR(EIO);
- }	/* xlog_grant_log_space */
- 
-@@ -2581,7 +2573,6 @@
- xlog_regrant_write_log_space(xlog_t	   *log,
- 			     xlog_ticket_t *tic)
- {
--	SPLDECL(s);
- 	int		free_bytes, need_bytes;
- 	xlog_ticket_t	*ntic;
- #ifdef DEBUG
-@@ -2599,7 +2590,7 @@
- 		panic("regrant Recovery problem");
- #endif
- 
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter");
- 
- 	if (XLOG_FORCED_SHUTDOWN(log))
-@@ -2638,14 +2629,14 @@
- 			/* If we're shutting down, this tic is already
- 			 * off the queue */
- 			if (XLOG_FORCED_SHUTDOWN(log)) {
--				s = GRANT_LOCK(log);
-+				spin_lock(&log->l_grant_lock);
- 				goto error_return;
- 			}
- 
- 			xlog_trace_loggrant(log, tic,
- 				    "xlog_regrant_write_log_space: wake 1");
- 			xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
--			s = GRANT_LOCK(log);
-+			spin_lock(&log->l_grant_lock);
- 		}
- 	}
- 
-@@ -2665,14 +2656,14 @@
- 
- 		/* If we're shutting down, this tic is already off the queue */
- 		if (XLOG_FORCED_SHUTDOWN(log)) {
--			s = GRANT_LOCK(log);
-+			spin_lock(&log->l_grant_lock);
- 			goto error_return;
- 		}
- 
- 		xlog_trace_loggrant(log, tic,
- 				    "xlog_regrant_write_log_space: wake 2");
- 		xlog_grant_push_ail(log->l_mp, need_bytes);
--		s = GRANT_LOCK(log);
-+		spin_lock(&log->l_grant_lock);
- 		goto redo;
- 	} else if (tic->t_flags & XLOG_TIC_IN_Q)
- 		xlog_del_ticketq(&log->l_write_headq, tic);
-@@ -2689,7 +2680,7 @@
- 
- 	xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit");
- 	xlog_verify_grant_head(log, 1);
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	return 0;
- 
- 
-@@ -2704,7 +2695,7 @@
- 	 */
- 	tic->t_curr_res = 0;
- 	tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	return XFS_ERROR(EIO);
- }	/* xlog_regrant_write_log_space */
- 
-@@ -2720,14 +2711,12 @@
- xlog_regrant_reserve_log_space(xlog_t	     *log,
- 			       xlog_ticket_t *ticket)
- {
--	SPLDECL(s);
--
- 	xlog_trace_loggrant(log, ticket,
- 			    "xlog_regrant_reserve_log_space: enter");
- 	if (ticket->t_cnt > 0)
- 		ticket->t_cnt--;
- 
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	xlog_grant_sub_space(log, ticket->t_curr_res);
- 	ticket->t_curr_res = ticket->t_unit_res;
- 	xlog_tic_reset_res(ticket);
-@@ -2737,7 +2726,7 @@
- 
- 	/* just return if we still have some of the pre-reserved space */
- 	if (ticket->t_cnt > 0) {
--		GRANT_UNLOCK(log, s);
-+		spin_unlock(&log->l_grant_lock);
- 		return;
- 	}
- 
-@@ -2745,7 +2734,7 @@
- 	xlog_trace_loggrant(log, ticket,
- 			    "xlog_regrant_reserve_log_space: exit");
- 	xlog_verify_grant_head(log, 0);
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	ticket->t_curr_res = ticket->t_unit_res;
- 	xlog_tic_reset_res(ticket);
- }	/* xlog_regrant_reserve_log_space */
-@@ -2769,12 +2758,10 @@
- xlog_ungrant_log_space(xlog_t	     *log,
- 		       xlog_ticket_t *ticket)
- {
--	SPLDECL(s);
--
- 	if (ticket->t_cnt > 0)
- 		ticket->t_cnt--;
- 
--	s = GRANT_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
- 	xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
- 
- 	xlog_grant_sub_space(log, ticket->t_curr_res);
-@@ -2791,7 +2778,7 @@
- 
- 	xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
- 	xlog_verify_grant_head(log, 1);
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 	xfs_log_move_tail(log->l_mp, 1);
- }	/* xlog_ungrant_log_space */
- 
-@@ -2799,15 +2786,13 @@
- /*
-  * Atomically put back used ticket.
-  */
--void
-+STATIC void
- xlog_state_put_ticket(xlog_t	    *log,
- 		      xlog_ticket_t *tic)
- {
--	unsigned long s;
--
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	xlog_ticket_put(log, tic);
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- }	/* xlog_state_put_ticket */
- 
- /*
-@@ -2819,19 +2804,18 @@
-  *
-  *
-  */
--int
-+STATIC int
- xlog_state_release_iclog(xlog_t		*log,
- 			 xlog_in_core_t	*iclog)
- {
--	SPLDECL(s);
- 	int		sync = 0;	/* do we sync? */
- 
- 	xlog_assign_tail_lsn(log->l_mp);
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
- 	if (iclog->ic_state & XLOG_STATE_IOERROR) {
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		return XFS_ERROR(EIO);
- 	}
- 
-@@ -2843,12 +2827,12 @@
- 	    iclog->ic_state == XLOG_STATE_WANT_SYNC) {
- 		sync++;
- 		iclog->ic_state = XLOG_STATE_SYNCING;
--		INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, log->l_tail_lsn);
-+		iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn);
- 		xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn);
- 		/* cycle incremented when incrementing curr_block */
- 	}
- 
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 
- 	/*
- 	 * We let the log lock go, so it's possible that we hit a log I/O
-@@ -2860,6 +2844,7 @@
- 	if (sync) {
- 		return xlog_sync(log, iclog);
- 	}
-+
- 	return 0;
- 
- }	/* xlog_state_release_iclog */
-@@ -2881,7 +2866,7 @@
- 	if (!eventual_size)
- 		eventual_size = iclog->ic_offset;
- 	iclog->ic_state = XLOG_STATE_WANT_SYNC;
--	INT_SET(iclog->ic_header.h_prev_block, ARCH_CONVERT, log->l_prev_block);
-+	iclog->ic_header.h_prev_block = cpu_to_be32(log->l_prev_block);
- 	log->l_prev_block = log->l_curr_block;
- 	log->l_prev_cycle = log->l_curr_cycle;
- 
-@@ -2939,13 +2924,12 @@
- {
- 	xlog_in_core_t	*iclog;
- 	xfs_lsn_t	lsn;
--	SPLDECL(s);
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
- 	iclog = log->l_iclog;
- 	if (iclog->ic_state & XLOG_STATE_IOERROR) {
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		return XFS_ERROR(EIO);
- 	}
- 
-@@ -2978,15 +2962,15 @@
- 				 * the previous sync.
- 				 */
- 				iclog->ic_refcnt++;
--				lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-+				lsn = be64_to_cpu(iclog->ic_header.h_lsn);
- 				xlog_state_switch_iclogs(log, iclog, 0);
--				LOG_UNLOCK(log, s);
-+				spin_unlock(&log->l_icloglock);
- 
- 				if (xlog_state_release_iclog(log, iclog))
- 					return XFS_ERROR(EIO);
- 				*log_flushed = 1;
--				s = LOG_LOCK(log);
--				if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
-+				spin_lock(&log->l_icloglock);
-+				if (be64_to_cpu(iclog->ic_header.h_lsn) == lsn &&
- 				    iclog->ic_state != XLOG_STATE_DIRTY)
- 					goto maybe_sleep;
- 				else
-@@ -3016,7 +3000,7 @@
- 		 * sleep was disturbed by a bad news.
- 		 */
- 		if (iclog->ic_state & XLOG_STATE_IOERROR) {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 			return XFS_ERROR(EIO);
- 		}
- 		XFS_STATS_INC(xs_log_force_sleep);
-@@ -3033,7 +3017,7 @@
- 	} else {
- 
- no_sleep:
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 	}
- 	return 0;
- }	/* xlog_state_sync_all */
-@@ -3051,7 +3035,7 @@
-  * If filesystem activity goes to zero, the iclog will get flushed only by
-  * bdflush().
-  */
--int
-+STATIC int
- xlog_state_sync(xlog_t	  *log,
- 		xfs_lsn_t lsn,
- 		uint	  flags,
-@@ -3059,26 +3043,24 @@
- {
-     xlog_in_core_t	*iclog;
-     int			already_slept = 0;
--    SPLDECL(s);
--
- 
- try_again:
--    s = LOG_LOCK(log);
-+    spin_lock(&log->l_icloglock);
-     iclog = log->l_iclog;
- 
-     if (iclog->ic_state & XLOG_STATE_IOERROR) {
--	    LOG_UNLOCK(log, s);
-+	    spin_unlock(&log->l_icloglock);
- 	    return XFS_ERROR(EIO);
-     }
- 
-     do {
--	if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
--	    iclog = iclog->ic_next;
--	    continue;
-+	if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) {
-+	    	iclog = iclog->ic_next;
-+	    	continue;
- 	}
- 
- 	if (iclog->ic_state == XLOG_STATE_DIRTY) {
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		return 0;
- 	}
- 
-@@ -3113,11 +3095,11 @@
- 		} else {
- 			iclog->ic_refcnt++;
- 			xlog_state_switch_iclogs(log, iclog, 0);
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 			if (xlog_state_release_iclog(log, iclog))
- 				return XFS_ERROR(EIO);
- 			*log_flushed = 1;
--			s = LOG_LOCK(log);
-+			spin_lock(&log->l_icloglock);
- 		}
- 	}
- 
-@@ -3129,7 +3111,7 @@
- 		 * gotten a log write error.
- 		 */
- 		if (iclog->ic_state & XLOG_STATE_IOERROR) {
--			LOG_UNLOCK(log, s);
-+			spin_unlock(&log->l_icloglock);
- 			return XFS_ERROR(EIO);
- 		}
- 		XFS_STATS_INC(xs_log_force_sleep);
-@@ -3143,13 +3125,13 @@
- 			return XFS_ERROR(EIO);
- 		*log_flushed = 1;
- 	} else {		/* just return */
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 	}
- 	return 0;
- 
-     } while (iclog != log->l_iclog);
- 
--    LOG_UNLOCK(log, s);
-+    spin_unlock(&log->l_icloglock);
-     return 0;
- }	/* xlog_state_sync */
- 
-@@ -3158,12 +3140,10 @@
-  * Called when we want to mark the current iclog as being ready to sync to
-  * disk.
-  */
--void
-+STATIC void
- xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
- {
--	SPLDECL(s);
--
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
- 	if (iclog->ic_state == XLOG_STATE_ACTIVE) {
- 		xlog_state_switch_iclogs(log, iclog, 0);
-@@ -3172,7 +3152,7 @@
- 			(XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
- 	}
- 
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- }	/* xlog_state_want_sync */
- 
- 
-@@ -3194,7 +3174,6 @@
- 	xlog_ticket_t	*next;
- 	xfs_caddr_t	buf;
- 	uint		i = (NBPP / sizeof(xlog_ticket_t)) - 2;
--	SPLDECL(s);
- 
- 	/*
- 	 * The kmem_zalloc may sleep, so we shouldn't be holding the
-@@ -3202,7 +3181,7 @@
- 	 */
- 	buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 
- 	/* Attach 1st ticket to Q, so we can keep track of allocated memory */
- 	t_list = (xlog_ticket_t *)buf;
-@@ -3231,7 +3210,7 @@
- 	}
- 	t_list->t_next = NULL;
- 	log->l_tail = t_list;
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- }	/* xlog_state_ticket_alloc */
- 
- 
-@@ -3273,7 +3252,7 @@
- /*
-  * Grab ticket off freelist or allocation some more
-  */
--xlog_ticket_t *
-+STATIC xlog_ticket_t *
- xlog_ticket_get(xlog_t		*log,
- 		int		unit_bytes,
- 		int		cnt,
-@@ -3282,15 +3261,14 @@
- {
- 	xlog_ticket_t	*tic;
- 	uint		num_headers;
--	SPLDECL(s);
- 
-  alloc:
- 	if (log->l_freelist == NULL)
- 		xlog_state_ticket_alloc(log);		/* potentially sleep */
- 
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	if (log->l_freelist == NULL) {
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 		goto alloc;
- 	}
- 	tic		= log->l_freelist;
-@@ -3298,7 +3276,7 @@
- 	if (log->l_freelist == NULL)
- 		log->l_tail = NULL;
- 	log->l_ticket_cnt--;
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 
- 	/*
- 	 * Permanent reservations have up to 'cnt'-1 active log operations
-@@ -3476,7 +3454,7 @@
- 	SPLDECL(s);
- 
- 	/* check validity of iclog pointers */
--	s = LOG_LOCK(log);
-+	spin_lock(&log->l_icloglock);
- 	icptr = log->l_iclog;
- 	for (i=0; i < log->l_iclog_bufs; i++) {
- 		if (icptr == NULL)
-@@ -3485,21 +3463,21 @@
- 	}
- 	if (icptr != log->l_iclog)
- 		xlog_panic("xlog_verify_iclog: corrupt iclog ring");
--	LOG_UNLOCK(log, s);
-+	spin_unlock(&log->l_icloglock);
- 
- 	/* check log magic numbers */
--	ptr = (xfs_caddr_t) &(iclog->ic_header);
--	if (INT_GET(*(uint *)ptr, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM)
-+	if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM)
- 		xlog_panic("xlog_verify_iclog: invalid magic num");
- 
-+	ptr = (xfs_caddr_t) &(iclog->ic_header);
- 	for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&(iclog->ic_header))+count;
- 	     ptr += BBSIZE) {
--		if (INT_GET(*(uint *)ptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
-+		if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
- 			xlog_panic("xlog_verify_iclog: unexpected magic num");
- 	}
- 
- 	/* check fields */
--	len = INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT);
-+	len = be32_to_cpu(iclog->ic_header.h_num_logops);
- 	ptr = iclog->ic_datap;
- 	base_ptr = ptr;
- 	ophead = (xlog_op_header_t *)ptr;
-@@ -3517,9 +3495,11 @@
- 			if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- 				j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- 				k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
--				clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
-+				clientid = xlog_get_client_id(
-+					xhdr[j].hic_xheader.xh_cycle_data[k]);
- 			} else {
--				clientid = GET_CLIENT_ID(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
-+				clientid = xlog_get_client_id(
-+					iclog->ic_header.h_cycle_data[idx]);
- 			}
- 		}
- 		if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
-@@ -3531,16 +3511,16 @@
- 		field_offset = (__psint_t)
- 			       ((xfs_caddr_t)&(ophead->oh_len) - base_ptr);
- 		if (syncing == B_FALSE || (field_offset & 0x1ff)) {
--			op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
-+			op_len = be32_to_cpu(ophead->oh_len);
- 		} else {
- 			idx = BTOBBT((__psint_t)&ophead->oh_len -
- 				    (__psint_t)iclog->ic_datap);
- 			if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- 				j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- 				k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
--				op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
-+				op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]);
- 			} else {
--				op_len = INT_GET(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
-+				op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]);
- 			}
- 		}
- 		ptr += sizeof(xlog_op_header_t) + op_len;
-@@ -3597,8 +3577,6 @@
- 	xlog_t		*log;
- 	int		retval;
- 	int		dummy;
--	SPLDECL(s);
--	SPLDECL(s2);
- 
- 	log = mp->m_log;
- 
-@@ -3627,8 +3605,8 @@
- 	 * before we mark the filesystem SHUTDOWN and wake
- 	 * everybody up to tell the bad news.
- 	 */
--	s = GRANT_LOCK(log);
--	s2 = LOG_LOCK(log);
-+	spin_lock(&log->l_grant_lock);
-+	spin_lock(&log->l_icloglock);
- 	mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
- 	XFS_BUF_DONE(mp->m_sb_bp);
- 	/*
-@@ -3644,7 +3622,7 @@
- 	 */
- 	if (logerror)
- 		retval = xlog_state_ioerror(log);
--	LOG_UNLOCK(log, s2);
-+	spin_unlock(&log->l_icloglock);
- 
- 	/*
- 	 * We don't want anybody waiting for log reservations
-@@ -3667,7 +3645,7 @@
- 			tic = tic->t_next;
- 		} while (tic != log->l_write_headq);
- 	}
--	GRANT_UNLOCK(log, s);
-+	spin_unlock(&log->l_grant_lock);
- 
- 	if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
- 		ASSERT(!logerror);
-@@ -3676,9 +3654,9 @@
- 		 * log down completely.
- 		 */
- 		xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
--		s2 = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		retval = xlog_state_ioerror(log);
--		LOG_UNLOCK(log, s2);
-+		spin_unlock(&log->l_icloglock);
- 	}
- 	/*
- 	 * Wake up everybody waiting on xfs_log_force.
-@@ -3691,13 +3669,13 @@
- 	{
- 		xlog_in_core_t	*iclog;
- 
--		s = LOG_LOCK(log);
-+		spin_lock(&log->l_icloglock);
- 		iclog = log->l_iclog;
- 		do {
- 			ASSERT(iclog->ic_callback == 0);
- 			iclog = iclog->ic_next;
- 		} while (iclog != log->l_iclog);
--		LOG_UNLOCK(log, s);
-+		spin_unlock(&log->l_icloglock);
- 	}
- #endif
- 	/* return non-zero if log IOERROR transition had already happened */
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log.h linux-2.6.24-oxe810/fs/xfs/xfs_log.h
---- linux-2.6.24/fs/xfs/xfs_log.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log.h	2008-06-11 17:46:48.000000000 +0200
-@@ -23,7 +23,7 @@
- #define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
- #define BLOCK_LSN(lsn) ((uint)(lsn))
- /* this is used in a spot where we might otherwise double-endian-flip */
--#define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0])
-+#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
- 
- #ifdef __KERNEL__
- /*
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log_priv.h linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h
---- linux-2.6.24/fs/xfs/xfs_log_priv.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h	2008-06-11 17:46:48.000000000 +0200
-@@ -55,29 +55,19 @@
- 	BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
- 	 XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
- 
--/*
-- *  set lsns
-- */
--
--#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block)  \
--    { \
--	(lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \
--    }
--#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block)  \
--    { \
--	INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
--	INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
--    }
--#define ASSIGN_LSN(lsn,log) \
--    ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block);
- 
--#define XLOG_SET(f,b)		(((f) & (b)) == (b))
-+static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
-+{
-+	return ((xfs_lsn_t)cycle << 32) | block;
-+}
- 
--#define GET_CYCLE(ptr, arch) \
--    (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \
--	 INT_GET(*((uint *)(ptr)+1), arch) : \
--	 INT_GET(*(uint *)(ptr), arch) \
--    )
-+static inline uint xlog_get_cycle(char *ptr)
-+{
-+	if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
-+		return be32_to_cpu(*((__be32 *)ptr + 1));
-+	else
-+		return be32_to_cpu(*(__be32 *)ptr);
-+}
- 
- #define BLK_AVG(blk1, blk2)	((blk1+blk2) >> 1)
- 
-@@ -97,18 +87,15 @@
-  * this has endian issues, of course.
-  */
- 
--#ifndef XFS_NATIVE_HOST
--#define GET_CLIENT_ID(i,arch) \
--    ((i) & 0xff)
--#else
--#define GET_CLIENT_ID(i,arch) \
--    ((i) >> 24)
--#endif
-+static inline uint xlog_get_client_id(__be32 i)
-+{
-+	return be32_to_cpu(i) >> 24;
-+}
- 
--#define GRANT_LOCK(log)		mutex_spinlock(&(log)->l_grant_lock)
--#define GRANT_UNLOCK(log, s)	mutex_spinunlock(&(log)->l_grant_lock, s)
--#define LOG_LOCK(log)		mutex_spinlock(&(log)->l_icloglock)
--#define LOG_UNLOCK(log, s)	mutex_spinunlock(&(log)->l_icloglock, s)
-+//#define GRANT_LOCK(log)		mutex_spinlock(&(log)->l_grant_lock)
-+//#define GRANT_UNLOCK(log, s)	mutex_spinunlock(&(log)->l_grant_lock, s)
-+//#define LOG_LOCK(log)		mutex_spinlock(&(log)->l_icloglock)
-+//#define LOG_UNLOCK(log, s)	mutex_spinunlock(&(log)->l_icloglock, s)
- 
- #define xlog_panic(args...)	cmn_err(CE_PANIC, ## args)
- #define xlog_exit(args...)	cmn_err(CE_PANIC, ## args)
-@@ -285,11 +272,11 @@
- 
- 
- typedef struct xlog_op_header {
--	xlog_tid_t oh_tid;	/* transaction id of operation	:  4 b */
--	int	   oh_len;	/* bytes in data region		:  4 b */
--	__uint8_t  oh_clientid;	/* who sent me this		:  1 b */
--	__uint8_t  oh_flags;	/*				:  1 b */
--	ushort	   oh_res2;	/* 32 bit align			:  2 b */
-+	__be32	   oh_tid;	/* transaction id of operation	:  4 b */
-+	__be32	   oh_len;	/* bytes in data region		:  4 b */
-+	__u8	   oh_clientid;	/* who sent me this		:  1 b */
-+	__u8	   oh_flags;	/*				:  1 b */
-+	__u16	   oh_res2;	/* 32 bit align			:  2 b */
- } xlog_op_header_t;
- 
- 
-@@ -307,25 +294,25 @@
- #endif
- 
- typedef struct xlog_rec_header {
--	uint	  h_magicno;	/* log record (LR) identifier		:  4 */
--	uint	  h_cycle;	/* write cycle of log			:  4 */
--	int	  h_version;	/* LR version				:  4 */
--	int	  h_len;	/* len in bytes; should be 64-bit aligned: 4 */
--	xfs_lsn_t h_lsn;	/* lsn of this LR			:  8 */
--	xfs_lsn_t h_tail_lsn;	/* lsn of 1st LR w/ buffers not committed: 8 */
--	uint	  h_chksum;	/* may not be used; non-zero if used	:  4 */
--	int	  h_prev_block; /* block number to previous LR		:  4 */
--	int	  h_num_logops;	/* number of log operations in this LR	:  4 */
--	uint	  h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
-+	__be32	  h_magicno;	/* log record (LR) identifier		:  4 */
-+	__be32	  h_cycle;	/* write cycle of log			:  4 */
-+	__be32	  h_version;	/* LR version				:  4 */
-+	__be32	  h_len;	/* len in bytes; should be 64-bit aligned: 4 */
-+	__be64	  h_lsn;	/* lsn of this LR			:  8 */
-+	__be64	  h_tail_lsn;	/* lsn of 1st LR w/ buffers not committed: 8 */
-+	__be32	  h_chksum;	/* may not be used; non-zero if used	:  4 */
-+	__be32	  h_prev_block; /* block number to previous LR		:  4 */
-+	__be32	  h_num_logops;	/* number of log operations in this LR	:  4 */
-+	__be32	  h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
- 	/* new fields */
--	int       h_fmt;        /* format of log record                 :  4 */
--	uuid_t    h_fs_uuid;    /* uuid of FS                           : 16 */
--	int       h_size;	/* iclog size				:  4 */
-+	__be32    h_fmt;        /* format of log record                 :  4 */
-+	uuid_t	  h_fs_uuid;    /* uuid of FS                           : 16 */
-+	__be32	  h_size;	/* iclog size				:  4 */
- } xlog_rec_header_t;
- 
- typedef struct xlog_rec_ext_header {
--	uint	  xh_cycle;	/* write cycle of log			: 4 */
--	uint	  xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /*	: 256 */
-+	__be32	  xh_cycle;	/* write cycle of log			: 4 */
-+	__be32	  xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /*	: 256 */
- } xlog_rec_ext_header_t;
- 
- #ifdef __KERNEL__
-@@ -464,12 +451,12 @@
- 
- #define XLOG_FORCED_SHUTDOWN(log)	((log)->l_flags & XLOG_IO_ERROR)
- 
--
- /* common routines */
- extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
- extern int	 xlog_find_tail(xlog_t	*log,
- 				xfs_daddr_t *head_blk,
- 				xfs_daddr_t *tail_blk);
-+				
- extern int	 xlog_recover(xlog_t *log);
- extern int	 xlog_recover_finish(xlog_t *log, int mfsi_flags);
- extern void	 xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log_recover.c linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c
---- linux-2.6.24/fs/xfs/xfs_log_recover.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c	2008-06-11 17:46:48.000000000 +0200
-@@ -198,7 +198,7 @@
- 	cmn_err(CE_DEBUG, "    log : uuid = ");
- 	for (b = 0; b < 16; b++)
- 		cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
--	cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
-+	cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt));
- }
- #else
- #define xlog_header_check_dump(mp, head)
-@@ -212,14 +212,14 @@
- 	xfs_mount_t		*mp,
- 	xlog_rec_header_t	*head)
- {
--	ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-+	ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
- 
- 	/*
- 	 * IRIX doesn't write the h_fmt field and leaves it zeroed
- 	 * (XLOG_FMT_UNKNOWN). This stops us from trying to recover
- 	 * a dirty log created in IRIX.
- 	 */
--	if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
-+	if (unlikely(be32_to_cpu(head->h_fmt) != XLOG_FMT)) {
- 		xlog_warn(
- 	"XFS: dirty log written in incompatible format - can't recover");
- 		xlog_header_check_dump(mp, head);
-@@ -245,7 +245,7 @@
- 	xfs_mount_t		*mp,
- 	xlog_rec_header_t	*head)
- {
--	ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-+	ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
- 
- 	if (uuid_is_nil(&head->h_fs_uuid)) {
- 		/*
-@@ -311,7 +311,7 @@
- 		if ((error = xlog_bread(log, mid_blk, 1, bp)))
- 			return error;
- 		offset = xlog_align(log, mid_blk, 1, bp);
--		mid_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+		mid_cycle = xlog_get_cycle(offset);
- 		if (mid_cycle == cycle) {
- 			*last_blk = mid_blk;
- 			/* last_half_cycle == mid_cycle */
-@@ -371,7 +371,7 @@
- 
- 		buf = xlog_align(log, i, bcount, bp);
- 		for (j = 0; j < bcount; j++) {
--			cycle = GET_CYCLE(buf, ARCH_CONVERT);
-+			cycle = xlog_get_cycle(buf);
- 			if (cycle == stop_on_cycle_no) {
- 				*new_blk = i+j;
- 				goto out;
-@@ -447,8 +447,7 @@
- 
- 		head = (xlog_rec_header_t *)offset;
- 
--		if (XLOG_HEADER_MAGIC_NUM ==
--		    INT_GET(head->h_magicno, ARCH_CONVERT))
-+		if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) 
- 			break;
- 
- 		if (!smallmem)
-@@ -480,7 +479,7 @@
- 	 * record do we update last_blk.
- 	 */
- 	if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
--		uint	h_size = INT_GET(head->h_size, ARCH_CONVERT);
-+		uint	h_size = be32_to_cpu(head->h_size);
- 
- 		xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
- 		if (h_size % XLOG_HEADER_CYCLE_SIZE)
-@@ -489,8 +488,8 @@
- 		xhdrs = 1;
- 	}
- 
--	if (*last_blk - i + extra_bblks
--			!= BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs)
-+	if (*last_blk - i + extra_bblks !=
-+	    BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
- 		*last_blk = i;
- 
- out:
-@@ -550,13 +549,13 @@
- 	if ((error = xlog_bread(log, 0, 1, bp)))
- 		goto bp_err;
- 	offset = xlog_align(log, 0, 1, bp);
--	first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+	first_half_cycle = xlog_get_cycle(offset);
- 
- 	last_blk = head_blk = log_bbnum - 1;	/* get cycle # of last block */
- 	if ((error = xlog_bread(log, last_blk, 1, bp)))
- 		goto bp_err;
- 	offset = xlog_align(log, last_blk, 1, bp);
--	last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+	last_half_cycle = xlog_get_cycle(offset);
- 	ASSERT(last_half_cycle != 0);
- 
- 	/*
-@@ -799,21 +798,27 @@
- 	 * Find previous log record
- 	 */
- 	if ((error = xlog_find_head(log, head_blk)))
-+	{
-+		xlog_warn("XFS: xlog_find_tail: couldn't find previous log record \n");
- 		return error;
-+	}
- 
- 	bp = xlog_get_bp(log, 1);
- 	if (!bp)
-+	{
-+		xlog_warn("XFS: xlog_find_tail: ENOMEM \n");
- 		return ENOMEM;
-+	}
- 	if (*head_blk == 0) {				/* special case */
- 		if ((error = xlog_bread(log, 0, 1, bp)))
- 			goto bread_err;
- 		offset = xlog_align(log, 0, 1, bp);
--		if (GET_CYCLE(offset, ARCH_CONVERT) == 0) {
-+		if (xlog_get_cycle(offset) == 0) {
- 			*tail_blk = 0;
- 			/* leave all other log inited values alone */
- 			goto exit;
- 		}
--	}
-+	} 
- 
- 	/*
- 	 * Search backwards looking for log record header block
-@@ -823,8 +828,7 @@
- 		if ((error = xlog_bread(log, i, 1, bp)))
- 			goto bread_err;
- 		offset = xlog_align(log, i, 1, bp);
--		if (XLOG_HEADER_MAGIC_NUM ==
--		    INT_GET(*(uint *)offset, ARCH_CONVERT)) {
-+		if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
- 			found = 1;
- 			break;
- 		}
-@@ -841,7 +845,7 @@
- 				goto bread_err;
- 			offset = xlog_align(log, i, 1, bp);
- 			if (XLOG_HEADER_MAGIC_NUM ==
--			    INT_GET(*(uint*)offset, ARCH_CONVERT)) {
-+			    be32_to_cpu(*(__be32 *)offset)) {
- 				found = 2;
- 				break;
- 			}
-@@ -855,7 +859,7 @@
- 
- 	/* find blk_no of tail of log */
- 	rhead = (xlog_rec_header_t *)offset;
--	*tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT));
-+	*tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
- 
- 	/*
- 	 * Reset log values according to the state of the log when we
-@@ -869,11 +873,11 @@
- 	 */
- 	log->l_prev_block = i;
- 	log->l_curr_block = (int)*head_blk;
--	log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT);
-+	log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
- 	if (found == 2)
- 		log->l_curr_cycle++;
--	log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT);
--	log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT);
-+	log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn);
-+	log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn);
- 	log->l_grant_reserve_cycle = log->l_curr_cycle;
- 	log->l_grant_reserve_bytes = BBTOB(log->l_curr_block);
- 	log->l_grant_write_cycle = log->l_curr_cycle;
-@@ -891,8 +895,8 @@
- 	 * unmount record rather than the block after it.
- 	 */
- 	if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
--		int	h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
--		int	h_version = INT_GET(rhead->h_version, ARCH_CONVERT);
-+		int	h_size = be32_to_cpu(rhead->h_size);
-+		int	h_version = be32_to_cpu(rhead->h_version);
- 
- 		if ((h_version & XLOG_VERSION_2) &&
- 		    (h_size > XLOG_HEADER_CYCLE_SIZE)) {
-@@ -905,11 +909,12 @@
- 	} else {
- 		hblks = 1;
- 	}
-+
- 	after_umount_blk = (i + hblks + (int)
--		BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize;
-+		BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize;
- 	tail_lsn = log->l_tail_lsn;
- 	if (*head_blk == after_umount_blk &&
--	    INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) {
-+	    be32_to_cpu(rhead->h_num_logops) == 1) {
- 		umount_data_blk = (i + hblks) % log->l_logBBsize;
- 		if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
- 			goto bread_err;
-@@ -922,10 +927,12 @@
- 			 * log records will point recovery to after the
- 			 * current unmount record.
- 			 */
--			ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle,
--					after_umount_blk);
--			ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle,
--					after_umount_blk);
-+			log->l_tail_lsn =
-+				xlog_assign_lsn(log->l_curr_cycle,
-+						after_umount_blk);
-+			log->l_last_sync_lsn =
-+				xlog_assign_lsn(log->l_curr_cycle,
-+						after_umount_blk);
- 			*tail_blk = after_umount_blk;
- 
- 			/*
-@@ -986,7 +993,7 @@
-  *	-1 => use *blk_no as the first block of the log
-  *	>0 => error has occurred
-  */
--int
-+STATIC int
- xlog_find_zeroed(
- 	xlog_t		*log,
- 	xfs_daddr_t	*blk_no)
-@@ -1007,7 +1014,7 @@
- 	if ((error = xlog_bread(log, 0, 1, bp)))
- 		goto bp_err;
- 	offset = xlog_align(log, 0, 1, bp);
--	first_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+	first_cycle = xlog_get_cycle(offset);
- 	if (first_cycle == 0) {		/* completely zeroed log */
- 		*blk_no = 0;
- 		xlog_put_bp(bp);
-@@ -1018,7 +1025,7 @@
- 	if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
- 		goto bp_err;
- 	offset = xlog_align(log, log_bbnum-1, 1, bp);
--	last_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+	last_cycle = xlog_get_cycle(offset);
- 	if (last_cycle != 0) {		/* log completely written to */
- 		xlog_put_bp(bp);
- 		return 0;
-@@ -1098,13 +1105,13 @@
- 	xlog_rec_header_t	*recp = (xlog_rec_header_t *)buf;
- 
- 	memset(buf, 0, BBSIZE);
--	INT_SET(recp->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
--	INT_SET(recp->h_cycle, ARCH_CONVERT, cycle);
--	INT_SET(recp->h_version, ARCH_CONVERT,
-+	recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
-+	recp->h_cycle = cpu_to_be32(cycle);
-+	recp->h_version = cpu_to_be32(
- 			XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
--	ASSIGN_ANY_LSN_DISK(recp->h_lsn, cycle, block);
--	ASSIGN_ANY_LSN_DISK(recp->h_tail_lsn, tail_cycle, tail_block);
--	INT_SET(recp->h_fmt, ARCH_CONVERT, XLOG_FMT);
-+	recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
-+	recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
-+	recp->h_fmt = cpu_to_be32(XLOG_FMT);
- 	memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
- }
- 
-@@ -1214,6 +1221,11 @@
- 	head_cycle = log->l_curr_cycle;
- 	head_block = log->l_curr_block;
- 
-+	/* Temp fix - to ensure that the tail cycle and tail blocks both are never 0
-+	 */
-+	if ((tail_cycle == 0) && (tail_block == 0))
-+		tail_cycle = head_cycle;
-+
- 	/*
- 	 * Figure out the distance between the new head of the log
- 	 * and the tail.  We want to write over any blocks beyond the
-@@ -1231,6 +1243,8 @@
- 		if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
- 			XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
- 					 XFS_ERRLEVEL_LOW, log->l_mp);
-+			printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
-+				head_block, tail_block, head_cycle, tail_cycle);
- 			return XFS_ERROR(EFSCORRUPTED);
- 		}
- 		tail_distance = tail_block + (log->l_logBBsize - head_block);
-@@ -1243,6 +1257,8 @@
- 		if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
- 			XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
- 					 XFS_ERRLEVEL_LOW, log->l_mp);
-+			printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
-+				head_block, tail_block, head_cycle, tail_cycle);
- 			return XFS_ERROR(EFSCORRUPTED);
- 		}
- 		tail_distance = tail_block - head_block;
-@@ -2211,7 +2227,7 @@
- 	 * overlap with future reads of those inodes.
- 	 */
- 	if (XFS_DINODE_MAGIC ==
--	    INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) &&
-+	    be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
- 	    (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize,
- 			(__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
- 		XFS_BUF_STALE(bp);
-@@ -2581,8 +2597,7 @@
- 	/*
- 	 * This type of quotas was turned off, so ignore this record.
- 	 */
--	type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
--			(XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
-+	type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
- 	ASSERT(type);
- 	if (log->l_quotaoffs_flag & type)
- 		return (0);
-@@ -2736,21 +2751,13 @@
- 				 * AIL lock.
- 				 */
- 				xfs_trans_delete_ail(mp, lip, s);
--				break;
-+				xfs_efi_item_free(efip);
-+				return;
- 			}
- 		}
- 		lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- 	}
--
--	/*
--	 * If we found it, then free it up.  If it wasn't there, it
--	 * must have been overwritten in the log.  Oh well.
--	 */
--	if (lip != NULL) {
--		xfs_efi_item_free(efip);
--	} else {
--		AIL_UNLOCK(mp, s);
--	}
-+	AIL_UNLOCK(mp, s);
- }
- 
- /*
-@@ -2897,8 +2904,8 @@
- 	unsigned long		hash;
- 	uint			flags;
- 
--	lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT);
--	num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT);
-+	lp = dp + be32_to_cpu(rhead->h_len);
-+	num_logops = be32_to_cpu(rhead->h_num_logops);
- 
- 	/* check the log format matches our own - else we can't recover */
- 	if (xlog_header_check_recover(log->l_mp, rhead))
-@@ -2912,18 +2919,28 @@
- 		    ohead->oh_clientid != XFS_LOG) {
- 			xlog_warn(
- 		"XFS: xlog_recover_process_data: bad clientid");
-+			printk(KERN_INFO "Ticket ID - %d\n", ohead->oh_tid);
-+			printk(KERN_INFO "Bytes in Data Region - %d\n", ohead->oh_len);
-+			printk(KERN_INFO "Client ID - %d\n", ohead->oh_clientid);
-+			printk(KERN_INFO "Flags - %d\n", ohead->oh_flags);
-+			printk(KERN_INFO "Unused - %d\n", ohead->oh_res2);
- 			ASSERT(0);
- 			return (XFS_ERROR(EIO));
- 		}
--		tid = INT_GET(ohead->oh_tid, ARCH_CONVERT);
-+		tid = be32_to_cpu(ohead->oh_tid);
- 		hash = XLOG_RHASH(tid);
- 		trans = xlog_recover_find_tid(rhash[hash], tid);
- 		if (trans == NULL) {		   /* not found; add new tid */
- 			if (ohead->oh_flags & XLOG_START_TRANS)
- 				xlog_recover_new_tid(&rhash[hash], tid,
--					INT_GET(rhead->h_lsn, ARCH_CONVERT));
-+					be64_to_cpu(rhead->h_lsn));
- 		} else {
--			ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp);
-+			if (dp + be32_to_cpu(ohead->oh_len) > lp) {
-+				xlog_warn(
-+			"XFS: xlog_recover_process_data: bad length");
-+				WARN_ON(1);
-+				return (XFS_ERROR(EIO));
-+			}
- 			flags = ohead->oh_flags & ~XLOG_END_TRANS;
- 			if (flags & XLOG_WAS_CONT_TRANS)
- 				flags &= ~XLOG_CONTINUE_TRANS;
-@@ -2937,8 +2954,7 @@
- 				break;
- 			case XLOG_WAS_CONT_TRANS:
- 				error = xlog_recover_add_to_cont_trans(trans,
--						dp, INT_GET(ohead->oh_len,
--							ARCH_CONVERT));
-+						dp, be32_to_cpu(ohead->oh_len));
- 				break;
- 			case XLOG_START_TRANS:
- 				xlog_warn(
-@@ -2949,8 +2965,7 @@
- 			case 0:
- 			case XLOG_CONTINUE_TRANS:
- 				error = xlog_recover_add_to_trans(trans,
--						dp, INT_GET(ohead->oh_len,
--							ARCH_CONVERT));
-+						dp, be32_to_cpu(ohead->oh_len));
- 				break;
- 			default:
- 				xlog_warn(
-@@ -2962,7 +2977,7 @@
- 			if (error)
- 				return error;
- 		}
--		dp += INT_GET(ohead->oh_len, ARCH_CONVERT);
-+		dp += be32_to_cpu(ohead->oh_len);
- 		num_logops--;
- 	}
- 	return 0;
-@@ -3315,16 +3330,16 @@
- 	int		size)
- {
- 	int		i;
--	uint		*up;
-+	__be32		*up;
- 	uint		chksum = 0;
- 
--	up = (uint *)iclog->ic_datap;
-+	up = (__be32 *)iclog->ic_datap;
- 	/* divide length by 4 to get # words */
- 	for (i = 0; i < (size >> 2); i++) {
--		chksum ^= INT_GET(*up, ARCH_CONVERT);
-+		chksum ^= be32_to_cpu(*up);
- 		up++;
- 	}
--	INT_SET(iclog->ic_header.h_chksum, ARCH_CONVERT, chksum);
-+	iclog->ic_header.h_chksum = cpu_to_be32(chksum);
- }
- #else
- #define xlog_pack_data_checksum(log, iclog, size)
-@@ -3341,7 +3356,7 @@
- {
- 	int			i, j, k;
- 	int			size = iclog->ic_offset + roundoff;
--	uint			cycle_lsn;
-+	__be32			cycle_lsn;
- 	xfs_caddr_t		dp;
- 	xlog_in_core_2_t	*xhdr;
- 
-@@ -3352,8 +3367,8 @@
- 	dp = iclog->ic_datap;
- 	for (i = 0; i < BTOBB(size) &&
- 		i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
--		iclog->ic_header.h_cycle_data[i] = *(uint *)dp;
--		*(uint *)dp = cycle_lsn;
-+		iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp;
-+		*(__be32 *)dp = cycle_lsn;
- 		dp += BBSIZE;
- 	}
- 
-@@ -3362,8 +3377,8 @@
- 		for ( ; i < BTOBB(size); i++) {
- 			j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- 			k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
--			xhdr[j].hic_xheader.xh_cycle_data[k] = *(uint *)dp;
--			*(uint *)dp = cycle_lsn;
-+			xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp;
-+			*(__be32 *)dp = cycle_lsn;
- 			dp += BBSIZE;
- 		}
- 
-@@ -3380,21 +3395,21 @@
- 	xfs_caddr_t		dp,
- 	xlog_t			*log)
- {
--	uint			*up = (uint *)dp;
-+	__be32			*up = (__be32 *)dp;
- 	uint			chksum = 0;
- 	int			i;
- 
- 	/* divide length by 4 to get # words */
--	for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
--		chksum ^= INT_GET(*up, ARCH_CONVERT);
-+	for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) {
-+		chksum ^= be32_to_cpu(*up);
- 		up++;
- 	}
--	if (chksum != INT_GET(rhead->h_chksum, ARCH_CONVERT)) {
-+	if (chksum != be32_to_cpu(rhead->h_chksum)) {
- 	    if (rhead->h_chksum ||
- 		((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
- 		    cmn_err(CE_DEBUG,
- 			"XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
--			    INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
-+			    be32_to_cpu(rhead->h_chksum), chksum);
- 		    cmn_err(CE_DEBUG,
- "XFS: Disregard message if filesystem was created with non-DEBUG kernel");
- 		    if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
-@@ -3418,18 +3433,18 @@
- 	int			i, j, k;
- 	xlog_in_core_2_t	*xhdr;
- 
--	for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) &&
-+	for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
- 		  i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
--		*(uint *)dp = *(uint *)&rhead->h_cycle_data[i];
-+		*(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
- 		dp += BBSIZE;
- 	}
- 
- 	if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- 		xhdr = (xlog_in_core_2_t *)rhead;
--		for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) {
-+		for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
- 			j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- 			k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
--			*(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
-+			*(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
- 			dp += BBSIZE;
- 		}
- 	}
-@@ -3445,24 +3460,21 @@
- {
- 	int			hlen;
- 
--	if (unlikely(
--	    (INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
--			XLOG_HEADER_MAGIC_NUM))) {
-+	if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) {
- 		XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
- 				XFS_ERRLEVEL_LOW, log->l_mp);
- 		return XFS_ERROR(EFSCORRUPTED);
- 	}
- 	if (unlikely(
- 	    (!rhead->h_version ||
--	    (INT_GET(rhead->h_version, ARCH_CONVERT) &
--			(~XLOG_VERSION_OKBITS)) != 0))) {
-+	    (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
- 		xlog_warn("XFS: %s: unrecognised log version (%d).",
--			__FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT));
-+			__FUNCTION__, be32_to_cpu(rhead->h_version));
- 		return XFS_ERROR(EIO);
- 	}
- 
- 	/* LR body must have data or it wouldn't have been written */
--	hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
-+	hlen = be32_to_cpu(rhead->h_len);
- 	if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
- 		XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
- 				XFS_ERRLEVEL_LOW, log->l_mp);
-@@ -3522,9 +3534,8 @@
- 		error = xlog_valid_rec_header(log, rhead, tail_blk);
- 		if (error)
- 			goto bread_err1;
--		h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
--		if ((INT_GET(rhead->h_version, ARCH_CONVERT)
--				& XLOG_VERSION_2) &&
-+		h_size = be32_to_cpu(rhead->h_size);
-+		if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
- 		    (h_size > XLOG_HEADER_CYCLE_SIZE)) {
- 			hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
- 			if (h_size % XLOG_HEADER_CYCLE_SIZE)
-@@ -3561,7 +3572,7 @@
- 				goto bread_err2;
- 
- 			/* blocks in data section */
--			bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+			bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- 			error = xlog_bread(log, blk_no + hblks, bblks, dbp);
- 			if (error)
- 				goto bread_err2;
-@@ -3636,7 +3647,7 @@
- 			if (error)
- 				goto bread_err2;
- 
--			bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+			bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- 			blk_no += hblks;
- 
- 			/* Read in data for log record */
-@@ -3707,7 +3718,7 @@
- 			error = xlog_valid_rec_header(log, rhead, blk_no);
- 			if (error)
- 				goto bread_err2;
--			bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+			bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- 			if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
- 				goto bread_err2;
- 			offset = xlog_align(log, blk_no+hblks, bblks, dbp);
-@@ -3878,7 +3889,12 @@
- 
- 	/* find the tail of the log */
- 	if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
-+	{
-+		cmn_err(CE_NOTE, "Log head - 0x%llx Log Tail - 0x%llx \n",\
-+					(unsigned long long)head_blk, \
-+					(unsigned long long)tail_blk);
- 		return error;
-+	}
- 
- 	if (tail_blk != head_blk) {
- 		/* There used to be a comment here:
-diff -Nurd linux-2.6.24/fs/xfs/xfs_trans.c linux-2.6.24-oxe810/fs/xfs/xfs_trans.c
---- linux-2.6.24/fs/xfs/xfs_trans.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_trans.c	2008-06-11 17:46:48.000000000 +0200
-@@ -567,26 +567,26 @@
- 	 */
- 	if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
- 		if (tp->t_icount_delta)
--			be64_add(&sbp->sb_icount, tp->t_icount_delta);
-+			be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
- 		if (tp->t_ifree_delta)
--			be64_add(&sbp->sb_ifree, tp->t_ifree_delta);
-+			be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
- 		if (tp->t_fdblocks_delta)
--			be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
-+			be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
- 		if (tp->t_res_fdblocks_delta)
--			be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
-+			be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
- 	}
- 
- 	if (tp->t_frextents_delta)
--		be64_add(&sbp->sb_frextents, tp->t_frextents_delta);
-+		be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta);
- 	if (tp->t_res_frextents_delta)
--		be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta);
-+		be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta);
- 
- 	if (tp->t_dblocks_delta) {
--		be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta);
-+		be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_agcount_delta) {
--		be32_add(&sbp->sb_agcount, tp->t_agcount_delta);
-+		be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_imaxpct_delta) {
-@@ -594,19 +594,19 @@
- 		whole = 1;
- 	}
- 	if (tp->t_rextsize_delta) {
--		be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta);
-+		be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_rbmblocks_delta) {
--		be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
-+		be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_rblocks_delta) {
--		be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta);
-+		be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_rextents_delta) {
--		be64_add(&sbp->sb_rextents, tp->t_rextents_delta);
-+		be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
- 		whole = 1;
- 	}
- 	if (tp->t_rextslog_delta) {
-diff -Nurd linux-2.6.24/fs/xfs/xfs_vnodeops.c linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c
---- linux-2.6.24/fs/xfs/xfs_vnodeops.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c	2008-06-11 17:46:48.000000000 +0200
-@@ -3558,11 +3558,11 @@
- 		if (iip && iip->ili_last_lsn) {
- 			xlog_t		*log = mp->m_log;
- 			xfs_lsn_t	sync_lsn;
--			int		s, log_flags = XFS_LOG_FORCE;
-+			int		log_flags = XFS_LOG_FORCE;
- 
--			s = GRANT_LOCK(log);
-+			spin_lock(&log->l_grant_lock);
- 			sync_lsn = log->l_last_sync_lsn;
--			GRANT_UNLOCK(log, s);
-+			spin_unlock(&log->l_grant_lock);
- 
- 			if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
- 				if (flags & FLUSH_SYNC)
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc
---- linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,91 @@
-+/**
-+ * -- GPIO Function Enable Mappings --
-+ * Auto Generated by asic/chips/nas/root.user/docs/specs/map2CInlude
-+ */
-+// GPIO Primary Function Enables
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N0          (0) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N1          (1) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N2          (2) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N3          (3) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N0          (4) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N1          (5) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N2          (6) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N3          (7) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_PCI_CKO                (8) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_OE_N            (12) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR21          (13) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR20          (14) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR19          (15) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR18          (16) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR17          (17) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_ADDR16          (18) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_CS_N0           (19) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_CS_N1           (20) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_WE_N0           (21) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_STATIC_WE_N1           (22) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_USBA_PWRO              (23) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_USBA_OVERI             (24) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_USBB_PWRO              (25) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_USBB_OVERI             (26) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_USBC_PWRO              (27) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_USBC_OVERI             (28) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_FAN_TEMP               (29) //  Is Bidirectional
-+#define  PRIMARY_FUNCTION_ENABLE_FAN_TACHO              (30) //  As Input
-+#define  PRIMARY_FUNCTION_ENABLE_FAN_PWM0               (31) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_FAN_PWM1               (32) //  As Output
-+#define  PRIMARY_FUNCTION_ENABLE_IBIW_D                 (33) //  Is Bidirectional
-+#define  PRIMARY_FUNCTION_ENABLE_IBIW_LED               (34) //  As Output
-+// GPIO Secondary Function Enables
-+#define  SECONDARY_FUNCTION_ENABLE_SYSPCI_REQ_OUT_N       (0) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_SYSPCI_GNT_IN_N        (1) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_IDSEL              (2) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_IRRX_IN                (3) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_FAN_PWM3               (5) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TX_BITCK         (6) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TXLRCK           (7) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_FAN_PWM2               (8) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_USB_CKO                (10) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_CCLKRUN_N          (12) //  Is Bidirectional
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_LOCK_N             (13) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_PERR_N             (14) //  Is Bidirectional
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_SERR_N             (15) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_MEM_DLLTGL             (16) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_SATA_OBS_RBC0          (17) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_CINT_N             (18) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_CSTSCHG_N          (19) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_PCI_CKO                (23) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TXD0             (25) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RXD0             (26) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RXLRCK           (27) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RX_BITCK         (28) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TXD2             (29) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RXD2             (30) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TXD3             (31) //  As Output
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RXD3             (32) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_RXD1             (33) //  As Input
-+#define  SECONDARY_FUNCTION_ENABLE_AUDIO_TXD1             (34) //  As Output
-+// GPIO Tertiary Function Enables
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_RI_N             (0) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_CD_N             (1) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_CTS_N            (2) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_DSR_N            (3) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_DTR_N            (4) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_RTS_N            (5) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_SIN              (6) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART3_SOUT             (7) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_DSR_N            (8) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_RTS_N            (9) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_SOUT             (20) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_SIN              (22) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_RI_N             (23) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_CD_N             (24) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_DTR_N            (25) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART2_CTS_N            (26) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_RTS_N            (27) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_CTS_N            (28) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_DSR_N            (29) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_CD_N             (30) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_SOUT             (31) //  As Output
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_SIN              (32) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_RI_N             (33) //  As Input
-+#define  TERTIARY_FUNCTION_ENABLE_UART1_DTR_N            (34) //  As Output
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,27 @@
-+/* linux/include/asm-arm/arch-oxnas/ahb_mon.h
-+ *
-+ * 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.
-+ */
-+#ifdef CONFIG_OXNAS_AHB_MON
-+
-+#if !defined(__AHB_MON_H__)
-+#define __AHB_MON_H__
-+
-+extern void init_ahb_monitors(
-+    AHB_MON_HWRITE_T ahb_mon_hwrite,
-+    unsigned hburst_mask,
-+    unsigned hburst_match,
-+    unsigned hprot_mask,
-+    unsigned hprot_match);
-+extern void restart_ahb_monitors(void);
-+extern void read_ahb_monitors(void);
-+#else // CONFIG_OXNAS_AHB_MON
-+#define init_ahb_monitors(a, b, c, d, e) {}
-+#define restart_ahb_monitors(x) {}
-+#define read_ahb_monitors(x) {}
-+
-+#endif        //  #if !defined(__AHB_MON_H__)
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,139 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/cipher.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * Register locations in the cipher core
-+ *
-+ */
-+
-+#ifndef __ASM_ARCH_CIPHER_H
-+#define __ASM_ARCH_CIPHER_H
-+
-+#define OX800DPE_CTL_DIRECTION_ENC      0x002
-+#define OX800DPE_CTL_PRIMARY_IS_KEY3    0x004
-+#define OX800DPE_CTL_ENCRYPT_KEY        0x010
-+#define OX800DPE_CTL_ABORT              0x040
-+#define OX800DPE_CTL_MODE_ECB_AES       0x000
-+#define OX800DPE_CTL_MODE_LRW_AES       0x080   
-+#define OX800DPE_CTL_MODE_CBC_AES       0x100
-+
-+
-+#define OX800DPE_STAT_IDLE              0x1
-+#define OX800DPE_STAT_RX_SPACE          0x4
-+#define OX800DPE_STAT_TX_NOTEMPTY       0x8
-+
-+
-+#define OX800DPE_KEYSIZE 16
-+typedef volatile u32 oxnas_cipher_key_t[4];
-+
-+#define OX800DPE_CONTROL     ((DPE_REGS_BASE) + 0x00)
-+#define OX800DPE_STATUS      ((DPE_REGS_BASE) + 0x04)
-+#define OX800DPE_KEY00       ((DPE_REGS_BASE) + 0x10)
-+#define OX800DPE_KEY01       ((DPE_REGS_BASE) + 0x14)
-+#define OX800DPE_KEY02       ((DPE_REGS_BASE) + 0x18)
-+#define OX800DPE_KEY03       ((DPE_REGS_BASE) + 0x1c)
-+#define OX800DPE_KEY10       ((DPE_REGS_BASE) + 0x20)
-+#define OX800DPE_KEY11       ((DPE_REGS_BASE) + 0x24)
-+#define OX800DPE_KEY12       ((DPE_REGS_BASE) + 0x28)
-+#define OX800DPE_KEY13       ((DPE_REGS_BASE) + 0x2c)
-+#define OX800DPE_KEY20       ((DPE_REGS_BASE) + 0x30)
-+#define OX800DPE_KEY21       ((DPE_REGS_BASE) + 0x34)
-+#define OX800DPE_KEY22       ((DPE_REGS_BASE) + 0x38)
-+#define OX800DPE_KEY23       ((DPE_REGS_BASE) + 0x3c)
-+#define OX800DPE_DATA_IN0    ((DPE_REGS_BASE) + 0x40)
-+#define OX800DPE_DATA_IN1    ((DPE_REGS_BASE) + 0x44)
-+#define OX800DPE_DATA_IN2    ((DPE_REGS_BASE) + 0x48)
-+#define OX800DPE_DATA_IN3    ((DPE_REGS_BASE) + 0x4c)
-+#define OX800DPE_DATA_OUT0   ((DPE_REGS_BASE) + 0x50)
-+#define OX800DPE_DATA_OUT1   ((DPE_REGS_BASE) + 0x54)
-+#define OX800DPE_DATA_OUT2   ((DPE_REGS_BASE) + 0x58)
-+#define OX800DPE_DATA_OUT3   ((DPE_REGS_BASE) + 0x5c)
-+#define OX800DPE_DATA_LRW0   ((DPE_REGS_BASE) + 0x60)
-+#define OX800DPE_DATA_LRW1   ((DPE_REGS_BASE) + 0x64)
-+#define OX800DPE_DATA_CBC0   ((DPE_REGS_BASE) + 0x68)
-+#define OX800DPE_DATA_CBC1   ((DPE_REGS_BASE) + 0x6c)
-+
-+
-+#define OX800IBW_STAT_AUTHENTICATED       0x10
-+
-+#define OX800IBW_CONTROL	((IBW_REGS_BASE) + 0x00)
-+#define OX800IBW_STATUS		((IBW_REGS_BASE) + 0x04)
-+#define OX800IBW_SERIAL_LO	((IBW_REGS_BASE) + 0x08)
-+#define OX800IBW_SERIAL_HI	((IBW_REGS_BASE) + 0x0C)
-+
-+
-+// IBIW Control register bits
-+
-+#define OX800IBW_CTRL_LOAD_AES_KEY 		0x00100
-+#define OX800IBW_CTRL_BUFF_WR_SRC		0x00200
-+#define OX800IBW_CTRL_CRC_WR_SRC		0x00400
-+#define OX800IBW_CTRL_RESET 			0x00800
-+#define OX800IBW_CTRL_WR 				0x01000
-+#define OX800IBW_CTRL_RD  				0x02000
-+#define OX800IBW_CTRL_RX_INIT 			0x04000
-+#define OX800IBW_CTRL_TX_INIT			0x08000
-+#define OX800IBW_CTRL_DONE  			0x10000
-+#define OX800IBW_CTRL_ENABLE  			0x20000
-+
-+
-+// IBIW Status register bits
-+
-+#define OX800IBW_STATUS_PRESENT 		0x0001
-+#define OX800IBW_STATUS_ARRIVAL 		0x0002
-+#define OX800IBW_STATUS_DEPARTURE 		0x0004
-+#define OX800IBW_STATUS_HOLDOFF 		0x0008
-+#define OX800IBW_STATUS_CRC_OK 			0x0010
-+#define OX800IBW_STATUS_SERIAL_MATCH 	0x0020
-+#define OX800IBW_STATUS_KEY_MATCH 		0x0040
-+#define OX800IBW_STATUS_VALID_KEY	 	0x0080
-+#define OX800IBW_STATUS_AUTHENTICATED 	0x0100
-+#define OX800IBW_STATUS_RD_ENABLED		0x0200
-+
-+/*The number of storage fields in a DS1991 iButton */
-+#define DS1991_IBUTTON_FIELDS 4
-+#define DS1991_PASSWORD_SIZE 8
-+#define DS1991_ID_SIZE 8
-+#define DS1991_DATA_SIZE 48
-+#define DS1991_PLAINTEXT_SIZE 64
-+
-+/* DS1991 COMMANDS */
-+#define DS1991_WRITE_SCRATCHPAD 0x96
-+#define DS1991_READ_SCRATCHPAD  0x69
-+#define DS1991_COPY_SCRATCHPAD  0x3c
-+#define DS1991_READ_SUBKEY      0x66
-+#define DS1991_WRITE_SUBKEY     0x99
-+#define DS1991_WRITE_PASSWORD   0x5a
-+
-+/* prototype */
-+struct scatterlist;
-+
-+int ox800_aeslrw_encrypt(   struct scatterlist* in,
-+                            struct scatterlist* out,
-+                            unsigned int length,
-+                            u8  iv[],
-+                            u8 cipher_key[],
-+                            u8 tweak_key[]);
-+                            
-+int ox800_aeslrw_decrypt(   struct scatterlist* in,
-+                            struct scatterlist* out,
-+                            unsigned int length,
-+                            u8  iv[],
-+                            u8 cipher_key[], 
-+                            u8 tweak_key[]);
-+
-+#endif
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S
---- linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,47 @@
-+/* linux/include/asm-arm/arch-oxnas/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ *  Copyright (C) 2005 B.H.Clarke
-+ *
-+ * 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 <asm/arch/hardware.h>
-+
-+		.macro  addruart,rx
-+		mrc		p15, 0, \rx, c1, c0
-+		tst		\rx, #1					@ MMU enabled?
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+		ldreq	\rx, =UART_1_BASE_PA	@ physical base address
-+		ldrne	\rx, =UART_1_BASE		@ virtual address
-+#elif CONFIG_ARCH_OXNAS_UART2
-+		ldreq	\rx, =UART_2_BASE_PA	@ physical base address
-+		ldrne	\rx, =UART_2_BASE		@ virtual address
-+#elif CONFIG_ARCH_OXNAS_UART3
-+		ldreq	\rx, =UART_3_BASE_PA	@ physical base address
-+		ldrne	\rx, =UART_3_BASE		@ virtual address
-+#else
-+		ldreq	\rx, =UART_4_BASE_PA	@ physical base address
-+		ldrne	\rx, =UART_4_BASE		@ virtual address
-+#endif
-+		.endm
-+
-+		.macro	senduart,rd,rx			@ Load byte into Tx holding register
-+		strb	\rd, [\rx, #0]			@ THR
-+		.endm
-+
-+		.macro	waituart,rd,rx			@ Wait until there is space in the TX FIFO
-+1001:	ldrb	\rd, [\rx, #5]			@ LSR
-+		tst		\rd, #1 << 5			@ THR empty
-+		beq		1001b
-+		.endm
-+
-+		.macro	busyuart,rd,rx			@ Wait until the TX is idle
-+#1001:	ldrb	\rd, [\rx, #5]			@ LSR
-+#		tst		\rd, #1 << 6			@ THR and Tx FIFO empty
-+#		beq		1001b
-+		.endm
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,62 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/dma.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ *
-+ * Here we partition the available internal SRAM between the GMAC and generic
-+ * DMA descriptors. This requires defining the gmac_dma_desc_t structure here,
-+ * rather than in its more natural position within gmac.h
-+ */
-+#if !defined(__DESC_ALLOC_H__)
-+#define __DESC_ALLOC_H__
-+
-+#include <asm/arch/hardware.h>
-+
-+// GMAC DMA in-memory descriptor structures
-+typedef struct gmac_dma_desc
-+{
-+    /** The encoded status field of the GMAC descriptor */
-+    u32 status;
-+    /** The encoded length field of GMAC descriptor */
-+    u32 length;
-+    /** Buffer 1 pointer field of GMAC descriptor */
-+    u32 buffer1;
-+    /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
-+    u32 buffer2;
-+} __attribute ((aligned(4),packed)) gmac_dma_desc_t;
-+
-+#define NUM_GMAC_DMA_DESCRIPTORS CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
-+
-+#define GMAC_DESC_ALLOC_START       (SRAM_BASE)
-+#define GMAC_DESC_ALLOC_START_PA    (DESCRIPTORS_BASE_PA)
-+/** Must be modified to track gmac_dma_desc_t definition above */
-+#define GMAC_DESC_ALLOC_SIZE        ((NUM_GMAC_DMA_DESCRIPTORS) * (4*4))
-+
-+#if ((GMAC_DESC_ALLOC_SIZE) > (DESCRIPTORS_SIZE))
-+#error "Too many GMAC descriptors - descriptor SRAM allocation exceeded"
-+#endif
-+
-+#define DMA_DESC_ALLOC_START        ((GMAC_DESC_ALLOC_START)    + (GMAC_DESC_ALLOC_SIZE))
-+#define DMA_DESC_ALLOC_START_PA     ((GMAC_DESC_ALLOC_START_PA) + (GMAC_DESC_ALLOC_SIZE))
-+#define DMA_DESC_ALLOC_SIZE         ((DESCRIPTORS_SIZE) - (GMAC_DESC_ALLOC_SIZE))
-+
-+#define descriptors_virt_to_phys(x) ((x) - (SRAM_BASE) + (DESCRIPTORS_BASE_PA))
-+#define descriptors_phys_to_virt(x) ((x) - (DESCRIPTORS_BASE_PA) + (SRAM_BASE))
-+
-+#endif        //  #if !defined(__DESC_ALLOC_H__)
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/dma.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/dma.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,299 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/dma.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ *
-+ * We have a generic DMAC that is a two port, memory to memory design, supporting
-+ * multiple channels, each of which can transfer between any pair of memory
-+ * regions. This DMAC architecture does not sit well with the std. ARM DMA
-+ * architecture, thus we define a custom way of acquiring and operating on the
-+ * available channels of the DMAC
-+ */
-+
-+#ifndef __ASM_ARCH_DMA_H
-+#define __ASM_ARCH_DMA_H
-+
-+#include <asm/scatterlist.h>
-+#include <asm/semaphore.h>
-+#include <linux/ata.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+
-+/* All memory DMAable */
-+#define MAX_DMA_ADDRESS (~0UL)
-+
-+/* Do not want to use the std. ARM DMA architecure */
-+#define MAX_DMA_CHANNELS 0
-+
-+#define MAX_OXNAS_DMA_CHANNELS 5
-+
-+#define MAX_OXNAS_DMA_TRANSFER_LENGTH ((1 << 21) - 1)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+// Need to set this (unused) high order address bit in the start address of DMA
-+// transfers in order for checksum calculation to be performed
-+#define OXNAS_DMA_CSUM_ENABLE_ADR_BIT 28
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+//#define OXNAS_DMA_TEST
-+//#define OXNAS_DMA_TEST_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST
-+//#define OXNAS_DMA_SG_TEST_2
-+//#define OXNAS_DMA_SG_TEST_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST2_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+//#define OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+//#define OXNAS_DMA_TEST_AFTER_SG_ITERATIONS 0
-+//#define OXNAS_DMA_OVERALL_TEST_LOOPS 1
-+
-+// All other error codes are generated by the SG engine - refer to its
-+// documentation for details
-+typedef enum oxnas_dma_callback_status {
-+    OXNAS_DMA_ERROR_CODE_NONE
-+} oxnas_dma_callback_status_t;
-+
-+typedef enum oxnas_dma_mode {
-+    OXNAS_DMA_MODE_FIXED,
-+    OXNAS_DMA_MODE_INC
-+} oxnas_dma_mode_t;
-+
-+typedef enum oxnas_dma_direction {
-+    OXNAS_DMA_TO_DEVICE,
-+    OXNAS_DMA_FROM_DEVICE
-+} oxnas_dma_direction_t;
-+
-+struct oxnas_dma_channel;
-+typedef struct oxnas_dma_channel oxnas_dma_channel_t;
-+
-+#define OXNAS_DMA_CHANNEL_NUL ((oxnas_dma_channel_t*)0)
-+
-+typedef void* oxnas_callback_arg_t;
-+
-+#define OXNAS_DMA_CALLBACK_ARG_NUL ((oxnas_callback_arg_t)0)
-+
-+typedef void (*oxnas_dma_callback_t)(oxnas_dma_channel_t*, oxnas_callback_arg_t, oxnas_dma_callback_status_t, u16 checksum, int interrupt_count);
-+
-+#define OXNAS_DMA_CALLBACK_NUL ((oxnas_dma_callback_t)0)
-+
-+typedef enum oxnas_dma_eot_type {
-+    OXNAS_DMA_EOT_NONE,
-+    OXNAS_DMA_EOT_ALL,
-+    OXNAS_DMA_EOT_FINAL
-+} oxnas_dma_eot_type_t;
-+
-+// Will be exchanged with SG DMA controller
-+typedef struct oxnas_dma_sg_entry {
-+    dma_addr_t                 addr_;   // The physical address of the buffer described by this descriptor
-+    unsigned long              length_; // The length of the buffer described by this descriptor
-+    dma_addr_t                 p_next_; // The physical address of the next descriptor
-+    struct oxnas_dma_sg_entry *v_next_; // The virtual address of the next descriptor
-+    dma_addr_t                 paddr_;  // The physical address of this descriptor
-+    struct oxnas_dma_sg_entry *next_;   // To allow insertion into single-linked list
-+} __attribute ((aligned(4),packed)) oxnas_dma_sg_entry_t;
-+
-+// Will be exchanged with SG DMA controller
-+typedef struct oxnas_dma_sg_info {
-+    unsigned long         qualifer_;
-+    unsigned long         control_;
-+    dma_addr_t            p_srcEntries_; // The physical address of the first source SG descriptor
-+    dma_addr_t            p_dstEntries_; // The physical address of the first destination SG descriptor
-+    oxnas_dma_sg_entry_t *v_srcEntries_; // The virtual address of the first source SG descriptor
-+    oxnas_dma_sg_entry_t *v_dstEntries_; // The virtual address of the first destination SG descriptor
-+} __attribute ((aligned(4),packed)) oxnas_dma_sg_info_t;
-+
-+struct oxnas_dma_channel {
-+    unsigned                     channel_number_;
-+    oxnas_dma_callback_t         notification_callback_;
-+    oxnas_callback_arg_t         notification_arg_;
-+    dma_addr_t                   p_sg_info_;    // Physical address of sg_info structure
-+    oxnas_dma_sg_info_t         *v_sg_info_;    // Virtual address of sg_info structure
-+    oxnas_dma_callback_status_t  error_code_;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    int                          checksumming_;
-+    u16                          checksum_;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+    unsigned                     rps_interrupt_;
-+    struct oxnas_dma_channel    *next_;
-+    struct semaphore             default_semaphore_;
-+    atomic_t                     interrupt_count_;
-+    atomic_t                     active_count_;
-+	int							  auto_sg_entries_;
-+};
-+
-+typedef struct oxnas_dma_controller {
-+    oxnas_dma_channel_t        channels_[MAX_OXNAS_DMA_CHANNELS];
-+    unsigned                   numberOfChannels_;
-+    int                        version_;
-+    atomic_t                   run_bh_;
-+    spinlock_t                 spinlock_;
-+    struct                     tasklet_struct tasklet_;
-+    dma_addr_t                 p_sg_infos_;     // Physical address of the array of sg_info structures
-+    oxnas_dma_sg_info_t       *v_sg_infos_;     // Virtual address of the array of sg_info structures
-+    struct semaphore           csum_engine_sem_;
-+    spinlock_t                 alloc_spinlock_;  // Sync. for SG management
-+    spinlock_t                 channel_alloc_spinlock_;  // Sync. for channel management
-+    oxnas_dma_sg_entry_t      *sg_entry_head_;  // Pointer to head of free list for oxnas_dma_sg_entry_t objects
-+    struct semaphore           sg_entry_sem_;
-+    unsigned                   sg_entry_available_;
-+    oxnas_dma_channel_t       *channel_head_;
-+    struct semaphore           channel_sem_;
-+} oxnas_dma_controller_t;
-+
-+typedef struct oxnas_dma_device_settings {
-+    unsigned long address_;
-+    unsigned      fifo_size_;   // Chained transfers must take account of FIFO offset at end of previous transfer
-+    unsigned char dreq_;
-+    unsigned      read_eot_policy_:2;
-+    unsigned      write_eot_policy_:2;
-+    unsigned      bus_:1;
-+    unsigned      width_:2;
-+    unsigned      transfer_mode_:1;
-+    unsigned      address_mode_:1;
-+    unsigned      address_really_fixed_:1;
-+} oxnas_dma_device_settings_t;
-+
-+/* Pre-defined settings for known DMA devices */
-+extern oxnas_dma_device_settings_t oxnas_pata_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_sata_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings;
-+
-+extern void oxnas_dma_init(void);
-+
-+extern void oxnas_dma_shutdown(void);
-+
-+extern oxnas_dma_channel_t* oxnas_dma_request(int block);
-+
-+extern void oxnas_dma_free(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_is_active(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_raw_isactive(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_get_raw_direction(oxnas_dma_channel_t*);
-+
-+/**
-+ * @param do_checksum An int indicating that the checksum engine is required
-+ *                    and causing the OXNAS_DMA_CSUM_ENABLE_ADR_BIT to be set
-+ *                    automatically in the passed src and dst start addresses
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ *         exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_set(
-+    oxnas_dma_channel_t *channel,
-+    unsigned char       *src_adr,   // Physical address
-+    unsigned long        length,
-+    unsigned char       *dst_adr,   // Physical address
-+    oxnas_dma_mode_t     src_mode,
-+    oxnas_dma_mode_t     dst_mode,
-+    int                  do_checksum,
-+    int                  paused);
-+
-+/**
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ *         exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_device_set(
-+    oxnas_dma_channel_t         *channel,
-+    oxnas_dma_direction_t        direction,
-+    unsigned char               *mem_adr,   // Physical address
-+    unsigned long                length,
-+    oxnas_dma_device_settings_t *device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+    int                          paused);
-+
-+/**
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ *         exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_device_pair_set(
-+    oxnas_dma_channel_t         *channel,
-+    unsigned long                length,
-+    oxnas_dma_device_settings_t *src_device_settings,
-+    oxnas_dma_device_settings_t *dst_device_settings,
-+    int                          paused);
-+
-+/**
-+ * @param do_checksum An int indicating that the checksum engine is required
-+ *                    for this SG transfer. For the individual SG transfer
-+ *                    components to contribute to the checksum result, their
-+ *                    start addresses contained within the scatterlist
-+ *                    structures must have the OXNAS_DMA_CSUM_ENABLE_ADR_BIT
-+ *                    bit set
-+ *
-+ *  NB This function does not have an error return value, but if it is passed
-+ *     a transfer segment longer than the maximum allowed by the hardware, that
-+ *     entry will be zeroed in the SG descriptor list and a kernel warning
-+ *     message generated
-+ */
-+extern int oxnas_dma_set_sg(
-+    oxnas_dma_channel_t* channel,
-+    struct scatterlist*  src_sg,
-+    unsigned             src_sg_count,
-+    struct scatterlist*  dst_sg,
-+    unsigned             dst_sg_count,
-+    oxnas_dma_mode_t     src_mode,
-+    oxnas_dma_mode_t     dst_mode,
-+    int                  do_checksum,
-+	int                  in_atomic);
-+
-+/**
-+ *  NB This function does not have an error return value, but if it is passed
-+ *     a transfer segment longer than the maximum allowed by the hardware, that
-+ *     entry will be zeroed in the SG descriptor list and a kernel warning
-+ *     message generated
-+ */
-+extern int oxnas_dma_device_set_sg(
-+    oxnas_dma_channel_t*         channel,
-+    oxnas_dma_direction_t        direction,
-+    struct scatterlist*          mem_sg,
-+    unsigned                     mem_sg_count,
-+    oxnas_dma_device_settings_t* device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+	int                          in_atomic);
-+
-+extern int oxnas_dma_device_set_prd(
-+    oxnas_dma_channel_t			 *channel,
-+    oxnas_dma_direction_t        direction,
-+	struct ata_prd				 *prd,
-+    oxnas_dma_device_settings_t *device_settings,
-+    oxnas_dma_mode_t             mem_mode,
-+	oxnas_dma_sg_entry_t		 *sg_entries);
-+
-+/**
-+ * The callback function should complete quickly and must not sleep
-+ */
-+extern void oxnas_dma_set_callback(
-+    oxnas_dma_channel_t*,
-+    oxnas_dma_callback_t callback,
-+    oxnas_callback_arg_t callback_arg);
-+
-+extern void oxnas_dma_abort(oxnas_dma_channel_t*, int in_atomic);
-+
-+extern void oxnas_dma_start(oxnas_dma_channel_t*);
-+
-+extern void oxnas_dma_dump_registers(void);
-+
-+extern void oxnas_dma_dump_registers_single(int channel_number);
-+
-+extern int oxnas_dma_alloc_sg_entries(oxnas_dma_sg_entry_t** entries, unsigned required, int in_atomic);
-+
-+extern void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries);
-+#endif // __ASM_ARCH_DMA_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S
---- linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,40 @@
-+/*
-+ * include/asm-arm/arch-oxnas/entry-macro.S
-+ *
-+ * Low-level IRQ helper macros for Integrator platforms
-+ *
-+ * 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 <asm/arch/irqs.h>
-+#include <asm/arch/hardware.h>
-+
-+		.macro  disable_fiq
-+		.endm
-+
-+		.macro  get_irqnr_preamble, base, tmp
-+		.endm
-+
-+		.macro  arch_ret_to_user, tmp1, tmp2
-+		.endm
-+
-+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-+		ldr \irqstat, =RPS_IRQ_STATUS
-+		ldr \irqstat, [\irqstat, #0]
-+
-+		mov \irqnr, #0
-+1001:
-+		tst \irqstat, #1
-+		bne 1002f
-+		add \irqnr, \irqnr, #1
-+		mov \irqstat, \irqstat, lsr #1
-+		cmp \irqnr, #NR_IRQS
-+		bcc 1001b
-+
-+1002:
-+		.endm
-+
-+		.macro  irq_prio_table
-+		.endm
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,760 @@
-+/* linux/include/asm-arm/arch-oxnas/hardware.h
-+ *
-+ * 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_HARDWARE_H
-+#define __ASM_ARCH_HARDWARE_H
-+
-+#include <asm/page.h>
-+#include <asm/memory.h>
-+#include <asm/sizes.h>
-+#include <asm/arch/vmalloc.h>
-+#include <asm/arch/timex.h>
-+
-+// The base of virtual address mappings for hardware cores starts directly after
-+// the end of the vmalloc mapping region
-+#define OXNAS_HW_PA_TO_VA(x) (VMALLOC_END + (x))
-+
-+// Virtual address mapping of hardware cores
-+#define APB_BRIDGE_A_BASE    OXNAS_HW_PA_TO_VA(0)
-+#define STATIC_CONTROL_BASE  OXNAS_HW_PA_TO_VA(0x1000000)
-+#define CORE_MODULE_BASE     OXNAS_HW_PA_TO_VA(0x2000000)
-+#define EXTERNAL_UART_BASE   OXNAS_HW_PA_TO_VA(0x3000000)
-+#define EXTERNAL_UART_2_BASE OXNAS_HW_PA_TO_VA(0x3800000)
-+
-+/* 16 Mbyte address range on AMBA bus */
-+#define APB_BRIDGE_BASE_MASK    0x00FFFFFF
-+
-+#define APB_BRIDGE_B_BASE OXNAS_HW_PA_TO_VA(0x04000000)
-+#define SATA_DATA_BASE    OXNAS_HW_PA_TO_VA(0x05000000)
-+#define DPE_BASE          OXNAS_HW_PA_TO_VA(0x06000000)
-+#define USB_BASE          OXNAS_HW_PA_TO_VA(0x07000000)
-+#define MAC_BASE          OXNAS_HW_PA_TO_VA(0x08000000)
-+#define PCI_CSRS_BASE     OXNAS_HW_PA_TO_VA(0x0A000000)
-+#define STATIC_CS0_BASE   OXNAS_HW_PA_TO_VA(0x0B000000)
-+#define STATIC_CS1_BASE   OXNAS_HW_PA_TO_VA(0x0C000000)
-+#define STATIC_CS2_BASE   OXNAS_HW_PA_TO_VA(0x0D000000)
-+#define ROM_BASE          OXNAS_HW_PA_TO_VA(0x0E000000)
-+#define SDRAM_CTRL_BASE   OXNAS_HW_PA_TO_VA(0x0F000000)
-+#define LEON_IMAGE_BASE   OXNAS_HW_PA_TO_VA(0x10000000)
-+#define SRAM_BASE         OXNAS_HW_PA_TO_VA(0x11000000)
-+
-+#ifdef CONFIG_SUPPORT_LEON
-+#define LEON_IMAGE_SIZE			(CONFIG_LEON_PAGES * PAGE_SIZE)
-+#define LEON_IMAGE_BASE_PA		(((SRAM_END) + 1) - (LEON_IMAGE_SIZE))
-+#else // CONFIG_SUPPORT_LEON
-+#define LEON_IMAGE_SIZE		0
-+#define LEON_IMAGE_BASE_PA	0
-+#endif // CONFIG_SUPPORT_LEON
-+
-+#if (LEON_IMAGE_BASE_PA >= SRAM_PA) && (LEON_IMAGE_BASE_PA <= SRAM_END)
-+#define LEON_IMAGE_IN_SRAM
-+#endif
-+
-+#define DESCRIPTORS_SIZE        (CONFIG_DESCRIPTORS_PAGES * PAGE_SIZE)
-+
-+#ifdef CONFIG_DESCRIPTORS_PAGES
-+#if (CONFIG_DESCRIPTORS_PAGES > CONFIG_SRAM_NUM_PAGES)
-+#error "Too many descriptor pages defined - greater than total SRAM pages"
-+#endif
-+#endif // CONFIG_DESCRIPTORS_PAGES
-+
-+#define DESCRIPTORS_BASE_PA     (SRAM_PA)
-+#define DESCRIPTORS_END_PA      (SRAM_PA + DESCRIPTORS_SIZE)
-+
-+#ifdef LEON_IMAGE_IN_SRAM
-+#if (DESCRIPTORS_END_PA > LEON_IMAGE_BASE_PA)
-+#error "Overlapping LEON and Descriptor areas in SRAM"
-+#endif
-+#endif
-+
-+#define CORE_MODULE_BASE_PA    0x10000000
-+                                          
-+#define ROM_BASE_PA            0x40000000
-+#define USB_BASE_PA            0x40200000
-+#define MAC_BASE_PA            0x40400000
-+#define PCI_CSRS_BASE_PA       0x40600000      
-+#define PCI_BASE_PA            0x40800000
-+                                          
-+#define STATIC_CS0_BASE_PA     0x41000000
-+#define STATIC_CS1_BASE_PA     0x41400000
-+#define STATIC_CS2_BASE_PA     0x41800000
-+#define STATIC_CONTROL_BASE_PA 0x41C00000
-+                                          
-+#define SATA_DATA_BASE_PA      0x42000000
-+#define DPE_BASE_PA            0x43000000
-+#define APB_BRIDGE_A_BASE_PA   0x44000000
-+#define APB_BRIDGE_B_BASE_PA   0x45000000
-+
-+#define UART_1_BASE_PA         (APB_BRIDGE_A_BASE_PA + 0x200000) 
-+#define UART_2_BASE_PA         (APB_BRIDGE_A_BASE_PA + 0x300000) 
-+#define UART_3_BASE_PA         (APB_BRIDGE_A_BASE_PA + 0x900000) 
-+#define UART_4_BASE_PA         (APB_BRIDGE_A_BASE_PA + 0xA00000) 
-+
-+#define GPIO_A_BASE             APB_BRIDGE_A_BASE
-+#define GPIO_B_BASE            (APB_BRIDGE_A_BASE + 0x100000)
-+#define UART_1_BASE            (APB_BRIDGE_A_BASE + 0x200000)
-+#define UART_2_BASE            (APB_BRIDGE_A_BASE + 0x300000)
-+#define UART_3_BASE            (APB_BRIDGE_A_BASE + 0x900000)
-+#define UART_4_BASE            (APB_BRIDGE_A_BASE + 0xA00000)
-+#define I2C_BASE               (APB_BRIDGE_A_BASE + 0x400000)
-+#define I2S_BASE               (APB_BRIDGE_A_BASE + 0x500000)
-+#define FAN_MON_BASE           (APB_BRIDGE_A_BASE + 0x600000)
-+#define PWM_BASE               (APB_BRIDGE_A_BASE + 0x700000)
-+#define IRRX_BASE              (APB_BRIDGE_A_BASE + 0x800000)
-+
-+#define SYS_CONTROL_BASE        APB_BRIDGE_B_BASE
-+#define CLOCK_CONTROL_BASE     (APB_BRIDGE_B_BASE + 0x100000)
-+#define RTC_BASE               (APB_BRIDGE_B_BASE + 0x200000)
-+#define RPS_BASE               (APB_BRIDGE_B_BASE + 0x300000)
-+#define COPRO_RPS_BASE         (APB_BRIDGE_B_BASE + 0x400000)
-+#define AHB_MON_BASE           (APB_BRIDGE_B_BASE + 0x500000)
-+#define DMA_BASE               (APB_BRIDGE_B_BASE + 0x600000)
-+#define DPE_REGS_BASE          (APB_BRIDGE_B_BASE + 0x700000)
-+#define IBW_REGS_BASE          (APB_BRIDGE_B_BASE + 0x780000)
-+#define DDR_REGS_BASE          (APB_BRIDGE_B_BASE + 0x800000)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define SATA0_REGS_BASE        (APB_BRIDGE_B_BASE + 0x900000)
-+#define SATA0_LINK_REGS_BASE   (APB_BRIDGE_B_BASE + 0x940000)
-+#define SATA1_REGS_BASE        (APB_BRIDGE_B_BASE + 0x980000)
-+#define SATA1_LINK_REGS_BASE   (APB_BRIDGE_B_BASE + 0x9C0000)
-+#elif CONFIG_OXNAS_VERSION_0X810
-+#define SATA_REG_BASE          (APB_BRIDGE_B_BASE + 0x900000)
-+#define SATA0_REGS_BASE        (SATA_REG_BASE)
-+#define SATA1_REGS_BASE        (SATA_REG_BASE + 0x10000)
-+#define SATACORE_REGS_BASE     (SATA_REG_BASE + 0xe0000)
-+#define SATARAID_REGS_BASE     (SATA_REG_BASE + 0xf0000)
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+
-+#define DMA_CHECKSUM_BASE      (APB_BRIDGE_B_BASE + 0xA00000)
-+#define COPRO_REGS_BASE        (APB_BRIDGE_B_BASE + 0xB00000)
-+#define DMA_SG_BASE            (APB_BRIDGE_B_BASE + 0xC00000)
-+
-+/* Interrupt Controller registers */
-+#define RPS_IC_BASE         RPS_BASE
-+#define RPS_IRQ_STATUS     (RPS_IC_BASE)
-+#define RPS_IRQ_RAW_STATUS (RPS_IC_BASE + 0x04)
-+#define RPS_IRQ_ENABLE     (RPS_IC_BASE + 0x08)
-+#define RPS_IRQ_DISABLE    (RPS_IC_BASE + 0x0C)
-+#define RPS_IRQ_SOFT       (RPS_IC_BASE + 0x10)
-+
-+/* FIQ registers */
-+#define RPS_FIQ_BASE       (RPS_IC_BASE + 0x100)
-+#define RPS_FIQ_STATUS     (RPS_FIQ_BASE + 0x00)
-+#define RPS_FIQ_RAW_STATUS (RPS_FIQ_BASE + 0x04)
-+#define RPS_FIQ_ENABLE     (RPS_FIQ_BASE + 0x08)
-+#define RPS_FIQ_DISABLE    (RPS_FIQ_BASE + 0x0C)
-+
-+/* Timer registers */
-+#define RPS_TIMER_BASE  (RPS_BASE + 0x200)
-+#define RPS_TIMER1_BASE (RPS_TIMER_BASE)
-+#define RPS_TIMER2_BASE (RPS_TIMER_BASE + 0x20)
-+
-+#define TIMER1_LOAD    (RPS_TIMER1_BASE + 0x0)
-+#define TIMER1_VALUE   (RPS_TIMER1_BASE + 0x4)
-+#define TIMER1_CONTROL (RPS_TIMER1_BASE + 0x8)
-+#define TIMER1_CLEAR   (RPS_TIMER1_BASE + 0xc)
-+
-+#define TIMER2_LOAD    (RPS_TIMER2_BASE + 0x0)
-+#define TIMER2_VALUE   (RPS_TIMER2_BASE + 0x4)
-+#define TIMER2_CONTROL (RPS_TIMER2_BASE + 0x8)
-+#define TIMER2_CLEAR   (RPS_TIMER2_BASE + 0xc)
-+
-+#define TIMER_MODE_BIT          6
-+#define TIMER_MODE_FREE_RUNNING 0
-+#define TIMER_MODE_PERIODIC     1
-+#define TIMER_ENABLE_BIT        7
-+#define TIMER_ENABLE_DISABLE    0
-+#define TIMER_ENABLE_ENABLE     1
-+
-+/* System clock frequencies */
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+/* FPGA CPU clock is entirely independent of rest of SoC */
-+#define NOMINAL_ARMCLK (CONFIG_OXNAS_CORE_CLK)
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+/* ASIC CPU clock is derived from SoC master clock */
-+#define NOMINAL_ARMCLK (CONFIG_NOMINAL_PLL400_FREQ / 2)
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#define NOMINAL_SYSCLK (CONFIG_NOMINAL_PLL400_FREQ / 4)
-+#define NOMINAL_PCICLK 33000000
-+
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+/* FPGA has no PCI clock divider */
-+#define PCI_CLOCK_DIVIDER 1
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+/* ASIC PCI divider divides CONFIG_NOMINAL_PLL400_FREQ by 2(n + 1) to get 33MHz */
-+#define PCI_CLOCK_DIVIDER (((CONFIG_NOMINAL_PLL400_FREQ) / (2 * NOMINAL_PCICLK)) - 1)
-+#endif //CONFIG_ARCH_OXNAS_FPGA
-+
-+/* RPS timer setup */
-+#define TIMER_1_MODE           TIMER_MODE_PERIODIC
-+#define TIMER_2_PRESCALE_ENUM  TIMER_PRESCALE_256
-+#define TIMER_2_MODE           TIMER_MODE_FREE_RUNNING
-+
-+/* Useful macros for dealing with sub timer-interrupt intervals - preserve
-+ * as much precision as possible without using floating point and minimising
-+ * runtime CPU requirement */
-+#define TIMER_1_LOAD_VALUE     ((CLOCK_TICK_RATE) / HZ)
-+#define TICKS_TO_US_SCALING    1024
-+#define TICKS_TO_US_FACTOR     (((2 * TICKS_TO_US_SCALING * 1000000) + CLOCK_TICK_RATE) / (2 * CLOCK_TICK_RATE))
-+#define TICKS_TO_US(ticks)     ((((ticks) * TICKS_TO_US_FACTOR * 2) + TICKS_TO_US_SCALING) / (2 * TICKS_TO_US_SCALING))
-+
-+/* Remap and pause */
-+#define RPS_REMAP_AND_PAUSE    (RPS_BASE + 0x300)
-+
-+/* GPIO */
-+#define GPIO_0               (0x00)
-+#define GPIO_1               (0x01)
-+#define GPIO_2               (0x02)
-+#define GPIO_3               (0x03)
-+#define GPIO_4               (0x04)
-+#define GPIO_5               (0x05)
-+#define GPIO_6               (0x06)
-+#define GPIO_7               (0x07)
-+#define GPIO_8               (0x08)
-+#define GPIO_9               (0x09)
-+#define GPIO_10              (0x0a)
-+#define GPIO_11              (0x0b)
-+#define GPIO_12              (0x0c)
-+#define GPIO_13              (0x0d)
-+#define GPIO_14              (0x0e)
-+#define GPIO_15              (0x0f)
-+#define GPIO_16              (0x10)
-+#define GPIO_17              (0x11)
-+#define GPIO_18              (0x12)
-+#define GPIO_19              (0x13)
-+#define GPIO_20              (0x14)
-+#define GPIO_21              (0x15)
-+#define GPIO_22              (0x16)
-+#define GPIO_23              (0x17)
-+#define GPIO_24              (0x18)
-+#define GPIO_25              (0x19)
-+#define GPIO_26              (0x1a)
-+#define GPIO_27              (0x1b)
-+#define GPIO_28              (0x1c)
-+#define GPIO_29              (0x1d)
-+#define GPIO_30              (0x1e)
-+#define GPIO_31              (0x1f)
-+#define GPIO_32              (0x00)
-+#define GPIO_33              (0x01)
-+#define GPIO_34              (0x02)
-+
-+/* Symbols for functions mapped onto GPIO lines */
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+#define PCI_GPIO_INTA_PLANAR    8
-+#define PCI_GPIO_INTA_MINIPCI   9
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define PCI_GPIO_INTA_PLANAR    3
-+#define PCI_GPIO_INTA_MINIPCI   9
-+#elif CONFIG_OXNAS_VERSION_0X810
-+#define PCI_GPIO_INTA_PLANAR    3
-+#define PCI_GPIO_INTA_MINIPCI   9
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#define PCI_GPIO_CLKO_0 8
-+#define PCI_GPIO_CLKO_1 9
-+#define PCI_GPIO_CLKO_2 10
-+#define PCI_GPIO_CLKO_3 11
-+#define PCI_GPIO_CLKO_4 23
-+
-+#define PCI_GNT_N0 0
-+#define PCI_GNT_N1 1
-+#define PCI_GNT_N2 2
-+#define PCI_GNT_N3 3
-+#define PCI_REQ_N0 4
-+#define PCI_REQ_N1 5
-+#define PCI_REQ_N2 6
-+#define PCI_REQ_N3 7
-+
-+#define IBW_GPIO_DATA   (GPIO_33)
-+
-+#define USBA_POWO_GPIO  23
-+#define USBA_OVERI_GPIO 24
-+#define USBB_POWO_GPIO  25
-+#define USBB_OVERI_GPIO 26
-+#define USBC_POWO_GPIO  27
-+#define USBC_OVERI_GPIO 28
-+
-+/* RPS GPIO registers */
-+#define RPS_GPIO_BASE               GPIO_1_BASE /*(RPS_BASE + 0x3C0) ??????? */
-+
-+/* GPIO A registers */
-+#define GPIO_A_DATA                            GPIO_A_BASE
-+#define GPIO_A_OUTPUT_ENABLE                  (GPIO_A_BASE + 0x0004)
-+#define GPIO_A_INTERRUPT_ENABLE               (GPIO_A_BASE + 0x0008)
-+#define GPIO_A_INTERRUPT_EVENT                (GPIO_A_BASE + 0x000C)
-+#define GPIO_A_OUTPUT_VALUE                   (GPIO_A_BASE + 0x0010)
-+#define GPIO_A_OUTPUT_SET                     (GPIO_A_BASE + 0x0014)
-+#define GPIO_A_OUTPUT_CLEAR                   (GPIO_A_BASE + 0x0018)
-+#define GPIO_A_OUTPUT_ENABLE_SET              (GPIO_A_BASE + 0x001C)
-+#define GPIO_A_OUTPUT_ENABLE_CLEAR            (GPIO_A_BASE + 0x0020)
-+#define GPIO_A_INPUT_DEBOUNCE_ENABLE          (GPIO_A_BASE + 0x0024)
-+#define GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_A_BASE + 0x0028)
-+#define GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_A_BASE + 0x002C)
-+#define GPIO_A_RISING_EDGE_DETECT             (GPIO_A_BASE + 0x0030)
-+#define GPIO_A_FALLING_EDGE_DETECT            (GPIO_A_BASE + 0x0034)
-+#define GPIO_A_LEVEL_INTERRUPT_ENABLE         (GPIO_A_BASE + 0x0038)
-+#define GPIO_A_INTERRUPT_STATUS_REGISTER      (GPIO_A_BASE + 0x003C)
-+
-+/* GPIO B registers */
-+#define GPIO_B_DATA                            GPIO_B_BASE
-+#define GPIO_B_OUTPUT_ENABLE                  (GPIO_B_BASE + 0x0004)
-+#define GPIO_B_INTERRUPT_ENABLE               (GPIO_B_BASE + 0x0008)
-+#define GPIO_B_INTERRUPT_EVENT                (GPIO_B_BASE + 0x000C)
-+#define GPIO_B_OUTPUT_VALUE                   (GPIO_B_BASE + 0x0010)
-+#define GPIO_B_OUTPUT_SET                     (GPIO_B_BASE + 0x0014)
-+#define GPIO_B_OUTPUT_CLEAR                   (GPIO_B_BASE + 0x0018)
-+#define GPIO_B_OUTPUT_ENABLE_SET              (GPIO_B_BASE + 0x001C)
-+#define GPIO_B_OUTPUT_ENABLE_CLEAR            (GPIO_B_BASE + 0x0020)
-+#define GPIO_B_INPUT_DEBOUNCE_ENABLE          (GPIO_B_BASE + 0x0024)
-+#define GPIO_B_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_B_BASE + 0x0028)
-+#define GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_B_BASE + 0x002C)
-+#define GPIO_B_RISING_EDGE_DETECT             (GPIO_B_BASE + 0x0030)
-+#define GPIO_B_FALLING_EDGE_DETECT            (GPIO_B_BASE + 0x0034)
-+#define GPIO_B_LEVEL_INTERRUPT_ENABLE         (GPIO_B_BASE + 0x0038)
-+#define GPIO_B_INTERRUPT_STATUS_REGISTER      (GPIO_B_BASE + 0x003C)
-+
-+/* CoProcessor RPS GPIO registers */
-+#define COPRO_GPIO_A_BASE            (COPRO_RPS_BASE + 0x3C0)
-+#define COPRO_GPIO_A_DATA             COPRO_GPIO_A_BASE
-+#define COPRO_GPIO_A_OUTPUT_ENABLE   (COPRO_GPIO_A_BASE + 0x04)
-+#define COPRO_GPIO_A_INTERRUPT_MASK  (COPRO_GPIO_A_BASE + 0x08)
-+#define COPRO_GPIO_A_INTERRUPT_EVENT (COPRO_GPIO_A_BASE + 0x0C)
-+
-+/* Static bus registers */
-+#define STATIC_CONTROL_VERSION (STATIC_CONTROL_BASE + 0x0)
-+#define STATIC_CONTROL_BANK0   (STATIC_CONTROL_BASE + 0x4)
-+#define STATIC_CONTROL_BANK1   (STATIC_CONTROL_BASE + 0x8)
-+#define STATIC_CONTROL_BANK2   (STATIC_CONTROL_BASE + 0xC)
-+
-+/* System Control registers */
-+#define SYS_CTRL_USB11_CTRL             (SYS_CONTROL_BASE + 0x00)
-+#define SYS_CTRL_PCI_CTRL0              (SYS_CONTROL_BASE + 0x04)
-+#define SYS_CTRL_PCI_CTRL1              (SYS_CONTROL_BASE + 0x08)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0    (SYS_CONTROL_BASE + 0x0C)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1    (SYS_CONTROL_BASE + 0x10)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_0     (SYS_CONTROL_BASE + 0x14)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_1     (SYS_CONTROL_BASE + 0x18)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_0    (SYS_CONTROL_BASE + 0x8C)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_1    (SYS_CONTROL_BASE + 0x90)
-+#define SYS_CTRL_USB11_STAT             (SYS_CONTROL_BASE + 0x1c)
-+#define SYS_CTRL_PCI_STAT               (SYS_CONTROL_BASE + 0x20)
-+#define SYS_CTRL_CKEN_CTRL              (SYS_CONTROL_BASE + 0x24)
-+#define SYS_CTRL_RSTEN_CTRL             (SYS_CONTROL_BASE + 0x28)
-+#define SYS_CTRL_CKEN_SET_CTRL          (SYS_CONTROL_BASE + 0x2C)
-+#define SYS_CTRL_CKEN_CLR_CTRL          (SYS_CONTROL_BASE + 0x30)
-+#define SYS_CTRL_RSTEN_SET_CTRL         (SYS_CONTROL_BASE + 0x34)
-+#define SYS_CTRL_RSTEN_CLR_CTRL         (SYS_CONTROL_BASE + 0x38)
-+#define SYS_CTRL_USBHSMPH_CTRL          (SYS_CONTROL_BASE + 0x40)
-+#define SYS_CTRL_USBHSMPH_STAT          (SYS_CONTROL_BASE + 0x44)
-+#define SYS_CTRL_PLLSYS_CTRL            (SYS_CONTROL_BASE + 0x48)
-+#define SYS_CTRL_SEMA_STAT              (SYS_CONTROL_BASE + 0x4C)
-+#define SYS_CTRL_SEMA_SET_CTRL          (SYS_CONTROL_BASE + 0x50)
-+#define SYS_CTRL_SEMA_CLR_CTRL          (SYS_CONTROL_BASE + 0x54)
-+#define SYS_CTRL_SEMA_MASKA_CTRL        (SYS_CONTROL_BASE + 0x58)
-+#define SYS_CTRL_SEMA_MASKB_CTRL        (SYS_CONTROL_BASE + 0x5C)
-+#define SYS_CTRL_SEMA_MASKC_CTRL        (SYS_CONTROL_BASE + 0x60)
-+#define SYS_CTRL_CKCTRL_CTRL            (SYS_CONTROL_BASE + 0x64)
-+#define SYS_CTRL_COPRO_CTRL             (SYS_CONTROL_BASE + 0x68)
-+#define SYS_CTRL_PLLSYS_KEY_CTRL        (SYS_CONTROL_BASE + 0x6C)
-+#define SYS_CTRL_GMAC_CTRL              (SYS_CONTROL_BASE + 0x78)
-+#define SYS_CTRL_USBHSPHY_CTRL          (SYS_CONTROL_BASE + 0x84)
-+#define SYS_CTRL_UART_CTRL              (SYS_CONTROL_BASE + 0x94)
-+#define SYS_CTRL_GPIO_PWMSEL_CTRL_0    (SYS_CONTROL_BASE + 0x9C)
-+#define SYS_CTRL_GPIO_PWMSEL_CTRL_1    (SYS_CONTROL_BASE + 0xA0)
-+#define SYSCTRL_GPIO_MONSEL_CTRL_0 	(SYS_CONTROL_BASE + 0xA4)
-+#define SYSCTRL_GPIO_MONSEL_CTRL_1 	(SYS_CONTROL_BASE + 0xA8)
-+#define SYSCTRL_GPIO_PULLUP_CTRL_0 	(SYS_CONTROL_BASE + 0xAC)
-+#define SYSCTRL_GPIO_PULLUP_CTRL_1 	(SYS_CONTROL_BASE + 0xB0)
-+#define SYSCTRL_GPIO_ODRIVEHI_CTRL_0 	(SYS_CONTROL_BASE + 0xB4)
-+#define SYSCTRL_GPIO_ODRIVEHI_CTRL_1 	(SYS_CONTROL_BASE + 0xB8)
-+#define SYSCTRL_GPIO_ODRIVELO_CTRL_0 	(SYS_CONTROL_BASE + 0xBC)
-+#define SYSCTRL_GPIO_ODRIVELO_CTRL_1 	(SYS_CONTROL_BASE + 0xC0)
-+
-+
-+/* System control register field definitions */
-+#define SYSCTL_CB_CIS_OFFSET_0  SYS_CTRL_PCI_CTRL0
-+
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5   19
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4   18
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3   17
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2   16
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1   15
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0   14
-+#define SYSCTL_PCI_CTRL1_ENPU                   13
-+#define SYSCTL_PCI_CTRL1_ENCB                   12
-+#define SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ      11
-+#define SYSCTL_PCI_CTRL1_SS_HOST_E              10
-+#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE   9
-+#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE    7
-+#define SYSCTL_PCI_CTRL1_SS_CADBUS_E            6
-+#define SYSCTL_PCI_CTRL1_SS_MINIPCI_            5
-+#define SYSCTL_PCI_CTRL1_SS_INT_MASK_0          4
-+#define SYSCTL_PCI_CTRL1_INT_STATUS_0           3
-+#define SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK     2
-+#define SYSCTL_PCI_CTRL1_APP_CBUS_INT_N         1
-+#define SYSCTL_PCI_CTRL1_APP_CSTSCHG_N          0
-+
-+#define SYSCTL_PCI_STAT_SYSPCI_CLKCHG_EQ    3
-+#define SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT   2
-+#define SYSCTL_PCI_STAT_INT_DISABLE_0       1
-+#define SYSCTL_PCI_STAT_CLK_CHANGED         0
-+
-+#define SYS_CTRL_CKEN_COPRO_BIT  0
-+#define SYS_CTRL_CKEN_DMA_BIT    1
-+#define SYS_CTRL_CKEN_DPE_BIT    2
-+#define SYS_CTRL_CKEN_DDR_BIT    3
-+#define SYS_CTRL_CKEN_SATA_BIT   4
-+#define SYS_CTRL_CKEN_I2S_BIT    5
-+#define SYS_CTRL_CKEN_USBHS_BIT  6
-+#define SYS_CTRL_CKEN_MAC_BIT    7
-+#define SYS_CTRL_CKEN_PCI_BIT    8
-+#define SYS_CTRL_CKEN_STATIC_BIT 9
-+
-+#define SYS_CTRL_RSTEN_ARM_BIT      0
-+#define SYS_CTRL_RSTEN_COPRO_BIT    1
-+#define SYS_CTRL_RSTEN_USBHS_BIT    4
-+#define SYS_CTRL_RSTEN_USBHSPHY_BIT 5
-+#define SYS_CTRL_RSTEN_MAC_BIT      6
-+#define SYS_CTRL_RSTEN_PCI_BIT      7
-+#define SYS_CTRL_RSTEN_DMA_BIT      8
-+#define SYS_CTRL_RSTEN_DPE_BIT      9
-+#define SYS_CTRL_RSTEN_DDR_BIT      10
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+    #define SYS_CTRL_RSTEN_SATA_BIT      11
-+    #define SYS_CTRL_RSTEN_SATA_PHY_BIT  12
-+#elif CONFIG_OXNAS_VERSION_0X810
-+    #define SYS_CTRL_RSTEN_SATA_BIT      11
-+    #define SYS_CTRL_RSTEN_SATA_LINK_BIT 12
-+    #define SYS_CTRL_RSTEN_SATA_PHY_BIT  13
-+#endif
-+
-+#define SYS_CTRL_RSTEN_STATIC_BIT   15
-+#define SYS_CTRL_RSTEN_GPIO_BIT     16
-+#define SYS_CTRL_RSTEN_UART1_BIT    17
-+#define SYS_CTRL_RSTEN_UART2_BIT    18
-+#define SYS_CTRL_RSTEN_MISC_BIT     19
-+#define SYS_CTRL_RSTEN_I2S_BIT      20
-+#define SYS_CTRL_RSTEN_AHB_MON_BIT  21
-+#define SYS_CTRL_RSTEN_UART3_BIT    22
-+#define SYS_CTRL_RSTEN_UART4_BIT    23
-+#define SYS_CTRL_RSTEN_SGDMA_BIT    24
-+#define SYS_CTRL_RSTEN_BUS_BIT      31
-+
-+#define SYS_CTRL_USBHSMPH_IP_POL_A_BIT  0
-+#define SYS_CTRL_USBHSMPH_IP_POL_B_BIT  1
-+#define SYS_CTRL_USBHSMPH_IP_POL_C_BIT  2
-+#define SYS_CTRL_USBHSMPH_OP_POL_A_BIT  3
-+#define SYS_CTRL_USBHSMPH_OP_POL_B_BIT  4
-+#define SYS_CTRL_USBHSMPH_OP_POL_C_BIT  5
-+
-+#define SYS_CTRL_GMAC_RGMII         2
-+#define SYS_CTRL_GMAC_SIMPLE_MAX    1
-+#define SYS_CTRL_GMAC_CKEN_GTX      0
-+
-+#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT 0
-+#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS 4
-+
-+#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_ENABLE    16
-+#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_STATE     15
-+#define SYS_CTRL_USBHSPHY_ATE_ESET                  14
-+#define SYS_CTRL_USBHSPHY_TEST_DIN                   6
-+#define SYS_CTRL_USBHSPHY_TEST_ADD                   2
-+#define SYS_CTRL_USBHSPHY_TEST_DOUT_SEL              1
-+#define SYS_CTRL_USBHSPHY_TEST_CLK                   0
-+
-+#define SYS_CTRL_UART2_DEQ_EN       0
-+#define SYS_CTRL_UART3_DEQ_EN       1
-+#define SYS_CTRL_UART3_IQ_EN        2
-+#define SYS_CTRL_UART4_IQ_EN        3
-+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
-+
-+/* DDR core registers */
-+#define DDR_CFG_REG     (DDR_REGS_BASE + 0x00)
-+#define DDR_BLKEN_REG   (DDR_REGS_BASE + 0x04)
-+#define DDR_STAT_REG    (DDR_REGS_BASE + 0x08)
-+#define DDR_CMD_REG     (DDR_REGS_BASE + 0x0C)
-+#define DDR_AHB_REG     (DDR_REGS_BASE + 0x10)
-+#define DDR_DLL_REG     (DDR_REGS_BASE + 0x14)
-+#define DDR_MON_REG     (DDR_REGS_BASE + 0x18)
-+#define DDR_DIAG_REG    (DDR_REGS_BASE + 0x1C)
-+#define DDR_DIAG2_REG   (DDR_REGS_BASE + 0x20)
-+#define DDR_IOC_REG     (DDR_REGS_BASE + 0x24)
-+#define DDR_ARB_REG     (DDR_REGS_BASE + 0x28)
-+#define DDR_AHB2_REG    (DDR_REGS_BASE + 0x2C)
-+#define DDR_BUSY_REG    (DDR_REGS_BASE + 0x30)
-+#define DDR_TIMING0_REG (DDR_REGS_BASE + 0x34)
-+#define DDR_TIMING1_REG (DDR_REGS_BASE + 0x38)
-+#define DDR_TIMING2_REG (DDR_REGS_BASE + 0x3C)
-+#define DDR_AHB3_REG    (DDR_REGS_BASE + 0x40)
-+#define DDR_AHB4_REG    (DDR_REGS_BASE + 0x44)
-+#define DDR_PHY0_REG    (DDR_REGS_BASE + 0x48)
-+#define DDR_PHY1_REG    (DDR_REGS_BASE + 0x4C)
-+#define DDR_PHY2_REG    (DDR_REGS_BASE + 0x50)
-+#define DDR_PHY3_REG    (DDR_REGS_BASE + 0x54)
-+
-+/* DDR core register field definitions */
-+#define DDR_BLKEN_CLIENTS_BIT       0
-+#define DDR_BLKEN_CLIENTS_NUM_BITS  16
-+#define DDR_BLKEN_DDR_BIT           31
-+
-+#define DDR_AHB_FLUSH_RCACHE_BIT       0
-+#define DDR_AHB_FLUSH_RCACHE_NUM_BITS  16
-+
-+#define DDR_AHB_FLUSH_RCACHE_ARMD_BIT  0
-+#define DDR_AHB_FLUSH_RCACHE_ARMI_BIT  1
-+#define DDR_AHB_FLUSH_RCACHE_COPRO_BIT 2
-+#define DDR_AHB_FLUSH_RCACHE_DMAA_BIT  3
-+#define DDR_AHB_FLUSH_RCACHE_DMAB_BIT  4
-+#define DDR_AHB_FLUSH_RCACHE_PCI_BIT   5
-+#define DDR_AHB_FLUSH_RCACHE_GMAC_BIT  6
-+#define DDR_AHB_FLUSH_RCACHE_USB_BIT   7
-+
-+#define DDR_AHB_NO_RCACHE_BIT       16
-+#define DDR_AHB_NO_RCACHE_NUM_BITS  16
-+
-+#define DDR_AHB_NO_RCACHE_ARMD_BIT  16
-+#define DDR_AHB_NO_RCACHE_ARMI_BIT  17
-+#define DDR_AHB_NO_RCACHE_COPRO_BIT 18
-+#define DDR_AHB_NO_RCACHE_DMAA_BIT  19
-+#define DDR_AHB_NO_RCACHE_DMAB_BIT  20
-+#define DDR_AHB_NO_RCACHE_PCI_BIT   21
-+#define DDR_AHB_NO_RCACHE_GMAC_BIT  22
-+#define DDR_AHB_NO_RCACHE_USB_BIT   23
-+
-+#define DDR_MON_CLIENT_BIT          0
-+#define DDR_MON_ALL_BIT             4
-+
-+#define DDR_DIAG_HOLDOFFS_BIT       20
-+#define DDR_DIAG_HOLDOFFS_NUM_BITS  12
-+#define DDR_DIAG_WRITES_BIT         10
-+#define DDR_DIAG_WRITES_NUM_BITS    10
-+#define DDR_DIAG_READS_BIT          0
-+#define DDR_DIAG_READS_NUM_BITS     10
-+
-+#define DDR_DIAG2_DIRCHANGES_BIT        0
-+#define DDR_DIAG2_DIRCHANGES_NUM_BITS   10
-+
-+#define DDR_ARB_DATDIR_NCH_BIT  0
-+#define DDR_ARB_DATDIR_EN_BIT   1
-+#define DDR_ARB_REQAGE_EN_BIT   2
-+#define DDR_ARB_LRUBANK_EN_BIT  3
-+#define DDR_ARB_MIDBUF_BIT      4
-+
-+#define DDR_AHB2_IGNORE_HPROT_BIT       0
-+#define DDR_AHB2_IGNORE_HPROT_NUM_BITS  16
-+
-+#define DDR_AHB2_IGNORE_HPROT_ARMD_BIT  0
-+#define DDR_AHB2_IGNORE_HPROT_ARMI_BIT  1
-+#define DDR_AHB2_IGNORE_HPROT_COPRO_BIT 2
-+#define DDR_AHB2_IGNORE_HPROT_DMAA_BIT  3
-+#define DDR_AHB2_IGNORE_HPROT_DMAB_BIT  4
-+#define DDR_AHB2_IGNORE_HPROT_PCI_BIT   5
-+#define DDR_AHB2_IGNORE_HPROT_GMAC_BIT  6
-+#define DDR_AHB2_IGNORE_HPROT_USB_BIT   7
-+
-+#define DDR_AHB2_IGNORE_WRAP_BIT        16
-+#define DDR_AHB2_IGNORE_WRAP_NUM_BITS   16
-+
-+#define DDR_AHB2_IGNORE_WRAP_ARMD_BIT  16
-+#define DDR_AHB2_IGNORE_WRAP_ARMI_BIT  17
-+#define DDR_AHB2_IGNORE_WRAP_COPRO_BIT 18
-+#define DDR_AHB2_IGNORE_WRAP_DMAA_BIT  19
-+#define DDR_AHB2_IGNORE_WRAP_DMAB_BIT  20
-+#define DDR_AHB2_IGNORE_WRAP_PCI_BIT   21
-+#define DDR_AHB2_IGNORE_WRAP_GMAC_BIT  22
-+#define DDR_AHB2_IGNORE_WRAP_US_BIT    23
-+
-+#define DDR_AHB3_DIS_BURST_BIT          0
-+#define DDR_AHB3_DIS_BURST_NUM_BITS     16
-+
-+#define DDR_AHB3_DIS_BURST_ARMD_BIT     0
-+#define DDR_AHB3_DIS_BURST_ARMI_BIT     1
-+#define DDR_AHB3_DIS_BURST_COPRO_BIT    2
-+#define DDR_AHB3_DIS_BURST_DMAA_BIT     3
-+#define DDR_AHB3_DIS_BURST_DMAB_BIT     4
-+#define DDR_AHB3_DIS_BURST_PCI_BIT      5
-+#define DDR_AHB3_DIS_BURST_GMAC_BIT     6
-+#define DDR_AHB3_DIS_BURST_USB_BIT      7
-+
-+#define DDR_AHB3_DIS_NONCACHE_BIT       16
-+#define DDR_AHB3_DIS_NONCACHE_NUM_BITS  16
-+
-+#define DDR_AHB3_DIS_NONCACHE_ARMD_BIT  16
-+#define DDR_AHB3_DIS_NONCACHE_ARMI_BIT  17
-+#define DDR_AHB3_DIS_NONCACHE_COPRO_BIT 18
-+#define DDR_AHB3_DIS_NONCACHE_DMAA_BIT  19
-+#define DDR_AHB3_DIS_NONCACHE_DMAB_BIT  20
-+#define DDR_AHB3_DIS_NONCACHE_PCI_BIT   21
-+#define DDR_AHB3_DIS_NONCACHE_GMAC_BIT  22
-+#define DDR_AHB3_DIS_NONCACHE_USB_BIT   23
-+
-+#define DDR_AHB4_EN_TIMEOUT_BIT        0
-+#define DDR_AHB4_EN_TIMEOUT_NUM_BITS   16
-+
-+#define DDR_AHB4_EN_TIMEOUT_ARMD_BIT   0
-+#define DDR_AHB4_EN_TIMEOUT_ARMI_BIT   1
-+#define DDR_AHB4_EN_TIMEOUT_COPRO_BIT  2
-+#define DDR_AHB4_EN_TIMEOUT_DMAA_BIT   3
-+#define DDR_AHB4_EN_TIMEOUT_DMAB_BIT   4
-+#define DDR_AHB4_EN_TIMEOUT_PCI_BIT    5
-+#define DDR_AHB4_EN_TIMEOUT_GMAC_BIT   6
-+#define DDR_AHB4_EN_TIMEOUT_USB_BIT    7
-+
-+#define DDR_AHB4_EN_WRBEHIND_BIT       16
-+#define DDR_AHB4_EN_WRBEHIND_NUM_BITS  16
-+
-+#define DDR_AHB4_EN_WRBEHIND_ARMD_BIT  16
-+#define DDR_AHB4_EN_WRBEHIND_ARMI_BIT  17
-+#define DDR_AHB4_EN_WRBEHIND_COPRO_BIT 18
-+#define DDR_AHB4_EN_WRBEHIND_DMAA_BIT  19
-+#define DDR_AHB4_EN_WRBEHIND_DMAB_BIT  20
-+#define DDR_AHB4_EN_WRBEHIND_PCI_BIT   21
-+#define DDR_AHB4_EN_WRBEHIND_GMAC_BIT  22
-+#define DDR_AHB4_EN_WRBEHIND_USB_BIT   23
-+
-+/* AHB monitor base addresses */
-+#define AHB_MON_ARM_D (AHB_MON_BASE + 0x00000)
-+#define AHB_MON_ARM_I (AHB_MON_BASE + 0x10000)
-+#define AHB_MON_DMA_A (AHB_MON_BASE + 0x20000)
-+#define AHB_MON_DMA_B (AHB_MON_BASE + 0x30000)
-+#define AHB_MON_LEON  (AHB_MON_BASE + 0x40000)
-+#define AHB_MON_USB   (AHB_MON_BASE + 0x50000)
-+#define AHB_MON_MAC   (AHB_MON_BASE + 0x60000)
-+#define AHB_MON_PCI   (AHB_MON_BASE + 0x70000)
-+
-+/* AHB write monitor registers */
-+#define AHB_MON_MODE_REG_OFFSET         0x00
-+#define AHB_MON_HWRITE_REG_OFFSET       0x04
-+#define AHB_MON_HADDR_LOW_REG_OFFSET    0x08
-+#define AHB_MON_HADDR_HIGH_REG_OFFSET   0x0C
-+#define AHB_MON_HBURST_REG_OFFSET       0x10
-+#define AHB_MON_HPROT_REG_OFFSET        0x14
-+
-+/* AHB monitor write register field definitions */
-+#define AHB_MON_MODE_MODE_BIT           0
-+#define AHB_MON_MODE_MODE_NUM_BITS      2
-+#define AHB_MON_HWRITE_COUNT_BIT        0
-+#define AHB_MON_HWRITE_COUNT_NUM_BITS   2
-+#define AHB_MON_HBURST_MASK_BIT         0
-+#define AHB_MON_HBURST_MASK_NUM_BITS    3
-+#define AHB_MON_HBURST_MATCH_BIT        4
-+#define AHB_MON_HBURST_MATCH_NUM_BITS   3
-+#define AHB_MON_HPROT_MASK_BIT          0
-+#define AHB_MON_HPROT_MASK_NUM_BITS     4
-+#define AHB_MON_HPROT_MATCH_BIT         4
-+#define AHB_MON_HPROT_MATCH_NUM_BITS    4
-+
-+#ifndef __ASSEMBLY__
-+typedef enum AHB_MON_MODES {
-+    AHB_MON_MODE_IDLE,
-+    AHB_MON_MODE_ACTIVE,
-+    AHB_MON_MODE_RESET
-+} AHB_MON_MODES_T;
-+
-+typedef enum AHB_MON_HWRITE {
-+    AHB_MON_HWRITE_INACTIVE,
-+    AHB_MON_HWRITE_WRITES,
-+    AHB_MON_HWRITE_READS,
-+    AHB_MON_HWRITE_READS_AND_WRITES
-+} AHB_MON_HWRITE_T;
-+
-+typedef enum AHB_MON_HBURST {
-+    AHB_MON_HBURST_SINGLE,
-+    AHB_MON_HBURST_INCR,
-+    AHB_MON_HBURST_WRAP4,
-+    AHB_MON_HBURST_INCR4,
-+    AHB_MON_HBURST_WRAP8,
-+    AHB_MON_HBURST_INCR8,
-+    AHB_MON_HBURST_WRAP16,
-+    AHB_MON_HBURST_INCR16
-+} AHB_MON_HBURST_T;
-+#endif // __ASSEMBLY__
-+
-+/* AHB read monitor registers */
-+#define AHB_MON_CYCLES_REG_OFFSET       0x00
-+#define AHB_MON_TRANSFERS_REG_OFFSET    0x04
-+#define AHB_MON_WAITS_REG_OFFSET        0x08
-+
-+#define STATIC_BUS1_CONTROL_VALUE   0x04010484  /*  200nS rd/wr cycles to allow DMAing to SMC91x on static bus */
-+
-+/* PCI bus definitions */
-+#define pcibios_assign_all_busses() 1
-+#define PCIBIOS_MIN_IO              0x1000      /* used for memory alignememnt guesstimate */
-+#define PCIBIOS_MIN_MEM             0x00100000  /* used for memory alignememnt guesstimate */
-+
-+/* PCI bus commands - see pci spec */
-+#define PCI_BUS_CMD_INTERRUPT_ACKNOWLEDGE       0x00  
-+#define PCI_BUS_CMD_SPECIAL_CYCLE               0x01  
-+#define PCI_BUS_CMD_IO_READ                     0x02  
-+#define PCI_BUS_CMD_IO_WRITE                    0x03  
-+/*#define PCI_BUS_RESERVED                      0x04  */  
-+/*#define PCI_BUS_RESERVED                      0x05  */  
-+#define PCI_BUS_CMD_MEMORY_READ                 0x06  
-+#define PCI_BUS_CMD_MEMORY_WRITE                0x07  
-+/*#define PCI_BUS_RESERVED                      0x08  */
-+/*#define PCI_BUS_RESERVED                      0x09  */
-+#define PCI_BUS_CMD_CONFIGURATION_READ          0x0a  
-+#define PCI_BUS_CMD_CONFIGURATION_WRITE         0x0b  
-+#define PCI_BUS_CMD_MEMORY_READ_MULTIPLE        0x0c  
-+#define PCI_BUS_CMD_DUAL_ADDRESS_CYCLE          0x0d  
-+#define PCI_BUS_CMD_MEMORY_READ_LINE            0x0e  
-+#define PCI_BUS_CMD_MEMORY_WRITE_AND_INVALIDATE 0x0f  
-+
-+/* synopsis PCI core register set */
-+#define PCI_CORE_REG_START                     PCI_CSRS_BASE
-+#define PCI_CRP_CMD_AND_ADDR                   PCI_CORE_REG_START
-+#define PCI_CRP_WRITE_DATA                    (PCI_CRP_CMD_AND_ADDR       + 4)
-+#define PCI_CRP_READ_DATA                     (PCI_CRP_WRITE_DATA         + 4)
-+#define PCI_CONFIG_IO_CYCLE_ADDR              (PCI_CRP_READ_DATA          + 4)
-+#define PCI_CONFIG_IO_BYTE_CMD                (PCI_CONFIG_IO_CYCLE_ADDR   + 4)
-+#define PCI_CONFIG_IO_WRITE_DATA              (PCI_CONFIG_IO_BYTE_CMD     + 4)
-+#define PCI_CONFIG_IO_READ_DATA               (PCI_CONFIG_IO_WRITE_DATA   + 4)
-+#define PCI_ERROR_MSG                         (PCI_CONFIG_IO_READ_DATA    + 4)
-+#define PCI_TRANS_ERROR_START_ADDR            (PCI_ERROR_MSG              + 4)
-+#define PCI_AHB_ERROR_LSB                     (PCI_TRANS_ERROR_START_ADDR + 4)
-+#define PCI_AHB_ERROR_START_ADDR              (PCI_AHB_ERROR_LSB          + 4)
-+#define PCI_FLUSH_FIFO_ON_ERR                 (PCI_AHB_ERROR_START_ADDR   + 4)
-+#define PCI_TAR_ID                            (PCI_FLUSH_FIFO_ON_ERR      + 4)
-+#define PCI_MAS_ID_IN                         (PCI_TAR_ID                 + 4)
-+#define PCI_CORE_REG_END                      (PCI_MAS_ID_IN              + 4)
-+
-+/* register bit offsets */
-+#define PCI_CRP_ADDRESS_START                   0
-+#define PCI_CRP_ADDRESS_END                     10
-+#define PCI_CRP_CMD_START                       16
-+#define PCI_CRP_CMD_END                         19
-+#define PCI_CRP_BYTE_ENABLES_START              20
-+#define PCI_CRP_BYTE_ENABLES_END                23
-+
-+#define PCI_CONFIG_IO_CMD_START                 0
-+#define PCI_CONFIG_IO_CMD_END                   3
-+#define PCI_CONFIG_IO_BYTE_ENABLES_START        4
-+#define PCI_CONFIG_IO_BYTE_ENABLES_END          7
-+
-+#define PCI_ERR_MESSAGE_START                   0
-+#define PCI_ERR_MESSAGE_END                     1
-+
-+#define PCI_AHB_ERR_BIT                         0
-+
-+#define PCI_FLUSH_FIFO_ON_ERR_BIT               0
-+
-+#define PCI_TAR_ID_START                        0
-+#define PCI_TAR_ID_END                          2
-+
-+#define PCI_MAS_ID_IN_START                     0
-+#define PCI_MAS_ID_IN_END                       2
-+
-+/* PWM register definitions */
-+#define PWM_DATA_REGISTER_BASE (PWM_BASE)
-+#define PWM_CLOCK_REGISTER  (PWM_BASE+0X400)
-+
-+#endif // __ASM_ARCH_HARDWARE_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,1023 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/i2s.h
-+ * 
-+ * 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_ARM_ARCH_I2S_H
-+#define __ASM_ARM_ARCH_I2S_H
-+
-+#include "hardware.h"
-+
-+/* Routines ----------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+extern void DumpI2SRegisters(void);
-+
-+
-+
-+/* Registers ---------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+
-+#define    TX_CONTROL                      (0x0000 + I2S_BASE)
-+#define    TX_SETUP                        (0x0004 + I2S_BASE)
-+#define    TX_SETUP1                       (0x0008 + I2S_BASE)
-+#define    TX_STATUS                       (0x000C + I2S_BASE)
-+#define    RX_CONTROL                      (0x0010 + I2S_BASE)
-+#define    RX_SETUP                        (0x0014 + I2S_BASE)
-+#define    RX_SETUP1                       (0x0018 + I2S_BASE)
-+#define    RX_STATUS                       (0x001C + I2S_BASE)
-+#define    TX_DEBUG                        (0x0020 + I2S_BASE)
-+#define    TX_DEBUG2                       (0x0024 + I2S_BASE)
-+#define    TX_DEBUG3                       (0x0028 + I2S_BASE)
-+#define    RX_DEBUG_                       (0x0030 + I2S_BASE)
-+#define    RX_DEBUG2                       (0x0034 + I2S_BASE)
-+#define    RX_DEBUG3                       (0x0038 + I2S_BASE)
-+#define    TX_BUFFER_LEVEL                 (0x0040 + I2S_BASE)
-+#define    TX_BUFFER_INTERRUPT_LEVEL       (0x0048 + I2S_BASE)
-+#define    RX_BUFFER_LEVEL                 (0x0050 + I2S_BASE)
-+#define    RX_BUFFER_INTERRUPT_LEVEL       (0x0058 + I2S_BASE)
-+#define    RX_SPDIF_DEBUG                  (0x0070 + I2S_BASE)
-+#define    RX_SPDIF_DEBUG2                 (0x0074 + I2S_BASE)
-+#define    INTERRUPT_CONTROL_STATUS        (0x0080 + I2S_BASE)
-+#define    INTERRUPT_MASK                  (0x0084 + I2S_BASE)
-+#define    VERSION                         (0x008C + I2S_BASE)
-+#define    TX_DATA_IN_FORMAT               (0x0100 + I2S_BASE)
-+#define    TX_CHANNELS_ENABLE              (0x0104 + I2S_BASE)
-+#define    TX_WRITES_TO                    (0x0108 + I2S_BASE)
-+#define    RX_DATA_OUT_FORMAT              (0x0200 + I2S_BASE)
-+#define    RX_CHANNELS_ENABLE              (0x0204 + I2S_BASE)
-+#define    RX_READS_FROM                   (0x0208 + I2S_BASE)
-+#define    TX_CPU_DATA_WRITES_ALT          (0x04FF + I2S_BASE)
-+#define    RX_CPU_DATA_READS_ALT           (0x08FF + I2S_BASE)
-+#define    TX_CPU_DATA_WRITES              (0x1FFF + I2S_BASE)
-+#define    RX_CPU_DATA_READS               (0x2FFF + I2S_BASE)
-+
-+
-+
-+/* TX_CONTROL ------------ */
-+#define    TX_CONTROL_ENABLE                0
-+    /**
-+     * 0 - Audio transmit is disabled 
-+     * 1 - Audio transmit is enabled. 
-+     */
-+#define    TX_CONTROL_FLUSH                 1
-+    /**
-+     * 0 - Normal Operation 
-+     * 1 - Flush TX buffer 
-+     */
-+#define    TX_CONTROL_MUTE                  2
-+    /**
-+     * 0 - Normal Operation 
-+     * 1 - Muted operation 
-+     */
-+#define    TX_CONTROL_TRICK                 3
-+    /**
-+     *     (UNTESTED FEATURE)   
-+     * 0 - Trickplay features disabled 
-+     * 1 - Trickplay features enabled 
-+     */
-+#define    TX_CONTROL_SPEED                 4
-+    /**
-+     *  (UNTESTED FEATURE)  
-+     * 00 - Quarter speed playback    - DOESN’T WORK 
-+     * 01 - Half speed playback       - DOESN’T WORK 
-+     * 10 - Double speed playback 
-+     * 11 - Quadruple speed playback. 
-+     */
-+    #define QUARTER_SPEED_PLAYBACK          0x00 
-+    #define HALF_SPEED_PLAYBACK             0x01 
-+    #define DOUBLE_SPEED_PLAYBACK           0x02 
-+    #define QUADRUPLE_SPEED_PLAYBACK        0x03 
-+#define    TX_CONTROL_ABORT_DMA             6    
-+    /**
-+     * Write a 1 to abort any outstanding DMAs (self-clearing)     
-+     */
-+#define    TX_CONTROL_AHB_ENABLE            8
-+    /**
-+     * 0 - AHB disabled (APB only) 
-+     * 1 - AHB enabled (APB disabled for data plane) 
-+     */
-+#define    TX_CONTROL_QUAD_BURSTS           9
-+    /**
-+     * 0 - DMA transfers up to Single Quads 
-+     * 1 - DMA transfers up to Bursts of 4 Quads 
-+     */
-+    
-+    
-+/* TX_SETUP ------------ */ 
-+/**
-+ * In order for the changes made to the fields in bold to propagate to the Tx  
-+ * audio clock domain, a write must be performed to TX_SETUP1  And the TX_CLK   
-+ * must be running. 
-+ */
-+
-+#define    TX_SETUP_FORMAT                  0  
-+    /**
-+     * 00 - True/Early-I2S (standard format) 
-+     * 01 - Late-I2S 
-+     * 10 - MP3 Valid 
-+     * 11 - MP3 Start 
-+     */
-+    #define TRUE_I2S                        0x00
-+    #define LATE_I2S                        0x01
-+    #define MP3_VALID                       0x02
-+    #define MP3_START                       0x03
-+#define    TX_SETUP_MODE                    2
-+    /**
-+     * 0 - Slave 
-+     * 1 - Master 
-+     */
-+    #define I2S_SLAVE                       0x00
-+    #define I2S_MASTER                      0x01
-+#define    TX_SETUP_FLOW_INVERT             3
-+    /**
-+     * 0 - Flow Control is active high  
-+     *     (ie. Audio core is held off when TX_FLOW_CONTROL=’1’) 
-+     * 1 - Flow Control is active low 
-+     *     (ie. Audio core is held off when TX_FLOW_CONTROL=’0’) 
-+     */
-+    #define FLOW_CONTROL_ACTIVE_HIGH        0
-+    #define FLOW_CONTROL_ACTIVE_LOW         1
-+#define    TX_SETUP_POS_EDGE                4
-+    /**
-+     * 0 - Data is output on the negative edge of the TX Audio clock 
-+     * 1 - Data is output on the positive edge of the TX Audio clock 
-+     */
-+#define    TX_SETUP_CLOCK_STOP              5
-+    /**
-+     * 0 - Audio TX clock should not be stopped during flow control hold off 
-+     * 1 - Audio TX clock should be stopped during flow control hold off 
-+     */
-+#define    TX_SETUP_SPLIT_QUAD              6
-+    /**
-+     * 0 - No splitting 
-+     * 1 - Split quadlet into two 16 bit samples - NOT VALID FOR S/PDIF 
-+     */
-+#define    TX_SETUP_INSPECT_WORD_CLOCK      7
-+    /**
-+     * Used when recovering from underrun. This bit is set to look for either  
-+     * a high or low word clock before the hardware carries on as normal. 
-+     */
-+#define    TX_SETUP_SPDIF_EN                8
-+    /**
-+     * 0 - No SPDIF on Channel 0 (disables biphase coding on output) 
-+     * 1 - SPDIF on Channel 0 (enables the biphase coding even when Tx disabled) 
-+     */
-+
-+ 
-+/* TX_SETUP1 ------------ */
-+#define    TX_SETUP1_INPUT                  0    
-+    /**
-+     * 00 - Twos Compliment (pass-thru) 
-+     * 01 - Offset Binary 
-+     * 10 - Sign Magnitude 
-+     * 11 - Reserved 
-+     */
-+    #define TWOS_COMPLIMENT                 0x00
-+    #define OFFSET_BINARY                   0x01
-+    #define SIGN_MAGNITUDE                  0x02
-+    #define RESERVED                        0x03
-+#define    TX_SETUP1_REVERSE                2
-+    /**
-+     * 0 - Normal operation 
-+     * 1 - Reverse Stereo        - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3 
-+     */
-+#define    TX_SETUP1_INVERT                 3
-+    /**
-+     * 0 - Normal operation 
-+     * 1 - Inverted word clock 
-+     */
-+#define    TX_SETUP1_BIG_ENDIAN             4
-+    /**
-+     * 0 - System data is in little endian format 
-+     * 1 - System data is in big endian format 
-+     */
-+#define    TX_SETUP1_QUAD_ENDIAN            5
-+    /**
-+     * 0 - System data is 16 bit. 
-+     * 1 - System data is 32 bit 
-+     */
-+#define    TX_SETUP1_QUAD_SAMPLES           6
-+    /**
-+     * 0 - I2S Master word clock uses 16 bit samples    - NOT VALID FOR S/PDIF 
-+     * 1 - I2S Master word clock uses 32 bit samples 
-+     */
-+#define    TX_SETUP1_FLOW_CONTROL           7
-+    /**
-+     * 0 - No flow control (MP3 only) 
-+     * 1 - Flow control (MP3 only) 
-+     */
-+
-+/* TX_STATUS ------------ */
-+#define    TX_STATUS_UNDERRUN               0
-+    /**
-+     * 0 - Underrun has not occurred. 
-+     * 1 - Underrun has occurred. (Note that this bit must be written to with  
-+     *     a ‘1’ to clear) 
-+     */
-+#define    TX_STATUS_OVERRUN                1
-+    /**
-+     * 0 - Overrun has not occurred. 
-+     * 1 - Overrun has occurred. (Note that this bit must be written to with  
-+     *     a ‘1’ to clear) 
-+     */
-+#define    TX_STATUS_FIFO_UNDERRUN          2
-+    
-+    /**
-+     * 0 - FIFO Underrun has not occurred. 
-+     * 1 - FIFO Underrun has occurred. (Note that this bit must be written to  
-+     *     with a ‘1’ to clear) 
-+     */
-+#define    TX_STATUS_FIFO_OVERRUN           3    
-+    /**
-+     * 0 - FIFO Overrun has not occurred. 
-+     * 1 - FIFO Overrun has occurred. (Note that this bit must be written to  
-+     *     with a ‘1’ to clear) 
-+     */
-+#define    TX_STATUS_HW_READ                8
-+    /**
-+     * 0 - H/W Read of FIFO has not occurred. 
-+     * 1 - H/W Read of FIFO has occurred. (Note that this bit must be written  
-+     *     to with a ‘1’ to clear) 
-+     */
-+#define    TX_STATUS_BUFFER_LEVEL_MET       9
-+    /**
-+     * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL. 
-+     * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL 
-+     */
-+
-+ 
-+/* RX_CONTROL ------------ */
-+#define    RX_CONTROL_ENABLE                0
-+    /**
-+     * 0 - Audio receive is disabled 
-+     * 1 - Audio receive is enabled. 
-+     */
-+#define    RX_CONTROL_FLUSH                 1
-+    /**
-+     * 0 - Normal Operation 
-+     * 1 - Flush RX buffer 
-+     */
-+#define    RX_CONTROL_MUTE                  2
-+    /**
-+     * 0 - Normal Operation 
-+     * 1 - Muted operation 
-+     */
-+#define    RX_CONTROL_TRICK                 3
-+    /**
-+     * (UNTESTED FEATURE) 
-+     * 0 - Trickplay features disabled 
-+     * 1 - Trickplay features enabled 
-+     */
-+#define    RX_CONTROL_SPEED                 4   
-+    /**
-+     * (UNTESTED FEATURE) 
-+     * 00 - Quarter speed playback     - DOESN’T WORK 
-+     * 01 - Half speed playback        - DOESN’T WORK 
-+     * 10 - Double speed playback 
-+     * 11 - Quadruple speed playback. 
-+     */
-+#define    RX_CONTROL_ABORT_DMA             6
-+    /**
-+     * Write a 1 to abort any outstanding DMAs (self-clearing)  
-+     */
-+#define    RX_CONTROL_AHB_ENABLE            8    
-+    /**
-+     * 0 - AHB disabled (APB only) 
-+     * 1 - AHB enabled (APB disabled for data plane) 
-+     */
-+#define    RX_CONTROL_QUAD_BURSTS           9
-+    /**
-+     * 0 - DMA transfers up to Single Quads 
-+     * 1 - DMA transfers up to Bursts of 4 Quads 
-+     */
-+
-+    
-+/* RX_SETUP ------------ */ 
-+/**
-+ * In order for the changes made to the fields in bold to propagate to the Rx 
-+ * audio clock domain, a write must be performed to RX_SETUP1  And the RX_CLK 
-+ * must be running. 
-+ */
-+
-+#define    RX_SETUP_FORMAT                  0   
-+    /**
-+     * 00 - True/Early-I2S (standard format) 
-+     * 01 - Late-I2S 
-+     * 10 - MP3 Valid 
-+     * 11 - MP3 Start 
-+     */
-+#define    RX_SETUP_MODE                    2
-+    /**
-+     * 0 - Slave 
-+     * 1 - Master - NOT VALID FOR S/PDIF 
-+     */
-+#define    RX_SETUP_POS_EDGE                4
-+    /**
-+     * 0 - Data is output on the negative edge of the RX Audio clock 
-+     * 1 - Data is output on the positive edge of the RX Audio clock 
-+     */
-+#define    RX_SETUP_COMBINE_QUAD            6
-+    /**
-+     * 0 - No combining 
-+     * 1 - Combine two 16 bit samples into single quadlet - NOT VALID FOR S/PDIF 
-+     */
-+#define    RX_SETUP_INSPECT_WORD_CLOCK      7
-+    /**
-+     * Used when recovering from overrun. This bit is set to look for either  
-+     * a high or low word clock before the hardware carries on as normal.   
-+     */
-+#define    RX_SETUP_SPDIF_EN                8
-+    /**
-+     * 0 - No SPDIF on Channel 0 (disables biphase decoding and clk recovery on input) 
-+     * 1 - SPDIF on Channel 0 (enables the biphase decoding and clk recovery even when Rx disabled) 
-+     */
-+#define    RX_SETUP_SPDIF_DEBUG_EN          9
-+    /**
-+     * Provides direct control over RX_SPDIF_OE  Output signal 
-+     */
-+
-+ 
-+/* RX_SETUP1 ------------ */
-+#define    RX_SETUP1_INPUT                  0       
-+    /**
-+     * 00 - Twos Compliment (pass-thru) 
-+     * 01 - Offset Binary 
-+     * 10 - Sign Magnitude 
-+     * 11 - Reserved 
-+     */
-+#define    RX_SETUP1_REVERSE                2
-+    /**
-+     * 0 - Normal operation 
-+     * 1 - Reverse Stereo - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3 
-+     */
-+#define    RX_SETUP1_INVERT                 3
-+    /**
-+     * 0 - Normal operation 
-+     * 1 - Inverted word clock 
-+     */
-+#define    RX_SETUP1_BIG_ENDIAN             4
-+    /**
-+     * 0 - System data is in little endian format 
-+     * 1 - System data is in big endian format 
-+     */
-+#define    RX_SETUP1_QUAD_ENDIAN            5
-+    /**
-+     * 0 - System data is 16 bit. 
-+     * 1 - System data is 32 bit 
-+     */
-+#define    RX_SETUP1_QUAD_SAMPLES           6
-+    /**
-+     * 0 - I2S Master word clock uses 16 bit samples    - NOT VALID FOR S/PDIF 
-+     * 1 - I2S Master word clock uses 32 bit samples 
-+     */
-+
-+    
-+/* RX_STATUS ------------ */
-+#define    RX_STATUS_UNDERRUN               0
-+    /**
-+     * 0 - Underrun has not occurred. 
-+     * 1 - Underrun has occurred. (Note that this bit must be written to with
-+     *     a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_OVERRUN                1
-+    /**
-+     * 0 - Overrun has not occurred. 
-+     * 1 - Overrun has occurred. (Note that this bit must be written to with
-+     *     a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_FIFO_UNDERRUN          2
-+    /**
-+     * 0 - FIFO Underrun has not occurred. 
-+     * 1 - FIFO Underrun has occurred. (Note that this bit must be written to 
-+     *     with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_FIFO_OVERRUN           3
-+    /**
-+     * 0 - FIFO Overrun has not occurred. 
-+     * 1 - FIFO Overrun has occurred. (Note that this bit must be written to 
-+     *     with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_SPDIF_PARITY_ERROR     4
-+    /**
-+     * 0 - Rx S/PDIF Parity Error has not occurred. 
-+     * 1 - Rx S/PDIF Parity Error has occurred. (Note that this bit must be 
-+     *     written to with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_SPDIF_PREAMBLE_ERROR   5
-+    /**
-+     * 0 - Rx S/PDIF Preamble Error has not occurred. 
-+     * 1 - Rx S/PDIF Preamble Error has occurred. (Note that this bit must be 
-+     *     written to with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_SPDIF_FRAMING_ERROR    6
-+    /**
-+     * 0 - Rx S/PDIF Framing Error has not occurred. 
-+     * 1 - Rx S/PDIF Framing Error has occurred. (Note that this bit must be 
-+     *     written to with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_SPDIF_LOCK_EVENT       7
-+    /**
-+     * 0 - Rx S/PDIF Lock status has not changed. 
-+     * 1 - Rx S/PDIF Lock status has changed. (Note that this bit must be 
-+     *     written to with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_HW_WRITE               8
-+    /**
-+     * 0 - H/W Write of FIFO has not occurred. 
-+     * 1 - H/W Write of FIFO has occurred. (Note that this bit must be written 
-+     *     to with a ‘1’ to clear) 
-+     */
-+#define    RX_STATUS_BUFFER_LEVEL_MET       9
-+    /**
-+     * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL. 
-+     * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL 
-+     */
-+#define    RX_STATUS_SPDIF_LOCK             10
-+    /**
-+     * 0 - Rx S/PDIF timing is not locked. 
-+     * 1 - Rx S/PDIF timing is locked. 
-+     */
-+
-+ 
-+/* TX_DEBUG ------------ */
-+#define TX_DEBUG_TX_DMA_STATE               0
-+    /**
-+     * 00 - START 
-+     * 01 - IDLE 
-+     * 10 - BURST 
-+     * 11 - NON_ALIGNED 
-+     */
-+#define TX_DEBUG_WRITE_OFFSET               4
-+    /**
-+     * Write Offset Determines the alignment of the writes  
-+     * (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned) 
-+     */
-+#define    TX_DEBUG_TX_DREQ                 31
-+    /**
-+     * Set if DMA request for Tx is set 
-+     */
-+    
-+
-+/* TX_DEBUG2 ------------ */
-+#define TX_DEBUG2_TX_CTRL_STATE             0
-+    /**
-+     * 000 - WAITING 
-+     * 001 - WAITING_HALF 
-+     * 010 - Invalid 
-+     * 011 - WAIT_LEFT 
-+     * 100 - READ_FIFO 
-+     * 101 - WAIT_TILL_DATA_TAKEN 
-+     * 11x - Invalid 
-+     */
-+#define    TX_DEBUG2_FIFO_READER_2ND_STAGE  3
-+    /**
-+     * 0 - First stage (L) of FIFO read 
-+     * 1 - Second stage (R) of FIFO read 
-+     */
-+#define    TX_DEBUG2_FIFO_READER_CHANNEL    4
-+    /**
-+     * Current channel being read from FIFO 
-+     */
-+#define    TX_DEBUG2_NUM_WRITES             8
-+    /**
-+     * Number of writes to be performed every interrupt
-+     */
-+#define    TX_DEBUG2_SAFE_TO_UPDATE_REGS    12
-+    /**
-+     * 0 - Changes to registers will be deferred 
-+     * 1 - Changes to registers will be immediate 
-+     */
-+#define    TX_DEBUG2_WR_DMARQ               13
-+    /**
-+     * 0 - No writes being requested 
-+     * 1 - Writes being requested (=DMA DREQ when using APB) 
-+     */
-+#define    TX_DEBUG2_FIFO_READ_ADDRESS      16
-+    /**
-+     * 19 - 16    Current read pointer of FIFO 
-+     */
-+#define    TX_DEBUG2_FIFO_WRITE_ADDRESS     24
-+    /**
-+     * 27 - 24     Current write pointer of FIFO 
-+     */
-+#define    TX_DEBUG2_WORD_CLK               31
-+    /** 
-+     * State of internal safe TX_WORD_CLK 
-+     */
-+
-+ 
-+/* TX_DEBUG3 ------------ */ 
-+/**
-+ * This register is a read back of status directly from the TX_CLK  domain.   
-+ * For this reason it may be unstable during operation.  Several back-to-back  
-+ * reads might need to be made to get an accurate reflection of the status  
-+ * during operation. 
-+ */
-+
-+#define    TX_DEBUG3_TX_STATE               0
-+    /**
-+     * 000 - DISABLED 
-+     * 001 - WAITING 
-+     * 010 - WAIT_FOR_8 
-+     * 011 - SAMPLE_8 
-+     * 100 - WAIT_FOR_LEFT 
-+     * 101 - SAMPLE_LEFT 
-+     * 110 - WAIT_FOR_RIGHT 
-+     * 111 - SAMPLE_RIGHT 
-+     */
-+#define    TX_DEBUG3_TX_IN_RESET            31
-+    /**
-+     * 0 - Tx domain is out of reset 
-+     * 1 - Tx domain is in reset 
-+     */
-+
-+
-+ 
-+/* RX_DEBUG ------------ */
-+#define    RX_DEBUG_RX_DMA_STATE            0
-+    /**
-+     * 00 - START 
-+     * 01 - IDLE 
-+     * 10 - BURST 
-+     * 11 - NON_ALIGNED 
-+     */
-+#define    RX_DEBUG_READ_OFFSET             4
-+    /**
-+     * 5 - 4  Determines the alignment of the reads  
-+     *        (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned) 
-+     */
-+#define    RX_DEBUG_RX_DREQ                 31
-+    /**
-+     * Set if DMA request for Rx is set 
-+     */
-+
-+    
-+/* RX_DEBUG2 ------------ */
-+#define    RX_DEBUG2_RX_CTRL_STATE          0
-+    /**
-+     * 000 - WAITING 
-+     * 001 - WAITING_HALF 
-+     * 01x - Invalid 
-+     * 100 - WRITE_FIFO 
-+     * 101 - WAIT_TILL_DATA_PUT 
-+     * 11x - Invalid 
-+     */
-+#define    RX_DEBUG2_FIFO_WRITER_2ND_STAGE  3
-+    /**
-+     * 0 - First stage (L) of FIFO write 
-+     * 1 - Second stage (R) of FIFO write 
-+     */
-+#define    RX_DEBUG2_FIFO_WRITER_CHANNEL    4
-+    /**
-+     * 7 - 4  Current channel being written to FIFO 
-+     */
-+#define    RX_DEBUG2_NUM_READS              8
-+    /**
-+     * 11 - 8  Number of reads to be performed every interrupt 
-+     */
-+#define    RX_DEBUG2_SAFE_TO_UPDATE_REGS    12
-+    /**
-+     * 0 - Changes to registers will be deferred 
-+     * 1 - Changes to registers will be immediate 
-+     */
-+#define    RX_DEBUG2_RD_DMARQ               13
-+    /**
-+     * 0 - No reads being requested 
-+     * 1 - Reads being requested (=DMA DREQ when using APB) 
-+     */
-+#define    RX_DEBUG2_FIFO_READ_ADDRESS      16
-+    /**
-+     * 19 - 16   Current read pointer of FIFO 
-+     */
-+#define    RX_DEBUG2_FIFO_WRITE_ADDRESS     24
-+    /**
-+     * 27 - 24   Current write pointer of FIFO 
-+     */
-+#define    RX_DEBUG2_WORD_CLK               31
-+    /**
-+     * State of internal safe RX_WORD_CLK     
-+     */
-+
-+ 
-+/* RX_DEBUG3 ------------ */ 
-+/**
-+ * This register is a read back of status directly from the RX_CLK  domain.   
-+ * For this reason it may be unstable during operation.  Several back-to-back  
-+ * reads might need to be made to get an accurate reflection of the status 
-+ * during operation. 
-+ */
-+
-+#define    RX_DEBUG3_RX_STATE               0
-+    /**
-+     * 000 - DISABLED 
-+     * 001 - WAITING 
-+     * 010 - WAIT_FOR_8 
-+     * 011 - SAMPLE_8 
-+     * 100 - WAIT_FOR_LEFT 
-+     * 101 - SAMPLE_LEFT 
-+     * 110 - WAIT_FOR_RIGHT 
-+     * 111 - SAMPLE_RIGHT 
-+     */
-+#define    RX_DEBUG3_RX_IN_RESET            31
-+    /**
-+     * 0 - Rx domain is out of reset 
-+     * 1 - Rx domain is in reset 
-+     */
-+
-+
-+/**
-+ * VERSION* ------------ 
-+ * Refer to VERSION. ?? 
-+ */
-+
-+ 
-+/* TX_BUFFER_LEVEL ------------ */ 
-+/**
-+ * When this register is read it returns the current fill level of the buffer  
-+ * within the audio core, when a ‘1’ is written to the lower bit, the buffer  
-+ * fill level, read and write pointers are all set to zero. 
-+ * FT - 0    Buffer Level    Fill level of Tx buffer 
-+ */
-+
-+/**
-+ * INTERRUPT_CONTROL* ------------ 
-+ * Refer to INTERRUPT_CONTROL_STATUS. ?? 
-+ */
-+
-+/* TX_BUFFER_INTERRUPT_LEVEL ------------ */ 
-+/**
-+ * FT - 0    Interrupt Level    Programmable Buffer Level to initiate Interrupt 
-+ */
-+
-+
-+/* RX_BUFFER_LEVEL ------------ */ 
-+/**
-+ * When this register is read it returns the current fill level of the buffer 
-+ * within the audio core, when a ‘1’ is written to the lower bit, the buffer  
-+ * fill level, read and write pointers are all set to zero. 
-+ * FR - 0    Buffer Level    Fill level of Rx buffer 
-+ */
-+
-+
-+/* RX_BUFFER_INTERRUPT_LEVEL ------------ */ 
-+/**
-+ * FR - 0    Interrupt Level    Programmable Buffer Level to initiate Interrupt 
-+ */
-+
-+ 
-+/* RX_SPDIF_DEBUG ------------ */
-+#define    RX_SPDIF_DEBUG_MAX_PULSE         0
-+    /**
-+     * 7 - 0    Number of cycles of RX_SPDIF_OSAMP_CLK  in maximum pulse width  
-+     *          detected (=1.5x BIT_CLK) 
-+     */
-+#define    RX_SPDIF_DEBUG_MIN_PULSE         8
-+    /**
-+     * 15 - 8   Number of cycles of RX_SPDIF_OSAMP_CLK  in minimum pulse width  
-+     *          detected (=0.5x BIT_CLK) 
-+     */
-+#define    RX_SPDIF_DEBUG_VALID             16
-+    /**
-+     * 0 - Min Pulse is not valid (<2) for doing recovery 
-+     * 1 - Min Pulse is valid (?2) and recovery is possible 
-+     */
-+#define    RX_SPDIF_DEBUG_LOCK              17
-+    /**
-+     * 0 - Rx S/PDIF timing is not locked. 
-+     * 1 - Rx S/PDIF timing is locked. 
-+     */
-+#define    RX_SPDIF_DEBUG_NO_PULSE          18
-+    /**
-+     * 0 - Pulse detected 
-+     * 1 - Pulse detection has timed out 
-+     */
-+#define    RX_SPDIF_DEBUG_BLOCK_START       20
-+    /**
-+     * 0 - Current frame is not at start of block 
-+     * 1 - Current frame is at start of block 
-+     */
-+#define    RX_SPDIF_DEBUG_CHAN_A            21
-+    /**
-+     * 0 - Current subframe is B 
-+     * 1 - Current subframe is A 
-+     */
-+
-+    
-+/* RX_SPDIF_DEBUG2 ------------ */
-+#define    RX_SPDIF_DEBUG2_FRAME            0
-+    /**
-+     * 7 - 0    Current frame counter (0 to 191) 
-+     */
-+#define    RX_SPDIF_DEBUG2_BLOCK_SYNC       8
-+    /**
-+     * 0 - Not yet achieved block sync 
-+     * 1 - Block sync has been achieved (i.e. received a start of block) 
-+     */
-+
-+ 
-+/* INTERRUPT_CONTROL_STATUS ------------ */
-+#define    INTERRUPT_CONTROL_STATUS_AUDIO_IRQ 0
-+    /**
-+     * ** BACKWARDS COMPATIBLE, DO NOT USE 
-+     * Set if the Audio Core Interrupt is set. Write ‘0’ to clear                  
-+     */
-+#define    INTERRUPT_CONTROL_STATUS_AUTO_CLEAR 2
-+    /**
-+     * 0 - Auto Clear disabled 
-+     * 1 - Auto clear of H/W read/write interrupt on next data write/read (Tx/Rx) 
-+     */
-+#define    INTERRUPT_CONTROL_STATUS_TX_IRQ  8
-+    /**
-+     * Set if the Audio Core Tx Interrupt is set  
-+     * Set to ‘1’ to trigger a Normal Interrupt (TX_READ/RX_WRITE  IRQ Enable 
-+     * must be set) 
-+     */
-+#define    INTERRUPT_CONTROL_STATUS_TX_ERR_IRQ 9
-+    /**
-+     * Set if the Audio Core Tx Error Interrupt is set 
-+     * Set to ‘1’ to trigger an Error Interrupt (TX_URUN/RX_ORUN  IRQ Enable  
-+     * must be set) 
-+     */
-+#define    INTERRUPT_CONTROL_STATUS_RX_IRQ  16
-+    /**
-+     * Set if the Audio Core Rx Interrupt is set 
-+     * Set to ‘1’ to trigger a Normal Interrupt (RX_WRITE/TX_READ  IRQ Enable 
-+     * must be set) 
-+     */
-+#define    INTERRUPT_CONTROL_STATUS_RX_ERR_IRQ 17
-+   /**
-+    * Set if the Audio Core Rx Error Interrupt is set 
-+    * Set to ‘1’ to trigger an Error Interrupt (RX_ORUN/TX_URUN  IRQ Enable must 
-+    * be set) 
-+    */
-+   
-+
-+/* INTERRUPT_MASK ------------ */
-+#define    INTERRUPT_MASK_TX_READ_IRQ_ENABLE 0    
-+    /**
-+     * 0 - No Normal Interrupt generated by TX_READ 
-+     * 1 - Normal Interrupt generated by TX_READ 
-+     */
-+#define    INTERRUPT_MASK_TX_LEVEL_IRQ_ENABLE 1
-+    /**
-+     * 0 - No Normal Interrupt generated by TX_BUFFER_LEVEL 
-+     * 1 - Normal Interrupt generated by TX_BUFFER_LEVEL 
-+     */
-+#define    INTERRUPT_MASK_TX_ERROR_IRQ_ENABLE 2
-+    /**
-+     * 0 - No Normal Interrupt generated by TX_ERROR 
-+     * 1 - Normal Interrupt generated by TX_ERROR 
-+     */
-+#define    INTERRUPT_MASK_RX_WRITE_IRQ_ENABLE 8
-+    /**
-+     * 0 - No Normal Interrupt generated by RX_WRITE 
-+     * 1 - Normal Interrupt generated by RX_WRITE 
-+     */
-+#define    INTERRUPT_MASK_RX_LEVEL_IRQ_ENABLE 9
-+    /**
-+     * 0 - No Normal Interrupt generated by RX_BUFFER_LEVEL 
-+     * 1 - Normal Interrupt generated by RX_BUFFER_LEVEL 
-+     */
-+#define    INTERRUPT_MASK_RX_ERROR_IRQ_ENABLE 10
-+    /**
-+     * 0 - No Normal Interrupt generated by RX_ERROR 
-+     * 1 - Normal Interrupt generated by RX_ERROR 
-+     */
-+#define    INTERRUPT_MASK_TX_URUN_IRQ_ENABLE 16
-+    /**
-+     * 0 - No Error Interrupt generated by Tx Underrun 
-+     * 1 - Error Interrupt generated by Tx Underrun 
-+     */
-+#define    INTERRUPT_MASK_TX_ORUN_IRQ_ENABLE 17
-+    /**
-+     * 0 - No Error Interrupt generated by Tx Overrun 
-+     * 1 - Error Interrupt generated by Tx Overrun 
-+     */
-+#define    INTERRUPT_MASK_TX_FIFO_URUN_ERR_IRQ_ENABLE 18
-+    /**
-+     * 0 - No Error Interrupt generated by Tx FIFO Underrun 
-+     * 1 - Error Interrupt generated by Tx FIFO Underrun 
-+     */
-+#define    INTERRUPT_MASK_TX_FIFO_ORUN_ERR_IRQ_ENABLE 19
-+    /**
-+     * 0 - No Error Interrupt generated by Tx FIFO Overrun 
-+     * 1 - Error Interrupt generated by Tx FIFO Overrun 
-+     */
-+#define    INTERRUPT_MASK_RX_URUN_ERR_IRQ_ENABLE 24
-+    /**
-+     * 0 - No Error Interrupt generated by Rx Underrun 
-+     * 1 - Error Interrupt generated by Rx Underrun 
-+     */
-+#define    INTERRUPT_MASK_RX_ORUN_ERR_IRQ_ENABLE 25    
-+    /**
-+     * 0 - No Error Interrupt generated by Rx Overrun 
-+     * 1 - Error Interrupt generated by Rx Overrun 
-+     */
-+#define    INTERRUPT_MASK_RX_FIFO_URUN_ERR_IRQ_ENABLE 26    
-+    /**
-+     * 0 - No Error Interrupt generated by Rx FIFO Underrun 
-+     * 1 - Error Interrupt generated by Rx FIFO Underrun 
-+     */
-+#define    INTERRUPT_MASK_RX_FIFO_ORUN_ERR_IRQ_ENABLE 27    
-+    /**
-+     * 0 - No Error Interrupt generated by Rx FIFO Overrun 
-+     * 1 - Error Interrupt generated by Rx FIFO Overrun 
-+     */
-+#define    INTERRUPT_MASK_SPDIF_RX_ERROR    28
-+    /**
-+     * 0 - No Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/Framing) 
-+     * 1 - Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/ Framing) 
-+     */
-+#define    INTERRUPT_MASK_SPDIF_RX_LOCK     29
-+    /**
-+     * 0 - No Error Interrupt generated by Rx S/PDIF Lock event 
-+     * 1 - Error Interrupt generated by Rx S/PDIF Lock event 
-+     */
-+
-+    
-+/* VERSION ------------ */ 
-+/**
-+ * Returns a 32 bit value that indicates the version and build options of the  
-+ * audio core being used. See the version list at the end of the document to  
-+ * find out how they translate. 
-+ */
-+
-+#define    VERSION_NUMBER                   0
-+    /**
-+     * 0 - 7        Version of the core 
-+     */
-+#define    VERSION_AUX_APB                  12         
-+    /**
-+     * AUX_APB  build option    
-+     */
-+#define    VERSION_RX_SPDIF                 13       
-+    /**
-+     * RX_SPDIF  build option  
-+     */
-+#define    VERSION_TX_SPDIF                 14      
-+    /**
-+     * TX_SPDIF  build option  
-+     */
-+#define    VERSION_AHB_DMA                  15        
-+    /**
-+     * DMA_AHB  build option 
-+     */
-+#define    VERSION_RX_FIFO_ADDR_BITS        19   
-+    /**
-+     * 16 - 19    G_RX_FIFO_A_BITS  generic
-+     */
-+#define    VERSION_RX_CHANS                 23   
-+    /**
-+     * 20 - 23    G_RX_CHANNELS  generic 
-+     */
-+#define    VERSION_TX_FIFO_ADDR_BITS        27   
-+    /**
-+     * 24 - 27    G_TX_FIFO_A_BITS  generic 
-+     */
-+#define    VERSION_TX_CHANS                 31   
-+    /**
-+     * 28 - 31    G_TX_CHANNELS  generic 
-+     */
-+
-+
-+ 
-+/* TX_DATA_IN_FORMAT ------------ */
-+#define    TX_DATA_IN_FORMAT_SAMPLE_ORDER   0
-+    /**
-+     * 0 - Samples written in as left/right pairs 
-+     * 1 - All left channels written then all right 
-+     */
-+#define    TX_DATA_IN_FORMAT_24_BIT_SAMPLE  1
-+    /**
-+     * Set to ‘1’ to indicate write contains 24 bit data (used in conjunction  
-+     * with following setting) 
-+     * ** NOT VALID FOR S/PDIF 
-+     */
-+#define    TX_DATA_IN_FORMAT_PAD_TOP_BYTE   2
-+    /**
-+     * 0 - Output data becomes WRITE_DATA(23 downto 0) & “00000000” 
-+     * 1 - Output data becomes “0000000” & WRITE_DATA(23 downto 0) 
-+     */
-+#define    TX_DATA_IN_FORMAT_WAIT_FOR_HALF  4
-+    /**
-+     * 0 - Hardware waits for full number of writes before progressing 
-+     * 1 - Hardware waits for half the number of writes before progressing 
-+     */
-+
-+    
-+/* TX_CHANNELS_ENABLE ------------ */ 
-+/**
-+ * If a channel is disabled, then no new data is presented to the data line of  
-+ * that I2S channel 
-+ *   0 - Tx Channel N disabled 
-+ *   1 - Tx Channel N enabled 
-+ */
-+
-+
-+/* TX_WRITES_TO ------------ */ 
-+/**
-+ * Can be used in conjunction with the Tx Channel Enable, whereby if an output 
-+ * channel is disabled then software can select whether or not it still wishes  
-+ * to write to this channel or not, effectively reduces its number of writes  
-+ * per interrupt. If it chooses to still write to this location then the write  
-+ * data is effectively ignored. 
-+ *   0 - Tx Channel N not included in data 
-+ *   1 - Tx Channel N included in data 
-+ */
-+
-+ 
-+/* RX_DATA_OUT_FORMAT ------------ */
-+#define    RX_DATA_OUT_FORMAT_SAMPLE_ORDER  0
-+    /**
-+     * 0 - Samples read in as left/right pairs 
-+     * 1 - All left channels read then all right 
-+     */
-+#define    RX_DATA_OUT_FORMAT_24_BIT_SAMPLE 1   
-+    /**
-+     * Set to ‘1’ to indicate read contains 24 bit data (used in conjunction  
-+     * with following setting)          
-+     * ** NOT VALID FOR S/PDIF    
-+     */
-+#define    RX_DATA_OUT_FORMAT_PAD_TOP_BYTE  2
-+    /**
-+     * 0 - Read data becomes RX_DATA(23 downto 0) & “00000000” 
-+     * 1 - Read data becomes “0000000” & RX_DATA(23 downto 0) 
-+     */
-+#define    RX_DATA_OUT_FORMAT_WAIT_FOR_HALF 4
-+    /**
-+     * 0 - Hardware waits for full number of reads before progressing 
-+     * 1 - Hardware waits for half the number of reads before progressing 
-+     */
-+
-+    
-+/* RX_CHANNELS_ENABLE ------------ */ 
-+/**
-+ * If a channel is disabled, then no new data is presented to the data line of 
-+ * that I2S channel 
-+ *   0 - Rx Channel N disabled 
-+ *   1 - Rx Channel N enabled 
-+ */
-+
-+
-+/* RX_READS_FROM ------------ */ 
-+/**
-+ * Can be used in conjunction with the Rx Channel Enable, whereby if an input 
-+ * channel is disabled then software can select whether or not it still wishes  
-+ * to read from this channel or not, effectively reduces its number of reads  
-+ * per interrupt. If it chooses to still read from this location then the read 
-+ * data is invalid. 
-+ *    0 - Rx Channel N not included in data 
-+ *    1 - Rx Channel N included in data 
-+ */
-+
-+
-+ 
-+/* TX_CPU_DATA_WRITES_ALT ------------ */ 
-+/**
-+ * See TX_CPU_DATA_WRITES.   
-+ * This alternative address has been provided as it may be referenced within a  
-+ * 13 bit immediate address (which may have benefits when being accessed by a  
-+ * CPU with only a 13 bit immediate offset such as the LEON2 IU). 
-+ * 0x0400-0x04FF    TX_CPU_DATA_WRITES_ALT 
-+ */
-+
-+
-+/* RX_CPU_DATA_READS_ALT ------------ */ 
-+/**
-+ * See RX_CPU_DATA_READS.  This alternative address has been provided as it may 
-+ * be referenced within a 13 bit immediate address (which may have benefits  
-+ * when being accessed by a CPU with only a 13 bit immediate offset such as the 
-+ * LEON2 IU). 
-+ * 0x0800-0x08FF    RX_CPU_DATA_READS_ALT 
-+ */
-+
-+
-+/* TX_CPU_DATA_WRITES ------------ */ 
-+/**
-+ * Any writes to this location writes a valid sample into the internal buffer  
-+ * of the audio core.  All writes should be the full 32 bits. 
-+ * This address is WRITE ONLY - any reads will return the previous read value  
-+ * on the bus. 
-+ * 0x1000-0x1FFF    TX_CPU_DATA_WRITES 
-+ */
-+
-+
-+/* RX_CPU_DATA_READS ------------ */ 
-+/**
-+ * Any reads from this location read a valid sample from the internal buffer of  
-+ * the audio core.  All reads should be the full 32 bits. 
-+ * This address is READ ONLY - any writes will be ignored. 
-+ * 0x2000-0x2FFF    RX_CPU_DATA_READS 
-+ */
-+
-+#endif /* __ASM_ARM_ARCH_I2S_H */
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/io.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/io.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,17 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/io.h
-+ * 
-+ * 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_ARM_ARCH_IO_H
-+#define __ASM_ARM_ARCH_IO_H
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#define __io(a) 	  ((void __iomem*)(a))
-+#define __mem_pci(a) (a)
-+
-+#endif //__ASM_ARM_ARCH_IO_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,42 @@
-+/* linux/include/asm-arm/arch-oxnas/irqs.h
-+ *
-+ * 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_IRQS_H
-+#define __ASM_ARCH_IRQS_H
-+
-+#define FIQ_INTERRUPT              0
-+#define SOFTWARE_INTERRUPT         1
-+#define TIMER_1_INTERRUPT          4
-+#define TIMER_2_INTERRUPT          5
-+#define USB_FS_INTERRUPT           7
-+#define MAC_INTERRUPT              8
-+#define SEM_A_INTERRUPT           10
-+#define SEM_B_INTERRUPT           11
-+#define DMA_INTERRUPT_0           13
-+#define DMA_INTERRUPT_1           14
-+#define DMA_INTERRUPT_2           15
-+#define DMA_INTERRUPT_3           16
-+#define DPE_INTERRUPT             17
-+#define SATA_1_INTERRUPT          18
-+#define SATA_2_INTERRUPT          19
-+#define DMA_INTERRUPT_4           20
-+#define GPIO_1_INTERRUPT          21
-+#define GPIO_2_INTERRUPT          22
-+#define UART_1_INTERRUPT          23
-+#define UART_2_INTERRUPT          24
-+#define I2S_INTERRUPT             25
-+#define SATA_1_ERROR              26
-+#define SATA_2_ERROR              27
-+#define I2C_INTERRUPT             28
-+#define UART_3_INTERRUPT          29
-+#define UART_4_INTERRUPT          30
-+
-+#define PCI_A_INTERRUPT           GPIO_1_INTERRUPT
-+
-+#define NR_IRQS 32
-+
-+#endif // __ASM_ARCH_IRQ_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h	2008-07-01 09:46:51.000000000 +0200
-@@ -0,0 +1,73 @@
-+static const s8 leon_srec[] =
-+"S01400006C656F6E2D706F7765722D627574746F6E1A\n"
-+"S3159801E00081D820000326007881984000821020C08C\n"
-+"S3159801E010818840008190000003116C008210601481\n"
-+"S3159801E020213D4040A014200FE02040001D26007F8E\n"
-+"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
-+"S30D9801E0404000004501000000B3\n"
-+"S3159801E110A7480000A8100001AA100002AC1000033D\n"
-+"S3159801E120AE100004A14000009C10001E400000EAB9\n"
-+"S3159801E13001000000818400008810001786100016DF\n"
-+"S3159801E1408410001582100014818CC00081C440008F\n"
-+"S3099801E15081CC80005F\n"
-+"S3159801E1549C03BFB8FE23A020BE23BFB8DE23A02408\n"
-+"S3159801E164E03BA028E43BA030E823A03803160076C8\n"
-+"S3159801E17484102030821063FCC42840002511500075\n"
-+"S3159801E18486103FFF8214A00CC62040008414A10C6B\n"
-+"S3159801E1940316007FC6208000821063FC4000008924\n"
-+"S3159801E1A4E600400090102000921020004000008E56\n"
-+"S3159801E1B4941023E88210200083306008821060202E\n"
-+"S3159801E1C4A21020FFA3346008A1480000A02C0011D6\n"
-+"S3159801E1D4A0140001818C0000A0102010A414A0089A\n"
-+"S3159801E1E4E0248000400000950100000009114000D8\n"
-+"S3159801E1F49A11200CC203400082087FFEC223400074\n"
-+"S3159801E20498112014C203000082087FFEC2230000DD\n"
-+"S3159801E2148811208CC201000082087FFEC221000069\n"
-+"S3159801E224C40340008408BFEFC4234000C20300001E\n"
-+"S3159801E23482087FEFC2230000C40100008408BFEF5F\n"
-+"S3159801E244C4210000073F7FFFC20340008610E3FF05\n"
-+"S3159801E25482084003C2234000C40300008408800353\n"
-+"S3159801E264C4230000C201000082084003C2210000B1\n"
-+"S3159801E2741B1100008610200188136014C621000022\n"
-+"S3159801E2848213601CC620400084136020E02080001D\n"
-+"S3159801E29480A4E0000280003C030080008413601887\n"
-+"S3159801E2A4C2208000071100008410E01C030080003E\n"
-+"S3159801E2B4C2208000A8100003C2050000808860105F\n"
-+"S3159801E2C40280000DA0102000C2050000808860100D\n"
-+"S3159801E2D41280000925000009231100004000005E00\n"
-+"S3159801E2E49014A310C20440008088601002BFFFFCFA\n"
-+"S3159801E2F40100000023000009251100004000005682\n"
-+"S3159801E30490146310C20480008088601012800021E2\n"
-+"S3159801E31480A42031A004200180A4203104BFFFF8F1\n"
-+"S3159801E324031100000500800080A4E0001280000516\n"
-+"S3159801E3348210601403110000050080008210601891\n"
-+"S3159801E344C420400023000009A01020634000004225\n"
-+"S3159801E35490146310A0843FFF1CBFFFFD031600763B\n"
-+"S3159801E364821063FC84102031C428400003110000F4\n"
-+"S3159801E3748610200182106018C62040001080000083\n"
-+"S3159801E38401000000C221000010BFFFC80711000058\n"
-+"S3159801E39404BFFFCA0311000010BFFFE40500800003\n"
-+"S3159801E3A49C07FFB8FE03A020DE03A024E01BA02847\n"
-+"S3159801E3B4E41BA030E803A03881C3E0089C23BFB8C6\n"
-+"S3159801E3C4051150008610A20882102044C220C0006C\n"
-+"S3159801E3D48410A22882102088C220800081C3E00874\n"
-+"S3159801E3E401000000932A601003000061821062A064\n"
-+"S3159801E3F493326010925A4001952AA010030005F5AC\n"
-+"S3159801E40482106384900A20FF9532A010905A0001D5\n"
-+"S3159801E41493326006945AA320900200099532A00972\n"
-+"S3159801E424031150009002000A82106200D020400025\n"
-+"S3159801E43481C3E00801000000051150008410A20868\n"
-+"S3159801E444C200800082106080C220800081C3E008E7\n"
-+"S3159801E4540100000003041893821061D380520001CD\n"
-+"S3159801E46491400000913220068810000682380008EF\n"
-+"S3159801E47480A040041A80000D8401000882020004D9\n"
-+"S3159801E484900060018210000680A0400486603FFFD8\n"
-+"S3159801E49480A2000184603FFF8090C00212BFFFFAF8\n"
-+"S3159801E4A401000000308000098210000680A0400215\n"
-+"S3159801E4B41A800006010000008210000680A040021E\n"
-+"S3159801E4C40ABFFFFA0100000081C3E00801000000B9\n"
-+"S3159801E4D405115000C200800080A060000280000BE4\n"
-+"S3159801E4E48610A20C80886010028000040100000046\n"
-+"S3159801E4F4C020C0008C01A001C200800080A06000E9\n"
-+"S3159801E50412BFFFFA8088601081C3E00801000000F9\n"
-+"S7059801E00081\n";
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h	2008-07-01 09:46:44.000000000 +0200
-@@ -0,0 +1,404 @@
-+static const s8 leon_srec[] =
-+"S00700006C656F6E4A\n"
-+"S3159801E00081D820000326007881984000821020C08C\n"
-+"S3159801E010818840008190000003116C008210601481\n"
-+"S3159801E020213FC040A014200FE02040001D26007F0C\n"
-+"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
-+"S30D9801E0404000005A010000009E\n"
-+"S3159801E050051150008410A208C200800082106080C9\n"
-+"S3159801E060C220800081C3E00801000000051150001C\n"
-+"S3159801E0708610A20882102044C220C0008410A228CB\n"
-+"S3159801E08082102088C220800081C3E0080100000028\n"
-+"S3159801E110A7480000A8100001AA100002AC1000033D\n"
-+"S3159801E120AE100004A14000009C10001E4000007F24\n"
-+"S3159801E13001000000818400008810001786100016DF\n"
-+"S3159801E1408410001582100014818CC00081C440008F\n"
-+"S3099801E15081CC80005F\n"
-+"S3159801E154932A601003000061821062A093326010C2\n"
-+"S3159801E164925A4001952AA010030005F582106384FA\n"
-+"S3159801E174900A20FF9532A010905A000193326006B6\n"
-+"S3159801E184945AA320900200099532A00903115000CC\n"
-+"S3159801E1949002000A82106200D020400081C3E008F0\n"
-+"S3159801E1A4010000009C03BFB8FE23A020BE23BFB87C\n"
-+"S3159801E1B4DE23A024E03BA028E43BA030033D404065\n"
-+"S3159801E1C48210600FA610200021116C00A01420144F\n"
-+"S3159801E1D4C2240000400001BF2511500086103FFF5C\n"
-+"S3159801E1E48214A00CC62040008414A10CC620800079\n"
-+"S3159801E1F47FFFFF9E010000009010200092102000DE\n"
-+"S3159801E2047FFFFFD4941023E8400001A30100000086\n"
-+"S3159801E2148A1000130326007EC60061700926007EC3\n"
-+"S3159801E224841061708211219CDA00A004C6206008CA\n"
-+"S3159801E234C621219C400001D5DA206004A734E00860\n"
-+"S3159801E244A614E020A21020FFA3346008A148000078\n"
-+"S3159801E254A02C0011A0140013818C000082102010A8\n"
-+"S3159801E264A414A008C224800084102400C424800025\n"
-+"S3159801E27482102100C22480004000055C0100000040\n"
-+"S3159801E2847FFFFF73010000008210000780A06000E1\n"
-+"S3159801E29402BFFFFEA6100001308000071280000F0E\n"
-+"S3159801E2A40100000082100007A690600002BFFFF7E4\n"
-+"S3159801E2B4010000008E29C013808CE00202BFFFF88A\n"
-+"S3159801E2C4808CE0014000020001000000808CE0018E\n"
-+"S3159801E2D402BFFFF5010000004000025B0100000047\n"
-+"S3159801E2E430BFFFF19C07FFB8FE03A020DE03A024EC\n"
-+"S3159801E2F4E01BA028E41BA03081C3E0089C23BFB887\n"
-+"S3159801E3049801E6949801E7A09801E7689801E724AB\n"
-+"S3159801E3149801E6B49801E8589801E83C9801E7EC25\n"
-+"S3159801E3249801E7C49C03BFA0FE23A020BE23BFA0E7\n"
-+"S3159801E334DE23A024E03BA028E43BA030E83BA038A8\n"
-+"S3159801E34403115000E400400080A4A0000280014A11\n"
-+"S3159801E354808CA1000280004E808CA01007101004B6\n"
-+"S3159801E364C400E014C200E01C88088001808920104A\n"
-+"S3159801E3749A1020009810200002800003841020002F\n"
-+"S3159801E3848410201080892080328000028410A08015\n"
-+"S3159801E39480892040328000028410A04080A0A00089\n"
-+"S3159801E3A40280000603000060C200E01C8228400235\n"
-+"S3159801E3B4C220E01C03000060821100010500006080\n"
-+"S3159801E3C4C220E014882900028143C000C2000000DB\n"
-+"S3159801E3D480892401028000068089202882102002DF\n"
-+"S3159801E3E48E11C00188093BFE808920280280000984\n"
-+"S3159801E3F480892002821020028E11C001808920080A\n"
-+"S3159801E40422800003981020019A1020018089200205\n"
-+"S3159801E414128000060310100480A360000280007F16\n"
-+"S3159801E42480A3200003101004C40060180700000894\n"
-+"S3159801E43484108003C4206018821000058210400459\n"
-+"S3159801E4448A100001091140008211204CC400400031\n"
-+"S3159801E4548088A1001280000E808CA0100326007E6D\n"
-+"S3159801E464C600617884100005C420C0008143C000A9\n"
-+"S3159801E474C20000008410210086112050C420C000D7\n"
-+"S3159801E484821020008A100001808CA0100280001C42\n"
-+"S3159801E494808CA400031150008210620CC0204000A5\n"
-+"S3159801E4A48C01A0018210000580A0600002800014EE\n"
-+"S3159801E4B4808CA400091140008211204CC4004000AC\n"
-+"S3159801E4C48088A1001280000E808CA4000326007E09\n"
-+"S3159801E4D4C600617884100005C420C0008143C00039\n"
-+"S3159801E4E4C20000008410210086112050C420C00067\n"
-+"S3159801E4F4821020008A100001808CA40002800039C1\n"
-+"S3159801E50403000400031140008410604CE600800067\n"
-+"S3159801E51482106054840CE003C4204000808CE0018E\n"
-+"S3159801E5240280002B808CE0022326007EAA07FFF442\n"
-+"S3159801E534A007FFF0A807FFEC9A14619C96103FFF79\n"
-+"S3159801E544C8036008108000051908000080A2E0003D\n"
-+"S3159801E55402800011C4236008C601000080A0E0006F\n"
-+"S3159801E564168000178088C00C028000418401200817\n"
-+"S3159801E574C2036004C624000080A0800112BFFFF480\n"
-+"S3159801E58488100002C803400080A2E00012BFFFF37E\n"
-+"S3159801E594C8236008C807FFF080A1200818800024C2\n"
-+"S3159801E5A40720000005260078832920028410A304F5\n"
-+"S3159801E5B4C600800181C0C0000100000080A2E0006D\n"
-+"S3159801E5C402BFFFF5C6240000808CE0020280000594\n"
-+"S3159801E5D403000400821020018E11C0010300040077\n"
-+"S3159801E5E4808C8001028000080311500003115800A1\n"
-+"S3159801E5F482106090C0204000841020048E11C002BD\n"
-+"S3159801E60403115000E400400080A4A00012BFFF52F9\n"
-+"S3159801E614808CA1003080009802BFFF8803101004F3\n"
-+"S3159801E624C020600430BFFF850720000086290003B7\n"
-+"S3159801E6349A14619CC807FFF48143C000C200000084\n"
-+"S3159801E644C40360088400A008C2036004C6210000BC\n"
-+"S3159801E65480A0800102800004C204619C10BFFFB7A8\n"
-+"S3159801E664C423600810BFFFB5C22360080507FFFFDE\n"
-+"S3159801E6748410A3FF031000008408C0028208C00115\n"
-+"S3159801E684C8254000C225000010BFFFC3C42400005A\n"
-+"S3159801E6940326007EC40061A880A0A000028000061B\n"
-+"S3159801E6A4C207FFEC400000E401000000C807FFF030\n"
-+"S3159801E6B4C207FFEC0708000080A0600002BFFFDBD9\n"
-+"S3159801E6C486110003C807FFF4032000008410200173\n"
-+"S3159801E6D48628C001C42120049A14619C8143C000F0\n"
-+"S3159801E6E4C2000000C62100008143C000C200000098\n"
-+"S3159801E6F4C40360088800A00803114000C603600497\n"
-+"S3159801E7040500004082106050C420400080A1000397\n"
-+"S3159801E71402BFFFD5C204619C10BFFF88C823600855\n"
-+"S3159801E724C807FFF4C601200405101004C200A01CF2\n"
-+"S3159801E7349A284003C207FFECDA20A01C80A0600047\n"
-+"S3159801E74402800013C607FFF0030800008610C00173\n"
-+"S3159801E754052000008628C002DA21200410BFFFE0B4\n"
-+"S3159801E7649A14619CC807FFF4C60120040510100485\n"
-+"S3159801E774C200A01C9A104003C207FFECDA20A01C21\n"
-+"S3159801E78480A0600012BFFFF1C607FFF003200000C6\n"
-+"S3159801E7948628C00110BFFFA99A14619C400000AF56\n"
-+"S3159801E7A401000000C207FFEC80A060000280000C03\n"
-+"S3159801E7B4C607FFF00308000010BFFFC38610C00107\n"
-+"S3159801E7C4821023D005101004C607FFECC220A014AA\n"
-+"S3159801E7D480A0E00012BFFFF8C607FFF003200000EF\n"
-+"S3159801E7E410BFFF948628C001C807FFF4C20120040C\n"
-+"S3159801E7F480A060000280001D05101004C200A018B4\n"
-+"S3159801E80482106002C220A018C207FFEC80A06000A3\n"
-+"S3159801E81402BFFFDFC607FFF0030800008610C00198\n"
-+"S3159801E82405200000821020018628C002C2212004F6\n"
-+"S3159801E83410BFFFAB9A14619CC207FFF4D000600421\n"
-+"S3159801E8444000003301000000C207FFEC10BFFFD857\n"
-+"S3159801E85480A060004000001201000000C207FFEC8E\n"
-+"S3159801E86410BFFFD380A06000C200A01810BFFFE6B6\n"
-+"S3159801E87482087FFD9C07FFA0FE03A020DE03A02447\n"
-+"S3159801E884E01BA028E41BA030E81BA03881C3E0084C\n"
-+"S3159801E8949C23BFA081C3E008010000000326007EE3\n"
-+"S3159801E8A40526007EC60061988410A17088102009F7\n"
-+"S3159801E8B4C200C000C22080008600E00488813FFF20\n"
-+"S3159801E8C41CBFFFFC8400A00481C3E008010000007A\n"
-+"S3159801E8D49C03BFD0FE23A01CBE23BFD0DE23A02059\n"
-+"S3159801E8E40316007F821063FCC60040000526007E4D\n"
-+"S3159801E8F47FFFFFEBC620A1989C07FFD0FE03A01CBF\n"
-+"S3159801E904DE03A02081C3E0089C23BFD00310100422\n"
-+"S3159801E914C6006018050000088428C002C42060183F\n"
-+"S3159801E9248610000105001C00C200E014808840028C\n"
-+"S3159801E93412BFFFFE80A22000228000090310100056\n"
-+"S3159801E94407101000C400C00003000020822880012B\n"
-+"S3159801E954C220C0001080000703101004C4004000B0\n"
-+"S3159801E9640700002084108003C422000103101004B8\n"
-+"S3159801E974C40060180700000884108003C420601836\n"
-+"S3159801E98481C3E008010000009C03BFD0FE23A01CAC\n"
-+"S3159801E994BE23BFD0DE23A020E023A0240326007E35\n"
-+"S3159801E9A4821061701B26007E1926007E841361C429\n"
-+"S3159801E9B4C600600C881321B4D60060102126007E07\n"
-+"S3159801E9C4D0006014C621200CC02361C4C020A010B5\n"
-+"S3159801E9D4C62321B4D6212004C020A004C020A008AF\n"
-+"S3159801E9E4C020A00CC6212008400003A9D02421B038\n"
-+"S3159801E9F4D02421B0400003BA921020360326007E13\n"
-+"S3159801EA04D02421B0C02061A88143C000C20000006F\n"
-+"S3159801EA140526007EC020A1ACD00421B09C07FFD066\n"
-+"S3159801EA24FE03A01CDE03A020E003A02481C3E00812\n"
-+"S3159801EA349C23BFD00526007EC200A1AC80A06000AD\n"
-+"S3159801EA441280000482102001C220A1AC8E11C0014B\n"
-+"S3159801EA5481C3E008010000009C03BFD0FE23A01CDB\n"
-+"S3159801EA64BE23BFD0DE23A0207FFFFFC8010000008C\n"
-+"S3159801EA748810201807101004C20100030500000825\n"
-+"S3159801EA8482104002C2210003841020010326007ECD\n"
-+"S3159801EA94C42061A89C07FFD0FE03A01CDE03A02016\n"
-+"S3159801EAA481C3E0089C23BFD0832A2010913060103B\n"
-+"S3159801EAB4900A20FF83306018912A200881C3E008C0\n"
-+"S3159801EAC4901040089C03BFD8DE23A008F43BA010FD\n"
-+"S3159801EAD4F83BA0180326007E3926007E961061D845\n"
-+"S3159801EAE4BA1721C43526007EF60061D89010200005\n"
-+"S3159801EAF49810000B9210001DC402E008C202E00CA3\n"
-+"S3159801EB0480A0800102800032D406A1ECC200800064\n"
-+"S3159801EB1480A0600026800047D426A1ECDA03200859\n"
-+"S3159801EB2484036010C203200480A080010280003F00\n"
-+"S3159801EB348610000CC4232008C200E01080A060004F\n"
-+"S3159801EB4432800002C020E010DE034000030000205A\n"
-+"S3159801EB54808BC00102800024808BE200028000052C\n"
-+"S3159801EB64808BEC00C202600882006001C2226008B0\n"
-+"S3159801EB7402800005808BE100C202600C820060016C\n"
-+"S3159801EB84C222600C0280000501000000C2026010D6\n"
-+"S3159801EB9482006010C2226010C203600C80A06000DB\n"
-+"S3159801EBA422800007C402E008C203600CD4206008DE\n"
-+"S3159801EBB4C020600494100001C402E008C202E00C6B\n"
-+"S3159801EBC480A0800112BFFFD290102001C202E010EA\n"
-+"S3159801EBD480A0600012BFFFCE0100000010800015CE\n"
-+"S3159801EBE4D426A1ECC8036004C60721C4820927FF69\n"
-+"S3159801EBF48600C001051000008089000202BFFFE764\n"
-+"S3159801EC04C62721C48333E003C4076004C60760108A\n"
-+"S3159801EC14820860078600C0018400A001C4276004A5\n"
-+"S3159801EC2410BFFFDEC627601010BFFFC4F623200865\n"
-+"S3159801EC34DE03A008F41BA010F81BA01881C3E008F2\n"
-+"S3159801EC449C23BFD89C03BF40FE23A020BE23BF406C\n"
-+"S3159801EC54DE23A024E03BA028E43BA030E83BA0387F\n"
-+"S3159801EC64EC3BA040F03BA048F43BA050F83BA0589D\n"
-+"S3159801EC740526007EC200A1A880A0600002800173C7\n"
-+"S3159801EC840726007EC200E1AC80A060001280017064\n"
-+"S3159801EC94010000003326007EB41661B4C606A008A6\n"
-+"S3159801ECA4C210E01A8328601083306010808860024D\n"
-+"S3159801ECB41280016680886001028001648800E08C74\n"
-+"S3159801ECC4C210E01A82106002C406A00480A1000250\n"
-+"S3159801ECD4028001F9C230E01AC826A008AE90E00075\n"
-+"S3159801ECE42280015B0726007EC215E01A808860049B\n"
-+"S3159801ECF432800028F005E0102326007EC405E0043E\n"
-+"S3159801ED04C205E008A21461D8A6208001A0100002C9\n"
-+"S3159801ED14E405E00CA8102000B8100011B605E01C13\n"
-+"S3159801ED24B005E0641B26007EFA036168AA100013F5\n"
-+"S3159801ED34AC100012E6160000E406C000B0062002E4\n"
-+"S3159801ED44B606E004A0240015C204601080A06000F1\n"
-+"S3159801ED541280000701000000C404600CC200800000\n"
-+"S3159801ED6480A06000168000A69A00A0108210000761\n"
-+"S3159801ED748288600202BFFFFE010000008E29C0014D\n"
-+"S3159801ED847FFFFF510100000010BFFFF1C20460101C\n"
-+"S3159801ED94C20E0000C405E00CC427FFB08208600FB8\n"
-+"S3159801EDA483286002C80E2009842600028400800103\n"
-+"S3159801EDB4860920FF80A0E006BA060001028001C3F5\n"
-+"S3159801EDC4C437FFF680A0E011228001BE8400A00812\n"
-+"S3159801EDD480A12006C027FFEC028001A0C027FFE886\n"
-+"S3159801EDE4C417FFF6DA15E018C215E0168528A0109F\n"
-+"S3159801EDF4DA27FFE080A36000C227FFE41280000CA3\n"
-+"S3159801EE04C427FFB40326007EC617FFF6C40061889B\n"
-+"S3159801EE148728E0108400A00E8330E01084208001B6\n"
-+"S3159801EE249A102001C427FFE0DA27FFE4C607FFB446\n"
-+"S3159801EE34E205E004C205E0088530E0108224400129\n"
-+"S3159801EE4482204002C427FFCCDA07FFB0840340022C\n"
-+"S3159801EE54C227FFD0C427FFD47FFFFF14D0162004FE\n"
-+"S3159801EE64912A2010C607FFB09132201082102000F3\n"
-+"S3159801EE74C407FFE48608E003C027FFBCD037FFC662\n"
-+"S3159801EE8480A04002C027FFDCC027FFD816800099CE\n"
-+"S3159801EE94C627FFACDA07FFCCA224400DC207FFE0D0\n"
-+"S3159801EEA480A4400104800003E227FFB8C227FFB873\n"
-+"S3159801EEB4D017FFC6912A20107FFFFEFC91322010AD\n"
-+"S3159801EEC4C407FFB8C617FFF68200800382007FF253\n"
-+"S3159801EED483286010D03620047FFFFEF491306010A9\n"
-+"S3159801EEE4DA17FFC6C20E20099A036001D0362002AA\n"
-+"S3159801EEF480A0600602800110DA37FFC680A06011EF\n"
-+"S3159801EF0402800145C207FFB8C407FFB8C036200A74\n"
-+"S3159801EF14C427FFDCA41000020726007EE200E1EC78\n"
-+"S3159801EF2480A460000280002D84102004C204600825\n"
-+"S3159801EF34C220E1ECC207FFB49B306010E0044000A4\n"
-+"S3159801EF44820C200382208001C607FFAC84208003AB\n"
-+"S3159801EF5480A04002DA246004C607FFB0028000CF7D\n"
-+"S3159801EF64881000101080000698102000C22900000D\n"
-+"S3159801EF74980320018600E0018801200180A3000DF1\n"
-+"S3159801EF842ABFFFFBC208C0002726007EA614E1D833\n"
-+"S3159801EF94C204E01080A060001280000701000000FE\n"
-+"S3159801EFA4C204E00CC400400080A0A0003680014C45\n"
-+"S3159801EFB41B26007E821000078288600202BFFFFE2C\n"
-+"S3159801EFC4010000008E29C0017FFFFEBF01000000E9\n"
-+"S3159801EFD410BFFFF1C204E010821000078288600214\n"
-+"S3159801EFE402BFFFFE010000008E29C0017FFFFEB615\n"
-+"S3159801EFF40100000010BFFFCA0726007EC20720043D\n"
-+"S3159801F0048810000280A34001028001E99810001C2F\n"
-+"S3159801F014C20120048208401DC2212004C40120048F\n"
-+"S3159801F0248408B800C4212004872D6010C2012004E5\n"
-+"S3159801F0348730E01082104003C2212004EC21200875\n"
-+"S3159801F044C021200CC6012004031800008228C0019F\n"
-+"S3159801F054C4032008C2212004841B400280A0000214\n"
-+"S3159801F064C60120040306000084603FFF8228C0017C\n"
-+"S3159801F074DA23200CC4232010C221200480A4200062\n"
-+"S3159801F0841280000780A52000C20120040510000003\n"
-+"S3159801F09482104002C221200480A52000028001BE6C\n"
-+"S3159801F0A4010000008143C000C20000000320000053\n"
-+"S3159801F0B4C401000084108001C421000080A42000AA\n"
-+"S3159801F0C412BFFF1CAA1000138143C000C20000009E\n"
-+"S3159801F0D403200000C405000084108001C4250000A3\n"
-+"S3159801F0E48143C000C200000005101004C020A0048A\n"
-+"S3159801F0F40726007E1B00003FC400E1C49A1363FFF0\n"
-+"S3159801F10480A0800D8810E1C4088000048210000252\n"
-+"S3159801F1141B26007EC403616C82204002C220E1C48E\n"
-+"S3159801F124C425E088C401200480A0A03F0880000378\n"
-+"S3159801F134821000028410203F82204002C2212004BA\n"
-+"S3159801F1448528A010C205E08882104002C225E0886D\n"
-+"S3159801F154C401200880A0A007088000038210000239\n"
-+"S3159801F1648410200782204002C22120088528A016EF\n"
-+"S3159801F174C205E08882104002C225E088C401200CA9\n"
-+"S3159801F18480A0A0070880000382100002841020073B\n"
-+"S3159801F19482204002C221200C8528A019C205E08844\n"
-+"S3159801F1A482104002C225E088C401201080A0A00FD5\n"
-+"S3159801F1B408800003821000028410200F82204002E6\n"
-+"S3159801F1C4C2212010C205E0888528A01C821040021D\n"
-+"S3159801F1D4C225E0888143C000C20000000326007E50\n"
-+"S3159801F1E4881061B4C215E01AC401200C82087FFC08\n"
-+"S3159801F1F48400A08CC6012004C235E01A80A080033D\n"
-+"S3159801F2042280008B0526007EC421200C8143C000F0\n"
-+"S3159801F214C20000000311400005000080821060506E\n"
-+"S3159801F224C42040001B26007EC60361A880A0E00086\n"
-+"S3159801F234028000060526007EC200A1AC80A060006B\n"
-+"S3159801F24422BFFE98C606A0080726007EC200E1AC36\n"
-+"S3159801F25480A0600002800159051150008210A00C0B\n"
-+"S3159801F2649A102400DA20400009101004C6012018C7\n"
-+"S3159801F274030000088228C001C22120188410A0081E\n"
-+"S3159801F28403114000DA2080000700010082106050C3\n"
-+"S3159801F294C62040003080014980A0A0041280000A4B\n"
-+"S3159801F2A4981020001080000C8423400C02BFFF376D\n"
-+"S3159801F2B498032001C208C000C22900008600E00113\n"
-+"S3159801F2C48801200180A300020ABFFFF980A3000DDB\n"
-+"S3159801F2D48423400C8530A0028328A002822340010E\n"
-+"S3159801F2E49A20400C1080000698102000C221000034\n"
-+"S3159801F2F4980320018600E0048801200480A3000273\n"
-+"S3159801F3042ABFFFFBC200C000108000069810200097\n"
-+"S3159801F314C2290000980320018600E0018801200192\n"
-+"S3159801F32480A3000D2ABFFFFBC208C00010BFFF18B7\n"
-+"S3159801F3342726007E0300003FC807600482106300F5\n"
-+"S3159801F344860900011B003FC0852920188209000DF2\n"
-+"S3159801F3548728E0088410800383306008841080012C\n"
-+"S3159801F3648931201888108004C407FFDC80A0A00086\n"
-+"S3159801F37422800012DA07FFE80700003F880100029D\n"
-+"S3159801F3848610E300840900038528A0088329201898\n"
-+"S3159801F394821040028609000D053FC0008730E008B7\n"
-+"S3159801F3A484090002821040038530A0188210400215\n"
-+"S3159801F3B4C2276004DA07FFE880A1000D1A80001FAE\n"
-+"S3159801F3C4C207FFE89023400490023FFF912A201038\n"
-+"S3159801F3D47FFFFDB691322010D0376012C407FFEC37\n"
-+"S3159801F3E480A0A00002BFFECAC407FFB8C607FFE4FF\n"
-+"S3159801F3F48200FFFFDA07FFBC80A0400D32BFFEC52D\n"
-+"S3159801F404C036200AC217600C8210610010BFFEBF75\n"
-+"S3159801F414C237600C90006008912A20107FFFFDA3E3\n"
-+"S3159801F4249132201010BFFEB9D0376004C200A1B43E\n"
-+"S3159801F43410BFFF77C221200C80A0600002BFFFE9AC\n"
-+"S3159801F444C407FFECC417600C033FFFC882288001E8\n"
-+"S3159801F45410BFFFE3C237600CE217600C0300000883\n"
-+"S3159801F464808C40010280000E0700003F7FFFFD8FCC\n"
-+"S3159801F474D0176012A12A20107FFFFD8CD017600641\n"
-+"S3159801F484912A2010A134201091322010A00400084A\n"
-+"S3159801F494A0042001E027FFE80700003F8610E2FF59\n"
-+"S3159801F4A4820C4003A20C6100C237600C10BFFE4D5A\n"
-+"S3159801F4B4E227FFECC20661B410BFFE09C226A00872\n"
-+"S3159801F4C410BFFE44C437FFF6C217600C833060023E\n"
-+"S3159801F4D48208603C10BFFFFB84008001981361D8B1\n"
-+"S3159801F4E4E803200C88052010C203200480A100019A\n"
-+"S3159801F4F422800002C80361D8053FF001C2052004A1\n"
-+"S3159801F5048410A3FF82084002C2252004C40520045E\n"
-+"S3159801F5148408B800C4252004C607FFB4C20520048C\n"
-+"S3159801F5248530E01082104002C2252004E025200887\n"
-+"S3159801F534E225200CC205200405060000821040022B\n"
-+"S3159801F544C2252004C605200403180000C403200814\n"
-+"S3159801F5548228C00184190002C2252004DA07FFD83B\n"
-+"S3159801F56480A00002C823200CC6052004852B6002BE\n"
-+"S3159801F5748803400D030800008610C0019A603FFF76\n"
-+"S3159801F5848400801788010017DA232010C6252004E1\n"
-+"S3159801F594B800A01CB6012064C207FFD080A48001DC\n"
-+"S3159801F5A406800076E207FFD4DA07FFD8C416C000AE\n"
-+"S3159801F5B4C60700009A036001A0100001C427FFD072\n"
-+"S3159801F5C4C627FFD4DA27FFD8B606E002B80720047F\n"
-+"S3159801F5D42726007EA614E1D80726007E80A420005B\n"
-+"S3159801F5E4AC1000130280003FEA00E168C204E010FF\n"
-+"S3159801F5F480A060001280005501000000C404E00C4C\n"
-+"S3159801F604C200800080A06000068000508810000225\n"
-+"S3159801F6148400A010C205A00480A080010280005431\n"
-+"S3159801F62486100016C200E0088218800180A00001A5\n"
-+"S3159801F634C420E00C84603FFFC420E01080A427FF17\n"
-+"S3159801F644188000039A1027FF9A100010C20120040B\n"
-+"S3159801F65482084015C2212004C40120048408B800F4\n"
-+"S3159801F664C4212004872B6010C20120048730E0103E\n"
-+"S3159801F67482104003C2212004E2212008C021200CD3\n"
-+"S3159801F684C20120040506000082104002C22120040A\n"
-+"S3159801F694C40120040318000082288001C221200491\n"
-+"S3159801F6A4A4A4800D1280000601000000C201200462\n"
-+"S3159801F6B40510000082104002C22120048143C00033\n"
-+"S3159801F6C4C200000003200000C401000084108001D8\n"
-+"S3159801F6D4C4210000A0A4000D12BFFFC5A204400DC9\n"
-+"S3159801F6E480A4A00012BFFFAEC207FFD08143C00019\n"
-+"S3159801F6F4C200000003200000C405000084108001A4\n"
-+"S3159801F704C42500008143C000C2000000C207FFBCA3\n"
-+"S3159801F71482006001C227FFBC03101004C407FFCC02\n"
-+"S3159801F724C0206004C607FFB884008003DA07FFBCCB\n"
-+"S3159801F734C207FFE480A3400116BFFE6EC427FFCC1F\n"
-+"S3159801F74410BFFDD5E205E0048210000782886002A5\n"
-+"S3159801F75402BFFFFE010000008E29C0017FFFFCDA7B\n"
-+"S3159801F7640100000010BFFFA3C204E0101B26007E0F\n"
-+"S3159801F77410BFFFADC40361D8C207FFD082204012DF\n"
-+"S3159801F78484044012C227FFD0A010001210BFFF9123\n"
-+"S3159801F794C427FFD4C2012004050800008210400240\n"
-+"S3159801F7A4C221200410BFFE46A81000040326007E39\n"
-+"S3159801F7B410BFFE18DA0061D89C07FF40FE03A0200B\n"
-+"S3159801F7C4DE03A024E01BA028E41BA030E81BA03884\n"
-+"S3159801F7D4EC1BA040F01BA048F41BA050F81BA058A2\n"
-+"S3159801F7E481C3E0089C23BF40031140008410200381\n"
-+"S3159801F7F482106060C420400081C3E00801000000C3\n"
-+"S3159801F8049C03BFF0DE23A0041F26007E84102000EB\n"
-+"S3159801F814C603E1D8092000008328A004C020C001AA\n"
-+"S3159801F8248200C001C8206004C02060088400A00139\n"
-+"S3159801F834C020600C80A0A03404BFFFF98328A004DB\n"
-+"S3159801F844C020E3508600E350C820E004C200E004D7\n"
-+"S3159801F8540500800082104002C220E004C020E0081E\n"
-+"S3159801F8648213E1D8C020E00CC02060108143C00007\n"
-+"S3159801F874C200000003101004C403E1D8C420601028\n"
-+"S3159801F884DE03A00481C3E0089C23BFF09C03BFD088\n"
-+"S3159801F894FE23A01CBE23BFD0DE23A020E023A024F0\n"
-+"S3159801F8A40326007EA01061D884022360D02061D8F3\n"
-+"S3159801F8B4D024200CD02420087FFFFFD2C42420040E\n"
-+"S3159801F8C4D00420049C07FFD0FE03A01CDE03A020CD\n"
-+"S3159801F8D4E003A02481C3E0089C23BFD09C03BFF016\n"
-+"S3159801F8E4DE23A0048202400982004009832860022B\n"
-+"S3159801F8F4860200010526007E8600E0041926007E0C\n"
-+"S3159801F9049A1020000326007ED020A1F4D22061F01B\n"
-+"S3159801F9148608FFFC80A340091680000FC02321ECBA\n"
-+"S3159801F9249E1020008810200084010008C621000832\n"
-+"S3159801F934DE20A0089A036001C020A0048600E04A4C\n"
-+"S3159801F9448801200C80A3400906BFFFF89E10000287\n"
-+"S3159801F954C42321EC90100003DE03A00481C3E008BC\n"
-+"S3099801F9649C23BFF092\n"
-+"S30D9801F968FFC007FF0000FFFF35\n"
-+"S7059801E00081\n";
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,36 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leon.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifdef CONFIG_SUPPORT_LEON
-+
-+#if !defined(__LEON_H__)
-+#define __LEON_H__
-+
-+/**
-+ * Load the LEON's program image into the memory as defined by the s-records
-+ * holding the LEON program image, and begin execution at the start address
-+ * defined by the s-records
-+ */
-+extern void init_copro(const s8 *srec, unsigned long arg);
-+
-+extern void shutdown_copro(void);
-+
-+#endif        //  #if !defined(__LEON_H__)
-+#endif // CONFIG_SUPPORT_LEON
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/memory.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/memory.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,107 @@
-+/*
-+ *  linux/include/asm-arm/arch-oxnas/memory.h
-+ *
-+ * 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_MEMORY_H
-+#define __ASM_ARCH_MEMORY_H
-+
-+/* Max. size of each memory node */
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define NODE_MAX_MEM_SHIFT (26) /* 64MB*/
-+#elif defined (CONFIG_OXNAS_VERSION_0X810)
-+#define NODE_MAX_MEM_SHIFT (28) /* 256MB */
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define MEM_MAP_ALIAS_SHIFT 28
-+#elif defined (CONFIG_OXNAS_VERSION_0X810)
-+#define MEM_MAP_ALIAS_SHIFT 30
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* All current OXNAS versions have two memory nodes; SDRAM followed contiguously
-+ * by SRAM */
-+#define SDRAM_PA    (0x48000000)
-+#define SDRAM_SIZE  (1UL << (NODE_MAX_MEM_SHIFT))
-+#define SRAM_PA     ((SDRAM_PA) + (SDRAM_SIZE))
-+
-+/* Only a portion of the SRAM may be available for the use of Linux */
-+#define SRAM_SIZE   (CONFIG_SRAM_NUM_PAGES * PAGE_SIZE)
-+
-+#define SDRAM_END   (SDRAM_PA + SDRAM_SIZE - 1)
-+#define SRAM_END    (SRAM_PA  + SRAM_SIZE  - 1)
-+
-+#define PHYS_OFFSET SDRAM_PA
-+#define PAGE_OFFSET 0xC0000000
-+
-+#define __virt_to_phys(x)   ((x) - PAGE_OFFSET + PHYS_OFFSET)
-+#define __phys_to_virt(x)   ((x) - PHYS_OFFSET + PAGE_OFFSET)
-+
-+#define __virt_to_bus(x) __virt_to_phys(x)
-+#define __bus_to_virt(x) __phys_to_virt(x)
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+/*
-+ * Memory map aliased every 1GByte, i.e. top 2 bits are ignored.
-+ *
-+ * Currently (0X800) we have:
-+ *
-+ *  Start of physical memory: 0x08000000
-+ *                            0x48000000 - alias
-+ *                            0x88000000 - alias
-+ *                            0xC8000000 - alias
-+ *
-+ *  Node 0 SDRAM: 0x08000000 - 0x09FFFFFF   32MB populated
-+ *              : 0x48000000 - alias
-+ *              : 0x88000000 - alias
-+ *              : 0xC8000000 - alias
-+ *
-+ *  Node 1 SRAM : 0x0C000000 - 0x00008000   32KB populated
-+ *              : 0x4C000000 - alias
-+ *              : 0x8C000000 - alias
-+ *              : 0xCC000000 - alias
-+ *
-+ * It will be assumed that no single memory node can be larger than
-+ * (1 << NODE_MAX_MEM_SIZE) and that nodes will be contiguous, although
-+ * individual nodes may not be fully populated
-+ */
-+
-+/*
-+ * Given a kernel address, find the home node of the underlying memory.
-+ */
-+#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
-+
-+/*
-+ * Given a page frame number, convert it to a node id.
-+ */
-+#define PFN_TO_NID(pfn) (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
-+
-+/*
-+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
-+ * and return the mem_map of that node.
-+ */
-+#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
-+
-+/*
-+ * Given a page frame number, find the owning node of the memory
-+ * and return the mem_map of that node.
-+ */
-+#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
-+
-+/*
-+ * Given a kaddr, LOCAL_MAP_NR finds the owning node of the memory
-+ * and returns the index corresponding to the appropriate page in the
-+ * node's mem_map.
-+ */
-+#define LOCAL_MAP_NR(addr) (((unsigned long)(addr) & ((1 << NODE_MAX_MEM_SHIFT) - 1)) >> PAGE_SHIFT)
-+
-+#else
-+
-+#define PFN_TO_NID(addr) (0)
-+
-+#endif
-+
-+#endif // __ASM_ARCH_MEMORY_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,162 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/sata.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * Definitions for using the SATA core in the ox800
-+ */
-+
-+#ifndef __ASM_ARCH_SATA_H__
-+#define __ASM_ARCH_SATA_H__
-+
-+/* number of ports per interface */
-+#define OX810SATA_MAX_PORTS 1
-+
-+
-+/** sata host port register offsets */
-+#define OX810SATA_ORB1          (0x00 / sizeof(u32))
-+#define OX810SATA_ORB2          (0x04 / sizeof(u32))
-+#define OX810SATA_ORB3          (0x08 / sizeof(u32))
-+#define OX810SATA_ORB4          (0x0C / sizeof(u32))
-+#define OX810SATA_ORB5          (0x10 / sizeof(u32))
-+
-+#define OX810SATA_MASTER_STATUS  (0x10 / sizeof(u32))
-+#define OX810SATA_FIS_CTRL       (0x18 / sizeof(u32))
-+#define OX810SATA_FIS_DATA       (0x1C / sizeof(u32))
-+
-+#define OX810SATA_INT_STATUS     (0x30 / sizeof(u32))
-+#define OX810SATA_INT_CLEAR      (0x30 / sizeof(u32))
-+#define OX810SATA_INT_ENABLE     (0x34 / sizeof(u32))
-+#define OX810SATA_INT_DISABLE    (0x38 / sizeof(u32))
-+#define OX810SATA_VERSION        (0x3C / sizeof(u32))
-+#define OX810SATA_SATA_CONTROL   (0x5C / sizeof(u32))
-+#define OX810SATA_SATA_COMMAND   (0x60 / sizeof(u32))
-+#define OX810SATA_HID_FEATURES   (0x64 / sizeof(u32))
-+#define OX810SATA_PORT_CONTROL   (0x68 / sizeof(u32))
-+#define OX810SATA_DRIVE_CONTROL  (0x6C / sizeof(u32))
-+
-+/** These registers allow access to the link layer registers
-+that reside in a different clock domain to the processor bus */
-+#define OX810SATA_LINK_DATA      (0x70 / sizeof(u32))
-+#define OX810SATA_LINK_RD_ADDR   (0x74 / sizeof(u32))
-+#define OX810SATA_LINK_WR_ADDR   (0x78 / sizeof(u32))
-+#define OX810SATA_LINK_CONTROL   (0x7C / sizeof(u32))
-+
-+/** Backup registers contain a copy of the command sent to the disk */
-+#define OX810SATA_BACKUP1        (0xB0 / sizeof(u32))
-+#define OX810SATA_BACKUP2        (0xB4 / sizeof(u32))
-+#define OX810SATA_BACKUP3        (0xB8 / sizeof(u32))
-+#define OX810SATA_BACKUP4        (0xBC / sizeof(u32))
-+
-+/**
-+ * commands to issue in the master status to tell it to move shadow 
-+ * registers to the actual device 
-+ */
-+#define SATA_OPCODE_MASK                    0x00000007
-+#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND    0x4
-+#define CMD_WRITE_TO_ORB_REGS               0x2
-+#define CMD_SYNC_ESCAPE                     0x7
-+#define CMD_CORE_BUSY                       (1 << 7)
-+
-+/** interrupt bits */
-+#define OX810SATA_INT_END_OF_CMD      (1 << 0)
-+#define OX810SATA_INT_LINK_SERROR     (1 << 1)
-+#define OX810SATA_INT_ERROR           (1 << 2)
-+#define OX810SATA_INT_LINK_IRQ        (1 << 3)
-+#define OX810SATA_INT_REG_ACCESS_ERR  (1 << 7)
-+#define OX810SATA_INT_BIST_FIS        (1 << 11)
-+#define OX810SATA_INT_MASKABLE        (OX810SATA_INT_END_OF_CMD     |\
-+                                       OX810SATA_INT_LINK_SERROR    |\
-+                                       OX810SATA_INT_ERROR          |\
-+                                       OX810SATA_INT_LINK_IRQ       |\
-+                                       OX810SATA_INT_REG_ACCESS_ERR |\
-+                                       OX810SATA_INT_BIST_FIS       )
-+
-+#define OX810SATA_INT_WANT            (OX810SATA_INT_END_OF_CMD  |\
-+                                       OX810SATA_INT_LINK_SERROR |\
-+                                       OX810SATA_INT_REG_ACCESS_ERR |\
-+                                       OX810SATA_INT_ERROR       )                                        
-+                                       
-+/** raw interrupt bits, unmaskable, but do not generate interrupts */
-+#define OX810SATA_RAW_END_OF_CMD      (OX810SATA_INT_END_OF_CMD     << 16)
-+#define OX810SATA_RAW_LINK_SERROR     (OX810SATA_INT_LINK_SERROR    << 16)
-+#define OX810SATA_RAW_ERROR           (OX810SATA_INT_ERROR          << 16)
-+#define OX810SATA_RAW_LINK_IRQ        (OX810SATA_INT_LINK_IRQ       << 16)
-+#define OX810SATA_RAW_REG_ACCESS_ERR  (OX810SATA_INT_REG_ACCESS_ERR << 16)
-+#define OX810SATA_RAW_BIST_FIS        (OX810SATA_INT_BIST_FIS       << 16)
-+
-+/** SATA core register offsets */
-+#define OX810SATA_DM_DEBUG1           ( SATACORE_REGS_BASE + 0x000 )
-+#define OX810SATA_RAID_SET            ( SATACORE_REGS_BASE + 0x004 )
-+#define OX810SATA_DM_DEBUG2           ( SATACORE_REGS_BASE + 0x008 )
-+#define OX810SATA_CORE_ISR            ( SATACORE_REGS_BASE + 0x030 )
-+#define OX810SATA_CORE_IES            ( SATACORE_REGS_BASE + 0x034 )
-+#define OX810SATA_CORE_IEC            ( SATACORE_REGS_BASE + 0x038 )
-+#define OX810SATA_DEVICE_CONTROL      ( SATACORE_REGS_BASE + 0x068 )
-+#define OX810SATA_EXCESS              ( SATACORE_REGS_BASE + 0x06C )
-+#define OX810SATA_IDLE_STATUS         ( SATACORE_REGS_BASE + 0x07C )
-+#define OX810SATA_RAID_CONTROL        ( SATACORE_REGS_BASE + 0x090 )
-+
-+/** sata core control register bits */
-+#define OX810SATA_SCTL_CLR_ERR        (0x00003016)
-+
-+/* Interrupts direct from the ports */
-+#define OX810SATA_NORMAL_INTS_WANTED  (0x00000003)
-+
-+/* Interrupts from the RAID controller only */
-+#define OX810SATA_RAID_INTS_WANTED    (0x00008000)
-+
-+/* The bits in the OX810SATA_IDLE_STATUS that, when set indicate an idle core */
-+#define OX810SATA_IDLE_CORES          ((1 << 18) | (1 << 19))
-+
-+/** Device Control register bits */
-+#define OX810SATA_DEVICE_CONTROL_ABORT (1 << 2)
-+#define OX810SATA_DEVICE_CONTROL_PAD   (1 << 3)
-+#define OX810SATA_DEVICE_CONTROL_PADPAT (1 << 16)
-+
-+/** ORB4 register bits */
-+#define OX810SATA_ORB4_SRST	       (1 << 26)
-+
-+/** standard HW raid flags */
-+#define OXNASSATA_NOTRAID 3
-+#define OXNASSATA_RAID1 1
-+#define OXNASSATA_RAID0 0
-+#define OXNASSATA_RAID_TWODISKS 3
-+
-+/**
-+ * variables to write to the device control register to set the current device
-+ * ie, master or slave
-+ */
-+#define OX810SATA_DR_CON_48 2
-+#define OX810SATA_DR_CON_28 0
-+
-+/** A ficticious device id used for matching device and driver */
-+#define OX810SATA_DEVICEID 0x00100002
-+
-+/** The different Oxsemi SATA core version numbers */
-+#define OX810SATA_CORE_VERSION 0x1f2
-+
-+/** Occasionally we get interrupts, even though there is no outstanding command,
-+these can be caused by dodgy SATA cables, this is a divider for reporting these
-+interrupts */
-+#define OX810SATA_NO_CMD_ERROR_RPT_COUNT 8
-+            
-+extern int oxnassata_RAID_faults( void );
-+extern int oxnassata_get_port_no(struct request_queue* );
-+extern int oxnassata_LBA_schemes_compatible( void );
-+
-+#endif  /*  #if !defined(__ASM_ARCH_SATA_H__) */
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/sata.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,181 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/sata.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * Definitions for using the SATA core in the ox800
-+ */
-+
-+#ifndef __ASM_ARCH_SATA_H__
-+#define __ASM_ARCH_SATA_H__
-+
-+#include <linux/blkdev.h>
-+
-+/* number of ports per interface */
-+#define OX800SATA_MAX_PORTS 1
-+
-+
-+/** ata core register offsets */
-+#define OX800SATA_ORB1          (0x00 / sizeof(u32))
-+#define OX800SATA_ORB2          (0x04 / sizeof(u32))
-+#define OX800SATA_ORB3          (0x08 / sizeof(u32))
-+#define OX800SATA_ORB4          (0x0C / sizeof(u32))
-+#define OX800SATA_ORB5          (0x10 / sizeof(u32))
-+
-+#define OX800SATA_MASTER_STATUS  (0x10 / sizeof(u32))
-+#define OX800SATA_DEVICE_CTRL    (0x18 / sizeof(u32))
-+#define OX800SATA_REG_ACCESS     (0x2c / sizeof(u32))
-+#define OX800SATA_INT_STATUS     (0x30 / sizeof(u32))
-+#define OX800SATA_INT_CLEAR      (0x30 / sizeof(u32))
-+#define OX800SATA_INT_ENABLE     (0x34 / sizeof(u32))
-+#define OX800SATA_INT_DISABLE    (0x38 / sizeof(u32))
-+#define OX800SATA_VERSION        (0x3C / sizeof(u32))
-+#define OX800SATA_SATA_CONTROL   (0x5C / sizeof(u32))
-+#define OX800SATA_SATA_COMMAND   (0x60 / sizeof(u32))
-+#define OX800SATA_DEVICE_SELECT  (0x64 / sizeof(u32))
-+#define OX800SATA_DEVICE_CONTROL (0x68 / sizeof(u32))
-+#define OX800SATA_DRIVE_CONTROL  (0x6C / sizeof(u32))
-+
-+/** ata core registers that only work on port 0 */
-+#define OX800SATA_BURST_BUFFER  (0x1C / sizeof(u32))
-+#define OX800SATA_BURST_CONTROL (0x48 / sizeof(u32))
-+#define OX800SATA_RAID_CONTROL  (0x70 / sizeof(u32))
-+
-+
-+
-+
-+/** These registers allow access to the link layer registers
-+that reside in a different clock domain to the processor bus */
-+#define OX800SATA_LINK_DATA     (0x00000000)
-+#define OX800SATA_LINK_RD_ADDR  (0x00000001)
-+#define OX800SATA_LINK_WR_ADDR  (0x00000002)
-+#define OX800SATA_LINK_CONTROL  (0x00000003)
-+
-+/**
-+ * commands to issue in the master status to tell it to move shhadow 
-+ * registers to the actual device 
-+ */
-+#define OX800SATA_MASTER_STATUS_WRITEOP 6 | (1 << 31)  
-+#define OX800SATA_MASTER_STATUS_READOP  5 | (1 << 31) | (1 << 29)
-+#define OX800SATA_MASTER_STATUS_ORBWRITEOP 1 | (1 << 31)  
-+#define OX800SATA_MASTER_STATUS_ORBWRITE_RUN  2 | (1 << 31) | (1 << 29)
-+#define OX800SATA_MASTER_STATUS_READY 64
-+#define OX800SATA_MASTER_STATUS_BUSY 128
-+
-+#define OX800SATA_ORB2_SECTORS_MASK (0x0000ffff)
-+
-+#define SATA_OPCODE_MASK                    0x00000003
-+#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND    0x01
-+#define CMD_WRITE_TO_ORB_REGS               0x02
-+#define CMD_READ_ALL_REGISTERS              0x03
-+#define CMD_READ_STATUS_REG                 0x04
-+#define CMD_CORE_BUSY                       (1 << 7)
-+
-+/** interrupt bits */
-+#define OX800SATA_INT_END_OF_CMD      (1 << 0)
-+#define OX800SATA_INT_END_OF_DATA_CMD (1 << 1)
-+#define OX800SATA_INT_ERROR           (1 << 2)
-+#define OX800SATA_INT_FIFO_EMPTY      (1 << 3)
-+#define OX800SATA_INT_FIFO_FULL       (1 << 4)
-+#define OX800SATA_INT_END_OF_TRANSF   (1 << 5)
-+#define OX800SATA_INT_MASKABLE        (OX800SATA_INT_END_OF_CMD      |\
-+                                       OX800SATA_INT_END_OF_DATA_CMD |\
-+                                       OX800SATA_INT_ERROR           |\
-+                                       OX800SATA_INT_FIFO_EMPTY      |\
-+                                       OX800SATA_INT_FIFO_FULL       |\
-+                                       OX800SATA_INT_END_OF_TRANSF   )
-+
-+/** raw interrupt bits, unmaskable, but do not generate interrupts */
-+#define OX800SATA_RAW_END_OF_CMD      (1 << 8)
-+#define OX800SATA_RAW_END_OF_DATA_CMD (1 << 9)
-+#define OX800SATA_RAW_ERROR           (1 << 10)
-+#define OX800SATA_RAW_FIFO_EMPTY      (1 << 11)
-+#define OX800SATA_RAW_FIFO_FULL       (1 << 12)
-+#define OX800SATA_RAW_END_OF_TRANSF   (1 << 13)
-+
-+/** burst buffer control bits */
-+#define OX800SATA_BBC_FORCE_EOT       (1 << 0)
-+#define OX800SATA_BBC_DIRECTION       (1 << 2)
-+#define OX800SATA_BBC_FIFO_DIS        (1 << 4)
-+#define OX800SATA_BBC_DREQ_DIS        (1 << 5)
-+#define OX800SATA_BBC_DREQ            (1 << 6)
-+
-+/** sata control register bits */
-+#define OX800SATA_SCTL_RESET          (1 << 0)
-+#define OX800SATA_SCTL_ABORT          (1 << 2)
-+
-+/** Device Control register bits */
-+#define OX800SATA_DEVICE_CONTROL_ABORT (1 << 2)
-+
-+/** ORB4 register bits */
-+#define OX800SATA_ORB4_SRST	       (1 << 26)
-+
-+/** SATA control transport state machine mask */
-+#define OX800SATA_SATA_CONTROL_TRANS_MASK  (0x0000001e)
-+#define OX800SATA_TRANS_CHECKTYPE     (0x00000008)
-+#define OX800SATA_TRANS_PIOITRANS     (0x00000018)
-+#define OX800SATA_TRANS_PIOOTRANS     (0x0000001C)
-+
-+/** RAID control bit definitions */
-+#define OX800SATA_RAID_SPAN_EN        (1 <<  0)
-+#define OX800SATA_RAID_STRI_EN        (1 <<  1)
-+#define OX800SATA_RAID_STRI16         (1 <<  2)
-+#define OX800SATA_RAID_STRI32         (1 <<  3)
-+#define OX800SATA_RAID_STRI64         (1 <<  4)
-+#define OX800SATA_RAID_STRI128        (1 <<  5)
-+#define OX800SATA_RAID_STRI256        (1 <<  6)
-+#define OX800SATA_RAID_STRI512        (1 <<  7)
-+#define OX800SATA_RAID_STRI1M         (1 <<  8)
-+#define OX800SATA_RAID_STRI2M         (1 <<  9)
-+#define OX800SATA_RAID_STRI_TEST      (1 << 10)
-+#define OX800SATA_RAID_XSOFF2         (0 << 11)
-+#define OX800SATA_RAID_XSOFF4         (1 << 11)
-+#define OX800SATA_RAID_XSOFF6         (2 << 11)
-+#define OX800SATA_RAID_XSOFF8         (3 << 11)
-+#define OX800SATA_RAID_LOOP_BK        (1 << 12)
-+#define OX800SATA_RAID_MIR0           (0 << 13)
-+#define OX800SATA_RAID_MIR1           (1 << 13)
-+#define OX800SATA_RAID_MIRALT         (2 << 13)
-+#define OX800SATA_RAID_MIR_EN         (1 << 16)
-+#define OX800SATA_RAID_OVERLAP        (1 << 23)
-+
-+/* standard HW raid flags */
-+#define OXNASSATA_RAID1 (OX800SATA_RAID_MIR0 | OX800SATA_RAID_MIR_EN | OX800SATA_RAID_OVERLAP )
-+#define OXNASSATA_RAID0 (OX800SATA_RAID_OVERLAP | OX800SATA_RAID_STRI_EN )
-+/**
-+ * variables to write to the device control register to set the current device
-+ * ie, master or slave
-+ */
-+#define OX800SATA_DEVICE_CONTROL_MASTER 0
-+#define OX800SATA_DEVICE_CONTROL_SLAVE  1
-+
-+/** A ficticious device id used for matching device and driver */
-+#define OX800SATA_DEVICEID 0x00100001
-+
-+/** The different Oxsemi SATA core version numbers */
-+#define OX800SATA_CORE_VERSION 0xf0
-+
-+/** Occasionally we get interrupts, even though there is no outstanding command,
-+these can be caused by dodgy SATA cables, this is a divider for reporting these
-+interrupts */
-+#define OX800SATA_NO_CMD_ERROR_RPT_COUNT 8
-+            
-+extern int oxnassata_RAID_faults( void );
-+extern int oxnassata_get_port_no(struct request_queue* );
-+extern int oxnassata_LBA_schemes_compatible( void );
-+
-+#endif  /*  #if !defined(__ASM_ARCH_SATA_H__) */
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/system.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/system.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,103 @@
-+/* linux/include/asm-arm/arch-oxnas/system.h
-+ *
-+ * 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_SYSTEM_H
-+#define __ASM_ARCH_SYSTEM_H
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+extern void sata_power_off(void);
-+extern int oxnas_global_invert_leds;
-+
-+#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
-+#include <asm/arch/leon.h>
-+#include <asm/arch/leon-power-button-prog.h>
-+#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
-+
-+static inline void arch_idle(void)
-+{
-+    /*
-+     * This should do all the clock switching
-+     * and wait for interrupt tricks
-+     */
-+    cpu_do_idle();
-+}
-+
-+static void disable_gmac(void)
-+{
-+    writel((1UL << SYS_CTRL_RSTEN_MAC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+    writel((1UL << SYS_CTRL_CKEN_MAC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
-+}
-+
-+static void arch_poweroff(void)
-+{
-+	disable_gmac();
-+
-+#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
-+    // Load CoPro program and start it running
-+    init_copro(leon_srec, oxnas_global_invert_leds);
-+#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
-+
-+    // Turn of power to SATA disk if possible
-+    sata_power_off();
-+}
-+
-+static void arch_reset(char mode)
-+{
-+    // Assert reset to cores as per power on defaults
-+    writel((1UL << SYS_CTRL_RSTEN_COPRO_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_USBHS_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
-+           (1UL << SYS_CTRL_RSTEN_MAC_BIT)      |
-+           (1UL << SYS_CTRL_RSTEN_PCI_BIT)      |
-+           (1UL << SYS_CTRL_RSTEN_DMA_BIT)      |
-+           (1UL << SYS_CTRL_RSTEN_DPE_BIT)      |
-+           (1UL << SYS_CTRL_RSTEN_SATA_BIT)     |
-+           (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+           (1UL << SYS_CTRL_RSTEN_STATIC_BIT)   |
-+           (1UL << SYS_CTRL_RSTEN_UART1_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_UART2_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_MISC_BIT)     |
-+           (1UL << SYS_CTRL_RSTEN_I2S_BIT)      |
-+           (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT)  |
-+           (1UL << SYS_CTRL_RSTEN_UART3_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_UART4_BIT)    |
-+           (1UL << SYS_CTRL_RSTEN_SGDMA_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+
-+    // Release reset to cores as per power on defaults
-+    writel((1UL << SYS_CTRL_RSTEN_GPIO_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+    // Disable clocks to cores as per power-on defaults
-+    writel((1UL << SYS_CTRL_CKEN_COPRO_BIT) |
-+           (1UL << SYS_CTRL_CKEN_DMA_BIT)   |
-+           (1UL << SYS_CTRL_CKEN_DPE_BIT)   |
-+           (1UL << SYS_CTRL_CKEN_SATA_BIT)  |
-+           (1UL << SYS_CTRL_CKEN_I2S_BIT)   |
-+           (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
-+           (1UL << SYS_CTRL_CKEN_MAC_BIT)   |
-+           (1UL << SYS_CTRL_CKEN_STATIC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
-+
-+    // Enable clocks to cores as per power-on defaults
-+    writel((1UL << SYS_CTRL_CKEN_PCI_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+    // Set sys-control pin mux'ing as per power-on defaults
-+    writel(0x800UL, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+    writel(0x0UL,   SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
-+    writel(0x0UL,   SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+    writel(0x0UL,   SYS_CTRL_GPIO_SECSEL_CTRL_1);
-+    writel(0x0UL,   SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+    writel(0x0UL,   SYS_CTRL_GPIO_TERTSEL_CTRL_1);
-+
-+    // No need to save any state, as the ROM loader can determine whether reset
-+    // is due to power cycling or programatic action, just hit the (self-
-+    // clearing) CPU reset bit of the block reset register
-+    writel(1UL << SYS_CTRL_RSTEN_ARM_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+}
-+
-+#endif // __ASM_ARCH_SYSTEM_H
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/taco.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/taco.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,227 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/tacho.h
-+ * 
-+ * 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_ARM_ARCH_TACHO_H
-+#define __ASM_ARM_ARCH_TACHO_H
-+
-+#include "hardware.h"
-+
-+/* Routines ----------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+/**
-+ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
-+ */
-+extern void DumpTachoRegisters(void);
-+
-+
-+/**
-+ * GetTemperature will read the thermistor register and convert the value to 
-+ * kelvin.
-+ * @return an int that represents the thermister temperature in Kelvin, or a
-+ * negative value in the case of error.
-+ */
-+extern int GetTemperature(void);
-+
-+
-+/**
-+ * GetFanRPM will read the fan tacho register and convert the value to 
-+ * RPM.
-+ * @return an int that represents the fan speed in RPM, or a
-+ * negative value in the case of error.
-+ */
-+extern int GetFanRPM(void);
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X810
-+#define OXNAS_TACHO_Ox810
-+#endif
-+
-+
-+#ifndef OXNAS_TACHO_Ox810
-+#define DEGREES_C_0                     273
-+#define TACHO_TARGET_THERM_FREQ_HZ      1000000
-+#define TACHO_CORE_THERM_DIVIDER_VALUE    (((NOMINAL_SYSCLK / TACHO_TARGET_THERM_FREQ_HZ) - 1)) 
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#define TACHO_TARGET_CORE_FREQ_HZ       128000
-+#define TACHO_CORE_TACHO_DIVIDER_VALUE    (((NOMINAL_SYSCLK / TACHO_TARGET_CORE_FREQ_HZ) - 1))
-+
-+#ifndef OXNAS_TACHO_Ox810
-+#define TACHO_FAN_SPEED_DIVIDER         (64)
-+#endif /*OXNAS_TACHO_Ox810 */
-+
-+#define SECONDARY_FUNCTION_ENABLE_FAN_PWM2 	8
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TEMP 	29
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TACHO 	30
-+
-+#ifdef OXNAS_TACHO_Ox810
-+#define TEMP_TACHO_PULLUP_CTRL_VALUE 		0x20000000
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+// 256kHz with 50MHz pclk (reset value)
-+#ifdef OXNAS_TACHO_Ox810
-+#define PWM_CORE_CLK_DIVIDER_VALUE      (130)
-+#else /* OXNAS_TACHO_Ox810 */
-+#define PWM_CORE_CLK_DIVIDER_VALUE      (194)
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* Registers ---------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+/* FAN Speed Counter ----------------------------------- */
-+
-+#ifdef OXNAS_TACHO_Ox810
-+
-+#define TACHO_FAN_SPEED_COUNTER                    (FAN_MON_BASE + 0x00)
-+    // 31:17 - RO - Unused (0x00)
-+	// 16 	 - R0 - Fan Count Valid - used in one shot mode
-+	// 15:10 - R0 - Unused
-+    //  9:0  - RO - Fan counter value. (See DD for conversion to rpm)
-+    #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT       0
-+	#define TACHO_FAN_SPEED_COUNTER_COUNT_VALID 	16
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+#define TACHO_FAN_SPEED_COUNTER                    (FAN_MON_BASE + 0x00)
-+    // 31:10 - RO - Unused (0x00)
-+    //  9:0  - RO - Fan counter value. (See DD for conversion to rpm)
-+    #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT       0  
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+	#define TACHO_FAN_SPEED_COUNTER_MASK 	1023
-+
-+/* Thermistor RC Counter ------------------------------- */
-+#define TACHO_THERMISTOR_RC_COUNTER                (FAN_MON_BASE + 0x04)
-+    // 31:10 - RO - Unused (0x00)
-+    //  9:0  - RO - Thermistor counter value (See DD for conversion to temperature)
-+    #define TACHO_THERMISTOR_RC_COUNTER_THERM_COUNT 0
-+
-+	#define TACHO_THERMISTOR_RC_COUNTER_MASK 	1023
-+
-+
-+/* Thermistor Control ---------------------------------- */
-+#define TACHO_THERMISTOR_CONTROL                   (FAN_MON_BASE + 0x08)
-+    // 31:2  - RO - Unused (0x00)
-+    //  1:1  - R0 � THERM_COUNT value is valid
-+    //  0:0  - RW - Set to 1 to enable thermistor PWM output
-+    #define TACHO_THERMISTOR_CONTROL_THERM_VALID    1
-+    #define TACHO_THERMISTOR_CONTROL_THERM_ENABLE   0 
-+
-+
-+/* Clock divider ---------------------------- */
-+#define TACHO_CLOCK_DIVIDER                        (FAN_MON_BASE + 0x0C)
-+    // 31:10 - RO - Unused (0x00)
-+    //  0:9  - RW - set PWM effective clock frequency to a division of pclk (0x030C )
-+    //         0000 � pclk divided by 1 (=pclk)
-+    //         0001 - pclk divided by 2
-+    //         0780 - ~128kHz with 100MHz pclk (reset value)
-+    //         1023 - pclk divided by 1024
-+    #define TACHO_CLOCK_DIVIDER_PWM_DIVIDER         0 
-+	#define TACHO_CLOCK_DIVIDER_MASK 	1023 
-+
-+
-+/* New hardware registers added for 810 */
-+#ifdef OXNAS_TACHO_Ox810 
-+
-+/* Fan Speed Control ..........................*/
-+#define TACHO_FAN_SPEED_CONTROL 					(FAN_MON_BASE + 0x10)
-+	// 31:N+16 - R0 - Unused (0x0000)
-+	// N+15:16 - RW - Select PWM which controls FAN speed
-+	// 15:1 - 		  Unused 0
-+	// 0 	-	 RW - Fan Count mode 0 - Continuous running mode 1 - One shot mode
-+	#define TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE 	16
-+	#define TACHO_FAN_SPEED_CONTROL_PWM_USED 			2
-+	#define TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE 		0
-+
-+
-+/* Fan One Shot Control .........................*/
-+#define TACHO_FAN_ONE_SHOT_CONTROL 					(FAN_MON_BASE + 0x14)
-+	// 31:1 - R - Unused
-+	// 0 - W - Start One-shot - Tacho - Self Clearing bit
-+	#define TACHO_FAN_ONE_SHOT_CONTROL_START 			0
-+   
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* PWM SECTION ------------------------------ */
-+
-+// 0x00 Channel 0 PWM data 
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define  PWM_DATA_0 (PWM_BASE+0x00) 
-+    // value    0  � Output aways lo
-+    // value    1  � hi for 1 clock, lo for 255
-+    // . . . 
-+    // value   127 � 50:50 hi/lo
-+    // . . .
-+    // value   255 � hi for 255 clocks, lo for 1
-+    
-+// 0x04 Channel 1 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define  PWM_DATA_1 (PWM_BASE+0x04) 
-+    // value    0  � Output aways lo
-+    // value    1  � hi for 1 clock, lo for 255
-+    // . . . 
-+    // value   127 � 50:50 hi/lo
-+    // . . .
-+    // value   255 � hi for 255 clocks, lo for 1
-+    
-+// 0x08 Channel 2 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define  PWM_DATA_2 (PWM_BASE+0x08) 
-+    // value    0  � Output aways lo
-+    // value    1  � hi for 1 clock, lo for 255
-+    // . . . 
-+    // value   127 � 50:50 hi/lo
-+    // . . .
-+    // value   255 � hi for 255 clocks, lo for 1
-+    
-+// 0x0C Channel 3 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define  PWM_DATA_3 (PWM_BASE+0x0C) 
-+    // value    0  � Output aways lo
-+    // value    1  � hi for 1 clock, lo for 255
-+    // . . . 
-+    // value   127 � 50:50 hi/lo
-+    // . . .
-+    // value   255 � hi for 255 clocks, lo for 1
-+
-+#ifdef OXNAS_TACHO_Ox810
-+//0x400 PWM Clock Divider
-+// 15:0 R/W 0x00C2
-+// 31:16 Unused R 0x0000 Unused
-+#define  PWM_CLOCK_DIVIDER (PWM_BASE+0x400)
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+// 0x10 PWM clock divider
-+// 15:0 R/W 0x00C2
-+// 31:16 Unused R 0x0000 Unused
-+#define  PWM_CLOCK_DIVIDER (PWM_BASE+0x10) 
-+    // set PWM effective clock frequency to a division of pclk
-+    // value      0 � pclk divided by 1 (=pclk)
-+    // value      1 � pclk divided by 2
-+    // value    194 � 256kHz with 50MHz pclk (reset value)
-+    // . . .
-+    // value  65535 � pclk divided by 65536
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#endif // __ASM_ARM_ARCH_TACHO_H
-+
-+/* End oF File */
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/timex.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/timex.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,23 @@
-+/* linux/include/asm-arm/arch-oxnas/timex.h
-+ *
-+ * 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_TIMEX_H
-+#define __ASM_ARCH_TIMEX_H
-+
-+#define TIMER_PRESCALE_BIT      2
-+#define TIMER_PRESCALE_1        0
-+#define TIMER_PRESCALE_16       1
-+#define TIMER_PRESCALE_256      2
-+
-+#define TIMER_INPUT_CLOCK      CONFIG_NOMINAL_RPSCLK_FREQ
-+#define TIMER_1_PRESCALE_ENUM  TIMER_PRESCALE_16
-+#define TIMER_1_PRESCALE_VALUE (1 << (TIMER_1_PRESCALE_ENUM * 4))
-+#define TIMER_1_PRESCALED_CLK  (TIMER_INPUT_CLOCK / TIMER_1_PRESCALE_VALUE)
-+
-+#define CLOCK_TICK_RATE (TIMER_1_PRESCALED_CLK)
-+
-+#endif // __ASM_ARCH_TIMEX_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,43 @@
-+/* linux/include/asm-arm/arch-oxnas0/uncompress.h
-+ *
-+ * 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_UNCOMPRESS_H
-+#define __ASM_ARCH_UNCOMPRESS_H
-+
-+#include <asm/arch/hardware.h>
-+
-+static inline void putc(int c)
-+{
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+    static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART2)
-+    static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART3)
-+    static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART4)
-+    static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
-+#else
-+#define NO_UART
-+#endif
-+
-+#ifndef NO_UART
-+    while (!(uart[5] & 0x20)) { /* LSR reg THR empty bit */
-+        barrier();
-+    }
-+    uart[0] = c;                /* THR register */
-+#endif // NO_UART
-+}
-+
-+static inline void flush(void)
-+{
-+}
-+
-+#define arch_decomp_setup()
-+
-+#define arch_decomp_wdog()
-+
-+#endif // __ASM_ARCH_UNCOMPRESS_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h	2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,29 @@
-+/* linux/include/asm-arm/arch-oxnas/vmalloc.h
-+ *
-+ * 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_VMALLOC_H
-+#define __ASM_ARCH_VMALLOC_H
-+
-+/*
-+ * Just any arbitrary offset to the start of the vmalloc VM area: the
-+ * current 8MB value just means that there will be a 8MB "hole" after the
-+ * physical memory until the kernel virtual memory starts.  That means that
-+ * any out-of-bounds memory accesses will hopefully be caught.
-+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
-+ * area for the same reason. ;)
-+ */
-+
-+#define VMALLOC_OFFSET      (8*1024*1024)
-+/* Fix the VMALLOC start adr from the maximum possible SDRAM adr, so that
-+ * it's possible to have Linux use only part of the available SDRAM without
-+ * vmalloc/ioremap aliasing with the kernel mapping of the entire SDRAM */
-+#define MAX_SDRAM_ADR       (__phys_to_virt(SDRAM_PA) + (SDRAM_SIZE))
-+#define VMALLOC_START       (((unsigned long)MAX_SDRAM_ADR + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-+#define VMALLOC_VMADDR(x)   ((unsigned long)(x))
-+#define VMALLOC_END	         (0xE0000000)
-+
-+#endif // __ASM_ARCH_VMALLOC_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h
---- linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h	2008-06-11 17:45:03.000000000 +0200
-@@ -1669,6 +1669,7 @@
- #define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */
- #define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */
- #define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */
-+#define SSCR1_IFS		(1 << 16)	/* Invert Frame Signal */
- #define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */
- #define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */
- 
-diff -Nurd linux-2.6.24/include/asm-arm/assembler.h linux-2.6.24-oxe810/include/asm-arm/assembler.h
---- linux-2.6.24/include/asm-arm/assembler.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/assembler.h	2008-06-11 17:45:14.000000000 +0200
-@@ -48,8 +48,10 @@
- 
- /*
-  * Data preload for architectures that support it
-+ * OXNAS altered to >= 6 from >= 5 as 926 supports pld, but implements it as
-+ * nop, so wastes instruction cycles to include pld support
-  */
--#if __LINUX_ARM_ARCH__ >= 5
-+#if __LINUX_ARM_ARCH__ >= 6
- #define PLD(code...)	code
- #else
- #define PLD(code...)
-diff -Nurd linux-2.6.24/include/asm-arm/io.h linux-2.6.24-oxe810/include/asm-arm/io.h
---- linux-2.6.24/include/asm-arm/io.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/io.h	2008-06-11 17:45:14.000000000 +0200
-@@ -108,27 +108,24 @@
-  *
-  * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
-  */
--#ifdef __io
--#define outb(v,p)		__raw_writeb(v,__io(p))
--#define outw(v,p)		__raw_writew((__force __u16) \
--					cpu_to_le16(v),__io(p))
--#define outl(v,p)		__raw_writel((__force __u32) \
--					cpu_to_le32(v),__io(p))
-+extern unsigned int pciio_read( u32 addr, unsigned int size );
-+extern void pciio_write(unsigned int   data, u32 addr, unsigned int size );
- 
--#define inb(p)	({ __u8 __v = __raw_readb(__io(p)); __v; })
--#define inw(p)	({ __u16 __v = le16_to_cpu((__force __le16) \
--			__raw_readw(__io(p))); __v; })
--#define inl(p)	({ __u32 __v = le32_to_cpu((__force __le32) \
--			__raw_readl(__io(p))); __v; })
-+extern void outb(unsigned char  v, u32 p);
-+extern void outw(unsigned short v, u32 p);
-+extern void outl(unsigned long  v, u32 p);
- 
--#define outsb(p,d,l)		__raw_writesb(__io(p),d,l)
--#define outsw(p,d,l)		__raw_writesw(__io(p),d,l)
--#define outsl(p,d,l)		__raw_writesl(__io(p),d,l)
-+extern unsigned char   inb(u32 p);
-+extern unsigned short  inw(u32 p);
-+extern unsigned long   inl(u32 p);
- 
--#define insb(p,d,l)		__raw_readsb(__io(p),d,l)
--#define insw(p,d,l)		__raw_readsw(__io(p),d,l)
--#define insl(p,d,l)		__raw_readsl(__io(p),d,l)
--#endif
-+extern void outsb(u32 p, unsigned char  * from, u32 len);
-+extern void outsw(u32 p, unsigned short * from, u32 len);
-+extern void outsl(u32 p, unsigned long  * from, u32 len);
-+
-+extern void insb(u32 p, unsigned char  * to, u32 len);	
-+extern void insw(u32 p, unsigned short * to, u32 len);	
-+extern void insl(u32 p, unsigned long  * to, u32 len);	
- 
- #define outb_p(val,port)	outb((val),(port))
- #define outw_p(val,port)	outw((val),(port))
-diff -Nurd linux-2.6.24/include/asm-arm/uaccess.h linux-2.6.24-oxe810/include/asm-arm/uaccess.h
---- linux-2.6.24/include/asm-arm/uaccess.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/uaccess.h	2008-06-11 17:45:14.000000000 +0200
-@@ -383,9 +383,30 @@
- 
- 
- #ifdef CONFIG_MMU
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+extern unsigned long __must_check __copy_from_user_alt(void *to, const void __user *from, unsigned long n);
-+static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
-+{
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_from_user() %lu bytes\n", n);
-+	return __copy_from_user_alt(to, from , n);
-+}
-+extern unsigned long __must_check __copy_to_user_alt(void __user *to, const void *from, unsigned long n);
-+static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
-+{
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_to_user() %lu bytes\n", n);
-+	return __copy_to_user_alt(to, from , n);
-+}
-+extern unsigned long __must_check __clear_user_alt(void __user *addr, unsigned long n);
-+static inline unsigned long __must_check __clear_user(void __user *addr, unsigned long n)
-+{
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__clear_user() %lu bytes\n", n);
-+	return __clear_user_alt(addr, n);
-+}
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
- extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
- extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- #else
- #define __copy_from_user(to,from,n)	(memcpy(to, (void __force *)from, n), 0)
- #define __copy_to_user(to,from,n)	(memcpy((void __force *)to, from, n), 0)
-@@ -397,8 +418,15 @@
- 
- static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_from_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	if (access_ok(VERIFY_READ, from, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+		n = __copy_from_user_alt(to, from, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- 		n = __copy_from_user(to, from, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	else /* security hole - plug it */
- 		memzero(to, n);
- 	return n;
-@@ -406,8 +434,15 @@
- 
- static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_to_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	if (access_ok(VERIFY_WRITE, to, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+		n = __copy_to_user_alt(to, from, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- 		n = __copy_to_user(to, from, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	return n;
- }
- 
-@@ -416,8 +451,15 @@
- 
- static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+	if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("clear_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	if (access_ok(VERIFY_WRITE, to, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+		n = __clear_user_alt(to, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- 		n = __clear_user(to, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- 	return n;
- }
- 
-diff -Nurd linux-2.6.24/include/asm-arm/unaligned.h linux-2.6.24-oxe810/include/asm-arm/unaligned.h
---- linux-2.6.24/include/asm-arm/unaligned.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/unaligned.h	2008-06-11 17:45:14.000000000 +0200
-@@ -40,16 +40,16 @@
-  */
- 
- #define __get_unaligned_2_le(__p)					\
--	(__p[0] | __p[1] << 8)
-+	(unsigned int)(__p[0] | __p[1] << 8)
- 
- #define __get_unaligned_2_be(__p)					\
--	(__p[0] << 8 | __p[1])
-+	(unsigned int)(__p[0] << 8 | __p[1])
- 
- #define __get_unaligned_4_le(__p)					\
--	(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
-+	(unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
- 
- #define __get_unaligned_4_be(__p)					\
--	(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
-+	(unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
- 
- #define __get_unaligned_8_le(__p)					\
- 	((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 |	\
-diff -Nurd linux-2.6.24/include/asm-arm/unistd.h linux-2.6.24-oxe810/include/asm-arm/unistd.h
---- linux-2.6.24/include/asm-arm/unistd.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/unistd.h	2008-06-11 17:45:14.000000000 +0200
-@@ -379,6 +379,7 @@
- #define __NR_timerfd			(__NR_SYSCALL_BASE+350)
- #define __NR_eventfd			(__NR_SYSCALL_BASE+351)
- #define __NR_fallocate			(__NR_SYSCALL_BASE+352)
-+#define __NR_samba_reserve		(__NR_SYSCALL_BASE+353)
- 
- /*
-  * The following SWIs are ARM private.
-diff -Nurd linux-2.6.24/include/asm-powerpc/pmac_feature.h linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h
---- linux-2.6.24/include/asm-powerpc/pmac_feature.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h	2008-06-11 17:44:57.000000000 +0200
-@@ -392,6 +392,14 @@
- #define UN_BIS(r,v)	(UN_OUT((r), UN_IN(r) | (v)))
- #define UN_BIC(r,v)	(UN_OUT((r), UN_IN(r) & ~(v)))
- 
-+/* Uninorth variant:
-+ *
-+ * 0 = not uninorth
-+ * 1 = U1.x or U2.x
-+ * 3 = U3
-+ * 4 = U4
-+ */
-+extern int pmac_get_uninorth_variant(void);
- 
- #endif /* __ASM_POWERPC_PMAC_FEATURE_H */
- #endif /* __KERNEL__ */
-diff -Nurd linux-2.6.24/include/asm-x86/apic_32.h linux-2.6.24-oxe810/include/asm-x86/apic_32.h
---- linux-2.6.24/include/asm-x86/apic_32.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/apic_32.h	2008-06-11 17:44:30.000000000 +0200
-@@ -109,7 +109,7 @@
- extern void setup_secondary_APIC_clock (void);
- extern int APIC_init_uniprocessor (void);
- 
--extern void enable_NMI_through_LVT0 (void * dummy);
-+extern void enable_NMI_through_LVT0(void);
- 
- #define ARCH_APICTIMER_STOPS_ON_C3	1
- 
-diff -Nurd linux-2.6.24/include/asm-x86/futex_32.h linux-2.6.24-oxe810/include/asm-x86/futex_32.h
---- linux-2.6.24/include/asm-x86/futex_32.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/futex_32.h	2008-06-11 17:44:30.000000000 +0200
-@@ -28,7 +28,7 @@
- "1:	movl	%2, %0\n\
- 	movl	%0, %3\n"					\
- 	insn "\n"						\
--"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2:	lock ; cmpxchgl %3, %2\n\
- 	jnz	1b\n\
- 3:	.section .fixup,\"ax\"\n\
- 4:	mov	%5, %1\n\
-@@ -68,7 +68,7 @@
- #endif
- 		switch (op) {
- 		case FUTEX_OP_ADD:
--			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
-+			__futex_atomic_op1("lock ; xaddl %0, %2", ret,
- 					   oldval, uaddr, oparg);
- 			break;
- 		case FUTEX_OP_OR:
-@@ -111,7 +111,7 @@
- 		return -EFAULT;
- 
- 	__asm__ __volatile__(
--		"1:	" LOCK_PREFIX "cmpxchgl %3, %1		\n"
-+		"1:	lock ; cmpxchgl %3, %1			\n"
- 
- 		"2:	.section .fixup, \"ax\"			\n"
- 		"3:	mov     %2, %0				\n"
-diff -Nurd linux-2.6.24/include/asm-x86/futex_64.h linux-2.6.24-oxe810/include/asm-x86/futex_64.h
---- linux-2.6.24/include/asm-x86/futex_64.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/futex_64.h	2008-06-11 17:44:30.000000000 +0200
-@@ -27,7 +27,7 @@
- "1:	movl	%2, %0\n\
- 	movl	%0, %3\n"					\
- 	insn "\n"						\
--"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2:	lock ; cmpxchgl %3, %2\n\
- 	jnz	1b\n\
- 3:	.section .fixup,\"ax\"\n\
- 4:	mov	%5, %1\n\
-@@ -62,7 +62,7 @@
- 		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
- 		break;
- 	case FUTEX_OP_ADD:
--		__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
-+		__futex_atomic_op1("lock ; xaddl %0, %2", ret, oldval,
- 				   uaddr, oparg);
- 		break;
- 	case FUTEX_OP_OR:
-@@ -101,7 +101,7 @@
- 		return -EFAULT;
- 
- 	__asm__ __volatile__(
--		"1:	" LOCK_PREFIX "cmpxchgl %3, %1		\n"
-+		"1:	lock ; cmpxchgl %3, %1			\n"
- 
- 		"2:	.section .fixup, \"ax\"			\n"
- 		"3:	mov     %2, %0				\n"
-diff -Nurd linux-2.6.24/include/asm-x86/io_apic_64.h linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h
---- linux-2.6.24/include/asm-x86/io_apic_64.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h	2008-06-11 17:44:30.000000000 +0200
-@@ -129,7 +129,7 @@
- 
- extern int sis_apic_bug; /* dummy */ 
- 
--void enable_NMI_through_LVT0 (void * dummy);
-+void enable_NMI_through_LVT0(void);
- 
- extern spinlock_t i8259A_lock;
- 
-diff -Nurd linux-2.6.24/include/asm-x86/processor_32.h linux-2.6.24-oxe810/include/asm-x86/processor_32.h
---- linux-2.6.24/include/asm-x86/processor_32.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/processor_32.h	2008-06-11 17:44:30.000000000 +0200
-@@ -712,9 +712,10 @@
- #define ASM_NOP6 K7_NOP6
- #define ASM_NOP7 K7_NOP7
- #define ASM_NOP8 K7_NOP8
--#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
-+#elif (defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
-       defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
--      defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
-+      defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)) && \
-+      !defined(CONFIG_X86_GENERIC)
- #define ASM_NOP1 P6_NOP1
- #define ASM_NOP2 P6_NOP2
- #define ASM_NOP3 P6_NOP3
-diff -Nurd linux-2.6.24/include/linux/bio.h linux-2.6.24-oxe810/include/linux/bio.h
---- linux-2.6.24/include/linux/bio.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/bio.h	2008-06-11 17:45:39.000000000 +0200
-@@ -114,6 +114,15 @@
- 	void			*bi_private;
- 
- 	bio_destructor_t	*bi_destructor;	/* destructor */
-+
-+	/*
-+	 * The raid settings for the bio, this should only be used by the oxsemi
-+	 * sata driver to control raid hardware and the request merging code in 
-+	 * ll_rw_blk.c to prevent merging of requests to hwraid and non-hwraid 
-+	 *partitions.
-+	 */ 
-+  	u32                 bi_raid;
-+   
- };
- 
- /*
-diff -Nurd linux-2.6.24/include/linux/byteorder/generic.h linux-2.6.24-oxe810/include/linux/byteorder/generic.h
---- linux-2.6.24/include/linux/byteorder/generic.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/byteorder/generic.h	2008-06-11 17:45:26.000000000 +0200
-@@ -146,6 +146,36 @@
- #define htons(x) ___htons(x)
- #define ntohs(x) ___ntohs(x)
- 
-+static inline void le16_add_cpu(__le16 *var, u16 val)
-+{
-+        *var = cpu_to_le16(le16_to_cpu(*var) + val);
-+}
-+
-+static inline void le32_add_cpu(__le32 *var, u32 val)
-+{
-+        *var = cpu_to_le32(le32_to_cpu(*var) + val);
-+}
-+
-+static inline void le64_add_cpu(__le64 *var, u64 val)
-+{
-+        *var = cpu_to_le64(le64_to_cpu(*var) + val);
-+}
-+
-+static inline void be16_add_cpu(__be16 *var, u16 val)
-+{
-+        *var = cpu_to_be16(be16_to_cpu(*var) + val);
-+}
-+
-+static inline void be32_add_cpu(__be32 *var, u32 val)
-+{
-+        *var = cpu_to_be32(be32_to_cpu(*var) + val);
-+}
-+
-+static inline void be64_add_cpu(__be64 *var, u64 val)
-+{
-+        *var = cpu_to_be64(be64_to_cpu(*var) + val);
-+}
-+
- #endif /* KERNEL */
- 
- #endif /* _LINUX_BYTEORDER_GENERIC_H */
-diff -Nurd linux-2.6.24/include/linux/byteorder/swab.h linux-2.6.24-oxe810/include/linux/byteorder/swab.h
---- linux-2.6.24/include/linux/byteorder/swab.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/byteorder/swab.h	2008-06-11 17:45:26.000000000 +0200
-@@ -61,26 +61,37 @@
-  * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
-  */
- 
--static __inline__ __attribute_const__ __u16 ___swab16(__u16 x)
--{
--	return x<<8 | x>>8;
--}
--static __inline__ __attribute_const__ __u32 ___swab32(__u32 x)
--{
--	return x<<24 | x>>24 |
--		(x & (__u32)0x0000ff00UL)<<8 |
--		(x & (__u32)0x00ff0000UL)>>8;
--}
--static __inline__ __attribute_const__ __u64 ___swab64(__u64 x)
--{
--	return x<<56 | x>>56 |
--		(x & (__u64)0x000000000000ff00ULL)<<40 |
--		(x & (__u64)0x0000000000ff0000ULL)<<24 |
--		(x & (__u64)0x00000000ff000000ULL)<< 8 |
--	        (x & (__u64)0x000000ff00000000ULL)>> 8 |
--		(x & (__u64)0x0000ff0000000000ULL)>>24 |
--		(x & (__u64)0x00ff000000000000ULL)>>40;
--}
-+#define ___swab16(x) \
-+({ \
-+	__u16 __x = (x); \
-+	((__u16)( \
-+		(((__u16)(__x) & (__u16)0x00ffU) << 8) | \
-+		(((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
-+})
-+
-+#define ___swab32(x) \
-+({ \
-+	__u32 __x = (x); \
-+	((__u32)( \
-+		(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
-+		(((__u32)(__x) & (__u32)0x0000ff00UL) <<  8) | \
-+		(((__u32)(__x) & (__u32)0x00ff0000UL) >>  8) | \
-+		(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-+})
-+
-+#define ___swab64(x) \
-+({ \
-+	__u64 __x = (x); \
-+	((__u64)( \
-+		(__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
-+		(__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
-+		(__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
-+		(__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) <<  8) | \
-+	        (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >>  8) | \
-+		(__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
-+		(__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
-+		(__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
-+})
- 
- #define ___constant_swab16(x) \
- 	((__u16)( \
-@@ -103,6 +114,7 @@
- 		(__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
- 		(__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
- 
-+
- /*
-  * provide defaults when no architecture-specific optimization is detected
-  */
-diff -Nurd linux-2.6.24/include/linux/dmi.h linux-2.6.24-oxe810/include/linux/dmi.h
---- linux-2.6.24/include/linux/dmi.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/dmi.h	2008-06-11 17:45:39.000000000 +0200
-@@ -79,7 +79,6 @@
- extern int dmi_get_year(int field);
- extern int dmi_name_in_vendors(const char *str);
- extern int dmi_available;
--extern char *dmi_get_slot(int slot);
- 
- #else
- 
-@@ -90,7 +89,6 @@
- static inline int dmi_get_year(int year) { return 0; }
- static inline int dmi_name_in_vendors(const char *s) { return 0; }
- #define dmi_available 0
--static inline char *dmi_get_slot(int slot) { return NULL; }
- 
- #endif
- 
-diff -Nurd linux-2.6.24/include/linux/fs.h linux-2.6.24-oxe810/include/linux/fs.h
---- linux-2.6.24/include/linux/fs.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/fs.h	2008-06-11 17:45:39.000000000 +0200
-@@ -1147,7 +1147,7 @@
- 	int error;
- } read_descriptor_t;
- 
--typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
-+typedef int (*read_actor_t)(read_descriptor_t *, struct page **, unsigned long, unsigned long);
- 
- /* These macros are for out of kernel modules to test that
-  * the kernel supports the unlocked_ioctl and compat_ioctl
-@@ -1180,7 +1180,9 @@
- 	int (*aio_fsync) (struct kiocb *, int datasync);
- 	int (*fasync) (int, struct file *, int);
- 	int (*lock) (struct file *, int, struct file_lock *);
-+	ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
- 	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
-+	ssize_t (*sendpages) (struct file *, struct page **, int, size_t, loff_t *, int);
- 	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 	int (*check_flags)(int);
- 	int (*dir_notify)(struct file *filp, unsigned long arg);
-@@ -1791,7 +1793,8 @@
- 
- extern int generic_file_mmap(struct file *, struct vm_area_struct *);
- extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
--extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
-+extern int file_read_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
-+extern int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
- int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
- extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
- extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-@@ -1803,12 +1806,14 @@
- 		unsigned long, loff_t, loff_t *, size_t, ssize_t);
- extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
- extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
-+extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
- extern void do_generic_mapping_read(struct address_space *mapping,
- 				    struct file_ra_state *, struct file *,
- 				    loff_t *, read_descriptor_t *, read_actor_t);
- extern int generic_segment_checks(const struct iovec *iov,
- 		unsigned long *nr_segs, size_t *count, int access_flags);
- 
-+
- /* fs/splice.c */
- extern ssize_t generic_file_splice_read(struct file *, loff_t *,
- 		struct pipe_inode_info *, size_t, unsigned int);
-diff -Nurd linux-2.6.24/include/linux/futex.h linux-2.6.24-oxe810/include/linux/futex.h
---- linux-2.6.24/include/linux/futex.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/futex.h	2008-06-11 17:45:38.000000000 +0200
-@@ -153,6 +153,7 @@
- #ifdef CONFIG_FUTEX
- extern void exit_robust_list(struct task_struct *curr);
- extern void exit_pi_state_list(struct task_struct *curr);
-+extern int futex_cmpxchg_enabled;
- #else
- static inline void exit_robust_list(struct task_struct *curr)
- {
-diff -Nurd linux-2.6.24/include/linux/hrtimer.h linux-2.6.24-oxe810/include/linux/hrtimer.h
---- linux-2.6.24/include/linux/hrtimer.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/hrtimer.h	2008-06-11 17:45:39.000000000 +0200
-@@ -300,7 +300,7 @@
- 
- /* Precise sleep: */
- extern long hrtimer_nanosleep(struct timespec *rqtp,
--			      struct timespec *rmtp,
-+			      struct timespec __user *rmtp,
- 			      const enum hrtimer_mode mode,
- 			      const clockid_t clockid);
- extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
-diff -Nurd linux-2.6.24/include/linux/hugetlb.h linux-2.6.24-oxe810/include/linux/hugetlb.h
---- linux-2.6.24/include/linux/hugetlb.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/hugetlb.h	2008-06-11 17:45:39.000000000 +0200
-@@ -17,6 +17,7 @@
- }
- 
- int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
-+int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
- int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
- int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
- int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int);
-diff -Nurd linux-2.6.24/include/linux/i2c-id.h linux-2.6.24-oxe810/include/linux/i2c-id.h
---- linux-2.6.24/include/linux/i2c-id.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/i2c-id.h	2008-06-11 17:45:39.000000000 +0200
-@@ -203,6 +203,7 @@
- #define I2C_HW_B_CX2341X	0x010020 /* Conexant CX2341X MPEG encoder cards */
- #define I2C_HW_B_INTELFB	0x010021 /* intel framebuffer driver */
- #define I2C_HW_B_CX23885	0x010022 /* conexant 23885 based tv cards (bus1) */
-+#define I2C_HW_B_OXNAS 		0x010023 /* Oxford Semiconductor OX800 */
- 
- /* --- PCF 8584 based algorithms					*/
- #define I2C_HW_P_LP		0x020000 /* Parallel port interface */
-diff -Nurd linux-2.6.24/include/linux/irq.h linux-2.6.24-oxe810/include/linux/irq.h
---- linux-2.6.24/include/linux/irq.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/irq.h	2008-06-11 17:45:39.000000000 +0200
-@@ -367,6 +367,9 @@
- 	__set_irq_handler(irq, handle, 1, NULL);
- }
- 
-+extern void set_irq_noprobe(unsigned int irq);
-+extern void set_irq_probe(unsigned int irq);
-+
- /* Handle dynamic irq creation and destruction */
- extern int create_irq(void);
- extern void destroy_irq(unsigned int irq);
-diff -Nurd linux-2.6.24/include/linux/ktime.h linux-2.6.24-oxe810/include/linux/ktime.h
---- linux-2.6.24/include/linux/ktime.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/ktime.h	2008-06-11 17:45:39.000000000 +0200
-@@ -310,6 +310,8 @@
- 	return ktime_sub_ns(kt, usec * 1000);
- }
- 
-+extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
-+
- /*
-  * The resolution of the clocks. The resolution value is returned in
-  * the clock_getres() system call to give application programmers an
-diff -Nurd linux-2.6.24/include/linux/leds.h linux-2.6.24-oxe810/include/linux/leds.h
---- linux-2.6.24/include/linux/leds.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/leds.h	2008-06-11 17:45:38.000000000 +0200
-@@ -123,5 +123,11 @@
- 	struct gpio_led *leds;
- };
- 
-+/* Trigger specific functions */
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+extern void wdc_ledtrig_sata_activity(void);
-+#else
-+#define wdc_ledtrig_sata_activity() do {} while(0)
-+#endif
- 
- #endif		/* __LINUX_LEDS_H_INCLUDED */
-diff -Nurd linux-2.6.24/include/linux/libata.h linux-2.6.24-oxe810/include/linux/libata.h
---- linux-2.6.24/include/linux/libata.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/libata.h	2008-06-11 17:45:39.000000000 +0200
-@@ -238,7 +238,7 @@
- 	/* various lengths of time */
- 	ATA_TMOUT_BOOT		= 30 * HZ,	/* heuristic */
- 	ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* heuristic */
--	ATA_TMOUT_INTERNAL	= 30 * HZ,
-+	ATA_TMOUT_INTERNAL	= 10 * HZ,
- 	ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
- 
- 	/* FIXME: GoVault needs 2s but we can't afford that without
-@@ -662,7 +662,7 @@
- };
- 
- struct ata_port_operations {
--	void (*dev_config) (struct ata_device *);
-+	void (*dev_config) (struct ata_port *, struct ata_device *);
- 
- 	void (*set_piomode) (struct ata_port *, struct ata_device *);
- 	void (*set_dmamode) (struct ata_port *, struct ata_device *);
-@@ -675,6 +675,7 @@
- 	u8   (*check_status)(struct ata_port *ap);
- 	u8   (*check_altstatus)(struct ata_port *ap);
- 	void (*dev_select)(struct ata_port *ap, unsigned int device);
-+    unsigned int (*dev_chk)(struct ata_port *ap, unsigned int device);
- 
- 	void (*phy_reset) (struct ata_port *ap); /* obsolete */
- 	int  (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev);
-@@ -689,6 +690,8 @@
- 	void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
- 
- 	int (*qc_defer) (struct ata_queued_cmd *qc);
-+    struct ata_queued_cmd* (*qc_new)(struct ata_port *ap);
-+    void (*qc_free)(struct ata_queued_cmd *qc);
- 	void (*qc_prep) (struct ata_queued_cmd *qc);
- 	unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
- 
-@@ -724,6 +727,7 @@
- 
- 	void (*bmdma_stop) (struct ata_queued_cmd *qc);
- 	u8   (*bmdma_status) (struct ata_port *ap);
-+    void (*pio_task)(struct work_struct *work);
- };
- 
- struct ata_port_info {
-diff -Nurd linux-2.6.24/include/linux/mii.h linux-2.6.24-oxe810/include/linux/mii.h
---- linux-2.6.24/include/linux/mii.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/mii.h	2008-06-11 17:45:39.000000000 +0200
-@@ -21,18 +21,18 @@
- #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    */
-+#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...                   */
-@@ -121,9 +121,9 @@
- #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...                   */
-+//#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 */
-@@ -157,7 +157,9 @@
- 
- 	unsigned int full_duplex : 1;	/* is full duplex? */
- 	unsigned int force_media : 1;	/* is autoneg. disabled? */
--	unsigned int supports_gmii : 1; /* are GMII registers supported? */
-+	unsigned int using_1000 : 1;    /* the PHY is using 1000Mb rate */
-+	unsigned int using_100 : 1;     /* the PHY is using 100Mb rate */
-+	unsigned int using_pause : 1;	/* the PHY will generate pause frames */
- 
- 	struct net_device *dev;
- 	int (*mdio_read) (struct net_device *dev, int phy_id, int location);
-@@ -170,9 +172,16 @@
- extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
- extern int mii_check_gmii_support(struct mii_if_info *mii);
- extern void mii_check_link (struct mii_if_info *mii);
--extern unsigned int mii_check_media (struct mii_if_info *mii,
--				     unsigned int ok_to_print,
--				     unsigned int init_media);
-+extern unsigned int mii_check_media(struct mii_if_info *mii,
-+                                    unsigned int ok_to_print,
-+                                    unsigned int init_media);
-+extern unsigned int mii_check_media_ex(struct mii_if_info *mii,
-+                                    unsigned int ok_to_print,
-+                                    unsigned int init_media,
-+                                    int *has_gigabit_changed,
-+									 int *has_pause_changed,
-+									 void (*link_state_change_callback)(int link_state, void* arg),
-+									 void *link_state_change_arg);
- extern int generic_mii_ioctl(struct mii_if_info *mii_if,
-                       	     struct mii_ioctl_data *mii_data, int cmd,
- 			     unsigned int *duplex_changed);
-@@ -216,6 +225,23 @@
- 	return ret;
- }
- 
-+static inline unsigned int mii_nway_result_1000(unsigned int lpa_1000, unsigned int advertised_1000)
-+{
-+	int full_negotiated = (lpa_1000 & LPA_1000FULL) &&
-+						  (advertised_1000 & ADVERTISE_1000FULL);
-+
-+	int half_negotiated = (lpa_1000 & LPA_1000HALF) &&
-+						  (advertised_1000 & ADVERTISE_1000HALF);
-+	
-+	if (full_negotiated) {
-+		return LPA_1000FULL;
-+	} else if (half_negotiated) {
-+		return LPA_1000HALF;
-+	} else {
-+		return 0;
-+	}
-+}
-+
- /**
-  * mii_duplex
-  * @duplex_lock: Non-zero if duplex is locked at full
-diff -Nurd linux-2.6.24/include/linux/moduleparam.h linux-2.6.24-oxe810/include/linux/moduleparam.h
---- linux-2.6.24/include/linux/moduleparam.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/moduleparam.h	2008-06-11 17:45:39.000000000 +0200
-@@ -62,6 +62,16 @@
- 	void *elem;
- };
- 
-+/* On alpha, ia64 and ppc64 relocations to global data cannot go into
-+   read-only sections (which is part of respective UNIX ABI on these
-+   platforms). So 'const' makes no sense and even causes compile failures
-+   with some compilers. */
-+#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
-+#define __moduleparam_const
-+#else
-+#define __moduleparam_const const
-+#endif
-+
- /* This is the fundamental function for registering boot/module
-    parameters.  perm sets the visibility in sysfs: 000 means it's
-    not there, read bits mean it's readable, write bits mean it's
-@@ -71,7 +81,7 @@
- 	static int __param_perm_check_##name __attribute__((unused)) =	\
- 	BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2));	\
- 	static const char __param_str_##name[] = prefix #name;		\
--	static struct kernel_param const __param_##name			\
-+	static struct kernel_param __moduleparam_const __param_##name	\
- 	__attribute_used__						\
-     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
- 	= { __param_str_##name, perm, set, get, { arg } }
-diff -Nurd linux-2.6.24/include/linux/net.h linux-2.6.24-oxe810/include/linux/net.h
---- linux-2.6.24/include/linux/net.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/net.h	2008-06-11 17:45:39.000000000 +0200
-@@ -172,6 +172,8 @@
- 				      struct vm_area_struct * vma);
- 	ssize_t		(*sendpage)  (struct socket *sock, struct page *page,
- 				      int offset, size_t size, int flags);
-+	ssize_t		(*sendpages)  (struct socket *sock, struct page **page,
-+				      int offset, size_t size, int flags);
- };
- 
- struct net_proto_family {
-diff -Nurd linux-2.6.24/include/linux/raid/raid1.h linux-2.6.24-oxe810/include/linux/raid/raid1.h
---- linux-2.6.24/include/linux/raid/raid1.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/raid/raid1.h	2008-06-11 17:45:26.000000000 +0200
-@@ -61,6 +61,10 @@
- 
- 	mempool_t *r1bio_pool;
- 	mempool_t *r1buf_pool;
-+
-+    /** This contains flags that can be included with the BIOs generated by
-+    writes to set the correct hardware RAID modes */ 
-+    u32 hw_raid1_settings;
- };
- 
- typedef struct r1_private_data_s conf_t;
-diff -Nurd linux-2.6.24/include/linux/serial_reg.h linux-2.6.24-oxe810/include/linux/serial_reg.h
---- linux-2.6.24/include/linux/serial_reg.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/serial_reg.h	2008-06-11 17:45:39.000000000 +0200
-@@ -133,6 +133,15 @@
- 
- #define UART_SCR	7	/* I/O: Scratch Register */
- 
-+/* Oxsemi NAS UART extra registers */
-+#define UART_DLF            0x09  /* Oxsemi 16550 fractional divider */
-+#define UART_RX_FILL        0x0a
-+#define UART_TX_SPACE       0x0b
-+#define UART_WIDE_ACCESS    0x0c
-+#define UART_XON_CHAR       0x10
-+#define UART_XOFF_CHAR      0x11
-+#define UART_DMA            0x12
-+
- /*
-  * DLAB=1
-  */
-diff -Nurd linux-2.6.24/include/linux/syscalls.h linux-2.6.24-oxe810/include/linux/syscalls.h
---- linux-2.6.24/include/linux/syscalls.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/syscalls.h	2008-06-11 17:45:39.000000000 +0200
-@@ -611,6 +611,7 @@
- 			    const struct itimerspec __user *utmr);
- asmlinkage long sys_eventfd(unsigned int count);
- asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
-+asmlinkage long sys_samba_reserve(int fd, void __user *info);
- 
- int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
- 
-diff -Nurd linux-2.6.24/include/linux/trustees.h linux-2.6.24-oxe810/include/linux/trustees.h
---- linux-2.6.24/include/linux/trustees.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/trustees.h	2008-06-11 17:45:39.000000000 +0200
-@@ -0,0 +1,108 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * Structs, defines and function definitions intended for export
-+ *
-+ */
-+
-+#ifndef _LINUX_TRUSTEE_STRUCT_H
-+
-+#define _LINUX_TRUSTEE_STRUCT_H
-+#include <linux/types.h>
-+
-+#define TRUSTEES_APIVERSION 2
-+#define TRUSTEES_APIVERSION_STR "2"
-+
-+#define TRUSTEE_EXECUTE_BIT 0
-+#define TRUSTEE_READ_BIT 1
-+#define TRUSTEE_WRITE_BIT 2
-+#define TRUSTEE_BROWSE_BIT 3
-+#define TRUSTEE_READ_DIR_BIT 4
-+#define TRUSTEE_USE_UNIX_BIT 5
-+#define TRUSTEE_NUM_ACL_BITS (TRUSTEE_USE_UNIX_BIT+1)
-+#define TRUSTEE_EXECUTE_MASK (1 <<  TRUSTEE_EXECUTE_BIT)
-+#define TRUSTEE_READ_MASK (1 <<  TRUSTEE_READ_BIT)
-+#define TRUSTEE_WRITE_MASK (1 <<  TRUSTEE_WRITE_BIT)
-+#define TRUSTEE_BROWSE_MASK (1 <<  TRUSTEE_BROWSE_BIT)
-+#define TRUSTEE_READ_DIR_MASK (1 <<  TRUSTEE_READ_DIR_BIT)
-+#define TRUSTEE_USE_UNIX_MASK (1 <<  TRUSTEE_USE_UNIX_BIT)
-+#define TRUSTEE_ACL_MASK ((1 << TRUSTEE_NUM_ACL_BITS)-1)
-+
-+#define TRUSTEE_ALLOW_DENY_BIT 7
-+#define TRUSTEE_IS_GROUP_BIT 6
-+#define TRUSTEE_CLEAR_SET_BIT 8
-+#define TRUSTEE_ONE_LEVEL_BIT 9
-+#define TRUSTEE_NOT_BIT 10
-+#define TRUSTEE_ALL_BIT 11
-+#define TRUSTEE_ALLOW_DENY_MASK (1 <<  TRUSTEE_ALLOW_DENY_BIT)	/* set if deny */
-+#define TRUSTEE_IS_GROUP_MASK (1 <<  TRUSTEE_IS_GROUP_BIT)
-+#define TRUSTEE_CLEAR_SET_MASK (1 <<  TRUSTEE_CLEAR_SET_BIT)	/* set if clear */
-+#define TRUSTEE_ONE_LEVEL_MASK (1 <<  TRUSTEE_ONE_LEVEL_BIT)
-+#define TRUSTEE_NOT_MASK (1 <<  TRUSTEE_NOT_BIT)
-+#define TRUSTEE_ALL_MASK (1 <<  TRUSTEE_ALL_BIT)
-+
-+#define trustee_acl __u16
-+#define trustee_default_acl TRUSTEE_USE_UNIX_MASK
-+
-+struct trustee_permission {
-+	trustee_acl mask;
-+	union {
-+		__kernel_uid32_t uid;
-+		__kernel_gid32_t gid;
-+	} u;
-+};
-+
-+#ifndef __KERNEL__
-+#ifndef __user
-+#define __user
-+#endif
-+#endif
-+
-+struct trustee_command {
-+	unsigned command;
-+	unsigned numargs;
-+};
-+
-+/* Most arguments that any command will take */
-+
-+#define TRUSTEE_MAX_ARGS 6
-+
-+/* Starts a table
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_TABLE_START 1
-+
-+/* Ends a table successfully.
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_TABLE_STOP  2
-+
-+/* Adds a trustee
-+ * Arguments:
-+ * filename (char [])
-+ * struct trustee_permission
-+ * device-name (char [])
-+ * device number (u32)
-+ */
-+#define TRUSTEE_COMMAND_ADD 3
-+
-+/* Removes all trustees
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_REMOVE_ALL  2
-+
-+/* Makes a filesystem ignorecase
-+ * Arguments:
-+ * device-name (char [])
-+ * device number (u32)
-+ */
-+#define TRUSTEE_COMMAND_MAKE_IC 5
-+
-+#endif /* _LINUX_TRUSTEE_STRUCT_H */
-diff -Nurd linux-2.6.24/include/linux/wait.h linux-2.6.24-oxe810/include/linux/wait.h
---- linux-2.6.24/include/linux/wait.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/wait.h	2008-06-11 17:45:39.000000000 +0200
-@@ -161,6 +161,22 @@
- #define	wake_up_locked(x)		__wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
- #define wake_up_interruptible_sync(x)   __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
- 
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+/*
-+ * macro to avoid include hell
-+ */
-+#define wake_up_nested(x, s)						\
-+do {									\
-+	unsigned long flags;						\
-+									\
-+	spin_lock_irqsave_nested(&(x)->lock, flags, (s));		\
-+	wake_up_locked(x); 						\
-+	spin_unlock_irqrestore(&(x)->lock, flags);			\
-+} while (0)
-+#else
-+#define wake_up_nested(x, s)		wake_up(x)
-+#endif
-+
- #define __wait_event(wq, condition) 					\
- do {									\
- 	DEFINE_WAIT(__wait);						\
-diff -Nurd linux-2.6.24/include/net/inet_sock.h linux-2.6.24-oxe810/include/net/inet_sock.h
---- linux-2.6.24/include/net/inet_sock.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/inet_sock.h	2008-06-11 17:44:45.000000000 +0200
-@@ -175,7 +175,8 @@
- static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
- 					const __be32 faddr, const __be16 fport)
- {
--	return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
-+	return jhash_3words((__force __u32) laddr,
-+			    (__force __u32) faddr,
- 			    ((__u32) lport) << 16 | (__force __u32)fport,
- 			    inet_ehash_secret);
- }
-diff -Nurd linux-2.6.24/include/net/sock.h linux-2.6.24-oxe810/include/net/sock.h
---- linux-2.6.24/include/net/sock.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/sock.h	2008-06-11 17:44:45.000000000 +0200
-@@ -549,6 +549,8 @@
- 					int *addr_len);
- 	int			(*sendpage)(struct sock *sk, struct page *page,
- 					int offset, size_t size, int flags);
-+	int			(*sendpages)(struct sock *sk, struct page **page,
-+					int offset, size_t size, int flags);
- 	int			(*bind)(struct sock *sk, 
- 					struct sockaddr *uaddr, int addr_len);
- 
-diff -Nurd linux-2.6.24/include/net/tcp.h linux-2.6.24-oxe810/include/net/tcp.h
---- linux-2.6.24/include/net/tcp.h	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/tcp.h	2008-06-11 17:44:45.000000000 +0200
-@@ -285,6 +285,7 @@
- extern int			tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
- 					    struct msghdr *msg, size_t size);
- extern ssize_t			tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
-+extern ssize_t			tcp_sendpages(struct socket *sock, struct page **page, int offset, size_t size, int flags);
- 
- extern int			tcp_ioctl(struct sock *sk, 
- 					  int cmd, 
-diff -Nurd linux-2.6.24/kernel/audit.c linux-2.6.24-oxe810/kernel/audit.c
---- linux-2.6.24/kernel/audit.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/audit.c	2008-06-11 17:43:47.000000000 +0200
-@@ -1200,13 +1200,17 @@
- static inline int audit_expand(struct audit_buffer *ab, int extra)
- {
- 	struct sk_buff *skb = ab->skb;
--	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
--				   ab->gfp_mask);
-+	int oldtail = skb_tailroom(skb);
-+	int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
-+	int newtail = skb_tailroom(skb);
-+
- 	if (ret < 0) {
- 		audit_log_lost("out of memory in audit_expand");
- 		return 0;
- 	}
--	return skb_tailroom(skb);
-+
-+	skb->truesize += newtail - oldtail;
-+	return newtail;
- }
- 
- /*
-diff -Nurd linux-2.6.24/kernel/compat.c linux-2.6.24-oxe810/kernel/compat.c
---- linux-2.6.24/kernel/compat.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/compat.c	2008-06-11 17:43:47.000000000 +0200
-@@ -40,10 +40,36 @@
- 			__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
- }
- 
-+static long compat_nanosleep_restart(struct restart_block *restart)
-+{
-+	struct compat_timespec __user *rmtp;
-+	struct timespec rmt;
-+	mm_segment_t oldfs;
-+	long ret;
-+
-+	rmtp = (struct compat_timespec __user *)(restart->arg1);
-+	restart->arg1 = (unsigned long)&rmt;
-+	oldfs = get_fs();
-+	set_fs(KERNEL_DS);
-+	ret = hrtimer_nanosleep_restart(restart);
-+	set_fs(oldfs);
-+
-+	if (ret) {
-+		restart->fn = compat_nanosleep_restart;
-+		restart->arg1 = (unsigned long)rmtp;
-+
-+		if (rmtp && put_compat_timespec(&rmt, rmtp))
-+			return -EFAULT;
-+	}
-+
-+	return ret;
-+}
-+
- asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
- 				     struct compat_timespec __user *rmtp)
- {
- 	struct timespec tu, rmt;
-+	mm_segment_t oldfs;
- 	long ret;
- 
- 	if (get_compat_timespec(&tu, rqtp))
-@@ -52,11 +78,21 @@
- 	if (!timespec_valid(&tu))
- 		return -EINVAL;
- 
--	ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
--				CLOCK_MONOTONIC);
-+	oldfs = get_fs();
-+	set_fs(KERNEL_DS);
-+	ret = hrtimer_nanosleep(&tu,
-+				rmtp ? (struct timespec __user *)&rmt : NULL,
-+				HRTIMER_MODE_REL, CLOCK_MONOTONIC);
-+	set_fs(oldfs);
- 
--	if (ret && rmtp) {
--		if (put_compat_timespec(&rmt, rmtp))
-+	if (ret) {
-+		struct restart_block *restart
-+			= &current_thread_info()->restart_block;
-+
-+		restart->fn = compat_nanosleep_restart;
-+		restart->arg1 = (unsigned long)rmtp;
-+
-+		if (rmtp && put_compat_timespec(&rmt, rmtp))
- 			return -EFAULT;
- 	}
- 
-diff -Nurd linux-2.6.24/kernel/futex.c linux-2.6.24-oxe810/kernel/futex.c
---- linux-2.6.24/kernel/futex.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/futex.c	2008-06-11 17:43:47.000000000 +0200
-@@ -60,6 +60,8 @@
- 
- #include "rtmutex_common.h"
- 
-+int __read_mostly futex_cmpxchg_enabled;
-+
- #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
- 
- /*
-@@ -466,6 +468,8 @@
- 	struct futex_hash_bucket *hb;
- 	union futex_key key;
- 
-+	if (!futex_cmpxchg_enabled)
-+		return;
- 	/*
- 	 * We are a ZOMBIE and nobody can enqueue itself on
- 	 * pi_state_list anymore, but we have to be careful
-@@ -1854,6 +1858,8 @@
- sys_set_robust_list(struct robust_list_head __user *head,
- 		    size_t len)
- {
-+	if (!futex_cmpxchg_enabled)
-+		return -ENOSYS;
- 	/*
- 	 * The kernel knows only one size for now:
- 	 */
-@@ -1878,6 +1884,9 @@
- 	struct robust_list_head __user *head;
- 	unsigned long ret;
- 
-+	if (!futex_cmpxchg_enabled)
-+		return -ENOSYS;
-+
- 	if (!pid)
- 		head = current->robust_list;
- 	else {
-@@ -1980,6 +1989,9 @@
- 	unsigned long futex_offset;
- 	int rc;
- 
-+	if (!futex_cmpxchg_enabled)
-+		return;
-+
- 	/*
- 	 * Fetch the list head (which was registered earlier, via
- 	 * sys_set_robust_list()):
-@@ -2034,7 +2046,7 @@
- long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
- 		u32 __user *uaddr2, u32 val2, u32 val3)
- {
--	int ret;
-+	int ret = -ENOSYS;
- 	int cmd = op & FUTEX_CMD_MASK;
- 	struct rw_semaphore *fshared = NULL;
- 
-@@ -2062,13 +2074,16 @@
- 		ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3);
- 		break;
- 	case FUTEX_LOCK_PI:
--		ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
-+		if (futex_cmpxchg_enabled)
-+			ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
- 		break;
- 	case FUTEX_UNLOCK_PI:
--		ret = futex_unlock_pi(uaddr, fshared);
-+		if (futex_cmpxchg_enabled)
-+			ret = futex_unlock_pi(uaddr, fshared);
- 		break;
- 	case FUTEX_TRYLOCK_PI:
--		ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
-+		if (futex_cmpxchg_enabled)
-+			ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
- 		break;
- 	default:
- 		ret = -ENOSYS;
-@@ -2094,7 +2109,7 @@
- 
- 		t = timespec_to_ktime(ts);
- 		if (cmd == FUTEX_WAIT)
--			t = ktime_add(ktime_get(), t);
-+			t = ktime_add_safe(ktime_get(), t);
- 		tp = &t;
- 	}
- 	/*
-@@ -2123,8 +2138,29 @@
- 
- static int __init init(void)
- {
--	int i = register_filesystem(&futex_fs_type);
-+	u32 curval;
-+	int i;
-+
-+	/*
-+	 * This will fail and we want it. Some arch implementations do
-+	 * runtime detection of the futex_atomic_cmpxchg_inatomic()
-+	 * functionality. We want to know that before we call in any
-+	 * of the complex code paths. Also we want to prevent
-+	 * registration of robust lists in that case. NULL is
-+	 * guaranteed to fault and we get -EFAULT on functional
-+	 * implementation, the non functional ones will return
-+	 * -ENOSYS.
-+	 */
-+	curval = cmpxchg_futex_value_locked(NULL, 0, 0);
-+	if (curval == -EFAULT)
-+		futex_cmpxchg_enabled = 1;
- 
-+	for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
-+		plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
-+		spin_lock_init(&futex_queues[i].lock);
-+	}
-+
-+	i = register_filesystem(&futex_fs_type);
- 	if (i)
- 		return i;
- 
-@@ -2134,10 +2170,6 @@
- 		return PTR_ERR(futex_mnt);
- 	}
- 
--	for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
--		plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
--		spin_lock_init(&futex_queues[i].lock);
--	}
- 	return 0;
- }
- __initcall(init);
-diff -Nurd linux-2.6.24/kernel/futex_compat.c linux-2.6.24-oxe810/kernel/futex_compat.c
---- linux-2.6.24/kernel/futex_compat.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/futex_compat.c	2008-06-11 17:43:47.000000000 +0200
-@@ -54,6 +54,9 @@
- 	compat_long_t futex_offset;
- 	int rc;
- 
-+	if (!futex_cmpxchg_enabled)
-+		return;
-+
- 	/*
- 	 * Fetch the list head (which was registered earlier, via
- 	 * sys_set_robust_list()):
-@@ -115,6 +118,9 @@
- compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
- 			   compat_size_t len)
- {
-+	if (!futex_cmpxchg_enabled)
-+		return -ENOSYS;
-+
- 	if (unlikely(len != sizeof(*head)))
- 		return -EINVAL;
- 
-@@ -130,6 +136,9 @@
- 	struct compat_robust_list_head __user *head;
- 	unsigned long ret;
- 
-+	if (!futex_cmpxchg_enabled)
-+		return -ENOSYS;
-+
- 	if (!pid)
- 		head = current->compat_robust_list;
- 	else {
-@@ -175,7 +184,7 @@
- 
- 		t = timespec_to_ktime(ts);
- 		if (cmd == FUTEX_WAIT)
--			t = ktime_add(ktime_get(), t);
-+			t = ktime_add_safe(ktime_get(), t);
- 		tp = &t;
- 	}
- 	if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
-diff -Nurd linux-2.6.24/kernel/hrtimer.c linux-2.6.24-oxe810/kernel/hrtimer.c
---- linux-2.6.24/kernel/hrtimer.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/hrtimer.c	2008-06-11 17:43:47.000000000 +0200
-@@ -325,6 +325,24 @@
- }
- #endif /* BITS_PER_LONG >= 64 */
- 
-+/*
-+ * Add two ktime values and do a safety check for overflow:
-+ */
-+
-+ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs)
-+{
-+	ktime_t res = ktime_add(lhs, rhs);
-+
-+	/*
-+	 * We use KTIME_SEC_MAX here, the maximum timeout which we can
-+	 * return to user space in a timespec:
-+	 */
-+	if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
-+		res = ktime_set(KTIME_SEC_MAX, 0);
-+
-+	return res;
-+}
-+
- /* High resolution timer related functions */
- #ifdef CONFIG_HIGH_RES_TIMERS
- 
-@@ -409,6 +427,8 @@
- 	ktime_t expires = ktime_sub(timer->expires, base->offset);
- 	int res;
- 
-+	WARN_ON_ONCE(timer->expires.tv64 < 0);
-+
- 	/*
- 	 * When the callback is running, we do not reprogram the clock event
- 	 * device. The timer callback is either running on a different CPU or
-@@ -419,6 +439,15 @@
- 	if (hrtimer_callback_running(timer))
- 		return 0;
- 
-+	/*
-+	 * CLOCK_REALTIME timer might be requested with an absolute
-+	 * expiry time which is less than base->offset. Nothing wrong
-+	 * about that, just avoid to call into the tick code, which
-+	 * has now objections against negative expiry values.
-+	 */
-+	if (expires.tv64 < 0)
-+		return -ETIME;
-+
- 	if (expires.tv64 >= expires_next->tv64)
- 		return 0;
- 
-@@ -682,13 +711,7 @@
- 		 */
- 		orun++;
- 	}
--	timer->expires = ktime_add(timer->expires, interval);
--	/*
--	 * Make sure, that the result did not wrap with a very large
--	 * interval.
--	 */
--	if (timer->expires.tv64 < 0)
--		timer->expires = ktime_set(KTIME_SEC_MAX, 0);
-+	timer->expires = ktime_add_safe(timer->expires, interval);
- 
- 	return orun;
- }
-@@ -839,7 +862,7 @@
- 	new_base = switch_hrtimer_base(timer, base);
- 
- 	if (mode == HRTIMER_MODE_REL) {
--		tim = ktime_add(tim, new_base->get_time());
-+		tim = ktime_add_safe(tim, new_base->get_time());
- 		/*
- 		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
- 		 * to signal that they simply return xtime in
-@@ -848,16 +871,8 @@
- 		 * timeouts. This will go away with the GTOD framework.
- 		 */
- #ifdef CONFIG_TIME_LOW_RES
--		tim = ktime_add(tim, base->resolution);
-+		tim = ktime_add_safe(tim, base->resolution);
- #endif
--		/*
--		 * Careful here: User space might have asked for a
--		 * very long sleep, so the add above might result in a
--		 * negative number, which enqueues the timer in front
--		 * of the queue.
--		 */
--		if (tim.tv64 < 0)
--			tim.tv64 = KTIME_MAX;
- 	}
- 	timer->expires = tim;
- 
-@@ -1291,11 +1306,26 @@
- 	return t->task == NULL;
- }
- 
-+static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
-+{
-+	struct timespec rmt;
-+	ktime_t rem;
-+
-+	rem = ktime_sub(timer->expires, timer->base->get_time());
-+	if (rem.tv64 <= 0)
-+		return 0;
-+	rmt = ktime_to_timespec(rem);
-+
-+	if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
-+		return -EFAULT;
-+
-+	return 1;
-+}
-+
- long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
- {
- 	struct hrtimer_sleeper t;
--	struct timespec *rmtp;
--	ktime_t time;
-+	struct timespec __user  *rmtp;
- 
- 	restart->fn = do_no_restart_syscall;
- 
-@@ -1305,12 +1335,11 @@
- 	if (do_nanosleep(&t, HRTIMER_MODE_ABS))
- 		return 0;
- 
--	rmtp = (struct timespec *)restart->arg1;
-+	rmtp = (struct timespec __user *)restart->arg1;
- 	if (rmtp) {
--		time = ktime_sub(t.timer.expires, t.timer.base->get_time());
--		if (time.tv64 <= 0)
--			return 0;
--		*rmtp = ktime_to_timespec(time);
-+		int ret = update_rmtp(&t.timer, rmtp);
-+		if (ret <= 0)
-+			return ret;
- 	}
- 
- 	restart->fn = hrtimer_nanosleep_restart;
-@@ -1319,12 +1348,11 @@
- 	return -ERESTART_RESTARTBLOCK;
- }
- 
--long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
-+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
- 		       const enum hrtimer_mode mode, const clockid_t clockid)
- {
- 	struct restart_block *restart;
- 	struct hrtimer_sleeper t;
--	ktime_t rem;
- 
- 	hrtimer_init(&t.timer, clockid, mode);
- 	t.timer.expires = timespec_to_ktime(*rqtp);
-@@ -1336,10 +1364,9 @@
- 		return -ERESTARTNOHAND;
- 
- 	if (rmtp) {
--		rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
--		if (rem.tv64 <= 0)
--			return 0;
--		*rmtp = ktime_to_timespec(rem);
-+		int ret = update_rmtp(&t.timer, rmtp);
-+		if (ret <= 0)
-+			return ret;
- 	}
- 
- 	restart = &current_thread_info()->restart_block;
-@@ -1355,8 +1382,7 @@
- asmlinkage long
- sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
- {
--	struct timespec tu, rmt;
--	int ret;
-+	struct timespec tu;
- 
- 	if (copy_from_user(&tu, rqtp, sizeof(tu)))
- 		return -EFAULT;
-@@ -1364,15 +1390,7 @@
- 	if (!timespec_valid(&tu))
- 		return -EINVAL;
- 
--	ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
--				CLOCK_MONOTONIC);
--
--	if (ret && rmtp) {
--		if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
--			return -EFAULT;
--	}
--
--	return ret;
-+	return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
- }
- 
- /*
-diff -Nurd linux-2.6.24/kernel/irq/chip.c linux-2.6.24-oxe810/kernel/irq/chip.c
---- linux-2.6.24/kernel/irq/chip.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/irq/chip.c	2008-06-11 17:43:44.000000000 +0200
-@@ -246,6 +246,17 @@
- }
- 
- /*
-+ * default shutdown function
-+ */
-+static void default_shutdown(unsigned int irq)
-+{
-+	struct irq_desc *desc = irq_desc + irq;
-+
-+	desc->chip->mask(irq);
-+	desc->status |= IRQ_MASKED;
-+}
-+
-+/*
-  * Fixup enable/disable function pointers
-  */
- void irq_chip_set_defaults(struct irq_chip *chip)
-@@ -256,8 +267,15 @@
- 		chip->disable = default_disable;
- 	if (!chip->startup)
- 		chip->startup = default_startup;
-+	/*
-+	 * We use chip->disable, when the user provided its own. When
-+	 * we have default_disable set for chip->disable, then we need
-+	 * to use default_shutdown, otherwise the irq line is not
-+	 * disabled on free_irq():
-+	 */
- 	if (!chip->shutdown)
--		chip->shutdown = chip->disable;
-+		chip->shutdown = chip->disable != default_disable ?
-+			chip->disable : default_shutdown;
- 	if (!chip->name)
- 		chip->name = chip->typename;
- 	if (!chip->end)
-@@ -589,3 +607,39 @@
- 	set_irq_chip(irq, chip);
- 	__set_irq_handler(irq, handle, 0, name);
- }
-+
-+void __init set_irq_noprobe(unsigned int irq)
-+{
-+	struct irq_desc *desc;
-+	unsigned long flags;
-+
-+	if (irq >= NR_IRQS) {
-+		printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
-+
-+		return;
-+	}
-+
-+	desc = irq_desc + irq;
-+
-+	spin_lock_irqsave(&desc->lock, flags);
-+	desc->status |= IRQ_NOPROBE;
-+	spin_unlock_irqrestore(&desc->lock, flags);
-+}
-+
-+void __init set_irq_probe(unsigned int irq)
-+{
-+	struct irq_desc *desc;
-+	unsigned long flags;
-+
-+	if (irq >= NR_IRQS) {
-+		printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-+
-+		return;
-+	}
-+
-+	desc = irq_desc + irq;
-+
-+	spin_lock_irqsave(&desc->lock, flags);
-+	desc->status &= ~IRQ_NOPROBE;
-+	spin_unlock_irqrestore(&desc->lock, flags);
-+}
-diff -Nurd linux-2.6.24/kernel/posix-timers.c linux-2.6.24-oxe810/kernel/posix-timers.c
---- linux-2.6.24/kernel/posix-timers.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/posix-timers.c	2008-06-11 17:43:47.000000000 +0200
-@@ -766,9 +766,11 @@
- 	/* SIGEV_NONE timers are not queued ! See common_timer_get */
- 	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
- 		/* Setup correct expiry time for relative timers */
--		if (mode == HRTIMER_MODE_REL)
--			timer->expires = ktime_add(timer->expires,
--						   timer->base->get_time());
-+		if (mode == HRTIMER_MODE_REL) {
-+			timer->expires =
-+				ktime_add_safe(timer->expires,
-+					       timer->base->get_time());
-+		}
- 		return 0;
- 	}
- 
-@@ -981,20 +983,9 @@
- static int common_nsleep(const clockid_t which_clock, int flags,
- 			 struct timespec *tsave, struct timespec __user *rmtp)
- {
--	struct timespec rmt;
--	int ret;
--
--	ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
--				flags & TIMER_ABSTIME ?
--				HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
--				which_clock);
--
--	if (ret && rmtp) {
--		if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
--			return -EFAULT;
--	}
--
--	return ret;
-+	return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
-+				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-+				 which_clock);
- }
- 
- asmlinkage long
-diff -Nurd linux-2.6.24/kernel/printk.c linux-2.6.24-oxe810/kernel/printk.c
---- linux-2.6.24/kernel/printk.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/printk.c	2008-06-11 17:43:47.000000000 +0200
-@@ -625,6 +625,11 @@
- 	return r;
- }
- 
-+#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
-+/* Declare the printascii function that is specific to ARM platforms */
-+extern void printascii(const char *);
-+#endif
-+
- /* cpu currently holding logbuf_lock */
- static volatile unsigned int printk_cpu = UINT_MAX;
- 
-@@ -653,6 +658,11 @@
- 	/* Emit the output into the temporary buffer */
- 	printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
- 
-+#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
-+    /* Send output down the early UART */
-+    printascii(printk_buf);
-+#endif
-+
- 	/*
- 	 * Copy the output into log_buf.  If the caller didn't provide
- 	 * appropriate log level tags, we insert them here
-diff -Nurd linux-2.6.24/kernel/relay.c linux-2.6.24-oxe810/kernel/relay.c
---- linux-2.6.24/kernel/relay.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/relay.c	2008-06-11 17:43:47.000000000 +0200
-@@ -92,6 +92,7 @@
- 		return -EINVAL;
- 
- 	vma->vm_ops = &relay_file_mmap_ops;
-+	vma->vm_flags |= VM_DONTEXPAND;
- 	vma->vm_private_data = buf;
- 	buf->chan->cb->buf_mapped(buf, filp);
- 
-@@ -1071,7 +1072,7 @@
- 			       unsigned int flags,
- 			       int *nonpad_ret)
- {
--	unsigned int pidx, poff, total_len, subbuf_pages, ret;
-+	unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret;
- 	struct rchan_buf *rbuf = in->private_data;
- 	unsigned int subbuf_size = rbuf->chan->subbuf_size;
- 	uint64_t pos = (uint64_t) *ppos;
-@@ -1102,8 +1103,9 @@
- 	subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
- 	pidx = (read_start / PAGE_SIZE) % subbuf_pages;
- 	poff = read_start & ~PAGE_MASK;
-+	nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS);
- 
--	for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) {
-+	for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
- 		unsigned int this_len, this_end, private;
- 		unsigned int cur_pos = read_start + total_len;
- 
-diff -Nurd linux-2.6.24/kernel/sched.c linux-2.6.24-oxe810/kernel/sched.c
---- linux-2.6.24/kernel/sched.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sched.c	2008-06-11 17:43:47.000000000 +0200
-@@ -4028,11 +4028,10 @@
- 	oldprio = p->prio;
- 	on_rq = p->se.on_rq;
- 	running = task_current(rq, p);
--	if (on_rq) {
-+	if (on_rq)
- 		dequeue_task(rq, p, 0);
--		if (running)
--			p->sched_class->put_prev_task(rq, p);
--	}
-+	if (running)
-+		p->sched_class->put_prev_task(rq, p);
- 
- 	if (rt_prio(prio))
- 		p->sched_class = &rt_sched_class;
-@@ -4041,9 +4040,9 @@
- 
- 	p->prio = prio;
- 
-+	if (running)
-+		p->sched_class->set_curr_task(rq);
- 	if (on_rq) {
--		if (running)
--			p->sched_class->set_curr_task(rq);
- 		enqueue_task(rq, p, 0);
- 		/*
- 		 * Reschedule if we are currently running on this runqueue and
-@@ -4339,18 +4338,17 @@
- 	update_rq_clock(rq);
- 	on_rq = p->se.on_rq;
- 	running = task_current(rq, p);
--	if (on_rq) {
-+	if (on_rq)
- 		deactivate_task(rq, p, 0);
--		if (running)
--			p->sched_class->put_prev_task(rq, p);
--	}
-+	if (running)
-+		p->sched_class->put_prev_task(rq, p);
- 
- 	oldprio = p->prio;
- 	__setscheduler(rq, p, policy, param->sched_priority);
- 
-+	if (running)
-+		p->sched_class->set_curr_task(rq);
- 	if (on_rq) {
--		if (running)
--			p->sched_class->set_curr_task(rq);
- 		activate_task(rq, p, 0);
- 		/*
- 		 * Reschedule if we are currently running on this runqueue and
-@@ -7110,19 +7108,17 @@
- 	running = task_current(rq, tsk);
- 	on_rq = tsk->se.on_rq;
- 
--	if (on_rq) {
-+	if (on_rq)
- 		dequeue_task(rq, tsk, 0);
--		if (unlikely(running))
--			tsk->sched_class->put_prev_task(rq, tsk);
--	}
-+	if (unlikely(running))
-+		tsk->sched_class->put_prev_task(rq, tsk);
- 
- 	set_task_cfs_rq(tsk, task_cpu(tsk));
- 
--	if (on_rq) {
--		if (unlikely(running))
--			tsk->sched_class->set_curr_task(rq);
-+	if (unlikely(running))
-+		tsk->sched_class->set_curr_task(rq);
-+	if (on_rq)
- 		enqueue_task(rq, tsk, 0);
--	}
- 
- done:
- 	task_rq_unlock(rq, &flags);
-diff -Nurd linux-2.6.24/kernel/sched_fair.c linux-2.6.24-oxe810/kernel/sched_fair.c
---- linux-2.6.24/kernel/sched_fair.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sched_fair.c	2008-06-11 17:43:47.000000000 +0200
-@@ -511,7 +511,7 @@
- 
- 	if (!initial) {
- 		/* sleeps upto a single latency don't count. */
--		if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se))
-+		if (sched_feat(NEW_FAIR_SLEEPERS))
- 			vruntime -= sysctl_sched_latency;
- 
- 		/* ensure we never gain time by being placed backwards. */
-@@ -867,7 +867,11 @@
- 	}
- 
- 	gran = sysctl_sched_wakeup_granularity;
--	if (unlikely(se->load.weight != NICE_0_LOAD))
-+	/*
-+	 * More easily preempt - nice tasks, while not making
-+	 * it harder for + nice tasks.
-+	 */
-+	if (unlikely(se->load.weight > NICE_0_LOAD))
- 		gran = calc_delta_fair(gran, &se->load);
- 
- 	if (pse->vruntime + gran < se->vruntime)
-diff -Nurd linux-2.6.24/kernel/softirq.c linux-2.6.24-oxe810/kernel/softirq.c
---- linux-2.6.24/kernel/softirq.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/softirq.c	2008-06-11 17:43:47.000000000 +0200
-@@ -72,7 +72,7 @@
- {
- 	unsigned long flags;
- 
--	WARN_ON_ONCE(in_irq());
-+	//WARN_ON_ONCE(in_irq());
- 
- 	raw_local_irq_save(flags);
- 	add_preempt_count(SOFTIRQ_OFFSET);
-@@ -134,9 +134,9 @@
- #ifdef CONFIG_TRACE_IRQFLAGS
- 	unsigned long flags;
- 
--	WARN_ON_ONCE(in_irq());
-+	//WARN_ON_ONCE(in_irq());
- #endif
--	WARN_ON_ONCE(irqs_disabled());
-+	//WARN_ON_ONCE(irqs_disabled());
- 
- #ifdef CONFIG_TRACE_IRQFLAGS
- 	local_irq_save(flags);
-diff -Nurd linux-2.6.24/kernel/sysctl.c linux-2.6.24-oxe810/kernel/sysctl.c
---- linux-2.6.24/kernel/sysctl.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sysctl.c	2008-06-11 17:43:47.000000000 +0200
-@@ -306,7 +306,7 @@
- 		.procname	= "sched_nr_migrate",
- 		.data		= &sysctl_sched_nr_migrate,
- 		.maxlen		= sizeof(unsigned int),
--		.mode		= 644,
-+		.mode		= 0644,
- 		.proc_handler	= &proc_dointvec,
- 	},
- #endif
-@@ -910,7 +910,7 @@
- 		.data		= &nr_overcommit_huge_pages,
- 		.maxlen		= sizeof(nr_overcommit_huge_pages),
- 		.mode		= 0644,
--		.proc_handler	= &proc_doulongvec_minmax,
-+		.proc_handler	= &hugetlb_overcommit_handler,
- 	},
- #endif
- 	{
-diff -Nurd linux-2.6.24/mm/filemap.c linux-2.6.24-oxe810/mm/filemap.c
---- linux-2.6.24/mm/filemap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/filemap.c	2008-06-11 17:47:28.000000000 +0200
-@@ -884,12 +884,31 @@
- 	unsigned int prev_offset;
- 	int error;
- 
--	index = *ppos >> PAGE_CACHE_SHIFT;
-+    // Page table mod's
-+#define MAX_QUEUED_PAGES (65536/PAGE_CACHE_SIZE)
-+	// Create the page table
-+	struct page* page_table[MAX_QUEUED_PAGES];
-+	pgoff_t start_index;
-+	unsigned long loop_offset;
-+	unsigned long transfer_count;
-+	unsigned long start_desc_count;
-+	unsigned long index_count;
-+	unsigned long desc_remaining;     
-+
-+
-+    index = *ppos >> PAGE_CACHE_SHIFT;
- 	prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT;
- 	prev_offset = ra->prev_pos & (PAGE_CACHE_SIZE-1);
- 	last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
- 	offset = *ppos & ~PAGE_CACHE_MASK;
- 
-+    // Page table mod's
-+	start_index = index;
-+	index_count = 0;
-+	transfer_count = 0;
-+	desc_remaining = desc->count;
-+	loop_offset = offset;
-+
- 	for (;;) {
- 		struct page *page;
- 		pgoff_t end_index;
-@@ -935,12 +954,12 @@
- 		nr = PAGE_CACHE_SIZE;
- 		if (index == end_index) {
- 			nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
--			if (nr <= offset) {
-+			if (nr <= loop_offset) {
- 				page_cache_release(page);
- 				goto out;
- 			}
- 		}
--		nr = nr - offset;
-+		nr = nr - loop_offset;
- 
- 		/* If users can be writing to this page using arbitrary
- 		 * virtual addresses, take care about potential aliasing
-@@ -953,30 +972,84 @@
- 		 * When a sequential read accesses a page several times,
- 		 * only mark it as accessed the first time.
- 		 */
--		if (prev_index != index || offset != prev_offset)
-+		if (prev_index != index || loop_offset != prev_offset)
- 			mark_page_accessed(page);
- 		prev_index = index;
- 
- 		/*
- 		 * Ok, we have the page, and it's up-to-date, so
--		 * now we can copy it to user space...
--		 *
--		 * The actor routine returns how many bytes were actually used..
--		 * NOTE! This may not be the same as how much of a user buffer
--		 * we filled up (we may be padding etc), so we can only update
--		 * "pos" here (the actor routine has to update the user buffer
--		 * pointers and the remaining count).
-+		 * now we can mark it for copy it to user space...
- 		 */
--		ret = actor(desc, page, offset, nr);
--		offset += ret;
--		index += offset >> PAGE_CACHE_SHIFT;
--		offset &= ~PAGE_CACHE_MASK;
--		prev_offset = offset;
-+        page_table[index_count] = page;
- 
--		page_cache_release(page);
--		if (ret == nr && desc->count)
--			continue;
--		goto out;
-+        index_count++;
-+
-+        transfer_count += nr;
-+
-+        if (transfer_count >= desc->count) {            
-+            loop_offset += desc_remaining;
-+            index += loop_offset >> PAGE_CACHE_SHIFT;            
-+            loop_offset &= ~PAGE_CACHE_MASK;
-+            desc_remaining = 0;
-+        } else {            
-+            loop_offset = 0;
-+            index++;
-+            desc_remaining -= nr;
-+        }
-+        
-+        prev_offset = loop_offset;
-+        //ra.prev_offset = loop_offset;
-+
-+        /**
-+         *  Do we have enough data in the pages so far, or enough
-+         *  pages left, to satisfy the count specified in the descriptor ?
-+         */
-+        if ((transfer_count < desc->count) && (index <= end_index) && (index_count < MAX_QUEUED_PAGES)) {
-+            continue;
-+        }
-+        
-+    /*
-+     * The actor routine returns how many bytes were actually used..
-+     * NOTE! This may not be the same as how much of a user buffer
-+     * we filled up (we may be padding etc), so we can only update
-+     * "pos" here (the actor routine has to update the user buffer
-+     * pointers and the remaining count).
-+     */
-+    
-+    start_desc_count = desc->count;
-+        
-+    ret = actor(desc, page_table, offset, transfer_count);
-+
-+    /*
-+     * Some debug to test if our assumptions about the transfer length are correct
-+     * We shouldn't see this message under normal execution
-+     */
-+
-+    if ((start_desc_count != ret) && (transfer_count != ret)) {
-+        printk("desc_count %#x, ret %#x, transfer_count %#x\n",start_desc_count,ret, transfer_count);
-+    }
-+    
-+    offset += ret;
-+    index = start_index + (offset >> PAGE_CACHE_SHIFT);
-+    
-+    offset &= ~PAGE_CACHE_MASK;
-+    //ra.prev_offset = offset;
-+
-+    while (index_count) {
-+        index_count--;
-+        page_cache_release(page_table[index_count]);
-+    }
-+    
-+    if (ret == transfer_count && desc->count) {
-+        // should probably think of what to do...
-+        index_count = 0;
-+        start_index = index;
-+        transfer_count = 0;
-+        loop_offset = offset;
-+        desc_remaining = desc->count;
-+        continue;
-+    }
-+    goto out;
- 
- page_not_up_to_date:
- 		/* Get exclusive access to the page ... */
-@@ -1056,6 +1129,7 @@
- 		goto readpage;
- 	}
- 
-+
- out:
- 	ra->prev_pos = prev_index;
- 	ra->prev_pos <<= PAGE_CACHE_SHIFT;
-@@ -1067,42 +1141,96 @@
- }
- EXPORT_SYMBOL(do_generic_mapping_read);
- 
--int file_read_actor(read_descriptor_t *desc, struct page *page,
-+int file_read_actor(read_descriptor_t *desc, struct page **page,
- 			unsigned long offset, unsigned long size)
- {
- 	char *kaddr;
- 	unsigned long left, count = desc->count;
-+    unsigned char* dst;
-+    unsigned long ret_size;
-+    
- 
- 	if (size > count)
- 		size = count;
- 
-+    ret_size = size;
-+    
-+    dst = desc->arg.buf;
-+
- 	/*
- 	 * Faults on the destination of a read are common, so do it before
- 	 * taking the kmap.
- 	 */
--	if (!fault_in_pages_writeable(desc->arg.buf, size)) {
--		kaddr = kmap_atomic(page, KM_USER0);
--		left = __copy_to_user_inatomic(desc->arg.buf,
--						kaddr + offset, size);
--		kunmap_atomic(kaddr, KM_USER0);
--		if (left == 0)
--			goto success;
--	}
-+    while (size) {            
-+        unsigned long psize = PAGE_CACHE_SIZE - offset;
-+        struct page *page_it;
-+        
-+        psize = PAGE_CACHE_SIZE - offset;
-+        if (size <= psize) {
-+            psize = size;                
-+        }
-+
-+        if  (fault_in_pages_writeable(dst, psize))
-+            break;
-+        
-+        page_it = *page;
-+        
-+        kaddr = kmap_atomic(page_it, KM_USER0);
-+        left = __copy_to_user_inatomic(dst,
-+                                       kaddr + offset, psize);
-+        kunmap_atomic(kaddr, KM_USE R0);
-+        if (left != 0)  
-+            break;  
-+
-+        size -= psize;            
-+        page++;
-+        offset += psize;
-+        dst += psize;            
-+        offset &= (PAGE_CACHE_SIZE - 1);
-+    }
-+
-+    if (size == 0)
-+        goto success;
-+        
- 
- 	/* Do it the slow way */
--	kaddr = kmap(page);
--	left = __copy_to_user(desc->arg.buf, kaddr + offset, size);
--	kunmap(page);
- 
--	if (left) {
--		size -= left;
--		desc->error = -EFAULT;
--	}
-+    
-+    while (size) {
-+        unsigned long psize;
-+        struct page *page_it;
-+        
-+        psize = PAGE_CACHE_SIZE - offset;
-+        if (size <= psize) {
-+            psize = size;                
-+        }
-+            
-+
-+        page_it = *page;
-+
-+        kaddr = kmap(page_it);
-+        
-+        left = __copy_to_user(dst, kaddr + offset, psize);
-+        kunmap(page_it);
-+
-+        if (left) {
-+            size -= left;
-+            desc->error = -EFAULT;
-+            break;            
-+        }
-+        page++;
-+        offset += psize;
-+        dst += psize;            
-+        offset &= (PAGE_CACHE_SIZE - 1);
-+        
-+        size -= psize;
-+    }
-+
- success:
--	desc->count = count - size;
--	desc->written += size;
--	desc->arg.buf += size;
--	return size;
-+	desc->count = count - ret_size;
-+	desc->written += ret_size;
-+	desc->arg.buf += ret_size;
-+	return ret_size;
- }
- 
- /*
-@@ -1219,6 +1347,46 @@
- }
- EXPORT_SYMBOL(generic_file_aio_read);
- 
-+int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size)
-+{
-+    ssize_t written;
-+	unsigned long count = desc->count;
-+	struct file *file = desc->arg.data;
-+
-+	if (size > count)
-+		size = count;
-+
-+	written = file->f_op->sendpages(file, page, offset,
-+				       size, &file->f_pos, size<count);
-+	if (written < 0) {
-+		desc->error = written;
-+		written = 0;
-+	}
-+	desc->count = count - written;
-+	desc->written += written;
-+	return written;
-+}
-+
-+ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
-+			 size_t count, read_actor_t actor, void *target)
-+{
-+	read_descriptor_t desc;
-+
-+	if (!count)
-+		return 0;
-+
-+	desc.written = 0;
-+	desc.count = count;
-+	desc.arg.data = target;
-+	desc.error = 0;
-+
-+	do_generic_file_read(in_file, ppos, &desc, actor);
-+	if (desc.written)
-+		return desc.written;
-+	return desc.error;
-+}
-+EXPORT_SYMBOL(generic_file_sendfile);
-+
- static ssize_t
- do_readahead(struct address_space *mapping, struct file *filp,
- 	     pgoff_t index, unsigned long nr)
-@@ -1725,17 +1893,27 @@
- }
- EXPORT_SYMBOL(iov_iter_copy_from_user);
- 
--static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
-+void iov_iter_advance(struct iov_iter *i, size_t bytes)
- {
-+	BUG_ON(i->count < bytes);
-+
- 	if (likely(i->nr_segs == 1)) {
- 		i->iov_offset += bytes;
-+		i->count -= bytes;
- 	} else {
- 		const struct iovec *iov = i->iov;
- 		size_t base = i->iov_offset;
- 
--		while (bytes) {
--			int copy = min(bytes, iov->iov_len - base);
-+		/*
-+		 * The !iov->iov_len check ensures we skip over unlikely
-+		 * zero-length segments (without overruning the iovec).
-+		 */
-+		while (bytes || unlikely(!iov->iov_len && i->count)) {
-+			int copy;
- 
-+			copy = min(bytes, iov->iov_len - base);
-+			BUG_ON(!i->count || i->count < copy);
-+			i->count -= copy;
- 			bytes -= copy;
- 			base += copy;
- 			if (iov->iov_len == base) {
-@@ -1747,14 +1925,6 @@
- 		i->iov_offset = base;
- 	}
- }
--
--void iov_iter_advance(struct iov_iter *i, size_t bytes)
--{
--	BUG_ON(i->count < bytes);
--
--	__iov_iter_advance_iov(i, bytes);
--	i->count -= bytes;
--}
- EXPORT_SYMBOL(iov_iter_advance);
- 
- /*
-@@ -2251,6 +2421,7 @@
- 
- 		cond_resched();
- 
-+		iov_iter_advance(i, copied);
- 		if (unlikely(copied == 0)) {
- 			/*
- 			 * If we were unable to copy any data at all, we must
-@@ -2264,7 +2435,6 @@
- 						iov_iter_single_seg_count(i));
- 			goto again;
- 		}
--		iov_iter_advance(i, copied);
- 		pos += copied;
- 		written += copied;
- 
-diff -Nurd linux-2.6.24/mm/fremap.c linux-2.6.24-oxe810/mm/fremap.c
---- linux-2.6.24/mm/fremap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/fremap.c	2008-06-11 17:47:28.000000000 +0200
-@@ -190,10 +190,13 @@
- 		 */
- 		if (mapping_cap_account_dirty(mapping)) {
- 			unsigned long addr;
-+			struct file *file = vma->vm_file;
- 
- 			flags &= MAP_NONBLOCK;
--			addr = mmap_region(vma->vm_file, start, size,
-+			get_file(file);
-+			addr = mmap_region(file, start, size,
- 					flags, vma->vm_flags, pgoff, 1);
-+			fput(file);
- 			if (IS_ERR_VALUE(addr)) {
- 				err = addr;
- 			} else {
-diff -Nurd linux-2.6.24/mm/hugetlb.c linux-2.6.24-oxe810/mm/hugetlb.c
---- linux-2.6.24/mm/hugetlb.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/hugetlb.c	2008-06-11 17:47:28.000000000 +0200
-@@ -119,6 +119,7 @@
- 	struct address_space *mapping;
- 
- 	mapping = (struct address_space *) page_private(page);
-+	set_page_private(page, 0);
- 	BUG_ON(page_count(page));
- 	INIT_LIST_HEAD(&page->lru);
- 
-@@ -133,7 +134,6 @@
- 	spin_unlock(&hugetlb_lock);
- 	if (mapping)
- 		hugetlb_put_quota(mapping, 1);
--	set_page_private(page, 0);
- }
- 
- /*
-@@ -605,6 +605,16 @@
- 	return 0;
- }
- 
-+int hugetlb_overcommit_handler(struct ctl_table *table, int write,
-+			struct file *file, void __user *buffer,
-+			size_t *length, loff_t *ppos)
-+{
-+	spin_lock(&hugetlb_lock);
-+	proc_doulongvec_minmax(table, write, file, buffer, length, ppos);
-+	spin_unlock(&hugetlb_lock);
-+	return 0;
-+}
-+
- #endif /* CONFIG_SYSCTL */
- 
- int hugetlb_report_meminfo(char *buf)
-diff -Nurd linux-2.6.24/mm/memory.c linux-2.6.24-oxe810/mm/memory.c
---- linux-2.6.24/mm/memory.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/memory.c	2008-06-11 17:47:28.000000000 +0200
-@@ -980,6 +980,8 @@
- 	int i;
- 	unsigned int vm_flags;
- 
-+	if (len <= 0)
-+		return 0;
- 	/* 
- 	 * Require read or write permissions.
- 	 * If 'force' is set, we only require the "MAY" flags.
-diff -Nurd linux-2.6.24/mm/mmap.c linux-2.6.24-oxe810/mm/mmap.c
---- linux-2.6.24/mm/mmap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/mmap.c	2008-06-11 17:47:28.000000000 +0200
-@@ -2215,7 +2215,7 @@
- 	vma->vm_start = addr;
- 	vma->vm_end = addr + len;
- 
--	vma->vm_flags = vm_flags | mm->def_flags;
-+	vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
- 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
- 
- 	vma->vm_ops = &special_mapping_vmops;
-diff -Nurd linux-2.6.24/mm/shmem.c linux-2.6.24-oxe810/mm/shmem.c
---- linux-2.6.24/mm/shmem.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/shmem.c	2008-06-11 17:47:28.000000000 +0200
-@@ -1681,7 +1681,7 @@
- 		 * "pos" here (the actor routine has to update the user buffer
- 		 * pointers and the remaining count).
- 		 */
--		ret = actor(desc, page, offset, nr);
-+		ret = actor(desc, &page, offset, nr);
- 		offset += ret;
- 		index += offset >> PAGE_CACHE_SHIFT;
- 		offset &= ~PAGE_CACHE_MASK;
-diff -Nurd linux-2.6.24/mm/slab.c linux-2.6.24-oxe810/mm/slab.c
---- linux-2.6.24/mm/slab.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/slab.c	2008-06-11 17:47:28.000000000 +0200
-@@ -304,11 +304,11 @@
- /*
-  * Need this for bootstrapping a per node allocator.
-  */
--#define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
-+#define NUM_INIT_LISTS (3 * MAX_NUMNODES)
- struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
- #define	CACHE_CACHE 0
--#define	SIZE_AC 1
--#define	SIZE_L3 (1 + MAX_NUMNODES)
-+#define	SIZE_AC MAX_NUMNODES
-+#define	SIZE_L3 (2 * MAX_NUMNODES)
- 
- static int drain_freelist(struct kmem_cache *cache,
- 			struct kmem_list3 *l3, int tofree);
-@@ -1410,6 +1410,22 @@
- }
- 
- /*
-+ * For setting up all the kmem_list3s for cache whose buffer_size is same as
-+ * size of kmem_list3.
-+ */
-+static void __init set_up_list3s(struct kmem_cache *cachep, int index)
-+{
-+	int node;
-+
-+	for_each_online_node(node) {
-+		cachep->nodelists[node] = &initkmem_list3[index + node];
-+		cachep->nodelists[node]->next_reap = jiffies +
-+		    REAPTIMEOUT_LIST3 +
-+		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-+	}
-+}
-+
-+/*
-  * Initialisation.  Called after the page allocator have been initialised and
-  * before smp_init().
-  */
-@@ -1432,6 +1448,7 @@
- 		if (i < MAX_NUMNODES)
- 			cache_cache.nodelists[i] = NULL;
- 	}
-+	set_up_list3s(&cache_cache, CACHE_CACHE);
- 
- 	/*
- 	 * Fragmentation resistance on low memory - only use bigger
-@@ -1587,10 +1604,9 @@
- 	{
- 		int nid;
- 
--		/* Replace the static kmem_list3 structures for the boot cpu */
--		init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
--
- 		for_each_online_node(nid) {
-+			init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], nid);
-+
- 			init_list(malloc_sizes[INDEX_AC].cs_cachep,
- 				  &initkmem_list3[SIZE_AC + nid], nid);
- 
-@@ -1960,22 +1976,6 @@
- 	}
- }
- 
--/*
-- * For setting up all the kmem_list3s for cache whose buffer_size is same as
-- * size of kmem_list3.
-- */
--static void __init set_up_list3s(struct kmem_cache *cachep, int index)
--{
--	int node;
--
--	for_each_online_node(node) {
--		cachep->nodelists[node] = &initkmem_list3[index + node];
--		cachep->nodelists[node]->next_reap = jiffies +
--		    REAPTIMEOUT_LIST3 +
--		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
--	}
--}
--
- static void __kmem_cache_destroy(struct kmem_cache *cachep)
- {
- 	int i;
-@@ -2099,7 +2099,7 @@
- 			g_cpucache_up = PARTIAL_L3;
- 		} else {
- 			int node;
--			for_each_node_state(node, N_NORMAL_MEMORY) {
-+			for_each_online_node(node) {
- 				cachep->nodelists[node] =
- 				    kmalloc_node(sizeof(struct kmem_list3),
- 						GFP_KERNEL, node);
-@@ -2961,11 +2961,10 @@
- 	struct array_cache *ac;
- 	int node;
- 
--	node = numa_node_id();
--
-+retry:
- 	check_irq_off();
-+	node = numa_node_id();
- 	ac = cpu_cache_get(cachep);
--retry:
- 	batchcount = ac->batchcount;
- 	if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
- 		/*
-diff -Nurd linux-2.6.24/mm/slub.c linux-2.6.24-oxe810/mm/slub.c
---- linux-2.6.24/mm/slub.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/slub.c	2008-06-11 17:47:28.000000000 +0200
-@@ -2592,6 +2592,7 @@
- void kfree(const void *x)
- {
- 	struct page *page;
-+	void *object = (void *)x;
- 
- 	if (unlikely(ZERO_OR_NULL_PTR(x)))
- 		return;
-@@ -2601,7 +2602,7 @@
- 		put_page(page);
- 		return;
- 	}
--	slab_free(page->slab, page, (void *)x, __builtin_return_address(0));
-+	slab_free(page->slab, page, object, __builtin_return_address(0));
- }
- EXPORT_SYMBOL(kfree);
- 
-diff -Nurd linux-2.6.24/net/bluetooth/hci_sysfs.c linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c
---- linux-2.6.24/net/bluetooth/hci_sysfs.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c	2008-06-11 17:46:02.000000000 +0200
-@@ -12,6 +12,8 @@
- #undef  BT_DBG
- #define BT_DBG(D...)
- #endif
-+static struct workqueue_struct *btaddconn;
-+static struct workqueue_struct *btdelconn;
- 
- static inline char *typetostr(int type)
- {
-@@ -279,6 +281,8 @@
- 	struct hci_conn *conn = container_of(work, struct hci_conn, work);
- 	int i;
- 
-+	flush_workqueue(btdelconn);
-+
- 	if (device_add(&conn->dev) < 0) {
- 		BT_ERR("Failed to register connection device");
- 		return;
-@@ -313,7 +317,7 @@
- 
- 	INIT_WORK(&conn->work, add_conn);
- 
--	schedule_work(&conn->work);
-+	queue_work(btaddconn, &conn->work);
- }
- 
- static int __match_tty(struct device *dev, void *data)
-@@ -349,7 +353,7 @@
- 
- 	INIT_WORK(&conn->work, del_conn);
- 
--	schedule_work(&conn->work);
-+	queue_work(btdelconn, &conn->work);
- }
- 
- int hci_register_sysfs(struct hci_dev *hdev)
-@@ -398,28 +402,54 @@
- {
- 	int err;
- 
-+	btaddconn = create_singlethread_workqueue("btaddconn");
-+	if (!btaddconn) {
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+
-+	btdelconn = create_singlethread_workqueue("btdelconn");
-+	if (!btdelconn) {
-+		err = -ENOMEM;
-+		goto out_del;
-+	}
-+
- 	bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
--	if (IS_ERR(bt_platform))
--		return PTR_ERR(bt_platform);
-+	if (IS_ERR(bt_platform)) {
-+		err = PTR_ERR(bt_platform);
-+		goto out_platform;
-+	}
- 
- 	err = bus_register(&bt_bus);
--	if (err < 0) {
--		platform_device_unregister(bt_platform);
--		return err;
--	}
-+	if (err < 0)
-+		goto out_bus;
- 
- 	bt_class = class_create(THIS_MODULE, "bluetooth");
- 	if (IS_ERR(bt_class)) {
--		bus_unregister(&bt_bus);
--		platform_device_unregister(bt_platform);
--		return PTR_ERR(bt_class);
-+		err = PTR_ERR(bt_class);
-+		goto out_class;
- 	}
- 
- 	return 0;
-+
-+out_class:
-+	bus_unregister(&bt_bus);
-+out_bus:
-+	platform_device_unregister(bt_platform);
-+out_platform:
-+	destroy_workqueue(btdelconn);
-+out_del:
-+	destroy_workqueue(btaddconn);
-+out:
-+	return err;
- }
- 
- void bt_sysfs_cleanup(void)
- {
-+	destroy_workqueue(btaddconn);
-+
-+	destroy_workqueue(btdelconn);
-+
- 	class_destroy(bt_class);
- 
- 	bus_unregister(&bt_bus);
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_dnat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c
---- linux-2.6.24/net/bridge/netfilter/ebt_dnat.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c	2008-06-11 17:46:12.000000000 +0200
-@@ -20,8 +20,8 @@
- {
- 	struct ebt_nat_info *info = (struct ebt_nat_info *)data;
- 
--	if (skb_make_writable(skb, 0))
--		return NF_DROP;
-+	if (!skb_make_writable(skb, 0))
-+		return EBT_DROP;
- 
- 	memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
- 	return info->target;
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_redirect.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c
---- linux-2.6.24/net/bridge/netfilter/ebt_redirect.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c	2008-06-11 17:46:12.000000000 +0200
-@@ -21,8 +21,8 @@
- {
- 	struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
- 
--	if (skb_make_writable(skb, 0))
--		return NF_DROP;
-+	if (!skb_make_writable(skb, 0))
-+		return EBT_DROP;
- 
- 	if (hooknr != NF_BR_BROUTING)
- 		memcpy(eth_hdr(skb)->h_dest,
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_snat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c
---- linux-2.6.24/net/bridge/netfilter/ebt_snat.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c	2008-06-11 17:46:12.000000000 +0200
-@@ -22,8 +22,8 @@
- {
- 	struct ebt_nat_info *info = (struct ebt_nat_info *) data;
- 
--	if (skb_make_writable(skb, 0))
--		return NF_DROP;
-+	if (!skb_make_writable(skb, 0))
-+		return EBT_DROP;
- 
- 	memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
- 	if (!(info->target & NAT_ARP_BIT) &&
-diff -Nurd linux-2.6.24/net/core/dev.c linux-2.6.24-oxe810/net/core/dev.c
---- linux-2.6.24/net/core/dev.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/core/dev.c	2008-06-11 17:45:57.000000000 +0200
-@@ -1068,8 +1068,6 @@
- 	 */
- 	call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
- 
--	dev_deactivate(dev);
--
- 	clear_bit(__LINK_STATE_START, &dev->state);
- 
- 	/* Synchronize to scheduled poll. We cannot touch poll list,
-@@ -1080,6 +1078,8 @@
- 	 */
- 	smp_mb__after_clear_bit(); /* Commit netif_running(). */
- 
-+	dev_deactivate(dev);
-+
- 	/*
- 	 *	Call the device specific close. This cannot fail.
- 	 *	Only if device is UP
-@@ -2906,7 +2906,7 @@
- 		}
- 	}
- 
--	da = kmalloc(sizeof(*da), GFP_ATOMIC);
-+	da = kzalloc(sizeof(*da), GFP_ATOMIC);
- 	if (da == NULL)
- 		return -ENOMEM;
- 	memcpy(da->da_addr, addr, alen);
-diff -Nurd linux-2.6.24/net/ipv4/af_inet.c linux-2.6.24-oxe810/net/ipv4/af_inet.c
---- linux-2.6.24/net/ipv4/af_inet.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/af_inet.c	2008-06-11 17:46:09.000000000 +0200
-@@ -838,6 +838,7 @@
- 	.recvmsg	   = sock_common_recvmsg,
- 	.mmap		   = sock_no_mmap,
- 	.sendpage	   = tcp_sendpage,
-+	.sendpages	   = tcp_sendpages,
- #ifdef CONFIG_COMPAT
- 	.compat_setsockopt = compat_sock_common_setsockopt,
- 	.compat_getsockopt = compat_sock_common_getsockopt,
-diff -Nurd linux-2.6.24/net/ipv4/fib_hash.c linux-2.6.24-oxe810/net/ipv4/fib_hash.c
---- linux-2.6.24/net/ipv4/fib_hash.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/fib_hash.c	2008-06-11 17:46:09.000000000 +0200
-@@ -434,19 +434,43 @@
- 
- 	if (fa && fa->fa_tos == tos &&
- 	    fa->fa_info->fib_priority == fi->fib_priority) {
--		struct fib_alias *fa_orig;
-+		struct fib_alias *fa_first, *fa_match;
- 
- 		err = -EEXIST;
- 		if (cfg->fc_nlflags & NLM_F_EXCL)
- 			goto out;
- 
-+		/* We have 2 goals:
-+		 * 1. Find exact match for type, scope, fib_info to avoid
-+		 * duplicate routes
-+		 * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
-+		 */
-+		fa_match = NULL;
-+		fa_first = fa;
-+		fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+		list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
-+			if (fa->fa_tos != tos)
-+				break;
-+			if (fa->fa_info->fib_priority != fi->fib_priority)
-+				break;
-+			if (fa->fa_type == cfg->fc_type &&
-+			    fa->fa_scope == cfg->fc_scope &&
-+			    fa->fa_info == fi) {
-+				fa_match = fa;
-+				break;
-+			}
-+		}
-+
- 		if (cfg->fc_nlflags & NLM_F_REPLACE) {
- 			struct fib_info *fi_drop;
- 			u8 state;
- 
--			if (fi->fib_treeref > 1)
-+			fa = fa_first;
-+			if (fa_match) {
-+				if (fa == fa_match)
-+					err = 0;
- 				goto out;
--
-+			}
- 			write_lock_bh(&fib_hash_lock);
- 			fi_drop = fa->fa_info;
- 			fa->fa_info = fi;
-@@ -469,20 +493,11 @@
- 		 * uses the same scope, type, and nexthop
- 		 * information.
- 		 */
--		fa_orig = fa;
--		fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
--		list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
--			if (fa->fa_tos != tos)
--				break;
--			if (fa->fa_info->fib_priority != fi->fib_priority)
--				break;
--			if (fa->fa_type == cfg->fc_type &&
--			    fa->fa_scope == cfg->fc_scope &&
--			    fa->fa_info == fi)
--				goto out;
--		}
-+		if (fa_match)
-+			goto out;
-+
- 		if (!(cfg->fc_nlflags & NLM_F_APPEND))
--			fa = fa_orig;
-+			fa = fa_first;
- 	}
- 
- 	err = -ENOENT;
-diff -Nurd linux-2.6.24/net/ipv4/fib_trie.c linux-2.6.24-oxe810/net/ipv4/fib_trie.c
---- linux-2.6.24/net/ipv4/fib_trie.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/fib_trie.c	2008-06-11 17:46:09.000000000 +0200
-@@ -1203,20 +1203,45 @@
- 	 * and we need to allocate a new one of those as well.
- 	 */
- 
--	if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
--		struct fib_alias *fa_orig;
-+	if (fa && fa->fa_tos == tos &&
-+	    fa->fa_info->fib_priority == fi->fib_priority) {
-+		struct fib_alias *fa_first, *fa_match;
- 
- 		err = -EEXIST;
- 		if (cfg->fc_nlflags & NLM_F_EXCL)
- 			goto out;
- 
-+		/* We have 2 goals:
-+		 * 1. Find exact match for type, scope, fib_info to avoid
-+		 * duplicate routes
-+		 * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
-+		 */
-+		fa_match = NULL;
-+		fa_first = fa;
-+		fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+		list_for_each_entry_continue(fa, fa_head, fa_list) {
-+			if (fa->fa_tos != tos)
-+				break;
-+			if (fa->fa_info->fib_priority != fi->fib_priority)
-+				break;
-+			if (fa->fa_type == cfg->fc_type &&
-+			    fa->fa_scope == cfg->fc_scope &&
-+			    fa->fa_info == fi) {
-+				fa_match = fa;
-+				break;
-+			}
-+		}
-+
- 		if (cfg->fc_nlflags & NLM_F_REPLACE) {
- 			struct fib_info *fi_drop;
- 			u8 state;
- 
--			if (fi->fib_treeref > 1)
-+			fa = fa_first;
-+			if (fa_match) {
-+				if (fa == fa_match)
-+					err = 0;
- 				goto out;
--
-+			}
- 			err = -ENOBUFS;
- 			new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
- 			if (new_fa == NULL)
-@@ -1228,7 +1253,7 @@
- 			new_fa->fa_type = cfg->fc_type;
- 			new_fa->fa_scope = cfg->fc_scope;
- 			state = fa->fa_state;
--			new_fa->fa_state &= ~FA_S_ACCESSED;
-+			new_fa->fa_state = state & ~FA_S_ACCESSED;
- 
- 			list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
- 			alias_free_mem_rcu(fa);
-@@ -1245,20 +1270,11 @@
- 		 * uses the same scope, type, and nexthop
- 		 * information.
- 		 */
--		fa_orig = fa;
--		list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
--			if (fa->fa_tos != tos)
--				break;
--			if (fa->fa_info->fib_priority != fi->fib_priority)
--				break;
--			if (fa->fa_type == cfg->fc_type &&
--			    fa->fa_scope == cfg->fc_scope &&
--			    fa->fa_info == fi) {
--				goto out;
--			}
--		}
-+		if (fa_match)
-+			goto out;
-+
- 		if (!(cfg->fc_nlflags & NLM_F_APPEND))
--			fa = fa_orig;
-+			fa = fa_first;
- 	}
- 	err = -ENOENT;
- 	if (!(cfg->fc_nlflags & NLM_F_CREATE))
-@@ -1614,9 +1630,8 @@
- 	pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
- 
- 	fa_to_delete = NULL;
--	fa_head = fa->fa_list.prev;
--
--	list_for_each_entry(fa, fa_head, fa_list) {
-+	fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+	list_for_each_entry_continue(fa, fa_head, fa_list) {
- 		struct fib_info *fi = fa->fa_info;
- 
- 		if (fa->fa_tos != tos)
-diff -Nurd linux-2.6.24/net/ipv4/inet_diag.c linux-2.6.24-oxe810/net/ipv4/inet_diag.c
---- linux-2.6.24/net/ipv4/inet_diag.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/inet_diag.c	2008-06-11 17:46:09.000000000 +0200
-@@ -259,8 +259,10 @@
- 	const struct inet_diag_handler *handler;
- 
- 	handler = inet_diag_lock_handler(nlh->nlmsg_type);
--	if (!handler)
--		return -ENOENT;
-+	if (IS_ERR(handler)) {
-+		err = PTR_ERR(handler);
-+		goto unlock;
-+	}
- 
- 	hashinfo = handler->idiag_hashinfo;
- 	err = -EINVAL;
-@@ -708,8 +710,8 @@
- 	struct inet_hashinfo *hashinfo;
- 
- 	handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
--	if (!handler)
--		goto no_handler;
-+	if (IS_ERR(handler))
-+		goto unlock;
- 
- 	hashinfo = handler->idiag_hashinfo;
- 
-@@ -838,7 +840,6 @@
- 	cb->args[2] = num;
- unlock:
- 	inet_diag_unlock_handler(handler);
--no_handler:
- 	return skb->len;
- }
- 
-diff -Nurd linux-2.6.24/net/ipv4/ip_output.c linux-2.6.24-oxe810/net/ipv4/ip_output.c
---- linux-2.6.24/net/ipv4/ip_output.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ip_output.c	2008-06-11 17:46:09.000000000 +0200
-@@ -462,6 +462,7 @@
- 	if (skb_shinfo(skb)->frag_list) {
- 		struct sk_buff *frag;
- 		int first_len = skb_pagelen(skb);
-+		int truesizes = 0;
- 
- 		if (first_len - hlen > mtu ||
- 		    ((first_len - hlen) & 7) ||
-@@ -485,7 +486,7 @@
- 				sock_hold(skb->sk);
- 				frag->sk = skb->sk;
- 				frag->destructor = sock_wfree;
--				skb->truesize -= frag->truesize;
-+				truesizes += frag->truesize;
- 			}
- 		}
- 
-@@ -496,6 +497,7 @@
- 		frag = skb_shinfo(skb)->frag_list;
- 		skb_shinfo(skb)->frag_list = NULL;
- 		skb->data_len = first_len - skb_headlen(skb);
-+		skb->truesize -= truesizes;
- 		skb->len = first_len;
- 		iph->tot_len = htons(first_len);
- 		iph->frag_off = htons(IP_MF);
-diff -Nurd linux-2.6.24/net/ipv4/ip_sockglue.c linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c
---- linux-2.6.24/net/ipv4/ip_sockglue.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c	2008-06-11 17:46:09.000000000 +0200
-@@ -514,11 +514,6 @@
- 			val &= ~3;
- 			val |= inet->tos & 3;
- 		}
--		if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
--		    !capable(CAP_NET_ADMIN)) {
--			err = -EPERM;
--			break;
--		}
- 		if (inet->tos != val) {
- 			inet->tos = val;
- 			sk->sk_priority = rt_tos2priority(val);
-diff -Nurd linux-2.6.24/net/ipv4/ipcomp.c linux-2.6.24-oxe810/net/ipv4/ipcomp.c
---- linux-2.6.24/net/ipv4/ipcomp.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ipcomp.c	2008-06-11 17:46:09.000000000 +0200
-@@ -74,6 +74,7 @@
- 
- static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
- {
-+	int nexthdr;
- 	int err = -ENOMEM;
- 	struct ip_comp_hdr *ipch;
- 
-@@ -84,13 +85,15 @@
- 
- 	/* Remove ipcomp header and decompress original payload */
- 	ipch = (void *)skb->data;
-+	nexthdr = ipch->nexthdr;
-+
- 	skb->transport_header = skb->network_header + sizeof(*ipch);
- 	__skb_pull(skb, sizeof(*ipch));
- 	err = ipcomp_decompress(x, skb);
- 	if (err)
- 		goto out;
- 
--	err = ipch->nexthdr;
-+	err = nexthdr;
- 
- out:
- 	return err;
-@@ -105,8 +108,11 @@
- 	const int cpu = get_cpu();
- 	u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
- 	struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
--	int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+	int err;
- 
-+	local_bh_disable();
-+	err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+	local_bh_enable();
- 	if (err)
- 		goto out;
- 
-diff -Nurd linux-2.6.24/net/ipv4/ipconfig.c linux-2.6.24-oxe810/net/ipv4/ipconfig.c
---- linux-2.6.24/net/ipv4/ipconfig.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ipconfig.c	2008-06-11 17:46:09.000000000 +0200
-@@ -739,9 +739,9 @@
- 		printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
- 		b->htype = dev->type; /* can cause undefined behavior */
- 	}
-+
-+	/* server_ip and your_ip address are both already zero per RFC2131 */
- 	b->hlen = dev->addr_len;
--	b->your_ip = NONE;
--	b->server_ip = NONE;
- 	memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
- 	b->secs = htons(jiffies_diff / HZ);
- 	b->xid = d->xid;
-diff -Nurd linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c
---- linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c	2008-06-11 17:46:07.000000000 +0200
-@@ -19,7 +19,7 @@
- 	unsigned char *arpptr;
- 	int pln, hln;
- 
--	if (skb_make_writable(skb, skb->len))
-+	if (!skb_make_writable(skb, skb->len))
- 		return NF_DROP;
- 
- 	arp = arp_hdr(skb);
-diff -Nurd linux-2.6.24/net/ipv4/netfilter/ip_queue.c linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c
---- linux-2.6.24/net/ipv4/netfilter/ip_queue.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c	2008-06-11 17:46:07.000000000 +0200
-@@ -336,8 +336,8 @@
- ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
- {
- 	int diff;
--	int err;
- 	struct iphdr *user_iph = (struct iphdr *)v->payload;
-+	struct sk_buff *nskb;
- 
- 	if (v->data_len < sizeof(*user_iph))
- 		return 0;
-@@ -349,14 +349,16 @@
- 		if (v->data_len > 0xFFFF)
- 			return -EINVAL;
- 		if (diff > skb_tailroom(e->skb)) {
--			err = pskb_expand_head(e->skb, 0,
-+			nskb = skb_copy_expand(e->skb, 0,
- 					       diff - skb_tailroom(e->skb),
- 					       GFP_ATOMIC);
--			if (err) {
-+			if (!nskb) {
- 				printk(KERN_WARNING "ip_queue: error "
--				      "in mangle, dropping packet: %d\n", -err);
--				return err;
-+				      "in mangle, dropping packet\n");
-+				return -ENOMEM;
- 			}
-+			kfree_skb(e->skb);
-+			e->skb = nskb;
- 		}
- 		skb_put(e->skb, diff);
- 	}
-diff -Nurd linux-2.6.24/net/ipv4/sysctl_net_ipv4.c linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c
---- linux-2.6.24/net/ipv4/sysctl_net_ipv4.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c	2008-06-11 17:46:09.000000000 +0200
-@@ -248,7 +248,7 @@
- 
- 	tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
- 	ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
--	if (ret == 0 && newval && newlen)
-+	if (ret == 1 && newval && newlen)
- 		ret = tcp_set_allowed_congestion_control(tbl.data);
- 	kfree(tbl.data);
- 
-diff -Nurd linux-2.6.24/net/ipv4/tcp.c linux-2.6.24-oxe810/net/ipv4/tcp.c
---- linux-2.6.24/net/ipv4/tcp.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/tcp.c	2008-06-11 17:46:09.000000000 +0200
-@@ -269,6 +269,8 @@
- #include <asm/uaccess.h>
- #include <asm/ioctls.h>
- 
-+#include <linux/pagemap.h>
-+
- int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
- 
- DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
-@@ -636,6 +638,48 @@
- 	return res;
- }
- 
-+ssize_t tcp_sendpages(struct socket *sock, struct page **page, int offset,
-+ 		     size_t size, int flags)
-+{
-+ 	ssize_t res;
-+ 	struct sock *sk = sock->sk;
-+ 
-+#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-+
-+	if (!(sk->sk_route_caps & NETIF_F_SG) ||
-+	    !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS)) {
-+        // Iterate through each page
-+        ssize_t ret = 0;
-+
-+        while (size) {
-+            unsigned long psize = PAGE_CACHE_SIZE - offset;
-+            struct page *page_it;
-+        
-+            psize = PAGE_CACHE_SIZE - offset;
-+            if (size <= psize) {
-+                psize = size;                
-+            }
-+            page_it = *page;
-+            ret += sock_no_sendpage(sock, page_it, offset, psize, flags);
-+            size -= psize;            
-+            page++;
-+            offset += psize;
-+            offset &= (PAGE_CACHE_SIZE - 1);
-+        }
-+		return ret;        
-+    }
-+    
-+#undef TCP_ZC_CSUM_FLAGS
-+
-+ 	lock_sock(sk);
-+ 	TCP_CHECK_TIMER(sk);
-+ 	res = do_tcp_sendpages(sk, page, offset, size, flags);
-+ 	TCP_CHECK_TIMER(sk);
-+     
-+ 	release_sock(sk);
-+ 	return res;
-+}
-+
- #define TCP_PAGE(sk)	(sk->sk_sndmsg_page)
- #define TCP_OFF(sk)	(sk->sk_sndmsg_off)
- 
-diff -Nurd linux-2.6.24/net/ipv4/xfrm4_tunnel.c linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c
---- linux-2.6.24/net/ipv4/xfrm4_tunnel.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c	2008-06-11 17:46:09.000000000 +0200
-@@ -50,7 +50,7 @@
- 
- static int xfrm_tunnel_rcv(struct sk_buff *skb)
- {
--	return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
-+	return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
- }
- 
- static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
-diff -Nurd linux-2.6.24/net/ipv6/ip6_output.c linux-2.6.24-oxe810/net/ipv6/ip6_output.c
---- linux-2.6.24/net/ipv6/ip6_output.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ip6_output.c	2008-06-11 17:46:11.000000000 +0200
-@@ -593,7 +593,7 @@
- 	 * or if the skb it not generated by a local socket.  (This last
- 	 * check should be redundant, but it's free.)
- 	 */
--	if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
-+	if (!skb->local_df) {
- 		skb->dev = skb->dst->dev;
- 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
- 		IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
-@@ -609,6 +609,7 @@
- 
- 	if (skb_shinfo(skb)->frag_list) {
- 		int first_len = skb_pagelen(skb);
-+		int truesizes = 0;
- 
- 		if (first_len - hlen > mtu ||
- 		    ((first_len - hlen) & 7) ||
-@@ -631,7 +632,7 @@
- 				sock_hold(skb->sk);
- 				frag->sk = skb->sk;
- 				frag->destructor = sock_wfree;
--				skb->truesize -= frag->truesize;
-+				truesizes += frag->truesize;
- 			}
- 		}
- 
-@@ -662,6 +663,7 @@
- 
- 		first_len = skb_pagelen(skb);
- 		skb->data_len = first_len - skb_headlen(skb);
-+		skb->truesize -= truesizes;
- 		skb->len = first_len;
- 		ipv6_hdr(skb)->payload_len = htons(first_len -
- 						   sizeof(struct ipv6hdr));
-@@ -1387,6 +1389,10 @@
- 		tmp_skb->sk = NULL;
- 	}
- 
-+	/* Allow local fragmentation. */
-+	if (np->pmtudisc < IPV6_PMTUDISC_DO)
-+		skb->local_df = 1;
-+
- 	ipv6_addr_copy(final_dst, &fl->fl6_dst);
- 	__skb_pull(skb, skb_network_header_len(skb));
- 	if (opt && opt->opt_flen)
-diff -Nurd linux-2.6.24/net/ipv6/ip6_tunnel.c linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c
---- linux-2.6.24/net/ipv6/ip6_tunnel.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c	2008-06-11 17:46:11.000000000 +0200
-@@ -550,6 +550,7 @@
- 			ip_rt_put(rt);
- 			goto out;
- 		}
-+		skb2->dst = (struct dst_entry *)rt;
- 	} else {
- 		ip_rt_put(rt);
- 		if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
-diff -Nurd linux-2.6.24/net/ipv6/ipcomp6.c linux-2.6.24-oxe810/net/ipv6/ipcomp6.c
---- linux-2.6.24/net/ipv6/ipcomp6.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ipcomp6.c	2008-06-11 17:46:11.000000000 +0200
-@@ -64,6 +64,7 @@
- 
- static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
- {
-+	int nexthdr;
- 	int err = -ENOMEM;
- 	struct ip_comp_hdr *ipch;
- 	int plen, dlen;
-@@ -79,6 +80,8 @@
- 
- 	/* Remove ipcomp header and decompress original payload */
- 	ipch = (void *)skb->data;
-+	nexthdr = ipch->nexthdr;
-+
- 	skb->transport_header = skb->network_header + sizeof(*ipch);
- 	__skb_pull(skb, sizeof(*ipch));
- 
-@@ -108,7 +111,7 @@
- 	skb->truesize += dlen - plen;
- 	__skb_put(skb, dlen - plen);
- 	skb_copy_to_linear_data(skb, scratch, dlen);
--	err = ipch->nexthdr;
-+	err = nexthdr;
- 
- out_put_cpu:
- 	put_cpu();
-@@ -143,7 +146,9 @@
- 	scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
- 	tfm = *per_cpu_ptr(ipcd->tfms, cpu);
- 
-+	local_bh_disable();
- 	err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+	local_bh_enable();
- 	if (err || (dlen + sizeof(*ipch)) >= plen) {
- 		put_cpu();
- 		goto out_ok;
-diff -Nurd linux-2.6.24/net/ipv6/netfilter/ip6_queue.c linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c
---- linux-2.6.24/net/ipv6/netfilter/ip6_queue.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c	2008-06-11 17:46:10.000000000 +0200
-@@ -333,8 +333,8 @@
- ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
- {
- 	int diff;
--	int err;
- 	struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload;
-+	struct sk_buff *nskb;
- 
- 	if (v->data_len < sizeof(*user_iph))
- 		return 0;
-@@ -346,14 +346,16 @@
- 		if (v->data_len > 0xFFFF)
- 			return -EINVAL;
- 		if (diff > skb_tailroom(e->skb)) {
--			err = pskb_expand_head(e->skb, 0,
-+			nskb = skb_copy_expand(e->skb, 0,
- 					       diff - skb_tailroom(e->skb),
- 					       GFP_ATOMIC);
--			if (err) {
-+			if (!nskb) {
- 				printk(KERN_WARNING "ip6_queue: OOM "
- 				      "in mangle, dropping packet\n");
--				return err;
-+				return -ENOMEM;
- 			}
-+			kfree_skb(e->skb);
-+			e->skb = nskb;
- 		}
- 		skb_put(e->skb, diff);
- 	}
-diff -Nurd linux-2.6.24/net/ipv6/xfrm6_output.c linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c
---- linux-2.6.24/net/ipv6/xfrm6_output.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c	2008-06-11 17:46:11.000000000 +0200
-@@ -34,7 +34,7 @@
- 	if (mtu < IPV6_MIN_MTU)
- 		mtu = IPV6_MIN_MTU;
- 
--	if (skb->len > mtu) {
-+	if (!skb->local_df && skb->len > mtu) {
- 		skb->dev = dst->dev;
- 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
- 		ret = -EMSGSIZE;
-diff -Nurd linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c
---- linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c	2008-06-11 17:46:00.000000000 +0200
-@@ -135,7 +135,7 @@
-  * CLOSE_WAIT:	ACK seen (after FIN)
-  * LAST_ACK:	FIN seen (after FIN)
-  * TIME_WAIT:	last ACK seen
-- * CLOSE:	closed connection
-+ * CLOSE:	closed connection (RST)
-  *
-  * LISTEN state is not used.
-  *
-@@ -834,8 +834,21 @@
- 	case TCP_CONNTRACK_SYN_SENT:
- 		if (old_state < TCP_CONNTRACK_TIME_WAIT)
- 			break;
--		if ((conntrack->proto.tcp.seen[!dir].flags &
--			IP_CT_TCP_FLAG_CLOSE_INIT)
-+		/* RFC 1122: "When a connection is closed actively,
-+		 * it MUST linger in TIME-WAIT state for a time 2xMSL
-+		 * (Maximum Segment Lifetime). However, it MAY accept
-+		 * a new SYN from the remote TCP to reopen the connection
-+		 * directly from TIME-WAIT state, if..."
-+		 * We ignore the conditions because we are in the
-+		 * TIME-WAIT state anyway.
-+		 *
-+		 * Handle aborted connections: we and the server
-+		 * think there is an existing connection but the client
-+		 * aborts it and starts a new one.
-+		 */
-+		if (((conntrack->proto.tcp.seen[dir].flags
-+		      | conntrack->proto.tcp.seen[!dir].flags)
-+		     & IP_CT_TCP_FLAG_CLOSE_INIT)
- 		    || (conntrack->proto.tcp.last_dir == dir
- 		        && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
- 			/* Attempt to reopen a closed/aborted connection.
-@@ -848,18 +861,25 @@
- 		}
- 		/* Fall through */
- 	case TCP_CONNTRACK_IGNORE:
--		/* Ignored packets:
-+		/* Ignored packets: 
-+		 *
-+		 * Our connection entry may be out of sync, so ignore
-+		 * packets which may signal the real connection between
-+		 * the client and the server.
- 		 *
- 		 * a) SYN in ORIGINAL
- 		 * b) SYN/ACK in REPLY
- 		 * c) ACK in reply direction after initial SYN in original.
-+		 *
-+		 * If the ignored packet is invalid, the receiver will send 
-+		 * a RST we'll catch below.
- 		 */
- 		if (index == TCP_SYNACK_SET
- 		    && conntrack->proto.tcp.last_index == TCP_SYN_SET
- 		    && conntrack->proto.tcp.last_dir != dir
- 		    && ntohl(th->ack_seq) ==
- 			     conntrack->proto.tcp.last_end) {
--			/* This SYN/ACK acknowledges a SYN that we earlier
-+			/* b) This SYN/ACK acknowledges a SYN that we earlier
- 			 * ignored as invalid. This means that the client and
- 			 * the server are both in sync, while the firewall is
- 			 * not. We kill this session and block the SYN/ACK so
-@@ -884,7 +904,7 @@
- 		write_unlock_bh(&tcp_lock);
- 		if (LOG_INVALID(IPPROTO_TCP))
- 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
--				  "nf_ct_tcp: invalid packed ignored ");
-+				  "nf_ct_tcp: invalid packet ignored ");
- 		return NF_ACCEPT;
- 	case TCP_CONNTRACK_MAX:
- 		/* Invalid packet */
-@@ -938,8 +958,7 @@
- 
- 	conntrack->proto.tcp.state = new_state;
- 	if (old_state != new_state
--	    && (new_state == TCP_CONNTRACK_FIN_WAIT
--		|| new_state == TCP_CONNTRACK_CLOSE))
-+	    && new_state == TCP_CONNTRACK_FIN_WAIT)
- 		conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
- 	timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
- 		  && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
-diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_log.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c
---- linux-2.6.24/net/netfilter/nfnetlink_log.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c	2008-06-11 17:46:00.000000000 +0200
-@@ -594,7 +594,7 @@
- 	/* FIXME: do we want to make the size calculation conditional based on
- 	 * what is actually present?  way more branches and checks, but more
- 	 * memory efficient... */
--	size =    NLMSG_ALIGN(sizeof(struct nfgenmsg))
-+	size =    NLMSG_SPACE(sizeof(struct nfgenmsg))
- 		+ nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
- 		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
- 		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
-diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_queue.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c
---- linux-2.6.24/net/netfilter/nfnetlink_queue.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c	2008-06-11 17:46:00.000000000 +0200
-@@ -353,7 +353,7 @@
- 
- 	QDEBUG("entered\n");
- 
--	size =    NLMSG_ALIGN(sizeof(struct nfgenmsg))
-+	size =    NLMSG_SPACE(sizeof(struct nfgenmsg))
- 		+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
- 		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
- 		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
-@@ -616,8 +616,8 @@
- static int
- nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
- {
-+	struct sk_buff *nskb;
- 	int diff;
--	int err;
- 
- 	diff = data_len - e->skb->len;
- 	if (diff < 0) {
-@@ -627,14 +627,16 @@
- 		if (data_len > 0xFFFF)
- 			return -EINVAL;
- 		if (diff > skb_tailroom(e->skb)) {
--			err = pskb_expand_head(e->skb, 0,
-+			nskb = skb_copy_expand(e->skb, 0,
- 					       diff - skb_tailroom(e->skb),
- 					       GFP_ATOMIC);
--			if (err) {
-+			if (!nskb) {
- 				printk(KERN_WARNING "nf_queue: OOM "
- 				      "in mangle, dropping packet\n");
--				return err;
-+				return -ENOMEM;
- 			}
-+			kfree_skb(e->skb);
-+			e->skb = nskb;
- 		}
- 		skb_put(e->skb, diff);
- 	}
-diff -Nurd linux-2.6.24/net/netfilter/xt_time.c linux-2.6.24-oxe810/net/netfilter/xt_time.c
---- linux-2.6.24/net/netfilter/xt_time.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/xt_time.c	2008-06-11 17:46:00.000000000 +0200
-@@ -95,8 +95,11 @@
- 	 */
- 	r->dse = time / 86400;
- 
--	/* 1970-01-01 (w=0) was a Thursday (4). */
--	r->weekday = (4 + r->dse) % 7;
-+	/*
-+	 * 1970-01-01 (w=0) was a Thursday (4).
-+	 * -1 and +1 map Sunday properly onto 7.
-+	 */
-+	r->weekday = (4 + r->dse - 1) % 7 + 1;
- }
- 
- static void localtime_3(struct xtm *r, time_t time)
-diff -Nurd linux-2.6.24/net/sched/em_meta.c linux-2.6.24-oxe810/net/sched/em_meta.c
---- linux-2.6.24/net/sched/em_meta.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/sched/em_meta.c	2008-06-11 17:45:56.000000000 +0200
-@@ -719,11 +719,13 @@
- 
- static inline void meta_delete(struct meta_match *meta)
- {
--	struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
-+	if (meta) {
-+		struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
- 
--	if (ops && ops->destroy) {
--		ops->destroy(&meta->lvalue);
--		ops->destroy(&meta->rvalue);
-+		if (ops && ops->destroy) {
-+			ops->destroy(&meta->lvalue);
-+			ops->destroy(&meta->rvalue);
-+		}
- 	}
- 
- 	kfree(meta);
-diff -Nurd linux-2.6.24/net/sched/ematch.c linux-2.6.24-oxe810/net/sched/ematch.c
---- linux-2.6.24/net/sched/ematch.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/sched/ematch.c	2008-06-11 17:45:56.000000000 +0200
-@@ -305,10 +305,9 @@
- 	struct tcf_ematch_tree_hdr *tree_hdr;
- 	struct tcf_ematch *em;
- 
--	if (!rta) {
--		memset(tree, 0, sizeof(*tree));
-+	memset(tree, 0, sizeof(*tree));
-+	if (!rta)
- 		return 0;
--	}
- 
- 	if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
- 		goto errout;
-diff -Nurd linux-2.6.24/net/socket.c linux-2.6.24-oxe810/net/socket.c
---- linux-2.6.24/net/socket.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/socket.c	2008-06-11 17:46:19.000000000 +0200
-@@ -113,6 +113,9 @@
- static ssize_t sock_sendpage(struct file *file, struct page *page,
- 			     int offset, size_t size, loff_t *ppos, int more);
- 
-+static ssize_t sock_sendpages(struct file *file, struct page **page,
-+			     int offset, size_t size, loff_t *ppos, int more);
-+
- /*
-  *	Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
-  *	in the operation structures but are done directly via the socketcall() multiplexor.
-@@ -133,6 +136,7 @@
- 	.release =	sock_close,
- 	.fasync =	sock_fasync,
- 	.sendpage =	sock_sendpage,
-+	.sendpages =	sock_sendpages,
- 	.splice_write = generic_splice_sendpage,
- };
- 
-@@ -691,6 +695,21 @@
- 	return sock->ops->sendpage(sock, page, offset, size, flags);
- }
- 
-+static ssize_t sock_sendpages(struct file *file, struct page **page,
-+			     int offset, size_t size, loff_t *ppos, int more)
-+{
-+	struct socket *sock;
-+	int flags;
-+
-+	sock = file->private_data;
-+
-+	flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-+	if (more)
-+		flags |= MSG_MORE;
-+
-+	return sock->ops->sendpages(sock, page, offset, size, flags);
-+}
-+
- static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
- 					 struct sock_iocb *siocb)
- {
-diff -Nurd linux-2.6.24/scripts/mod/file2alias.c linux-2.6.24-oxe810/scripts/mod/file2alias.c
---- linux-2.6.24/scripts/mod/file2alias.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/scripts/mod/file2alias.c	2008-06-11 17:46:20.000000000 +0200
-@@ -155,7 +155,7 @@
- 	 * Some modules (visor) have empty slots as placeholder for
- 	 * run-time specification that results in catch-all alias
- 	 */
--	if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
-+	if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass))
- 		return;
- 
- 	/* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
-diff -Nurd linux-2.6.24/security/Kconfig linux-2.6.24-oxe810/security/Kconfig
---- linux-2.6.24/security/Kconfig	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/Kconfig	2008-06-11 17:46:44.000000000 +0200
-@@ -103,6 +103,32 @@
- 	  
- 	  If you are unsure how to answer this question, answer N.
- 
-+config SECURITY_TRUSTEES
-+	bool "Linux Trustees ACLs"
-+	depends on SECURITY
-+	help
-+	  Implements a system similar to Netware ACLs.  Trustees
-+	  allows a global configuration of recursive ACLs via a
-+	  centralized file.  ACLs can be added to an entire
-+	  directory tree and masked out on subdirectories.
-+
-+	  Trustees allows complex permissions to be enforced
-+	  system-wide without needing to touch every file or
-+	  maintain thousands of ugly POSIX ACLs.  See
-+	  http://trustees.sourceforge.net for more information on
-+	  trustees and the associated user-space tools.
-+
-+	  If you are unsure how to answer this question, answer N.
-+
-+config SECURITY_TRUSTEES_DEBUG
-+	bool "Enable debugging code and messages"
-+	depends on SECURITY_TRUSTEES
-+	help
-+	  Turns on certain diagnostic messages and debugging code
-+	  in trustees.
-+
-+	  If you are unsure how to answer this question, answer N.
-+
- source security/selinux/Kconfig
- 
- endmenu
-diff -Nurd linux-2.6.24/security/Makefile linux-2.6.24-oxe810/security/Makefile
---- linux-2.6.24/security/Makefile	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/Makefile	2008-06-11 17:46:44.000000000 +0200
-@@ -12,6 +12,7 @@
- 
- # Object file lists
- obj-$(CONFIG_SECURITY)			+= security.o dummy.o inode.o
-+obj-$(CONFIG_SECURITY_TRUSTEES)     += trustees/
- # Must precede capability.o in order to stack properly.
- obj-$(CONFIG_SECURITY_SELINUX)		+= selinux/built-in.o
- obj-$(CONFIG_SECURITY_CAPABILITIES)	+= commoncap.o capability.o
-diff -Nurd linux-2.6.24/security/commoncap.c linux-2.6.24-oxe810/security/commoncap.c
---- linux-2.6.24/security/commoncap.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/commoncap.c	2008-06-11 17:46:44.000000000 +0200
-@@ -539,7 +539,7 @@
- 	 * allowed.
- 	 * We must preserve legacy signal behavior in this case.
- 	 */
--	if (p->euid == 0 && p->uid == current->uid)
-+	if (p->uid == current->uid)
- 		return 0;
- 
- 	/* sigcont is permitted within same session */
-diff -Nurd linux-2.6.24/security/selinux/ss/services.c linux-2.6.24-oxe810/security/selinux/ss/services.c
---- linux-2.6.24/security/selinux/ss/services.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/selinux/ss/services.c	2008-06-11 17:46:43.000000000 +0200
-@@ -1744,6 +1744,9 @@
- 	struct ocontext *c;
- 	int rc = 0, cmp = 0;
- 
-+	while (path[0] == '/' && path[1] == '/')
-+		path++;
-+
- 	POLICY_RDLOCK;
- 
- 	for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
-@@ -2626,7 +2629,6 @@
- 
- netlbl_sid_to_secattr_failure:
- 	POLICY_RDUNLOCK;
--	netlbl_secattr_destroy(secattr);
- 	return rc;
- }
- #endif /* CONFIG_NETLABEL */
-diff -Nurd linux-2.6.24/security/trustees/Makefile linux-2.6.24-oxe810/security/trustees/Makefile
---- linux-2.6.24/security/trustees/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/Makefile	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,8 @@
-+ifeq ($(CONFIG_SECURITY_TRUSTEES_DEBUG),y)
-+	EXTRA_CFLAGS += -DTRUSTEES_DEBUG
-+endif
-+
-+obj-$(CONFIG_SECURITY_TRUSTEES) := trustees.o
-+trustees-objs := \
-+	security.o fs.o \
-+	init.o funcs.o ../commoncap.o
-diff -Nurd linux-2.6.24/security/trustees/fs.c linux-2.6.24-oxe810/security/trustees/fs.c
---- linux-2.6.24/security/trustees/fs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/fs.c	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,273 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * This code handles the virtual filesystem for trustees.
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/vmalloc.h>
-+#include <linux/security.h>
-+#include <asm/atomic.h>
-+#include <asm/uaccess.h>
-+
-+#include "internal.h"
-+
-+
-+/* initialization code for the trustees filesystem */
-+
-+/* File operations
-+ *
-+ * this is all the code for handling the file operations done on the few files
-+ * in the trustees filesystem
-+ */
-+static int trustees_open(struct inode *inode, struct file *filp);
-+static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
-+				   size_t count, loff_t * offset);
-+static ssize_t trustees_write_bogus(struct file *filp,
-+				    const char __user * buf, size_t count,
-+				    loff_t * offset);
-+static ssize_t trustees_read_status(struct file *filp, char __user * buf,
-+				    size_t count, loff_t * offset);
-+static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
-+				    size_t count, loff_t * offset);
-+static ssize_t trustees_write_trustees(struct file *filp,
-+				       const char __user * buf,
-+				       size_t count, loff_t * offset);
-+static int trustees_open_trustees(struct inode *inode, struct file *file);
-+static int trustees_release_trustees(struct inode *inode, struct file *file);
-+
-+/* Various structs
-+ */
-+
-+static struct file_operations trustees_ops_apiversion = {
-+	.open = trustees_open,
-+	.read = trustees_read_apiversion,
-+	.write = trustees_write_bogus,
-+};
-+
-+static struct file_operations trustees_ops_status = {
-+	.open = trustees_open,
-+	.read = trustees_read_status,
-+	.write = trustees_write_bogus
-+};
-+
-+static struct file_operations trustees_ops_trustees = {
-+	.open = trustees_open_trustees,
-+	.read = trustees_read_bogus,
-+	.write = trustees_write_trustees,
-+	.release = trustees_release_trustees
-+};
-+
-+static struct trustees_file_info {
-+	const char *name;
-+	struct file_operations *fops;
-+	int mode;
-+	struct dentry *dentry;
-+} trustees_files[] = {
-+	{.name = "device",
-+	 .fops = &trustees_ops_trustees,
-+	 .mode = S_IWUSR,
-+	 .dentry = 0
-+	 },
-+	{.name = "status",
-+	 .fops = &trustees_ops_status,
-+	 .mode = S_IRUSR,
-+	 .dentry = 0
-+	 },
-+	{.name = "apiversion",
-+	 .fops = &trustees_ops_apiversion,
-+	 .mode = S_IRUSR | S_IRGRP | S_IROTH,
-+	 .dentry = 0
-+	 },
-+	{"", NULL, 0, 0}
-+};
-+
-+struct trustee_command_reader {
-+	struct trustee_command command;
-+	unsigned curarg;
-+	void *arg[TRUSTEE_MAX_ARGS];
-+	size_t argsize[TRUSTEE_MAX_ARGS];
-+};
-+
-+
-+static struct dentry *toplevel = NULL;
-+
-+int trustees_init_fs(void)
-+{
-+	struct trustees_file_info *iter;
-+	toplevel = securityfs_create_dir("trustees", NULL);
-+	if (!toplevel) trustees_deinit_fs();
-+	for (iter = trustees_files; iter->fops && toplevel; iter++) {
-+		iter->dentry = securityfs_create_file(
-+		   iter->name, iter->mode, toplevel, NULL, iter->fops);
-+		if (!iter->dentry) trustees_deinit_fs();
-+	}
-+	return !toplevel;
-+}
-+
-+void trustees_deinit_fs(void)
-+{
-+	struct trustees_file_info *iter;
-+	for (iter = trustees_files; iter->fops; iter++) {
-+		securityfs_remove(iter->dentry);
-+		iter->dentry = NULL;
-+	}
-+	securityfs_remove(toplevel);
-+	toplevel = NULL;
-+}
-+
-+/*
-+ * They're opening the file...
-+ */
-+
-+static int trustees_open(struct inode *inode, struct file *filp)
-+{
-+	return 0;
-+}
-+
-+static int trustees_open_trustees(struct inode *inode, struct file *file)
-+{
-+	file->private_data = vmalloc(sizeof(struct trustee_command_reader));
-+	if (!file->private_data)
-+		return -ENOMEM;
-+
-+	memset(file->private_data, 0, sizeof(struct trustee_command_reader));
-+
-+	return 0;
-+}
-+
-+static int trustees_release_trustees(struct inode *inode, struct file *file)
-+{
-+	vfree(file->private_data);
-+	return 0;
-+}
-+
-+/* Do a read on a bogus file.  Just return nothing :) */
-+static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
-+				   size_t count, loff_t * offset)
-+{
-+	return 0;
-+}
-+
-+/* Similar way to handle writes.  Just say we wrote the data and return */
-+static ssize_t trustees_write_bogus(struct file *filp,
-+				    const char __user * buf, size_t count,
-+				    loff_t * offset)
-+{
-+	return count;
-+}
-+
-+/* Function for handling reading of the status. */
-+static ssize_t trustees_read_status(struct file *filp, char __user * buf,
-+				    size_t count, loff_t * offset)
-+{
-+	static const char msg[] = "Damnit, it works, OK?!\n";
-+	unsigned long nocopy;
-+
-+	if (*offset >= (sizeof(msg) - 1)) {
-+		return 0;
-+	}
-+
-+	if (count > (sizeof(msg) - 1 - *offset)) {
-+		count = sizeof(msg) - 1 - *offset;
-+	}
-+	nocopy = copy_to_user(buf, msg, count);
-+	(*offset) += count;
-+	(*offset) -= nocopy;
-+
-+	return count;
-+}
-+
-+/* Function for handling reading of the apiversion. */
-+static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
-+				    size_t count, loff_t * offset)
-+{
-+	static const char msg[] = TRUSTEES_APIVERSION_STR "\n";
-+	unsigned long nocopy;
-+
-+	if (*offset >= (sizeof(msg) - 1)) {
-+		return 0;
-+	}
-+
-+	if (count > (sizeof(msg) - 1 - *offset)) {
-+		count = sizeof(msg) - 1 - *offset;
-+	}
-+	nocopy = copy_to_user(buf, msg, count);
-+	(*offset) += count;
-+	(*offset) -= nocopy;
-+
-+	return count;
-+}
-+
-+/* Cleanup our reader (deallocate all the allocated memory) */
-+static void cleanup_reader(struct trustee_command_reader *reader) {
-+	int z;
-+	if (!reader) {
-+		TS_ERR_MSG("How does reader disappear on us?\n");
-+		return;
-+	}
-+
-+	for (z = reader->curarg - 1; z >= 0; z--) {
-+		vfree(reader->arg[z]);
-+		reader->argsize[z] = 0;
-+	}
-+	reader->command.command = 0;
-+	reader->curarg = 0;
-+}
-+
-+static ssize_t trustees_write_trustees(struct file *filp,
-+				       const char __user * buf,
-+				       size_t count, loff_t * offset)
-+{
-+	struct trustee_command_reader *reader = filp->private_data;
-+
-+	if (reader->command.command == 0) {
-+		reader->curarg = 0;
-+		if (count != sizeof(struct trustee_command)) {
-+			return -EIO;
-+		}
-+		if (copy_from_user(&reader->command, buf, count)) {
-+			reader->command.command = 0;
-+			TS_ERR_MSG("copy_from_user failed on command\n");
-+			return -EIO;
-+		}
-+		if (reader->command.numargs > TRUSTEE_MAX_ARGS) {
-+			TS_ERR_MSG("Too many arguments specified for command %d\n",
-+			  reader->command.command);
-+			return -EIO;
-+		}
-+	} else {
-+		unsigned curarg = reader->curarg;
-+		if (!(reader->arg[curarg] = vmalloc(count+1))) {
-+			cleanup_reader(reader);
-+			return -EIO;
-+		}
-+		reader->argsize[curarg] = count;
-+		((char *)reader->arg[curarg])[count] = '\0';
-+		reader->curarg++;
-+		if (copy_from_user(reader->arg[curarg], buf, count)) {
-+			cleanup_reader(reader);
-+			TS_ERR_MSG("copy_from_user failed on arg\n");
-+			return -EIO;
-+		}
-+	}
-+
-+	if (reader->command.command && reader->curarg == reader->command.numargs) {
-+		int ret = trustees_process_command(reader->command, reader->arg,
-+		                                   reader->argsize);
-+		cleanup_reader(reader);
-+		if (ret) return -EIO;
-+	}
-+
-+	return count;
-+}
-diff -Nurd linux-2.6.24/security/trustees/funcs.c linux-2.6.24-oxe810/security/trustees/funcs.c
---- linux-2.6.24/security/trustees/funcs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/funcs.c	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,810 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * This code contains the functions for handling the actual trustees data
-+ * and returning the permissions for a given file, etc.
-+ *
-+ *
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/mount.h>
-+#include <linux/dcache.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/poll.h>
-+#include <linux/sched.h>
-+#include <linux/limits.h>
-+#include <linux/list.h>
-+#include <linux/vmalloc.h>
-+#include <linux/ctype.h>
-+
-+#include "internal.h"
-+
-+/*
-+ * This is a hash of all the trustee_names currently added.  These values
-+ * are hashed on a combination of device/filename.  Before reading/writing
-+ * be sure to take care of the locking of trustee_hash_lock.
-+ */
-+rwlock_t trustee_hash_lock;
-+static struct hlist_head *trustee_hash = NULL;
-+
-+/*
-+ * This is the deepest level trustee.  When calculating filenames, we can
-+ * skip several of the levels in many case since we know it won't be any
-+ * deeper than this.
-+ *
-+ * Kept up to date by calculate_deepest_level
-+ *
-+ * /           => 0
-+ * /test       => 1
-+ * /test/blah  => 2
-+ */
-+static int deepest_level = 0;
-+
-+/*
-+ * A list of filesystems that need to have their case
-+ * ignored.  This is protected by trustee_hash_lock.
-+ */
-+static LIST_HEAD(trustee_ic_list);
-+
-+
-+/* The calling method needs to free the buffer created by this function
-+ * This method returns the filename for a dentry.  This is, of course,
-+ * relative to the device.  The filename can be truncated to be as deep as
-+ * the deepest trustee.  The depth returned in d will always be the true
-+ * depth, however.
-+ *
-+ * Args:
-+ *   dentry: The dentry we are interested in.
-+ *   d: a pointer to the place where the depth can be stored.
-+ *   trunc: ok to truncate the name to the longest that needs to be figured out.
-+ */
-+
-+#define FN_CHUNK_SIZE 64
-+char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc)
-+{
-+	char *buffer = NULL, *tmpbuf = NULL;
-+	int bufsize = FN_CHUNK_SIZE;
-+	char c;
-+	int i, j, k;
-+	int depth = 0;
-+	struct dentry *temp_dentry;
-+
-+	if (dentry->d_parent == NULL) {
-+		TS_ERR_MSG("d_parent is null\n");
-+		return NULL;
-+	}
-+
-+	if (dentry->d_name.name == NULL) {
-+		TS_ERR_MSG("name is null\n");
-+		return NULL;
-+	}
-+
-+	buffer = kmalloc(FN_CHUNK_SIZE, GFP_KERNEL);
-+	if (!buffer) {
-+		TS_ERR_MSG("could not allocate filename buffer\n");
-+		return NULL;
-+	}
-+
-+	buffer[0] = '/';
-+	buffer[i = 1] = '\0';
-+	for (temp_dentry = dentry; !IS_ROOT(temp_dentry); temp_dentry = temp_dentry->d_parent)
-+		depth++;
-+	if (d) *d = depth;
-+	if (deepest_level <= 0) return buffer;
-+
-+	for (;;) {
-+		if (IS_ROOT(dentry))
-+			break;
-+		if (depth-- > deepest_level) continue;
-+
-+		j = i + strlen(dentry->d_name.name);
-+		if ((j + 2) > bufsize) {	/* reallocate - won't fit */
-+			bufsize = (((j + 2) / FN_CHUNK_SIZE) + 1) * FN_CHUNK_SIZE;
-+			tmpbuf = kmalloc(bufsize, GFP_KERNEL);
-+			if (!tmpbuf) {
-+				kfree(buffer);
-+				TS_ERR_MSG
-+				    ("Out of memory allocating tmpbuf\n");
-+				return NULL;
-+			}
-+			memcpy(tmpbuf, buffer, i);
-+			kfree(buffer);
-+			buffer = tmpbuf;
-+		}
-+		/* Throw the name in there backward */
-+		for (k = 0; dentry->d_name.name[k]; k++) {
-+			buffer[j - 1 - k] = dentry->d_name.name[k];
-+		}
-+		i = j;
-+		buffer[i++] = '/';
-+		dentry = dentry->d_parent;
-+	}
-+	buffer[i] = 0;
-+
-+	/* buffer is backwards, reverse it */
-+	for (j = 0; j < (i / 2); ++j) {
-+		c = buffer[j];
-+		buffer[j] = buffer[i - j - 1];
-+		buffer[i - j - 1] = c;
-+	}
-+
-+	return buffer;
-+}
-+
-+/**
-+ * Allocate memory using vmalloc and return a duplicate of the passed in string.
-+ * Returns NULL if a problem occurs
-+ */
-+static char *vmalloc_strdup(const char *str, size_t len)
-+{
-+	char *r;
-+
-+	if (!str) return NULL;
-+	len = strlen(str);
-+	r = vmalloc(len + 1);
-+	if (!r) return NULL;
-+	memcpy(r, str, len + 1);
-+
-+	return r;
-+}
-+
-+/*
-+ * Add a filesystem as a ignored-case dev.
-+ */
-+static inline void add_ic_dev(u32 dev, char *devname)
-+{
-+	char *devname2;
-+	struct trustee_ic *ic;
-+	size_t dev_len;
-+
-+	dev_len = strlen(devname);
-+
-+	if (dev_len > PATH_MAX) {
-+		TS_ERR_MSG("devname bad, add_ic_dev ignored.\n");
-+		return;
-+	}
-+
-+	if (!dev_len) {
-+		TS_ERR_MSG("No devname specified in add_ic_dev.\n");
-+		return;
-+	}
-+
-+	devname2 = vmalloc_strdup(devname, dev_len);
-+	if (!devname2) {
-+		TS_ERR_MSG
-+		    ("Seems that we have ran out of memory adding ic dev!\n");
-+		return;
-+	}
-+
-+	ic = vmalloc(sizeof(struct trustee_ic));
-+	if (!ic) {
-+		TS_ERR_MSG
-+		    ("Seems that we ran out of memory allocating ic!\n");
-+		return;
-+	}
-+
-+	ic->dev = new_decode_dev(dev);
-+	ic->devname = devname2;
-+
-+	write_lock(&trustee_hash_lock);
-+	list_add(&ic->ic_list, &trustee_ic_list);
-+	write_unlock(&trustee_hash_lock);
-+}
-+
-+/*
-+ * Remove all ignored-case filesystems.
-+ */
-+static inline void remove_ic_devs(void)
-+{
-+	struct trustee_ic *ic, *temp_ic;
-+	struct list_head temp_ic_list;
-+
-+	INIT_LIST_HEAD(&temp_ic_list);
-+	list_splice_init(&trustee_ic_list, &temp_ic_list);
-+
-+	list_for_each_entry_safe(ic, temp_ic, &temp_ic_list, ic_list) {
-+		vfree(ic->devname);
-+		vfree(ic);
-+	}
-+}
-+
-+/*
-+ * This frees all the capsules in a trustee element.
-+ */
-+static inline void free_hash_element_list(struct trustee_hash_element *e)
-+{
-+	struct trustee_permission_capsule *capsule, *temp;
-+
-+	list_for_each_entry_safe(capsule, temp, &e->perm_list, perm_list) {
-+		list_del(&capsule->perm_list);
-+		vfree(capsule);
-+	}
-+}
-+
-+/*
-+ * Free a trustee name.  This frees the devname and the filename
-+ */
-+static inline void free_trustee_name(struct trustee_name *name)
-+{
-+	vfree(name->filename);
-+	vfree(name->devname);
-+}
-+
-+/*
-+ * Frees the capsules, and the filenames for a trustee hash element.
-+ * Also marks it as unused in the hash.
-+ */
-+static inline void free_hash_element(struct trustee_hash_element *e)
-+{
-+	free_hash_element_list(e);
-+	free_trustee_name(&e->name);
-+	vfree(e);
-+}
-+
-+/**
-+ * Copies from src to dest (duplicating the strings in the
-+ * trustee_name structure.  Returns zero for unsuccesful.
-+ */
-+static int copy_trustee_name(struct trustee_name *dst, struct trustee_name *src)
-+{
-+	*dst = *src;
-+	if (dst->filename) {
-+		dst->filename = vmalloc_strdup(src->filename, strlen(src->filename));
-+		if (!dst->filename) {
-+			TS_ERR_MSG("Ran out of memory duplicating src->filename\n");
-+			return 0;
-+		}
-+	}
-+
-+	if (dst->devname) {
-+		dst->devname = vmalloc_strdup(src->devname, strlen(src->devname));
-+		if (!dst->devname) {
-+			TS_ERR_MSG("Ran out of memory duplicating src->devname\n");
-+			vfree(dst->filename);
-+			return 0;
-+		}
-+	}
-+
-+	return 1;
-+}
-+
-+
-+/*
-+ * hashing function researched by Karl Nelson <kenelson @ ece ucdavis edu>
-+ * and is used in glib.
-+ */
-+static inline unsigned int hash_string(const char *s)
-+{
-+	unsigned int v = 0;
-+
-+	while (*s) {
-+		v = (v << 5) - v + tolower(*s);
-+		s++;
-+	}
-+
-+	return v;
-+}
-+
-+/*
-+ * Return the hash for a device.
-+ */
-+static inline unsigned int hash_device(const char *name, dev_t device)
-+{
-+	if (MAJOR(device) == 0) {
-+		return hash_string(name);
-+	}
-+
-+	return new_encode_dev(device);
-+}
-+
-+/*
-+ * Return the hash for a file.  This is a combination of the
-+ * hash of the filename and the hash for the device.
-+ */
-+static inline unsigned int hash(const struct trustee_name *name)
-+{
-+	return hash_string(name->filename) ^
-+	       hash_device(name->devname, name->dev);
-+}
-+
-+/*
-+ * Return the slot in the trustees_hash where a trustee is located
-+ */
-+static inline unsigned int hash_slot(const struct trustee_name *name)
-+{
-+    return hash(name) % trustee_hash_size;
-+}
-+
-+/*
-+ * Compare two devices.  Return 1 if they are equal otherwise return 0
-+ */
-+static inline int trustee_dev_cmp(dev_t dev1, dev_t dev2, char *devname1,
-+				  char *devname2)
-+{
-+	if ((MAJOR(dev1) == 0) && (MAJOR(dev2) == 0))
-+		return (strcmp(devname1, devname2) == 0);
-+	else if ((MAJOR(dev1) != 0) && (MAJOR(dev2) != 0))
-+		return (dev1 == dev2);
-+	return 0;
-+}
-+
-+/*
-+ * Compare two trustee_name's.  Returns 1 if they are are equal
-+ * otherwise return 0
-+ */
-+static inline int trustee_name_cmp(const struct trustee_name *n1,
-+				   const struct trustee_name *n2,
-+				   unsigned ignore_case)
-+{
-+	if (trustee_dev_cmp(n1->dev, n2->dev, n1->devname, n2->devname))
-+		return ignore_case ?
-+		    (strnicmp(n1->filename, n2->filename, PATH_MAX) == 0) :
-+		    (strcmp(n1->filename, n2->filename) == 0);
-+	return 0;
-+}
-+
-+/*
-+ * Calculate the deepest level.
-+ */
-+static inline void calculate_deepest_level(const struct trustee_name *name)
-+{
-+	char *fn = name->filename;
-+	char *x;
-+	int level = 0;
-+
-+	for (x = fn; *x; ++x) {
-+		if (*x == '/')
-+			++level;
-+	}
-+
-+	/* If it is the root, it should have
-+	 * a level of 0.
-+	 */
-+	if (x == (fn + 1)) level = 0;
-+
-+	if (level > deepest_level) deepest_level = level;
-+}
-+
-+/*
-+ * Return the trustee element for a name.
-+ * This should be called with a lock on the trustee_hash (which should
-+ * not be released until you are done with the returned hash_element)!
-+ */
-+static struct trustee_hash_element *get_trustee_for_name(const struct trustee_name *name,
-+							 unsigned ignore_case)
-+{
-+	struct trustee_hash_element *item = NULL;
-+	struct hlist_node *iter = NULL;
-+
-+	hlist_for_each_entry(item, iter, &trustee_hash[hash_slot(name)], hash_list) {
-+		if (trustee_name_cmp(&item->name, name, ignore_case))
-+			return item;
-+	}
-+
-+	return NULL;
-+}
-+
-+/**
-+ * Add a new blank trustee to the hash.
-+ *
-+ * If this returns zero, then the adding failed and name should be freed
-+ * (assuming must_copy is 0), otherwise assume we used its memory.
-+ */
-+static unsigned add_trustee(struct trustee_name *name, int must_copy) {
-+	struct trustee_name newname;
-+	struct trustee_name rootname;
-+	unsigned is_root = 1;
-+	unsigned r = 0;
-+	struct trustee_hash_element *new;
-+	struct trustee_hash_element *root;
-+
-+	if (!name->filename || !name->filename[0]) goto err0;
-+
-+	if (!copy_trustee_name(&rootname, name)) goto err0;
-+	rootname.filename[1] = '\0';
-+
-+	if (strlen(name->filename) > 1 && strcmp(name->filename, "/")) {
-+		add_trustee(&rootname, 1);
-+		is_root = 0;
-+	}
-+
-+	if (must_copy) {
-+		if (!copy_trustee_name(&newname, name)) goto err1;
-+	} else {
-+		newname = *name;
-+	}
-+
-+	new = vmalloc(sizeof(struct trustee_hash_element));
-+	if (!new) goto err2;
-+	new->name = newname;
-+	INIT_HLIST_NODE(&new->hash_list);
-+	INIT_LIST_HEAD(&new->perm_list);
-+	INIT_LIST_HEAD(&new->device_list);
-+
-+	write_lock(&trustee_hash_lock);
-+	if (get_trustee_for_name(&newname, 0)) goto err3;
-+
-+	if (is_root) {
-+		root = NULL;
-+	} else if (!(root = get_trustee_for_name(&rootname, 0))) {
-+		TS_ERR_MSG("Root trustee disappeared on us!\n");
-+		goto err3;
-+	}
-+	hlist_add_head(&new->hash_list, &trustee_hash[hash_slot(name)]);
-+	if (!is_root) {
-+		list_add_tail(&new->device_list, &root->device_list);
-+	}
-+	calculate_deepest_level(&newname);
-+	TS_DEBUG_MSG("Created '%s' trustee\n", newname.filename);
-+	r = 1;
-+err3:
-+	write_unlock(&trustee_hash_lock);
-+	if (!r) vfree(new);
-+err2:
-+	if (must_copy && !r) free_trustee_name(&newname);
-+err1:
-+	free_trustee_name(&rootname);
-+err0:
-+	return r;
-+}
-+
-+/**
-+ * Add a permissions module to the trustee specified by name.
-+ */
-+static unsigned add_trustee_perm
-+    (struct trustee_name *name, struct trustee_permission acl)
-+{
-+	struct trustee_hash_element *r = NULL;
-+	struct trustee_permission_capsule *capsule;
-+
-+	capsule = vmalloc(sizeof(struct trustee_permission_capsule));
-+	if (!capsule) {
-+		TS_ERR_MSG
-+		    ("Can not allocate memory for trustee capsule\n");
-+		return 0;
-+	}
-+	capsule->permission = acl;
-+
-+	write_lock(&trustee_hash_lock);
-+	r = get_trustee_for_name(name, 0);
-+
-+	if (r) {
-+		list_add_tail(&capsule->perm_list, &r->perm_list);
-+		write_unlock(&trustee_hash_lock);
-+		TS_DEBUG_MSG("Added permission capsule to '%s' trustee\n", name->filename);
-+		return 1;
-+	}
-+	write_unlock(&trustee_hash_lock);
-+	TS_ERR_MSG("trustee disappeared under us while trying to add perms\n");
-+	vfree(capsule);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Get the mask for a trustee name.
-+ * This should be called with a lock on the trustee_hash (which should
-+ * not be released until you are done with the returned hash_element)!
-+ */
-+static int get_trustee_mask_for_name(struct trustee_name *name,
-+				     int oldmask, int height,
-+				     struct trustee_hash_element **element,
-+				     unsigned ignore_case)
-+{
-+	struct trustee_hash_element *e;
-+	int m;
-+	struct trustee_permission_capsule *l;
-+	int appl;
-+	e = get_trustee_for_name(name, ignore_case);
-+	if (!e) {
-+		return oldmask;
-+	}
-+	list_for_each_entry(l, &e->perm_list, perm_list) {
-+		if ((height < 0)
-+		    && (l->permission.mask & TRUSTEE_ONE_LEVEL_MASK))
-+			continue;
-+		if (element) {
-+			*element = e;
-+			element = NULL;
-+		}
-+		appl = ((!(l->permission.mask & TRUSTEE_IS_GROUP_MASK))
-+			&& (current->fsuid == l->permission.u.uid))
-+		    || (((l->permission.mask & TRUSTEE_IS_GROUP_MASK))
-+			&& (in_group_p(l->permission.u.gid)))
-+		    || (l->permission.mask & TRUSTEE_ALL_MASK);
-+		if (l->permission.mask & TRUSTEE_NOT_MASK)
-+			appl = !appl;
-+
-+		if (!appl)
-+			continue;
-+
-+		m = l->permission.mask & TRUSTEE_ACL_MASK;
-+
-+		if (l->permission.mask & TRUSTEE_ALLOW_DENY_MASK)
-+			m <<= TRUSTEE_NUM_ACL_BITS;
-+
-+		oldmask =
-+		    l->permission.
-+		    mask & TRUSTEE_CLEAR_SET_MASK ? (oldmask & (~m))
-+		    : (oldmask | m);
-+	}
-+
-+	return oldmask;
-+}
-+
-+/*
-+ * Return non-zero if a trustee exists in a subpath.
-+ *
-+ * WARNING!
-+ * This function requires that you lock/unlock the trustees_hash_lock
-+ */
-+int trustee_has_child(struct vfsmount *mnt, char *file_name)
-+{
-+	struct trustee_name trustee_name;
-+	char tempchar;
-+	unsigned ignore_case = 0;
-+	struct trustee_hash_element *root;
-+	size_t len;
-+	struct trustee_ic *iter;
-+	struct trustee_hash_element *r;
-+
-+	if (!file_name || !*file_name) return 0;
-+
-+	list_for_each_entry(iter, &trustee_ic_list, ic_list) {
-+		if (trustee_dev_cmp
-+		    (iter->dev, trustee_name.dev, iter->devname,
-+		     trustee_name.devname)) {
-+			ignore_case = 1;
-+			break;
-+		}
-+	}
-+
-+	trustee_name.dev = mnt->mnt_sb->s_dev;
-+	trustee_name.devname = mnt->mnt_devname;
-+	trustee_name.filename = file_name;
-+	tempchar = file_name[1];
-+	file_name[1] = '\0';
-+
-+	root = get_trustee_for_name(&trustee_name, ignore_case);
-+	if (!root) return 0;
-+
-+	file_name[1] = tempchar;
-+
-+	len = strlen(file_name);
-+
-+	list_for_each_entry(r, &root->device_list, device_list) {
-+		size_t this_len = strlen(r->name.filename);
-+		if (this_len <= len) continue;
-+		if (!strncmp(file_name, r->name.filename, len) &&
-+			r->name.filename[len] != '\0')
-+			return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+/*
-+ * Return the mask for a file.
-+ *
-+ * WARNING!
-+ * This function requires that you lock/unlock the trustees_hash_lock
-+ */
-+int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
-+		 char *file_name, int unix_ret, int depth, int is_dir,
-+		 struct trustee_hash_element **deepest)
-+{
-+	static char dbl_nul_slash[3] = { '/', '\0', '\0' };
-+	int oldmask = trustee_default_acl;
-+	int height = 0;
-+	char *filecount;
-+	char c;
-+	struct trustee_name trustee_name;
-+	struct trustee_ic *iter;
-+	unsigned ignore_case = 0;
-+
-+	trustee_name.dev = mnt->mnt_sb->s_dev;
-+	trustee_name.devname = mnt->mnt_devname;
-+	trustee_name.filename = file_name;
-+
-+	list_for_each_entry(iter, &trustee_ic_list, ic_list) {
-+		if (trustee_dev_cmp
-+		    (iter->dev, trustee_name.dev, iter->devname,
-+		     trustee_name.devname)) {
-+			ignore_case = 1;
-+			break;
-+		}
-+	}
-+
-+	if (deepest) *deepest = NULL;
-+
-+	filecount = file_name + 1;
-+	/* Try to handle the unlikely case where the string will be '/'
-+	 * out here to simplify the logic inside the loop.  We do this
-+	 * by giving it a string with two nul byte terminators so that it
-+	 * will gracefully (and safely) make it through the loop below.
-+	 */
-+	if (*filecount == '\0') {
-+		file_name = dbl_nul_slash;
-+		filecount = file_name + 1;
-+	}
-+	do {
-+		c = *filecount;
-+		*filecount = 0;
-+		oldmask =
-+		    get_trustee_mask_for_name(&trustee_name, oldmask,
-+					      height - depth + !is_dir,
-+					      deepest, ignore_case);
-+		height++;
-+		*filecount = c;
-+		++filecount;
-+		while ((*filecount) && (*filecount != '/')) filecount++;
-+
-+	} while(*filecount);
-+
-+	return oldmask;
-+}
-+
-+/* Clear out the hash of trustees and release the hash itself.
-+ * Also gets rid of the ignore-case list
-+ */
-+static void trustees_clear_all(void)
-+{
-+	struct trustee_hash_element *item = NULL;
-+	struct hlist_node *iter, *temp = NULL;
-+	unsigned i;
-+	write_lock(&trustee_hash_lock);
-+
-+	for (i = 0; i < trustee_hash_size; i++) {
-+		hlist_for_each_entry_safe(item, iter, temp, &trustee_hash[i], hash_list) {
-+			free_hash_element(item);
-+		}
-+		INIT_HLIST_HEAD(&trustee_hash[i]);
-+	}
-+
-+	deepest_level = 0;
-+
-+	remove_ic_devs();
-+
-+	write_unlock(&trustee_hash_lock);
-+}
-+
-+/*
-+ * Initialize globals
-+ */
-+int trustees_funcs_init_globals(void)
-+{
-+	unsigned int iter;
-+
-+	if (trustee_hash_size <= 0)
-+		return 1;
-+
-+	rwlock_init(&trustee_hash_lock);
-+
-+	trustee_hash = vmalloc(sizeof(*trustee_hash) * trustee_hash_size);
-+	if (!trustee_hash)
-+		return 1;
-+
-+	for (iter = 0; iter < trustee_hash_size; iter++)
-+		INIT_HLIST_HEAD(trustee_hash + iter);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Clear globals
-+ */
-+int trustees_funcs_cleanup_globals(void)
-+{
-+	trustees_clear_all();
-+
-+	vfree(trustee_hash);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Prepare a trustee name from a passed in trustee name.
-+ */
-+static int prepare_trustee_name(u32 device, char *devname, char *filename, struct trustee_name *name)
-+{
-+	size_t devl, filel;
-+	char *devb = NULL, *fileb = NULL;
-+
-+	if ((!name))
-+		return 0;
-+
-+	filel = strlen(filename);
-+	devl = strlen(devname);
-+
-+	if (devl > PATH_MAX) {
-+		TS_ERR_MSG("device name bad, command ignored.\n");
-+		return 0;
-+	}
-+	if (filel > PATH_MAX) {
-+		TS_ERR_MSG("file name bad, command ignored.\n");
-+		return 0;
-+	}
-+
-+	devb = vmalloc_strdup(devname, devl);
-+	if (!devb) {
-+		TS_ERR_MSG("Couldn't allocate mem for devb.\n");
-+		return 0;
-+	}
-+
-+	fileb = vmalloc_strdup(filename, filel);
-+	if (!fileb) {
-+		TS_ERR_MSG("Couldn't allocate mem for fileb.\n");
-+		return 0;
-+	}
-+
-+	name->devname = devb;
-+	name->filename = fileb;
-+
-+	name->dev = new_decode_dev(device);
-+
-+	return 1;
-+}
-+
-+/*
-+ * Process a user command
-+ */
-+extern int trustees_process_command(struct trustee_command command,
-+                                    void **arg,
-+                                    size_t *argsize)
-+{
-+	int r = -ENOSYS;
-+	int must_free = 0;
-+	struct trustee_name name;
-+
-+	if ((current->euid != 0) && !capable(CAP_SYS_ADMIN)) {
-+		r = -EACCES;
-+		return r;
-+	}
-+
-+	switch (command.command) {
-+	case TRUSTEE_COMMAND_MAKE_IC:
-+		if (command.numargs != 2 ||
-+		    argsize[1] != sizeof(u32)) goto unlk;
-+		add_ic_dev(*(u32 *)arg[1], arg[0]);
-+		r = 0;
-+		break;
-+	case TRUSTEE_COMMAND_REMOVE_ALL:
-+		if (command.numargs != 0) goto unlk;
-+		trustees_clear_all();
-+		r = 0;
-+		break;
-+	case TRUSTEE_COMMAND_ADD:
-+		if (command.numargs != 4 ||
-+		    argsize[3] != sizeof(u32) ||
-+		    argsize[1] != sizeof(struct trustee_permission))
-+			goto unlk;
-+		if (!prepare_trustee_name(*(u32 *)arg[3], arg[2], arg[0], &name)) {
-+			r = -ENOMEM;
-+			goto unlk;
-+		}
-+		if (!add_trustee(&name, 0)) {
-+			must_free = 1;
-+		}
-+		if (!add_trustee_perm(&name, *(struct trustee_permission *)arg[1]))
-+			r = -ENOMEM;
-+		else
-+			r = 0;
-+
-+		if (must_free) free_trustee_name(&name);
-+		break;
-+	}
-+   unlk:
-+
-+	return r;
-+}
-diff -Nurd linux-2.6.24/security/trustees/init.c linux-2.6.24-oxe810/security/trustees/init.c
---- linux-2.6.24/security/trustees/init.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/init.c	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,57 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * Module initialization and cleanup
-+ *
-+ * History:
-+ *  2002-12-16 trustees 2.10 released by Vyacheslav Zavadsky
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/security.h>
-+#include <linux/capability.h>
-+
-+#include "internal.h"
-+
-+unsigned int trustee_hash_size = 256;
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Trustees ACL System");
-+MODULE_AUTHOR("Vyacheslav Zavadsky and Andrew E. Ruder <aeruder at ksu.edu>");
-+MODULE_VERSION("2.11");
-+
-+MODULE_PARM_DESC(hash_size, "Trustees hash size");
-+module_param_named(hash_size, trustee_hash_size, uint, 0444);
-+
-+
-+static int __init trustees_init(void)
-+{
-+	if (trustees_funcs_init_globals() != 0) {
-+		return -EINVAL;
-+	}
-+
-+	if (trustees_init_fs() != 0) {
-+		trustees_funcs_cleanup_globals();
-+		return -EINVAL;
-+	}
-+
-+	if (trustees_init_security() != 0) {
-+		trustees_deinit_fs();
-+		trustees_funcs_cleanup_globals();
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+fs_initcall(trustees_init);
-diff -Nurd linux-2.6.24/security/trustees/internal.h linux-2.6.24-oxe810/security/trustees/internal.h
---- linux-2.6.24/security/trustees/internal.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/internal.h	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,100 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * Private methods and definitions used only within the module.
-+ *
-+ */
-+
-+#ifndef _LINUX_TRUSTEES_H
-+#define _LINUX_TRUSTEES_H
-+#include <linux/types.h>
-+#include <linux/dcache.h>
-+#include <linux/kdev_t.h>
-+#include <linux/list.h>
-+#include <linux/version.h>
-+#include <linux/trustees.h>
-+
-+#define TRUSTEE_DEFAULT_MASK TRUSTEE_USE_UNIX_MASK
-+
-+struct trustee_ic {
-+	dev_t dev;
-+	char *devname;		/* ONLY if MAJOR(dev)==0 */
-+	struct list_head ic_list;
-+};
-+
-+struct trustee_name {
-+	dev_t dev;
-+	char *filename;
-+	char *devname;		/* ONLY if MAJOR(dev)==0 */
-+};
-+
-+struct trustee_permission_capsule {
-+	struct list_head perm_list;
-+	struct trustee_permission permission;
-+};
-+
-+/* For the usage field */
-+#define TRUSTEE_HASH_ELEMENT_USED 2
-+#define TRUSTEE_HASH_ELEMENT_DELETED 1
-+#define TRUSTEE_HASH_ELEMENT_NOTUSED 0
-+
-+struct trustee_hash_element {
-+	struct trustee_name name;
-+	struct list_head perm_list;
-+	struct hlist_node hash_list;
-+	struct list_head device_list;
-+};
-+
-+extern char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc);
-+
-+extern int trustees_funcs_init_globals(void);
-+extern int trustees_funcs_cleanup_globals(void);
-+
-+int trustee_has_child(struct vfsmount *mnt, char *file_name);
-+int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
-+		 char *file_name, int unix_ret, int depth, int is_dir,
-+		 struct trustee_hash_element **deepest);
-+
-+extern int trustees_process_command(struct trustee_command command,
-+                                    void **arg, size_t *argsize);
-+
-+extern unsigned int trustee_hash_size;
-+extern rwlock_t trustee_hash_lock;
-+
-+#define TRUSTEE_INITIAL_NAME_BUFFER 256
-+#define TRUSTEE_HASDEVNAME(TNAME) (MAJOR((TNAME).dev)==0)
-+
-+#define TS_ERR_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
-+
-+#ifdef TRUSTEES_DEBUG
-+#define TS_DEBUG_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
-+#else
-+#define TS_DEBUG_MSG(...)
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
-+#define NAMESPACE_SEM(_ns) (namespace_sem)
-+#else
-+#define NAMESPACE_SEM(_ns) ((_ns)->sem)
-+#endif
-+
-+/*
-+ * Magic number!
-+ *
-+ * FIXME: Do I just make this up or is there some system for coming
-+ * up with magic numbers?
-+ */
-+#define TRUSTEES_MAGIC 0x32236975
-+
-+int trustees_init_fs(void);
-+void trustees_deinit_fs(void);
-+
-+int trustees_init_security(void);
-+#endif				/* _LINUX_TRUSTEES_H */
-diff -Nurd linux-2.6.24/security/trustees/security.c linux-2.6.24-oxe810/security/trustees/security.c
---- linux-2.6.24/security/trustees/security.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/security.c	2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,423 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder at ksu.edu)
-+ *
-+ *	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, version 2.
-+ *
-+ * The security module (LSM API) component of the trustees system
-+ *
-+ * One quick note: generally security modules with the LSM are supposed
-+ * to be solely restrictive modules.  Unless the trustees module were to
-+ * require that people set all files rwx by all, it could not function
-+ * as it is meant to function as a solely restrictive module.
-+ *
-+ * To compensate, every process is given the capability CAP_DAC_OVERRIDE.
-+ * In other words, every process is first given full rights to the filesystem.
-+ * This is the only non-restricting portion of this module, since it -does-
-+ * in fact give additional permissions.  However, in the inode_permission hook,
-+ * any rights the user should not have are taken away.
-+ *
-+ * Side effects: Posix ACLs or other filesystem-specific permissions are not
-+ * honored.  Trustees ACLs can (and do) take into account the standard unix
-+ * permissions, but any permissions further than that are difficult, to say
-+ * the least, to take into account.  I, personally, do not find this to
-+ * be a problem since if you are using Trustees ACLs, why also require the use
-+ * of another ACL system?
-+ */
-+
-+#include <linux/security.h>
-+#include <linux/capability.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/nsproxy.h>
-+#include <linux/mnt_namespace.h>
-+
-+#include "internal.h"
-+
-+static int trustees_capable(struct task_struct *tsk, int cap);
-+static int trustees_inode_permission(struct inode *inode,
-+				     int mask, struct nameidata *nd);
-+
-+/* Checks if user has access to the inode due to root status
-+ */
-+static inline int has_root_perm(struct inode *inode, int mask)
-+{
-+	umode_t mode = inode->i_mode;
-+
-+	if (!(mask & MAY_EXEC) || (mode & S_IXUGO) || S_ISDIR(mode))
-+		if (current->fsuid == 0)
-+			return 0;
-+
-+	return -EACCES;
-+}
-+
-+/* The logic for this was mostly stolen from vfs_permission.  The security API
-+ * doesn't give a good way to use the actual vfs_permission for this since our
-+ * CAP_DAC_OVERRIDE causes it to always return 0.  But if we didn't return
-+ * CAP_DAC_OVERRIDE, we'd never get to handle permissions!  Since we don't need
-+ * to handle capabilities and dealing with ACLs with trustees loaded isn't an
-+ * issue for me, the function ends up being pretty simple.
-+ */
-+
-+static inline int has_unix_perm(struct inode *inode, int mask)
-+{
-+	umode_t mode = inode->i_mode;
-+	mask &= ~MAY_APPEND;
-+
-+	if (current->fsuid == inode->i_uid)
-+		mode >>= 6;
-+	else if (in_group_p(inode->i_gid))
-+		mode >>= 3;
-+
-+	if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
-+		return 0;
-+
-+	return -EACCES;
-+}
-+
-+/* Find a vfsmount given an inode */
-+static inline struct vfsmount *find_inode_mnt(struct inode *inode,
-+					      struct nameidata *nd)
-+{
-+	struct mnt_namespace *ns = NULL;
-+	struct vfsmount *mnt = NULL;
-+
-+	if (likely(nd))
-+		return mntget(nd->mnt);
-+
-+	/* Okay, we need to find the vfsmount by looking
-+	 * at the namespace now.
-+	 */
-+	task_lock(current);
-+	if (current->nsproxy) {
-+		ns = current->nsproxy->mnt_ns;
-+		if (ns)
-+			get_mnt_ns(ns);
-+	}
-+	task_unlock(current);
-+
-+	if (!ns) return NULL;
-+
-+	list_for_each_entry(mnt, &ns->list, mnt_list) {
-+		if (mnt->mnt_sb == inode->i_sb) {
-+			mntget(mnt);
-+			goto out;
-+		}
-+	}
-+
-+  out:
-+	put_mnt_ns(ns);
-+
-+	return mnt;
-+}
-+
-+/* Find a dentry given an inode */
-+static inline struct dentry *find_inode_dentry(struct inode *inode,
-+					       struct nameidata *nd)
-+{
-+	struct dentry *dentry;
-+
-+	if (likely(nd))
-+		return dget(nd->dentry);
-+
-+	dentry = d_find_alias(inode);
-+
-+	return dentry;
-+}
-+
-+/*
-+ * Return 1 if they are under the same set of trustees
-+ * otherwise return 0.  In the case that we are handling
-+ * a directory, we also check to see if there are subdirectories
-+ * with trustees.
-+ */
-+static inline int have_same_trustees(struct dentry *old_dentry,
-+				     struct dentry *new_dentry)
-+{
-+	struct vfsmount *mnt;
-+	char *old_file_name, *new_file_name;
-+	int old_depth, new_depth;
-+	struct trustee_hash_element *old_deep, *new_deep;
-+	int is_dir;
-+	int ret = 0;
-+
-+	mnt = find_inode_mnt(old_dentry->d_inode, NULL);
-+	if (unlikely(!mnt)) {
-+		TS_ERR_MSG("inode does not have a mnt!\n");
-+		return 0;
-+	}
-+
-+	old_file_name = trustees_filename_for_dentry(old_dentry, &old_depth, 1);
-+	if (!old_file_name) {
-+		TS_ERR_MSG("Couldn't allocate filename\n");
-+		goto out_old_dentry;
-+	}
-+
-+	new_file_name = trustees_filename_for_dentry(new_dentry, &new_depth, 1);
-+	if (!new_file_name) {
-+		TS_ERR_MSG("Couldn't allocate filename\n");
-+		goto out_new_dentry;
-+	}
-+
-+	is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-+
-+	read_lock(&trustee_hash_lock);
-+	trustee_perm(old_dentry, mnt, old_file_name, ret, old_depth, is_dir,
-+		     &old_deep);
-+	trustee_perm(new_dentry, mnt, new_file_name, ret, new_depth, is_dir,
-+		     &new_deep);
-+	if (old_deep == new_deep) {
-+		ret = 1;
-+		if (is_dir) {
-+			if (trustee_has_child(mnt, old_file_name) ||
-+				trustee_has_child(mnt, new_file_name)) ret = 0;
-+		}
-+	}
-+	read_unlock(&trustee_hash_lock);
-+
-+	kfree(new_file_name);
-+out_new_dentry:
-+	kfree(old_file_name);
-+out_old_dentry:
-+	mntput(mnt);
-+
-+	return ret;
-+}
-+
-+
-+static int trustees_inode_rename(struct inode *old_dir,
-+				 struct dentry *old_dentry,
-+				 struct inode *new_dir,
-+				 struct dentry *new_dentry);
-+static int trustees_inode_link(struct dentry *old_dentry,
-+			       struct inode *dir,
-+			       struct dentry *new_dentry);
-+
-+/* Structure where we fill in the various hooks we are implementing in this module
-+ */
-+struct security_operations trustees_security_ops = {
-+	.capable = trustees_capable,
-+	.inode_permission = trustees_inode_permission,
-+	.inode_link = trustees_inode_link,
-+	.inode_rename = trustees_inode_rename,
-+
-+	.ptrace =			cap_ptrace,
-+	.capget =			cap_capget,
-+	.capset_check =			cap_capset_check,
-+	.capset_set =			cap_capset_set,
-+	.settime =			cap_settime,
-+	.netlink_send =			cap_netlink_send,
-+	.netlink_recv =			cap_netlink_recv,
-+
-+	.bprm_apply_creds =		cap_bprm_apply_creds,
-+	.bprm_set_security =		cap_bprm_set_security,
-+	.bprm_secureexec =		cap_bprm_secureexec,
-+
-+	.inode_setxattr =		cap_inode_setxattr,
-+	.inode_removexattr =		cap_inode_removexattr,
-+
-+	.task_post_setuid =		cap_task_post_setuid,
-+	.task_reparent_to_init =	cap_task_reparent_to_init,
-+
-+	.syslog =                       cap_syslog,
-+
-+	.vm_enough_memory =             cap_vm_enough_memory
-+};
-+
-+#define ALL_MAYS (MAY_WRITE | MAY_EXEC | MAY_READ)
-+/* Converts a trustee_mask to a normal unix mask
-+ */
-+static int inline trustee_mask_to_normal_mask(int mask, int isdir)
-+{
-+	int r = 0;
-+	if ((mask & TRUSTEE_READ_MASK) && !isdir)
-+		r |= MAY_READ;
-+	if ((mask & TRUSTEE_READ_DIR_MASK) && isdir)
-+		r |= MAY_READ;
-+	if (mask & TRUSTEE_WRITE_MASK)
-+		r |= MAY_WRITE;
-+	if ((mask & TRUSTEE_BROWSE_MASK) && isdir)
-+		r |= MAY_EXEC;
-+	if ((mask & TRUSTEE_EXECUTE_MASK) && !isdir)
-+		r |= MAY_EXEC;
-+	return r;
-+}
-+
-+/* This is the meat of the permissions checking.  First it checks for root,
-+ * otherwise it first checks for any errors finding the dentry/vfsmount for
-+ * the inode, and then it looks up the dentry in the trustees hash.
-+ */
-+static int trustees_inode_permission(struct inode *inode,
-+				     int mask, struct nameidata *nd)
-+{
-+	struct dentry *dentry;
-+	struct vfsmount *mnt;
-+	char *file_name;
-+	int is_dir;
-+	int ret;
-+	int depth;
-+	int amask;
-+	int dmask;
-+	umode_t mode = inode->i_mode;
-+
-+	if (has_root_perm(inode, mask) == 0)
-+		return 0;
-+
-+	ret = has_unix_perm(inode, mask);
-+
-+	mnt = find_inode_mnt(inode, nd);
-+	if (unlikely(!mnt)) {
-+		TS_ERR_MSG("inode does not have a mnt!\n");
-+		return -EACCES;	/* has_unix_perm(inode, mask); */
-+	}
-+
-+	dentry = find_inode_dentry(inode, nd);
-+	if (unlikely(!dentry)) {
-+		/* Most of the time when this happens, it is the /
-+		 * If it is not, we need to dump as much information
-+		 * as possible on it and dump it to logs, because
-+		 * I'm really not sure how it happens.
-+		 */
-+		if (inode == mnt->mnt_root->d_inode) {
-+			dentry = dget(mnt->mnt_root);
-+		} else {
-+			/* I have seen this happen once but I did not have any
-+			 * way to see what caused it.  I am gonna dump_stack
-+			 * until I have that happen again to see if the cause
-+			 * is something that I need to worry about.
-+			 */
-+			dump_stack();	/* DEBUG FIXME */
-+			TS_ERR_MSG("Inode number: %ld\n", inode->i_ino);
-+			TS_ERR_MSG("dentry does not exist!\n");
-+			goto out_mnt;
-+		}
-+	}
-+	file_name = trustees_filename_for_dentry(dentry, &depth, 1);
-+	if (!file_name) {
-+		TS_ERR_MSG("Couldn't allocate filename\n");
-+		ret = -EACCES;
-+		goto out_dentry;
-+	}
-+
-+	is_dir = S_ISDIR(inode->i_mode);
-+
-+	read_lock(&trustee_hash_lock);
-+	amask = trustee_perm(dentry, mnt, file_name, ret, depth, is_dir,
-+			     (struct trustee_hash_element **)NULL);
-+	read_unlock(&trustee_hash_lock);
-+	dmask = amask >> TRUSTEE_NUM_ACL_BITS;
-+
-+	/* no permission if denied */
-+	if (trustee_mask_to_normal_mask(dmask, is_dir) & mask & ALL_MAYS) {
-+		ret = -EACCES;
-+		goto out;
-+	}
-+	/* use unix perms */
-+	if (!(dmask & TRUSTEE_USE_UNIX_MASK) &&
-+	    (amask & TRUSTEE_USE_UNIX_MASK) && (!ret))
-+		goto out;
-+
-+	/* if the file isn't executable, then the trustees shouldn't
-+	 * make it executable
-+	 */
-+	if ((mask & MAY_EXEC) && !(mode & S_IXOTH) &&
-+	    !((mode >> 3) & S_IXOTH) & !((mode >> 6) & S_IXOTH) &&
-+	    (!is_dir)) {
-+		ret = -EACCES;
-+		goto out;
-+	}
-+	/* Check trustees for permission
-+	 */
-+	if ((trustee_mask_to_normal_mask(amask, is_dir) & mask & ALL_MAYS)
-+	    == mask) {
-+		ret = 0;
-+		goto out;
-+	} else
-+		ret = -EACCES;
-+
-+      out:
-+	kfree(file_name);
-+      out_dentry:
-+	dput(dentry);
-+      out_mnt:
-+	mntput(mnt);
-+
-+	return ret;
-+}
-+
-+/* We should only allow hard links under one of two conditions:
-+ *   1. Its in the same trustee
-+ *        - if the two dentries are covered by the same trustee, there shouldn't
-+ *          be much of a problem with allowing the hardlink to occur.
-+ *   2. fsuid = 0
-+ */
-+static int trustees_inode_link(struct dentry *old_dentry,
-+			       struct inode *dir,
-+			       struct dentry *new_dentry)
-+{
-+	if (current->fsuid == 0)
-+		return 0;
-+
-+	if (have_same_trustees(old_dentry, new_dentry))
-+		return 0;
-+
-+	return -EXDEV;
-+}
-+
-+/* We have a few renames to protect against:
-+ *   1. Any file or directory that is affected by different trustees at its
-+ *      old location than at its new location.
-+ *   2. In the case of a directory, we should protect against moving a directory
-+ *      that has trustees set inside of it.
-+ *
-+ * In any case above, we return -EXDEV which signifies to the calling program that
-+ * the files are on different devices, and assuming the program is written correctly
-+ * it should then handle the situation by copying the files and removing the originals
-+ * ( which will then use the trustees permissions as they are meant to be used )
-+ */
-+static int trustees_inode_rename(struct inode *old_dir,
-+				 struct dentry *old_dentry,
-+				 struct inode *new_dir,
-+				 struct dentry *new_dentry)
-+{
-+	if (current->fsuid == 0)
-+		return 0;
-+
-+	if (have_same_trustees(old_dentry, new_dentry)) return 0;
-+
-+	return -EXDEV;
-+}
-+
-+/* Return CAP_DAC_OVERRIDE on everything.  We want to handle our own
-+ * permissions (overriding those normally allowed by unix permissions)
-+ */
-+static int trustees_capable(struct task_struct *tsk, int cap)
-+{
-+	if (cap == CAP_DAC_OVERRIDE)
-+		return 0;
-+
-+	return cap_capable(tsk, cap);
-+}
-+
-+/* Register the security module
-+ */
-+int trustees_init_security(void)
-+{
-+	/* FIXME: add in secondary module register
-+	 * not worry about it now since I have better
-+	 * things to worry about. Comprende?
-+	 */
-+	if (register_security(&trustees_security_ops)) {
-+		TS_ERR_MSG("Could not register security component\n");
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-diff -Nurd linux-2.6.24/sound/oss/via82cxxx_audio.c linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c
---- linux-2.6.24/sound/oss/via82cxxx_audio.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c	2008-06-11 17:46:29.000000000 +0200
-@@ -2104,6 +2104,7 @@
- {
- 	struct via_info *card = vma->vm_private_data;
- 	struct via_channel *chan = &card->ch_out;
-+	unsigned long max_bufs;
- 	struct page *dmapage;
- 	unsigned long pgoff;
- 	int rd, wr;
-@@ -2127,14 +2128,11 @@
- 	rd = card->ch_in.is_mapped;
- 	wr = card->ch_out.is_mapped;
- 
--#ifndef VIA_NDEBUG
--	{
--	unsigned long max_bufs = chan->frag_number;
--	if (rd && wr) max_bufs *= 2;
--	/* via_dsp_mmap() should ensure this */
--	assert (pgoff < max_bufs);
--	}
--#endif
-+	max_bufs = chan->frag_number;
-+	if (rd && wr)
-+		max_bufs *= 2;
-+	if (pgoff >= max_bufs)
-+		return NOPAGE_SIGBUS;
- 
- 	/* if full-duplex (read+write) and we have two sets of bufs,
- 	 * then the playback buffers come first, sez soundcard.c */
-diff -Nurd linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c
---- linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c	2008-06-11 17:46:26.000000000 +0200
-@@ -88,7 +88,7 @@
- 		us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
- 	}
- 	area->vm_ops = &us428ctls_vm_ops;
--	area->vm_flags |= VM_RESERVED;
-+	area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- 	area->vm_private_data = hw->private_data;
- 	return 0;
- }
-diff -Nurd linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c
---- linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c	2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c	2008-06-11 17:46:26.000000000 +0200
-@@ -728,7 +728,7 @@
- 		return -ENODEV;
- 	}
- 	area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
--	area->vm_flags |= VM_RESERVED;
-+	area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- 	area->vm_private_data = hw->private_data;
- 	return 0;
- }
diff --git a/recipes/linux/linux_2.6.24.bb b/recipes/linux/linux_2.6.24.bb
index ecaf5d7..31a8a04 100644
--- a/recipes/linux/linux_2.6.24.bb
+++ b/recipes/linux/linux_2.6.24.bb
@@ -8,7 +8,6 @@ DEFAULT_PREFERENCE_simpad = "1"
 DEFAULT_PREFERENCE_atngw100 = "1"
 DEFAULT_PREFERENCE_at32stk1000 = "1"
 DEFAULT_PREFERENCE_ts72xx = "1"
-DEFAULT_PREFERENCE_oxnas = "1"
 DEFAULT_PREFERENCE_hipox = "1"
 DEFAULT_PREFERENCE_cs-e9302 = "1"
 DEFAULT_PREFERENCE_smartq5 = "1"
@@ -87,13 +86,6 @@ SRC_URI_append_ts72xx = "\
 	file://ts72xx-use-cpld-reset.patch;patch=1 \
 	file://ts72xx-rs485.patch;patch=1"
 
-SRC_URI_append_oxnas = " \
-	file://oxnas.diff;patch=1 \
-	file://oxnas-uart.patch;patch=1 \
-	file://oxnas-pci-config-delay.patch;patch=1 \
-	file://oxnas-pci-max-size.patch;patch=1 \
-	"
-
 SRC_URI_append_hipox = " \
 	file://hipox-mach-type.patch;patch=1 \
 	file://hipox.patch;patch=1 \
diff --git a/recipes/u-boot/u-boot-1.1.2/oxnas.patch b/recipes/u-boot/u-boot-1.1.2/oxnas.patch
deleted file mode 100644
index f1fff14..0000000
--- a/recipes/u-boot/u-boot-1.1.2/oxnas.patch
+++ /dev/null
@@ -1,7257 +0,0 @@
-diff -Nurd u-boot-1.1.2/board/oxnas/config.mk u-boot-1.1.2-oxe810/board/oxnas/config.mk
---- u-boot-1.1.2/board/oxnas/config.mk	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/config.mk	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,26 @@
-+TEXT_BASE = 0x48d00000
-+CROSS_COMPILE = arm-linux-
-+
-+PLL400 ?= 733333333
-+RPSCLK ?=  25000000
-+
-+NAS_VERSION ?= 810
-+FPGA ?= 0
-+FPGA_ARM_CLK ?= 25000000
-+
-+PROBE_MEM_SIZE ?= 1
-+MEM_SIZE ?= 64	# Memory size in megabytes if probing is not enabled
-+MEM_ODT ?= 150
-+
-+USE_SATA ?= 1
-+USE_SATA_ENV ?= 1
-+USE_FLASH ?= 1
-+
-+LINUX_ROOT_RAIDED ?= 1
-+
-+USE_EXTERNAL_UART ?= 0
-+INTERNAL_UART ?= 2
-+
-+TEST_BRD ?= 0	# Only significant for OX800
-+
-+PLATFORM_CPPFLAGS += -DLINUX_ROOT_RAIDED=$(LINUX_ROOT_RAIDED) -DMEM_ODT=$(MEM_ODT) -DPROBE_MEM_SIZE=$(PROBE_MEM_SIZE) -DNAS_VERSION=$(NAS_VERSION) -DFPGA=$(FPGA) -DFPGA_ARM_CLK=$(FPGA_ARM_CLK) -DINTERNAL_UART=$(INTERNAL_UART) -DUSE_EXTERNAL_UART=$(USE_EXTERNAL_UART) -DMEM_SIZE=$(MEM_SIZE) -DPLL400=$(PLL400) -DRPSCLK=$(RPSCLK) -DTEST_BRD=$(TEST_BRD) -DUSE_SATA=$(USE_SATA) -DUSE_SATA_ENV=$(USE_SATA_ENV) -DUSE_FLASH=$(USE_FLASH)
-diff -Nurd u-boot-1.1.2/board/oxnas/eth.c u-boot-1.1.2-oxe810/board/oxnas/eth.c
---- u-boot-1.1.2/board/oxnas/eth.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/eth.c	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,1666 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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 <malloc.h>
-+#include <net.h>
-+#include <asm/barrier.h>
-+
-+//#define DEBUG_GMAC_INIT
-+
-+// The number of bytes wasted at the start of a received packet buffer in order
-+// to ensure the IP header will be aligned to a 32-bit boundary
-+static const int ETHER_FRAME_ALIGN_WASTAGE = 2;
-+static const int EXTRA_RX_SKB_SPACE = 32;   // Otherwise GMAC spans over >1 skb
-+static const int ETHER_MTU  = 1500;
-+
-+static const u32 MAC_BASE_OFFSET = 0x0000;
-+static const u32 DMA_BASE_OFFSET = 0x1000;
-+
-+static const int NUM_TX_DMA_DESCRIPTORS = 1;
-+static const int NUM_RX_DMA_DESCRIPTORS = 32;
-+
-+/* 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 */
-+
-+/* 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_100FULL2		0x0200	/* Can do 100BASE-T2 HDX */
-+#define BMSR_100HALF2		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  */
-+
-+/* 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 */
-+#define PHY_TYPE_NONE					0
-+#define PHY_TYPE_MICREL_KS8721BL		0x00221619
-+#define PHY_TYPE_VITESSE_VSC8201XVZ	0x000fc413
-+#define PHY_TYPE_REALTEK_RTL8211BGR	0x001cc912
-+#define PHY_TYPE_LSI_ET1011C			0x0282f013
-+
-+/* Specific PHY values */
-+#define VSC8201_MII_ACSR			0x1c	// Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
-+#define VSC8201_MII_ACSR_MDPPS_BIT	2		// Mode/Duplex Pin Priority Select
-+
-+#define ET1011C_MII_CONFIG	0x16
-+#define ET1011C_MII_CONFIG_IFMODESEL	0
-+#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS	3
-+#define ET1011C_MII_CONFIG_SYSCLKEN	4
-+#define ET1011C_MII_CONFIG_TXCLKEN		5
-+#define ET1011C_MII_CONFIG_TBI_RATESEL	8
-+#define ET1011C_MII_CONFIG_CRS_TX_EN	15
-+
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII		0
-+#define ET1011C_MII_CONFIG_IFMODESEL_TBI			1
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX	2
-+
-+#define ET1011C_MII_LED2 0x1c
-+#define ET1011C_MII_LED2_LED_TXRX		12
-+#define ET1011C_MII_LED2_LED_NUM_BITS	4
-+
-+#define ET1011C_MII_LED2_LED_TXRX_ON		0xe
-+#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY	0x7
-+
-+// Some typedefs to cope with std Linux types
-+typedef void sk_buff_t;
-+
-+// The in-memory descriptor structures
-+typedef struct gmac_dma_desc
-+{
-+    /** The encoded status field of the GMAC descriptor */
-+    u32 status;
-+    /** The encoded length field of GMAC descriptor */
-+    u32 length;
-+    /** Buffer 1 pointer field of GMAC descriptor */
-+    u32 buffer1;
-+    /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
-+    u32 buffer2;
-+    /** Not used for U-Boot */
-+    u32 skb;
-+} __attribute ((packed)) gmac_dma_desc_t;
-+
-+typedef struct gmac_desc_list_info
-+{
-+    gmac_dma_desc_t* base_ptr;
-+    int              num_descriptors;
-+    int              empty_count;
-+    int              full_count;
-+    int              r_index;
-+    int              w_index;
-+} gmac_desc_list_info_t;
-+
-+// Private data structure for the GMAC driver
-+typedef struct gmac_priv
-+{
-+    /** Base address of GMAC MAC registers */
-+    u32                     macBase;
-+    /** Base address of GMAC DMA registers */
-+    u32                     dmaBase;
-+
-+    /** The number of descriptors in the gmac_dma_desc_t array holding both the
-+     *  TX and RX descriptors. The TX descriptors reside at the start of the
-+     *  array */
-+    unsigned                total_num_descriptors;
-+
-+    /** The address of the start of the descriptor array */
-+    gmac_dma_desc_t        *desc_base_addr;
-+
-+    /** Descriptor list management */
-+    gmac_desc_list_info_t   tx_gmac_desc_list_info;
-+    gmac_desc_list_info_t   rx_gmac_desc_list_info;
-+
-+	/** PHY info */
-+	u32						 phy_type;
-+	u32						 phy_addr;
-+	int						 phy_id;
-+	int						 link_is_1000M;
-+} gmac_priv_t;
-+
-+/**
-+ * MAC register indices
-+ */
-+typedef enum gmac_mac_regs {
-+    MAC_CONFIG_REG       = 0,
-+    MAC_FRAME_FILTER_REG = 1,
-+    MAC_HASH_HIGH_REG    = 2,
-+    MAC_HASH_LOW_REG     = 3,
-+    MAC_GMII_ADR_REG     = 4,
-+    MAC_GMII_DATA_REG    = 5,
-+    MAC_FLOW_CNTL_REG    = 6,
-+    MAC_VLAN_TAG_REG     = 7,
-+    MAC_VERSION_REG      = 8,
-+    MAC_ADR0_HIGH_REG    = 16,
-+    MAC_ADR0_LOW_REG     = 17,
-+    MAC_ADR1_HIGH_REG    = 18,
-+    MAC_ADR1_LOW_REG     = 19,
-+    MAC_ADR2_HIGH_REG    = 20,
-+    MAC_ADR2_LOW_REG     = 21,
-+    MAC_ADR3_HIGH_REG    = 22,
-+    MAC_ADR3_LOW_REG     = 23,
-+    MAC_ADR4_HIGH_REG    = 24,
-+    MAC_ADR4_LOW_REG     = 25,
-+    MAC_ADR5_HIGH_REG    = 26,
-+    MAC_ADR5_LOW_REG     = 27,
-+    MAC_ADR6_HIGH_REG    = 28,
-+    MAC_ADR6_LOW_REG     = 29,
-+    MAC_ADR7_HIGH_REG    = 30,
-+    MAC_ADR7_LOW_REG     = 31,
-+    MAC_ADR8_HIGH_REG    = 32,
-+    MAC_ADR8_LOW_REG     = 33,
-+    MAC_ADR9_HIGH_REG    = 34,
-+    MAC_ADR9_LOW_REG     = 35,
-+    MAC_ADR10_HIGH_REG   = 36,
-+    MAC_ADR10_LOW_REG    = 37,
-+    MAC_ADR11_HIGH_REG   = 38,
-+    MAC_ADR11_LOW_REG    = 39,
-+    MAC_ADR12_HIGH_REG   = 40,
-+    MAC_ADR12_LOW_REG    = 41,
-+    MAC_ADR13_HIGH_REG   = 42,
-+    MAC_ADR13_LOW_REG    = 43,
-+    MAC_ADR14_HIGH_REG   = 44,
-+    MAC_ADR14_LOW_REG    = 45,
-+    MAC_ADR15_HIGH_REG   = 46,
-+    MAC_ADR15_LOW_REG    = 47
-+} gmac_mac_regs_t;
-+
-+
-+/**
-+ * MAC register field definitions
-+ */
-+typedef enum gmac_config_reg {
-+    MAC_CONFIG_WD_BIT  = 23,
-+    MAC_CONFIG_JD_BIT  = 22,
-+    MAC_CONFIG_BE_BIT  = 21,
-+    MAC_CONFIG_JE_BIT  = 20,
-+    MAC_CONFIG_IFG_BIT = 17,
-+    MAC_CONFIG_PS_BIT  = 15,
-+    MAC_CONFIG_DO_BIT  = 13,
-+    MAC_CONFIG_LM_BIT  = 12,
-+    MAC_CONFIG_DM_BIT  = 11,
-+    MAC_CONFIG_IPC_BIT = 10,
-+    MAC_CONFIG_DR_BIT  = 9,
-+    MAC_CONFIG_ACS_BIT = 7,
-+    MAC_CONFIG_BL_BIT  = 5,
-+    MAC_CONFIG_DC_BIT  = 4,
-+    MAC_CONFIG_TE_BIT  = 3,
-+    MAC_CONFIG_RE_BIT  = 2
-+} gmac_config_reg_t;
-+
-+#define MAC_CONFIG_IFG_NUM_BITS 3
-+#define MAC_CONFIG_BL_NUM_BITS 2
-+
-+typedef enum gmac_frame_filter_reg {
-+    MAC_FRAME_FILTER_RA_BIT   = 31,
-+    MAC_FRAME_FILTER_SAF_BIT  = 9,
-+    MAC_FRAME_FILTER_SAIF_BIT = 8,
-+    MAC_FRAME_FILTER_PCF_BIT  = 6,
-+    MAC_FRAME_FILTER_DBF_BIT  = 5,
-+    MAC_FRAME_FILTER_PM_BIT   = 4,
-+    MAC_FRAME_FILTER_DAIF_BIT = 3,
-+    MAC_FRAME_FILTER_HMC_BIT  = 2,
-+    MAC_FRAME_FILTER_HUC_BIT  = 1,
-+    MAC_FRAME_FILTER_PR_BIT   = 0
-+} gmac_frame_filter_reg_t;
-+
-+#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
-+
-+typedef enum gmac_hash_table_high_reg {
-+    MAC_HASH_HIGH_HTH_BIT = 0
-+} gmac_hash_table_high_reg_t;
-+
-+typedef enum gmac_hash_table_low_reg {
-+    MAC_HASH_LOW_HTL_BIT = 0
-+} gmac_hash_table_low_reg_t;
-+
-+typedef enum gmac_gmii_address_reg {
-+    MAC_GMII_ADR_PA_BIT = 11,
-+    MAC_GMII_ADR_GR_BIT = 6,
-+    MAC_GMII_ADR_CR_BIT = 2,
-+    MAC_GMII_ADR_GW_BIT = 1,
-+    MAC_GMII_ADR_GB_BIT = 0
-+} gmac_gmii_address_reg_t;
-+
-+#define MAC_GMII_ADR_PA_NUM_BITS 5
-+#define MAC_GMII_ADR_GR_NUM_BITS 5
-+#define MAC_GMII_ADR_CR_NUM_BITS 3
-+
-+typedef enum gmac_gmii_data_reg {
-+    MAC_GMII_DATA_GD_BIT = 0
-+} gmac_gmii_data_reg_t;
-+
-+#define MAC_GMII_DATA_GD_NUM_BITS 16
-+
-+typedef enum gmac_flow_control_reg {
-+    MAC_FLOW_CNTL_PT_BIT      = 16,
-+    MAC_FLOW_CNTL_PLT_BIT     = 4,
-+    MAC_FLOW_CNTL_UP_BIT      = 3,
-+    MAC_FLOW_CNTL_RFE_BIT     = 2,
-+    MAC_FLOW_CNTL_TFE_BIT     = 1,
-+    MAC_FLOW_CNTL_FCB_BPA_BIT = 0
-+} gmac_flow_control_reg_t;
-+
-+#define MAC_FLOW_CNTL_PT_NUM_BITS 16
-+#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
-+
-+typedef enum gmac_vlan_tag_reg {
-+    MAC_VLAN_TAG_LV_BIT = 0
-+} gmac_vlan_tag_reg_t;
-+
-+#define MAC_VLAN_TAG_LV_NUM_BITS 16
-+
-+typedef enum gmac_version_reg {
-+    MAC_VERSION_UD_BIT = 8,
-+    MAC_VERSION_SD_BIT = 0
-+} gmac_version_reg_t;
-+
-+#define MAC_VERSION_UD_NUM_BITS 8
-+#define MAC_VERSION_SD_NUM_BITS 8
-+
-+typedef enum gmac_mac_adr_0_high_reg {
-+    MAC_ADR0_HIGH_MO_BIT = 31,
-+    MAC_ADR0_HIGH_A_BIT  = 0
-+} gmac_mac_adr_0_high_reg_t;
-+
-+#define MAC_ADR0_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_0_low_reg {
-+    MAC_ADR0_LOW_A_BIT = 0
-+} gmac_mac_adr_0_low_reg_t;
-+
-+typedef enum gmac_mac_adr_1_high_reg {
-+    MAC_ADR1_HIGH_AE_BIT  = 31,
-+    MAC_ADR1_HIGH_SA_BIT  = 30,
-+    MAC_ADR1_HIGH_MBC_BIT = 24,
-+    MAC_ADR1_HIGH_A_BIT   = 0
-+} gmac_mac_adr_1_high_reg_t;
-+
-+#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
-+#define MAC_ADR1_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_1_low_reg {
-+    MAC_ADR1_LOW_A_BIT = 0
-+} gmac_mac_adr_1_low_reg_t;
-+
-+
-+/**
-+ * MMC register indices - registers accessed via the MAC accessor functions
-+ */
-+typedef enum gmac_mmc_regs {
-+    MMC_CONTROL_REG = 64,
-+    MMC_RX_INT_REG  = 65,
-+    MMC_TX_INT_REG  = 66,
-+    MMC_RX_MASK_REG = 67,
-+    MMC_TX_MASK_REG = 68
-+} gmac_mmc_regs_t;
-+
-+/**
-+ * DMA register indices
-+ */
-+typedef enum gmac_dma_regs {
-+    DMA_BUS_MODE_REG        = 0,
-+    DMA_TX_POLL_REG         = 1,
-+    DMA_RX_POLL_REG         = 2,
-+    DMA_RX_DESC_ADR_REG     = 3,
-+    DMA_TX_DESC_ADR_REG     = 4,
-+    DMA_STATUS_REG          = 5,
-+    DMA_OP_MODE_REG         = 6,
-+    DMA_INT_ENABLE_REG      = 7,
-+    DMA_MISSED_OVERFLOW_REG = 8,
-+    DMA_CUR_TX_DESC_REG     = 18,
-+    DMA_CUR_RX_DESC_REG     = 19,
-+    DMA_CUR_TX_ADR_REG      = 20,
-+    DMA_CUR_RX_ADR_REG      = 21
-+} gmac_dma_regs_t;
-+
-+/**
-+ * DMA register field definitions
-+ */
-+
-+typedef enum gmac_dma_bus_mode_reg {
-+    DMA_BUS_MODE_FB_BIT  = 16,
-+    DMA_BUS_MODE_PR_BIT  = 14,
-+    DMA_BUS_MODE_PBL_BIT = 8,
-+    DMA_BUS_MODE_DSL_BIT = 2,
-+    DMA_BUS_MODE_DA_BIT  = 1,
-+    DMA_BUS_MODE_SWR_BIT = 0
-+} gmac_dma_bus_mode_reg_t;
-+
-+#define DMA_BUS_MODE_PR_NUM_BITS 2
-+#define DMA_BUS_MODE_PBL_NUM_BITS 6
-+#define DMA_BUS_MODE_DSL_NUM_BITS 5
-+
-+typedef enum gmac_dma_tx_poll_demand_reg {
-+    DMA_TX_POLL_TPD_BIT = 0
-+} gmac_dma_tx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_poll_demand_reg {
-+    DMA_RX_POLL_RPD_BIT = 0
-+} gmac_dma_rx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_desc_list_adr_reg {
-+    DMA_RX_DESC_ADR_SRL_BIT = 0
-+} gmac_dma_rx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_tx_desc_list_adr_reg {
-+    DMA_TX_DESC_ADR_STL_BIT = 0
-+} gmac_dma_tx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_status_reg {
-+    DMA_STATUS_GPI_BIT = 28,
-+    DMA_STATUS_GMI_BIT = 27,
-+    DMA_STATUS_GLI_BIT = 26,
-+    DMA_STATUS_EB_BIT  = 23,
-+    DMA_STATUS_TS_BIT  = 20,
-+    DMA_STATUS_RS_BIT  = 17,
-+    DMA_STATUS_NIS_BIT = 16,
-+    DMA_STATUS_AIS_BIT = 15,
-+    DMA_STATUS_ERI_BIT = 14,
-+    DMA_STATUS_FBE_BIT = 13,
-+    DMA_STATUS_ETI_BIT = 10,
-+    DMA_STATUS_RWT_BIT = 9,
-+    DMA_STATUS_RPS_BIT = 8,
-+    DMA_STATUS_RU_BIT  = 7,
-+    DMA_STATUS_RI_BIT  = 6,
-+    DMA_STATUS_UNF_BIT = 5,
-+    DMA_STATUS_OVF_BIT = 4,
-+    DMA_STATUS_TJT_BIT = 3,
-+    DMA_STATUS_TU_BIT  = 2,
-+    DMA_STATUS_TPS_BIT = 1,
-+    DMA_STATUS_TI_BIT  = 0
-+} gmac_dma_status_reg_t;
-+
-+#define DMA_STATUS_EB_NUM_BITS 3
-+#define DMA_STATUS_TS_NUM_BITS 3
-+#define DMA_STATUS_RS_NUM_BITS 3
-+
-+typedef enum gmac_dma_op_mode_reg {
-+    DMA_OP_MODE_SF_BIT  = 21,
-+    DMA_OP_MODE_FTF_BIT = 20,
-+    DMA_OP_MODE_TTC_BIT = 14,
-+    DMA_OP_MODE_ST_BIT  = 13,
-+    DMA_OP_MODE_RFD_BIT = 11,
-+    DMA_OP_MODE_RFA_BIT = 9,
-+    DMA_OP_MODE_EFC_BIT = 8,
-+    DMA_OP_MODE_FEF_BIT = 7,
-+    DMA_OP_MODE_FUF_BIT = 6,
-+    DMA_OP_MODE_RTC_BIT = 3,
-+    DMA_OP_MODE_OSF_BIT = 2,
-+    DMA_OP_MODE_SR_BIT  = 1
-+} gmac_dma_op_mode_reg_t;
-+
-+#define DMA_OP_MODE_TTC_NUM_BITS 3
-+#define DMA_OP_MODE_RFD_NUM_BITS 2
-+#define DMA_OP_MODE_RFA_NUM_BITS 2
-+#define DMA_OP_MODE_RTC_NUM_BITS 2
-+
-+typedef enum gmac_dma_intr_enable_reg {
-+    DMA_INT_ENABLE_NI_BIT  = 16,
-+    DMA_INT_ENABLE_AI_BIT  = 15,
-+    DMA_INT_ENABLE_ERE_BIT = 14,
-+    DMA_INT_ENABLE_FBE_BIT = 13,
-+    DMA_INT_ENABLE_ETE_BIT = 10,
-+    DMA_INT_ENABLE_RW_BIT  = 9,
-+    DMA_INT_ENABLE_RS_BIT  = 8,
-+    DMA_INT_ENABLE_RU_BIT  = 7,
-+    DMA_INT_ENABLE_RI_BIT  = 6,
-+    DMA_INT_ENABLE_UN_BIT  = 5,
-+    DMA_INT_ENABLE_OV_BIT  = 4,
-+    DMA_INT_ENABLE_TJ_BIT  = 3,
-+    DMA_INT_ENABLE_TU_BIT  = 2,
-+    DMA_INT_ENABLE_TS_BIT  = 1,
-+    DMA_INT_ENABLE_TI_BIT  = 0
-+} gmac_dma_intr_enable_reg_t;
-+
-+typedef enum gmac_dma_missed_overflow_reg {
-+    DMA_MISSED_OVERFLOW_OFOC_BIT  = 28,    // Overflow bit for FIFO Overflow Counter
-+    DMA_MISSED_OVERFLOW_AMFC_BIT  = 17,    // Application Missed Frames Count
-+    DMA_MISSED_OVERFLOW_OAMFO_BIT = 16,    // Overflow bit for Application Missed Frames Count
-+    DMA_MISSED_OVERFLOW_CMFC_BIT  = 0      // Controller Missed Frames Count
-+} gmac_dma_missed_overflow_reg_t;
-+
-+#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
-+#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
-+
-+typedef enum gmac_dma_current_tx_desc_reg {
-+    DMA_CUR_TX_DESC_A_BIT = 0
-+} gmac_dma_current_tx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_rx_desc_reg {
-+    DMA_CUR_RX_DESC_A_BIT = 0
-+} gmac_dma_current_rx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_tx_adr_reg {
-+    DMA_CUR_TX_ADR_A_BIT = 0
-+} gmac_dma_current_tx_adr_reg_t;
-+
-+typedef enum gmac_dma_current_rx_adr_reg {
-+    DMA_CUR_RX_ADR_A_BIT = 0
-+} gmac_dma_current_rx_adr_reg_t;
-+
-+/**
-+ * Descriptor support
-+ */
-+/** Descriptor status word field definitions */
-+typedef enum desc_status {
-+  descOwnByDma          = 0x80000000,   /* descriptor is owned by DMA engine  */
-+
-+  descFrameLengthMask   = 0x3FFF0000,   /* Receive descriptor frame length */
-+  descFrameLengthShift  = 16,
-+
-+  descError             = 0x00008000,   /* Error summary bit  - OR of the following bits:    v  */
-+
-+  descRxTruncated       = 0x00004000,   /* Rx - no more descriptors for receive frame        E  */
-+
-+  descRxLengthError     = 0x00001000,   /* Rx - frame size not matching with length field */
-+  descRxDamaged         = 0x00000800,   /* Rx - frame was damaged due to buffer overflow     E  */
-+  descRxFirst           = 0x00000200,   /* Rx - first descriptor of the frame                   */
-+  descRxLast            = 0x00000100,   /* Rx - last descriptor of the frame                    */
-+  descRxLongFrame       = 0x00000080,   /* Rx - frame is longer than 1518 bytes              E  */
-+  descRxCollision       = 0x00000040,   /* Rx - late collision occurred during reception     E  */
-+  descRxFrameEther      = 0x00000020,   /* Rx - Frame type - Ethernet, otherwise 802.3          */
-+  descRxWatchdog        = 0x00000010,   /* Rx - watchdog timer expired during reception      E  */
-+  descRxMiiError        = 0x00000008,   /* Rx - error reported by MII interface              E  */
-+  descRxDribbling       = 0x00000004,   /* Rx - frame contains noninteger multiple of 8 bits    */
-+  descRxCrc             = 0x00000002,   /* Rx - CRC error                                    E  */
-+
-+  descTxTimeout         = 0x00004000,   /* Tx - Transmit jabber timeout                      E  */
-+  descTxLostCarrier     = 0x00000800,   /* Tx - carrier lost during tramsmission             E  */
-+  descTxNoCarrier       = 0x00000400,   /* Tx - no carrier signal from the tranceiver        E  */
-+  descTxLateCollision   = 0x00000200,   /* Tx - transmission aborted due to collision        E  */
-+  descTxExcCollisions   = 0x00000100,   /* Tx - transmission aborted after 16 collisions     E  */
-+  descTxVLANFrame       = 0x00000080,   /* Tx - VLAN-type frame                                 */
-+  descTxCollMask        = 0x00000078,   /* Tx - Collision count                                 */
-+  descTxCollShift       = 3,
-+  descTxExcDeferral     = 0x00000004,   /* Tx - excessive deferral                           E  */
-+  descTxUnderflow       = 0x00000002,   /* Tx - late data arrival from the memory            E  */
-+  descTxDeferred        = 0x00000001,   /* Tx - frame transmision deferred                      */
-+} desc_status_t;
-+
-+/** Descriptor length word field definitions */
-+typedef enum desc_length {
-+  descTxIntEnable       = 0x80000000,   /* Tx - interrupt on completion                         */
-+  descTxLast            = 0x40000000,   /* Tx - Last segment of the frame                       */
-+  descTxFirst           = 0x20000000,   /* Tx - First segment of the frame                      */
-+  descTxDisableCrc      = 0x04000000,   /* Tx - Add CRC disabled (first segment only)           */
-+
-+  descEndOfRing         = 0x02000000,   /* End of descriptors ring                              */
-+  descChain             = 0x01000000,   /* Second buffer address is chain address               */
-+  descTxDisablePadd     = 0x00800000,   /* disable padding, added by - reyaz */
-+
-+  descSize2Mask         = 0x003FF800,   /* Buffer 2 size                                        */
-+  descSize2Shift        = 11,
-+  descSize1Mask         = 0x000007FF,   /* Buffer 1 size                                        */
-+  descSize1Shift        = 0,
-+} desc_length_t;
-+
-+typedef enum rx_desc_status {
-+    RX_DESC_STATUS_OWN_BIT  = 31,
-+    RX_DESC_STATUS_AFM_BIT  = 30,
-+    RX_DESC_STATUS_FL_BIT   = 16,
-+    RX_DESC_STATUS_ES_BIT   = 15,
-+    RX_DESC_STATUS_DE_BIT   = 14,
-+    RX_DESC_STATUS_SAF_BIT  = 13,
-+    RX_DESC_STATUS_LE_BIT   = 12,
-+    RX_DESC_STATUS_OE_BIT   = 11,
-+    RX_DESC_STATUS_IPC_BIT  = 10,
-+    RX_DESC_STATUS_FS_BIT   = 9,
-+    RX_DESC_STATUS_LS_BIT   = 8,
-+    RX_DESC_STATUS_VLAN_BIT = 7,
-+    RX_DESC_STATUS_LC_BIT   = 6,
-+    RX_DESC_STATUS_FT_BIT   = 5,
-+    RX_DESC_STATUS_RWT_BIT  = 4,
-+    RX_DESC_STATUS_RE_BIT   = 3,
-+    RX_DESC_STATUS_DRE_BIT  = 2,
-+    RX_DESC_STATUS_CE_BIT   = 1,
-+    RX_DESC_STATUS_MAC_BIT  = 0
-+} rx_desc_status_t;
-+
-+#define RX_DESC_STATUS_FL_NUM_BITS 14
-+
-+typedef enum rx_desc_length {
-+    RX_DESC_LENGTH_DIC_BIT  = 31,
-+    RX_DESC_LENGTH_RER_BIT  = 25,
-+    RX_DESC_LENGTH_RCH_BIT  = 24,
-+    RX_DESC_LENGTH_RBS2_BIT = 11,
-+    RX_DESC_LENGTH_RBS1_BIT = 0,
-+} rx_desc_length_t;
-+
-+#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
-+#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
-+
-+typedef enum tx_desc_status {
-+    TX_DESC_STATUS_OWN_BIT  = 31,
-+    TX_DESC_STATUS_ES_BIT   = 15,
-+    TX_DESC_STATUS_JT_BIT   = 14,
-+    TX_DESC_STATUS_FF_BIT   = 13,
-+    TX_DESC_STATUS_LOC_BIT  = 11,
-+    TX_DESC_STATUS_NC_BIT   = 10,
-+    TX_DESC_STATUS_LC_BIT   = 9,
-+    TX_DESC_STATUS_EC_BIT   = 8,
-+    TX_DESC_STATUS_VF_BIT   = 7,
-+    TX_DESC_STATUS_CC_BIT   = 3,
-+    TX_DESC_STATUS_ED_BIT   = 2,
-+    TX_DESC_STATUS_UF_BIT   = 1,
-+    TX_DESC_STATUS_DB_BIT   = 0
-+} tx_desc_status_t;
-+
-+#define TX_DESC_STATUS_CC_NUM_BITS 4
-+
-+typedef enum tx_desc_length {
-+    TX_DESC_LENGTH_IC_BIT   = 31,
-+    TX_DESC_LENGTH_LS_BIT   = 30,
-+    TX_DESC_LENGTH_FS_BIT   = 29,
-+    TX_DESC_LENGTH_DC_BIT   = 26,
-+    TX_DESC_LENGTH_TER_BIT  = 25,
-+    TX_DESC_LENGTH_TCH_BIT  = 24,
-+    TX_DESC_LENGTH_DP_BIT   = 23,
-+    TX_DESC_LENGTH_TBS2_BIT = 11,
-+    TX_DESC_LENGTH_TBS1_BIT = 0
-+} tx_desc_length_t;
-+
-+#define TX_DESC_LENGTH_TBS2_NUM_BITS 11
-+#define TX_DESC_LENGTH_TBS1_NUM_BITS 11
-+
-+/** Return the number of descriptors available for the CPU to fill with new
-+ *  packet info */
-+static inline int available_for_write(gmac_desc_list_info_t* desc_list)
-+{
-+    return desc_list->empty_count;
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ *  the GMAC DMA has finished */
-+static inline int tx_available_for_read(gmac_desc_list_info_t* desc_list)
-+{
-+    return desc_list->full_count &&
-+           !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << TX_DESC_STATUS_OWN_BIT));
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ *  the GMAC DMA has finished */
-+static inline int rx_available_for_read(gmac_desc_list_info_t* desc_list)
-+{
-+    return desc_list->full_count &&
-+           !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << RX_DESC_STATUS_OWN_BIT));
-+}
-+
-+/**
-+ * @param A u32 containing the status from a received frame's DMA descriptor
-+ * @return An int which is non-zero if a valid received frame is fully contained
-+ *  within the descriptor from whence the status came
-+ */
-+static inline int is_rx_valid(u32 status)
-+{
-+    return !(status & descError)  &&
-+           (status & descRxFirst) &&
-+           (status & descRxLast);
-+}
-+
-+static inline int is_rx_dribbling(u32 status)
-+{
-+    return status & descRxDribbling;
-+}
-+
-+static inline u32 get_rx_length(u32 status)
-+{
-+    return (status & descFrameLengthMask) >> descFrameLengthShift;
-+}
-+
-+static inline int is_rx_collision_error(u32 status)
-+{
-+    return status & (descRxDamaged | descRxCollision);
-+}
-+
-+static inline int is_rx_crc_error(u32 status)
-+{
-+    return status & descRxCrc;
-+}
-+
-+static inline int is_rx_frame_error(u32 status)
-+{
-+    return status & descRxDribbling;
-+}
-+
-+static inline int is_rx_length_error(u32 status)
-+{
-+    return status & descRxLengthError;
-+}
-+
-+static inline int is_rx_long_frame(u32 status)
-+{
-+    return status & descRxLongFrame;
-+}
-+
-+static inline int is_tx_valid(u32 status)
-+{
-+    return !(status & descError);
-+}
-+
-+static inline int is_tx_collision_error(u32 status)
-+{
-+    return (status & descTxCollMask) >> descTxCollShift;
-+}
-+
-+static inline int is_tx_aborted(u32 status)
-+{
-+    return status & (descTxLateCollision | descTxExcCollisions);
-+}
-+
-+static inline int is_tx_carrier_error(u32 status)
-+{
-+    return status & (descTxLostCarrier | descTxNoCarrier);
-+}
-+
-+/**
-+ * GMAC private metadata
-+ */
-+static gmac_priv_t priv_data;
-+static gmac_priv_t* priv = &priv_data;
-+
-+/**
-+ * Descriptor list management
-+ */
-+
-+static void init_rx_descriptor(
-+    gmac_dma_desc_t* desc,
-+    int              end_of_ring,
-+    int              disable_ioc)
-+{
-+    desc->status = 0;
-+    desc->length = 0;
-+    if (disable_ioc) {
-+        desc->length |= (1UL << RX_DESC_LENGTH_DIC_BIT);
-+    }
-+    if (end_of_ring) {
-+        desc->length |= (1UL << RX_DESC_LENGTH_RER_BIT);
-+    }
-+    desc->buffer1 = 0;
-+    desc->buffer2 = 0;
-+    desc->skb = 0;
-+}
-+
-+static void init_tx_descriptor(
-+    gmac_dma_desc_t* desc,
-+    int              end_of_ring,
-+    int              enable_ioc,
-+    int              disable_crc,
-+    int              disable_padding)
-+{
-+    desc->status = 0;
-+    desc->length = 0;
-+    if (enable_ioc) {
-+        desc->length |= (1UL << TX_DESC_LENGTH_IC_BIT);
-+    }
-+    if (disable_crc) {
-+        desc->length |= (1UL << TX_DESC_LENGTH_DC_BIT);
-+    }
-+    if (disable_padding) {
-+        desc->length |= (1UL << TX_DESC_LENGTH_DP_BIT);
-+    }
-+    if (end_of_ring) {
-+        desc->length |= (1UL << TX_DESC_LENGTH_TER_BIT);
-+    }
-+    desc->buffer1 = 0;
-+    desc->buffer2 = 0;
-+    desc->skb = 0;
-+}
-+
-+static void init_rx_desc_list(
-+    gmac_desc_list_info_t* desc_list,
-+    gmac_dma_desc_t*       base_ptr,
-+    int                    num_descriptors)
-+{
-+    int i;
-+    
-+    desc_list->base_ptr = base_ptr;
-+    desc_list->num_descriptors = num_descriptors;
-+    desc_list->empty_count = num_descriptors;
-+    desc_list->full_count = 0;
-+    desc_list->r_index = 0;
-+    desc_list->w_index = 0;
-+
-+    for (i=0; i < (num_descriptors - 1); i++) {
-+        init_rx_descriptor(base_ptr + i, 0, 0);
-+    }
-+    init_rx_descriptor(base_ptr + i, 1, 0);
-+}
-+
-+static void init_tx_desc_list(
-+    gmac_desc_list_info_t* desc_list,
-+    gmac_dma_desc_t*       base_ptr,
-+    int                    num_descriptors)
-+{
-+    int i;
-+    
-+    desc_list->base_ptr = base_ptr;
-+    desc_list->num_descriptors = num_descriptors;
-+    desc_list->empty_count = num_descriptors;
-+    desc_list->full_count = 0;
-+    desc_list->r_index = 0;
-+    desc_list->w_index = 0;
-+
-+    for (i=0; i < (num_descriptors - 1); i++) {
-+        init_tx_descriptor(base_ptr + i, 0, 1, 0, 0);
-+    }
-+    init_tx_descriptor(base_ptr + i, 1, 1, 0, 0);
-+}
-+
-+static void rx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+    int i;
-+    for (i=0; i < desc_list->num_descriptors; i++) {
-+        (desc_list->base_ptr + i)->status &= ~(1UL << RX_DESC_STATUS_OWN_BIT);
-+    }
-+}
-+
-+static void tx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+    int i;
-+    for (i=0; i < desc_list->num_descriptors; i++) {
-+        (desc_list->base_ptr + i)->status &= ~(1UL << TX_DESC_STATUS_OWN_BIT);
-+    }
-+}
-+
-+static int set_tx_descriptor(
-+    gmac_priv_t* priv,
-+    dma_addr_t   dma_address,
-+    u32          length,
-+    sk_buff_t*   skb)
-+{
-+    int index;
-+    gmac_dma_desc_t* tx;
-+
-+    // Are sufficicent descriptors available for writing by the CPU?
-+    if (!available_for_write(&priv->tx_gmac_desc_list_info)) {
-+        return -1;
-+    }
-+
-+    // Get the index of the next TX descriptor available for writing by the CPU
-+    index = priv->tx_gmac_desc_list_info.w_index;
-+
-+    // Get a pointer to the next TX descriptor available for writing by the CPU
-+    tx = priv->tx_gmac_desc_list_info.base_ptr + index;
-+
-+    // Initialise the TX descriptor length field for the passed single buffer,
-+    // without destroying any fields we wish to be persistent
-+
-+    // No chained second buffer
-+    tx->length &= ~(1UL << TX_DESC_LENGTH_TCH_BIT);
-+    // Single descriptor holds entire packet
-+    tx->length |= ((1UL << TX_DESC_LENGTH_LS_BIT) | (1UL << TX_DESC_LENGTH_FS_BIT));
-+    // Zero the second buffer length field
-+    tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS2_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS2_BIT);
-+    // Zero the first buffer length field
-+    tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS1_BIT);
-+    // Fill in the first buffer length
-+    tx->length |= (length << TX_DESC_LENGTH_TBS1_BIT);
-+
-+    // Initialise the first buffer pointer to the single passed buffer
-+    tx->buffer1 = dma_address;
-+
-+    // Remember the socket buffer associated with the single passed buffer
-+    tx->skb = (u32)skb;
-+
-+    // Update the index of the next descriptor available for writing by the CPU
-+    priv->tx_gmac_desc_list_info.w_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
-+
-+    // make sure all memory updates are complete before releasing the GMAC on the data.
-+    wmb();
-+    
-+    // Hand TX descriptor to the GMAC DMA by setting the status bit.
-+    tx->status = (1UL << TX_DESC_STATUS_OWN_BIT);
-+
-+    // Account for the number of descriptors used to hold the new packet
-+    --priv->tx_gmac_desc_list_info.empty_count;
-+    ++priv->tx_gmac_desc_list_info.full_count;
-+
-+    return index;
-+}
-+
-+static int get_tx_descriptor(
-+    gmac_priv_t* priv,
-+    u32*         status,
-+    dma_addr_t*  dma_address,
-+    u32*         length,
-+    sk_buff_t**  skb)
-+{
-+    int index;
-+    gmac_dma_desc_t *tx;
-+
-+    // Is there at least one descriptor with which the GMAC DMA has finished?
-+    if (!tx_available_for_read(&priv->tx_gmac_desc_list_info)) {
-+        return -1;
-+    }
-+
-+    // Get the index of the descriptor released the longest time ago by the
-+    // GMAC DMA 
-+    index = priv->tx_gmac_desc_list_info.r_index;
-+
-+    // Get a pointer to the descriptor released the longest time ago by the
-+    // GMAC DMA 
-+    tx = priv->tx_gmac_desc_list_info.base_ptr + index;
-+
-+    // Extract the status field
-+    if (status) {
-+        *status = tx->status;
-+    }
-+
-+    // Extract the length field - only cope with the first buffer associated
-+    // with the descriptor
-+    if (length) {
-+        *length = (tx->length >> TX_DESC_LENGTH_TBS1_BIT) &
-+                  ((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1);
-+    }
-+
-+    // Extract the pointer to the buffer containing the packet - only cope with
-+    // the first buffer associated with the descriptor
-+    if (dma_address) {
-+        *dma_address = tx->buffer1;
-+    }
-+
-+    // Extract the pointer to the socket buffer associated with the packet
-+    if (skb) {
-+        *skb = (sk_buff_t*)(tx->skb);
-+    }
-+
-+    // Update the index of the next descriptor with which the GMAC DMA may have
-+    // finished
-+    priv->tx_gmac_desc_list_info.r_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
-+
-+    // Account for the number of descriptors freed to hold new packets
-+    ++priv->tx_gmac_desc_list_info.empty_count;
-+    --priv->tx_gmac_desc_list_info.full_count;
-+
-+    return index;
-+}
-+
-+int set_rx_descriptor(
-+    gmac_priv_t* priv,
-+    dma_addr_t   dma_address,
-+    u32          length,
-+    sk_buff_t*   skb)
-+{
-+    int index;
-+    gmac_dma_desc_t* rx;
-+    int num_descriptors_required;
-+
-+    // Currently only support using a single descriptor to describe each packet
-+    // queued with the GMAc DMA
-+    num_descriptors_required = 1;
-+
-+    // Are sufficicent descriptors available for writing by the CPU?
-+    if (available_for_write(&priv->rx_gmac_desc_list_info) < num_descriptors_required) {
-+        index = -1;
-+    } else {
-+        // Get the index of the next RX descriptor available for writing by the CPU
-+        index = priv->rx_gmac_desc_list_info.w_index;
-+
-+        // Get a pointer to the next RX descriptor available for writing by the CPU
-+        rx = priv->rx_gmac_desc_list_info.base_ptr + index;
-+
-+        // Initialise the RX descriptor length field for the passed single buffer,
-+        // without destroying any fields we wish to be persistent
-+
-+        // No chained second buffer
-+        rx->length &= ~(1UL << RX_DESC_LENGTH_RCH_BIT);
-+        // Zero the second buffer length field
-+        rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS2_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS2_BIT);
-+        // Zero the first buffer length field
-+        rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS1_BIT);
-+        // Fill in the first buffer length
-+        rx->length |= (length << RX_DESC_LENGTH_RBS1_BIT);
-+
-+        // Initialise the first buffer pointer to the single passed buffer
-+        rx->buffer1 = dma_address;
-+
-+        // Remember the socket buffer associated with the single passed buffer
-+        rx->skb = (u32)skb;
-+        
-+        wmb();
-+        
-+        // Initialise RX descriptor status to be owned by the GMAC DMA
-+        rx->status = (1UL << RX_DESC_STATUS_OWN_BIT);
-+
-+        // Update the index of the next descriptor available for writing by the CPU
-+        priv->rx_gmac_desc_list_info.w_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
-+
-+        // Account for the number of descriptors used to hold the new packet
-+        priv->rx_gmac_desc_list_info.empty_count -= num_descriptors_required;
-+        priv->rx_gmac_desc_list_info.full_count  += num_descriptors_required;
-+    }
-+
-+    return index;
-+}
-+
-+int get_rx_descriptor(
-+    gmac_priv_t* priv,
-+    u32*         status,
-+    dma_addr_t*  dma_address,
-+    u32*         length,
-+    sk_buff_t**  skb)
-+{
-+    int index;
-+    gmac_dma_desc_t *rx;
-+    int num_descriptors_required;
-+
-+    // Is there at least one descriptor with which the GMAC DMA has finished?
-+    if (!rx_available_for_read(&priv->rx_gmac_desc_list_info)) {
-+        return -1;
-+    }
-+
-+    // Currently can only cope with packets entirely contained within a single
-+    // descriptor
-+    num_descriptors_required = 1;
-+
-+    // Get the index of the descriptor released the longest time ago by the
-+    // GMAC DMA 
-+    index = priv->rx_gmac_desc_list_info.r_index;
-+
-+    // Get a pointer to the descriptor released the longest time ago by the
-+    // GMAC DMA 
-+    rx = priv->rx_gmac_desc_list_info.base_ptr + index;
-+
-+    // Extract the status field
-+    if (status) {
-+        *status = rx->status;
-+    }
-+
-+    // Extract the length field - only cope with the first buffer associated
-+    // with the descriptor
-+    if (length) {
-+        *length = (rx->length >> RX_DESC_LENGTH_RBS1_BIT) &
-+                  ((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1);
-+    }
-+
-+    // Extract the pointer to the buffer containing the packet - only cope with
-+    // the first buffer associated with the descriptor
-+    if (dma_address) {
-+        *dma_address = rx->buffer1;
-+    }
-+
-+    // Extract the pointer to the socket buffer associated with the packet
-+    if (skb) {
-+        *skb = (sk_buff_t*)(rx->skb);
-+    }
-+
-+    wmb();
-+    // Update the index of the next descriptor with which the GMAC DMA may have
-+    // finished
-+    priv->rx_gmac_desc_list_info.r_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
-+
-+    // Account for the number of descriptors freed to hold new packets
-+    priv->rx_gmac_desc_list_info.empty_count += num_descriptors_required;
-+    priv->rx_gmac_desc_list_info.full_count  -= num_descriptors_required;
-+
-+    return index;
-+}
-+
-+/**
-+ * GMAC register access functions
-+ */
-+
-+/**
-+ * MAC register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+    return *(volatile u32*)(priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+    *(volatile u32*)(priv->macBase + (reg_num << 2)) = value;
-+   
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ *  clear. A set bit in this parameter will cause the matching bit in the
-+ *  register to be cleared
-+ */
-+static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+    mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ *  set. A set bit in this parameter will cause the matching bit in the register
-+ *  to be set
-+ */
-+static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+    mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
-+}
-+
-+
-+/**
-+ * DMA register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+    return *(volatile u32*)(priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+    *(volatile u32*)(priv->dmaBase + (reg_num << 2)) = value;
-+    wmb();
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ *  clear. A set bit in this parameter will cause the matching bit in the
-+ *  register to be cleared
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+    u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
-+    dma_reg_write(priv, reg_num, new_value);
-+    return new_value;
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ *  set. A set bit in this parameter will cause the matching bit in the register
-+ *  to be set
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+    u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
-+    dma_reg_write(priv, reg_num, new_value);
-+    return new_value;
-+}
-+
-+static void eth_down(void)
-+{
-+    // Stop transmitter, take ownership of all tx descriptors
-+    dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_ST_BIT);
-+    if (priv->desc_base_addr) {
-+        tx_take_ownership(&priv->tx_gmac_desc_list_info);
-+    }
-+
-+    // Stop receiver, take ownership of all rx descriptors
-+    dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_SR_BIT);
-+    if (priv->desc_base_addr) {
-+        rx_take_ownership(&priv->rx_gmac_desc_list_info);
-+    }
-+
-+    // Free descriptor resources. The TX descriptor will not have a packet
-+    // buffer attached, as this is provided by the stack when transmission is
-+    // required and ownership is not retained by the descriptor, as the stack
-+    // waits for transmission to complete via polling
-+    if (priv->desc_base_addr) {
-+        // Free receive descriptors, accounting for buffer offset used to
-+        // ensure IP header alignment
-+        while (1) {
-+            dma_addr_t dma_address;
-+            if (get_rx_descriptor(priv, 0, &dma_address, 0, 0) < 0) {
-+                break;
-+            }
-+            free((void*)(dma_address - ETHER_FRAME_ALIGN_WASTAGE));
-+        }
-+
-+        // Free DMA descriptors' storage
-+        free(priv->desc_base_addr);
-+
-+        // Remember that we've freed the descriptors memory
-+        priv->desc_base_addr = 0;
-+    }
-+}
-+
-+/*
-+ * Reads a register from the MII Management serial interface
-+ */
-+int phy_read(int phyaddr, int phyreg)
-+{
-+    int data = 0;
-+    u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+               (phyreg << MAC_GMII_ADR_GR_BIT) |
-+               (5 << MAC_GMII_ADR_CR_BIT) |
-+               (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+    mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+    for (;;) {
-+        if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+            // Successfully read from PHY
-+            data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
-+            break;
-+        }
-+    }
-+
-+#ifdef DEBUG_GMAC_INIT
-+    printf("phy_read() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, data);
-+#endif // DEBUG_GMAC_INIT
-+
-+    return data;
-+}
-+
-+/*
-+ * Writes a register to the MII Management serial interface
-+ */
-+void phy_write(int phyaddr, int phyreg, int phydata)
-+{
-+    u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+               (phyreg << MAC_GMII_ADR_GR_BIT) |
-+               (5 << MAC_GMII_ADR_CR_BIT) |
-+               (1UL << MAC_GMII_ADR_GW_BIT) |
-+               (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+    mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
-+    mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+    for (;;) {
-+        if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+            break;
-+        }
-+    }
-+
-+#ifdef DEBUG_GMAC_INIT
-+    printf("phy_write() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, phydata);
-+#endif // DEBUG_GMAC_INIT
-+}
-+
-+/*
-+ * Finds and reports the PHY address
-+ */
-+int phy_detect(void)
-+{
-+	int found = 0;
-+    int phyaddr;
-+
-+    // Scan all 32 PHY addresses if necessary
-+    priv->phy_type = 0;
-+    for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
-+        unsigned int id1, id2;
-+
-+        // Read the PHY identifiers
-+        id1 = phy_read(phyaddr & 31, MII_PHYSID1);
-+        id2 = phy_read(phyaddr & 31, MII_PHYSID2);
-+
-+#ifdef DEBUG_GMAC_INIT
-+        printf("phy_detect() PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", phyaddr, id1, id2);
-+#endif // DEBUG_GMAC_INIT
-+
-+        // Make sure it is a valid identifier
-+        if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-+            id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
-+#ifdef DEBUG_GMAC_INIT
-+            printf("phy_detect() Found PHY at address = %u\n", phyaddr);
-+#endif // DEBUG_GMAC_INIT
-+
-+            priv->phy_id   = phyaddr & 31;
-+            priv->phy_type = id1 << 16 | id2;
-+            priv->phy_addr = phyaddr;
-+
-+			found = 1;
-+            break;
-+        }
-+    }
-+
-+	return found;
-+}
-+
-+void start_phy_reset(void)
-+{
-+    // Ask the PHY to reset
-+    phy_write(priv->phy_addr, MII_BMCR, BMCR_RESET);
-+}
-+
-+int is_phy_reset_complete(void)
-+{
-+    int complete = 0;
-+    int bmcr;
-+
-+    // Read back the status until it indicates reset, or we timeout
-+    bmcr = phy_read(priv->phy_addr, MII_BMCR);
-+    if (!(bmcr & BMCR_RESET)) {
-+        complete = 1;
-+    }
-+
-+    return complete;
-+}
-+
-+void set_phy_type_rgmii(void)
-+{
-+	// Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
-+    *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_RGMII);
-+}
-+
-+void phy_initialise(void)
-+{
-+	switch (priv->phy_type) {
-+		case PHY_TYPE_VITESSE_VSC8201XVZ:
-+			{
-+				// Allow s/w to override mode/duplex pin settings
-+				u32 acsr = phy_read(priv->phy_id, VSC8201_MII_ACSR);
-+
-+				printf("PHY is Vitesse VSC8201XVZ\n");
-+				acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
-+				phy_write(priv->phy_id, VSC8201_MII_ACSR, acsr);
-+			}
-+			break;
-+		case PHY_TYPE_REALTEK_RTL8211BGR:
-+			printf("PHY is Realtek RTL8211BGR\n");
-+			set_phy_type_rgmii();
-+			break;
-+		case PHY_TYPE_LSI_ET1011C:
-+			{
-+				u32 phy_reg;
-+
-+				printf("PHY is LSI ET1011C\n");
-+
-+				// Configure clocks
-+				phy_reg = phy_read(priv->phy_id, ET1011C_MII_CONFIG);
-+				phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
-+				phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
-+				phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
-+                              (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
-+							   (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
-+							   (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
-+				phy_write(priv->phy_id, ET1011C_MII_CONFIG, phy_reg);
-+
-+				// Enable Tx/Rx LED
-+				phy_reg = phy_read(priv->phy_id, ET1011C_MII_LED2);
-+				phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
-+				phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
-+				phy_write(priv->phy_id, ET1011C_MII_LED2, phy_reg);
-+			}
-+			break;
-+	}
-+}
-+
-+int detect_link_speed(void)
-+{
-+	u32 lpa2 = phy_read(priv->phy_id, MII_STAT1000);
-+
-+	if (((lpa2 & LPA_1000FULL)) ||
-+		((lpa2 & LPA_1000HALF))) {
-+		priv->link_is_1000M = 1;
-+	} else {
-+		priv->link_is_1000M = 0;
-+	}
-+
-+	return 0;
-+}
-+
-+int is_autoneg_complete(void)
-+{
-+    return phy_read(priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE;
-+}
-+
-+int is_link_ok(void)
-+{
-+	return phy_read(priv->phy_id, MII_BMSR) & BMSR_LSTATUS;
-+}
-+
-+int eth_init(bd_t *bd)
-+{
-+    u32  version;
-+    u32  reg_contents;
-+    u8  *mac_addr;
-+    int  desc;
-+
-+    // Set hardware device base addresses
-+    priv->macBase = (MAC_BASE_PA + MAC_BASE_OFFSET);
-+    priv->dmaBase = (MAC_BASE_PA + DMA_BASE_OFFSET);
-+
-+#ifdef DEBUG_GMAC_INIT
-+    printf("eth_init(): About to reset MAC core\n");
-+#endif // DEBUG_GMAC_INIT
-+    // Ensure the MAC block is properly reset
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
-+
-+    // Enable the clock to the MAC block
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_MAC_BIT);
-+
-+    version = mac_reg_read(priv, MAC_VERSION_REG);
-+#ifdef DEBUG_GMAC_INIT
-+    printf("eth_init(): GMAC Synopsis version = 0x%x, vendor version = 0x%x\n", version & 0xff, (version >> 8) & 0xff);
-+#endif // DEBUG_GMAC_INIT
-+
-+    // Use simple mux for 25/125 Mhz clock switching
-+    *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_SIMPLE_MAX);
-+
-+    // Enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
-+    *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_CKEN_GTX);
-+
-+    // Disable all GMAC interrupts
-+    dma_reg_write(priv, DMA_INT_ENABLE_REG, 0);
-+
-+    // Reset the entire GMAC
-+    dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
-+
-+    // Wait for the reset operation to complete
-+	printf("Wait GMAC to reset");
-+    while (dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT)) {
-+		udelay(250000);
-+		printf(".");
-+    }
-+	printf("\n");
-+
-+	// Attempt to discover link speed from the PHY
-+	if (!phy_detect()) {
-+		printf("No PHY found\n");
-+	} else {
-+		// Ensure the PHY is in a sensible state by resetting it
-+		start_phy_reset();
-+
-+		// Read back the status until it indicates reset, or we timeout
-+		printf("Wait for PHY reset");
-+		while (!is_phy_reset_complete()) {
-+			udelay(250000);
-+			printf(".");
-+		}
-+		printf("\n");
-+
-+		// Setup the PHY based on its type
-+		phy_initialise();
-+
-+		printf("Wait for link to come up");
-+		while (!is_link_ok()) {
-+			udelay(250000);
-+			printf(".");
-+		}
-+		printf("Link up\n");
-+
-+		// Wait for PHY to have completed autonegotiation
-+		printf("Wait for auto-negotiation to complete");
-+		while (!is_autoneg_complete()) {
-+			udelay(250000);
-+			printf(".");
-+		}
-+		printf("\n");
-+
-+		// Interrogate the PHY for the link speed
-+		if (detect_link_speed()) {
-+			printf("Failed to detect link speed\n");
-+		} else {
-+			printf("Link is %s\n", priv->link_is_1000M ? "1000M" : "10M/100M");
-+		}
-+	}
-+
-+    // Form the MAC config register contents
-+    reg_contents = 0;
-+	if (!priv->link_is_1000M) {
-+		reg_contents |= (1UL << MAC_CONFIG_PS_BIT); // Gigabit
-+	}
-+    reg_contents |= (1UL << MAC_CONFIG_DM_BIT); // Full duplex
-+    reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
-+                     (1UL << MAC_CONFIG_RE_BIT));
-+    mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
-+
-+    // Form the MAC frame filter register contents
-+    reg_contents = 0;
-+    mac_reg_write(priv, MAC_FRAME_FILTER_REG, reg_contents);
-+
-+    // Form the hash table registers contents
-+    mac_reg_write(priv, MAC_HASH_HIGH_REG, 0);
-+    mac_reg_write(priv, MAC_HASH_LOW_REG, 0);
-+
-+    // Form the MAC flow control register contents
-+    reg_contents = 0;
-+    reg_contents |= ((1UL << MAC_FLOW_CNTL_RFE_BIT) |
-+                     (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+    mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
-+
-+    // Form the MAC VLAN tag register contents
-+    reg_contents = 0;
-+    mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
-+
-+    // Form the MAC addr0 high and low registers contents from the character
-+    // string representation from the environment
-+    mac_addr = getenv("ethaddr");
-+#ifdef DEBUG_GMAC_INIT
-+    printf("eth_init(): Mac addr = %s\n", mac_addr);
-+#endif // DEBUG_GMAC_INIT
-+    reg_contents  =  simple_strtoul(mac_addr+0, 0, 16);
-+    reg_contents |= (simple_strtoul(mac_addr+3, 0, 16) << 8);
-+    reg_contents |= (simple_strtoul(mac_addr+6, 0, 16) << 16);
-+    reg_contents |= (simple_strtoul(mac_addr+9, 0, 16) << 24);
-+    mac_reg_write(priv, MAC_ADR0_LOW_REG, reg_contents);
-+    reg_contents  =  simple_strtoul(mac_addr+12, 0, 16);
-+    reg_contents |= (simple_strtoul(mac_addr+15, 0, 16) << 8);
-+    mac_reg_write(priv, MAC_ADR0_HIGH_REG, reg_contents);
-+
-+    // Disable all MMC interrupt sources
-+    mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
-+    mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
-+
-+    // Remember how large the unified descriptor array is to be
-+    priv->total_num_descriptors = NUM_RX_DMA_DESCRIPTORS + NUM_TX_DMA_DESCRIPTORS;
-+
-+    // Need a consistent DMA mapping covering all the memory occupied by DMA
-+    // unified descriptor array, as both CPU and DMA engine will be reading and
-+    // writing descriptor fields.
-+    priv->desc_base_addr = (gmac_dma_desc_t*)malloc(sizeof(gmac_dma_desc_t) * priv->total_num_descriptors);
-+    if (!priv->desc_base_addr) {
-+       printf("eth_init(): Failed to allocate memory for DMA descriptors\n");
-+        goto err_out;
-+    }
-+
-+    // Initialise the structures managing the TX descriptor list
-+    init_tx_desc_list(&priv->tx_gmac_desc_list_info,
-+                      priv->desc_base_addr,
-+                      NUM_TX_DMA_DESCRIPTORS);
-+
-+    // Initialise the structures managing the RX descriptor list
-+    init_rx_desc_list(&priv->rx_gmac_desc_list_info,
-+                      priv->desc_base_addr + NUM_TX_DMA_DESCRIPTORS,
-+                      priv->total_num_descriptors - NUM_TX_DMA_DESCRIPTORS);
-+
-+    // Prepare receive descriptors
-+    desc = 0;
-+    while (available_for_write(&priv->rx_gmac_desc_list_info)) {
-+        // Allocate a new buffer for the descriptor which is large enough for
-+        // any packet received from the link
-+        dma_addr_t dma_address = (dma_addr_t)malloc(ETHER_MTU + ETHER_FRAME_ALIGN_WASTAGE + EXTRA_RX_SKB_SPACE);
-+        if (!dma_address) {
-+            printf("eth_init(): No memory for socket buffer\n");
-+            break;
-+        }
-+
-+        desc = set_rx_descriptor(priv,
-+                                 dma_address + ETHER_FRAME_ALIGN_WASTAGE,
-+                                 ETHER_MTU + EXTRA_RX_SKB_SPACE,
-+                                 0);
-+
-+        if (desc < 0) {
-+            // Release the buffer
-+            free((void*)dma_address);
-+
-+            printf("eth_init(): Error, no RX descriptor available\n");
-+            goto err_out;
-+        }
-+    }
-+
-+    // Initialise the GMAC DMA bus mode register
-+    dma_reg_write(priv, DMA_BUS_MODE_REG, ((0UL << DMA_BUS_MODE_FB_BIT)   |
-+                                           (0UL << DMA_BUS_MODE_PR_BIT)   |
-+                                           (32UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
-+                                           (1UL << DMA_BUS_MODE_DSL_BIT)  | 
-+                                           (0UL << DMA_BUS_MODE_DA_BIT)));
-+
-+    // Write the address of the start of the tx descriptor array
-+    dma_reg_write(priv, DMA_TX_DESC_ADR_REG, (u32)priv->desc_base_addr);
-+
-+    // Write the address of the start of the rx descriptor array
-+    dma_reg_write(priv, DMA_RX_DESC_ADR_REG,
-+        (u32)(priv->desc_base_addr + priv->tx_gmac_desc_list_info.num_descriptors));
-+
-+    // Clear any pending interrupt requests
-+    dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
-+
-+    // Initialise the GMAC DMA operation mode register, starting both the
-+    // transmitter and receiver
-+    dma_reg_write(priv, DMA_OP_MODE_REG, ((1UL << DMA_OP_MODE_SF_BIT)  |    // Store and forward
-+                                          (0UL << DMA_OP_MODE_TTC_BIT) |    // Tx threshold
-+                                          (1UL << DMA_OP_MODE_ST_BIT)  |    // Enable transmitter
-+                                          (0UL << DMA_OP_MODE_RTC_BIT) |    // Rx threshold
-+                                          (1UL << DMA_OP_MODE_SR_BIT)));    // Enable receiver
-+
-+    // Success
-+    return 1;
-+
-+err_out:
-+    eth_down();
-+
-+    return 0;
-+}
-+
-+void eth_halt(void)
-+{
-+    eth_down();
-+
-+    // Disable the clock to the MAC block
-+    *(volatile u32*)(SYS_CTRL_CKEN_CLR_CTRL) = (1UL << SYS_CTRL_CKEN_MAC_BIT);
-+}
-+
-+int eth_rx(void)
-+{
-+    static const int MAX_LOOPS = 2000;   // 2 seconds
-+
-+    int length = 0;
-+    dma_addr_t dma_address;
-+    u32 desc_status;
-+    int loops = 0;
-+
-+    // Look for the first available received packet
-+    while (loops++ < MAX_LOOPS) {
-+        if (get_rx_descriptor(priv, &desc_status, &dma_address, 0, 0) >= 0) {
-+            if (is_rx_valid(desc_status)) {
-+                // Get the length of the packet within the buffer
-+                length = get_rx_length(desc_status);
-+
-+                // Pass packet up the network stack - will block until processing is
-+                // completed
-+                NetReceive((uchar*)dma_address, length);
-+            } else {
-+                printf("eth_rx() Received packet has bad desc_status = 0x%08x\n", desc_status);
-+            }
-+
-+            // Re-initialise the RX descriptor with its buffer - relies on always
-+            // setting an RX descriptor directly after getting it
-+            if (set_rx_descriptor(priv, dma_address, ETHER_MTU + EXTRA_RX_SKB_SPACE, 0) < 0) {
-+                 printf("eth_rx(): Failed to set RX descriptor\n");
-+            }
-+
-+            break;
-+        }
-+
-+        // Wait a bit before trying again to get a descriptor
-+        udelay(1000);   // 1mS
-+    }
-+
-+    return length;
-+}
-+
-+int eth_send(volatile void *packet, int length)
-+{
-+    // Transmit the new packet
-+    while (1) {
-+        // Get the TX descriptor
-+        if (set_tx_descriptor(priv, (dma_addr_t)packet, length, 0) >= 0) {
-+            // Tell the GMAC to poll for the updated descriptor
-+            dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+            break;
-+        }
-+
-+        // Wait a bit before trying again to get a descriptor
-+        udelay(1000);   // 1mS
-+    }
-+
-+    // Wait for the packet buffer to be finished with
-+    while (get_tx_descriptor(priv, 0, 0, 0, 0) < 0) {
-+        // Wait a bit before examining the descriptor again
-+        udelay(1000);   // 1mS
-+    }
-+
-+    return length;
-+}
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/ide-810.c u-boot-1.1.2-oxe810/board/oxnas/ide-810.c
---- u-boot-1.1.2/board/oxnas/ide-810.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/ide-810.c	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,892 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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>
-+
-+#define SATA_DMA_CHANNEL 0
-+
-+#define DMA_CTRL_STATUS      (0x0)
-+#define DMA_BASE_SRC_ADR     (0x4)
-+#define DMA_BASE_DST_ADR     (0x8)
-+#define DMA_BYTE_CNT         (0xC)
-+#define DMA_CURRENT_SRC_ADR  (0x10)
-+#define DMA_CURRENT_DST_ADR  (0x14)
-+#define DMA_CURRENT_BYTE_CNT (0x18)
-+#define DMA_INTR_ID          (0x1C)
-+#define DMA_INTR_CLEAR_REG   (DMA_CURRENT_SRC_ADR)
-+
-+#define DMA_CALC_REG_ADR(channel, register) ((volatile u32*)(DMA_BASE_PA + ((channel) << 5) + (register)))
-+
-+#define DMA_CTRL_STATUS_FAIR_SHARE_ARB            (1 << 0)
-+#define DMA_CTRL_STATUS_IN_PROGRESS               (1 << 1)
-+#define DMA_CTRL_STATUS_SRC_DREQ_MASK             (0x0000003C)
-+#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT            (2)
-+#define DMA_CTRL_STATUS_DEST_DREQ_MASK            (0x000003C0)
-+#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT           (6)
-+#define DMA_CTRL_STATUS_INTR                      (1 << 10)
-+#define DMA_CTRL_STATUS_NXT_FREE                  (1 << 11)
-+#define DMA_CTRL_STATUS_RESET                     (1 << 12)
-+#define DMA_CTRL_STATUS_DIR_MASK                  (0x00006000)
-+#define DMA_CTRL_STATUS_DIR_SHIFT                 (13)
-+#define DMA_CTRL_STATUS_SRC_ADR_MODE              (1 << 15)
-+#define DMA_CTRL_STATUS_DEST_ADR_MODE             (1 << 16)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_A           (1 << 17)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_B           (1 << 18)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_MASK            (0x00380000)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT           (19)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_MASK           (0x01C00000)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT          (22)
-+#define DMA_CTRL_STATUS_PAUSE                     (1 << 25)
-+#define DMA_CTRL_STATUS_INTERRUPT_ENABLE          (1 << 26)
-+#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED      (1 << 27)
-+#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
-+#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY       (1 << 29)
-+#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE         (1 << 30)
-+
-+#define DMA_BYTE_CNT_MASK        ((1 << 21) - 1)
-+#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
-+#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
-+
-+#define MAKE_FIELD(value, num_bits, bit_num) (((value) & ((1 << (num_bits)) - 1)) << (bit_num))
-+
-+typedef enum oxnas_dma_mode {
-+    OXNAS_DMA_MODE_FIXED,
-+    OXNAS_DMA_MODE_INC
-+} oxnas_dma_mode_t;
-+
-+typedef enum oxnas_dma_direction {
-+    OXNAS_DMA_TO_DEVICE,
-+    OXNAS_DMA_FROM_DEVICE
-+} oxnas_dma_direction_t;
-+
-+/* The available buses to which the DMA controller is attached */
-+typedef enum oxnas_dma_transfer_bus
-+{
-+    OXNAS_DMA_SIDE_A,
-+    OXNAS_DMA_SIDE_B
-+} oxnas_dma_transfer_bus_t;
-+
-+/* Direction of data flow between the DMA controller's pair of interfaces */
-+typedef enum oxnas_dma_transfer_direction
-+{
-+    OXNAS_DMA_A_TO_A,
-+    OXNAS_DMA_B_TO_A,
-+    OXNAS_DMA_A_TO_B,
-+    OXNAS_DMA_B_TO_B
-+} oxnas_dma_transfer_direction_t;
-+
-+/* The available data widths */
-+typedef enum oxnas_dma_transfer_width
-+{
-+    OXNAS_DMA_TRANSFER_WIDTH_8BITS,
-+    OXNAS_DMA_TRANSFER_WIDTH_16BITS,
-+    OXNAS_DMA_TRANSFER_WIDTH_32BITS
-+} oxnas_dma_transfer_width_t;
-+
-+/* The mode of the DMA transfer */
-+typedef enum oxnas_dma_transfer_mode
-+{
-+    OXNAS_DMA_TRANSFER_MODE_SINGLE,
-+    OXNAS_DMA_TRANSFER_MODE_BURST
-+} oxnas_dma_transfer_mode_t;
-+
-+/* The available transfer targets */
-+typedef enum oxnas_dma_dreq
-+{
-+    OXNAS_DMA_DREQ_SATA   = 0,
-+    OXNAS_DMA_DREQ_MEMORY = 15
-+} oxnas_dma_dreq_t;
-+
-+typedef struct oxnas_dma_device_settings {
-+    unsigned long address_;
-+    unsigned      fifo_size_;   // Chained transfers must take account of FIFO offset at end of previous transfer
-+    unsigned char dreq_;
-+    unsigned      read_eot_:1;
-+    unsigned      read_final_eot_:1;
-+    unsigned      write_eot_:1;
-+    unsigned      write_final_eot_:1;
-+    unsigned      bus_:1;
-+    unsigned      width_:2;
-+    unsigned      transfer_mode_:1;
-+    unsigned      address_mode_:1;
-+    unsigned      address_really_fixed_:1;
-+} oxnas_dma_device_settings_t;
-+
-+static const int MAX_NO_ERROR_LOOPS  = 100000;  /* 1 second in units of 10uS */
-+static const int MAX_DMA_XFER_LOOPS  = 300000;  /* 30 seconds in units of 100uS */
-+static const int MAX_DMA_ABORT_LOOPS = 10000;   /* 0.1 second in units of 10uS */
-+static const int MAX_SRC_READ_LOOPS  = 10000;   /* 0.1 second in units of 10uS */
-+static const int MAX_SRC_WRITE_LOOPS = 10000;   /* 0.1 second in units of 10uS */
-+static const int MAX_NOT_BUSY_LOOPS  = 10000;   /* 1 second in units of 100uS */
-+
-+/* The internal SATA drive on which we should attempt to find partitions */
-+static volatile u32* sata_regs_base[2] = 
-+{
-+    (volatile u32*)SATA_0_REGS_BASE,
-+    (volatile u32*)SATA_1_REGS_BASE,
-+    
-+};
-+static u32 wr_sata_orb1[2] = { 0, 0 };
-+static u32 wr_sata_orb2[2] = { 0, 0 };
-+static u32 wr_sata_orb3[2] = { 0, 0 };
-+static u32 wr_sata_orb4[2] = { 0, 0 };
-+
-+static oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
-+    .address_              = SATA_DATA_BASE_PA,
-+    .fifo_size_            = 16,
-+    .dreq_                 = OXNAS_DMA_DREQ_SATA,
-+    .read_eot_             = 0,
-+    .read_final_eot_       = 1,
-+    .write_eot_            = 0,
-+    .write_final_eot_      = 1,
-+    .bus_                  = OXNAS_DMA_SIDE_A,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_ram_dma_settings = {
-+    .address_              = 0,
-+    .fifo_size_            = 0,
-+    .dreq_                 = OXNAS_DMA_DREQ_MEMORY,
-+    .read_eot_             = 1,
-+    .read_final_eot_       = 1,
-+    .write_eot_            = 1,
-+    .write_final_eot_      = 1,
-+    .bus_                  = OXNAS_DMA_SIDE_B,
-+    .width_                = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+    .transfer_mode_        = OXNAS_DMA_TRANSFER_MODE_BURST,
-+    .address_mode_         = OXNAS_DMA_MODE_FIXED,
-+    .address_really_fixed_ = 1
-+};
-+
-+static void xfer_wr_shadow_to_orbs(int device)
-+{
-+    *(sata_regs_base[device] + SATA_ORB1_OFF) = wr_sata_orb1[device];
-+    *(sata_regs_base[device] + SATA_ORB2_OFF) = wr_sata_orb2[device];
-+    *(sata_regs_base[device] + SATA_ORB3_OFF) = wr_sata_orb3[device];
-+    *(sata_regs_base[device] + SATA_ORB4_OFF) = wr_sata_orb4[device];
-+}
-+
-+static inline void device_select(int device)
-+{
-+    /* master/slave has no meaning to SATA core */
-+}
-+
-+static int disk_present[CFG_IDE_MAXDEVICE];
-+
-+#include <ata.h>
-+
-+unsigned char oxnas_sata_inb(int device, int port)
-+{
-+    unsigned char val = 0;
-+
-+    /* Only permit accesses to disks found to be present during ide_preinit() */
-+    if (!disk_present[device]) {
-+        return ATA_STAT_FAULT;
-+    }
-+
-+    device_select(device);
-+
-+    switch (port) {
-+        case ATA_PORT_CTL:
-+            val = (*(sata_regs_base[device] + SATA_ORB4_OFF) & (0xFFUL << SATA_CTL_BIT)) >> SATA_CTL_BIT;
-+            break;
-+        case ATA_PORT_FEATURE:
-+            val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_FEATURE_BIT)) >> SATA_FEATURE_BIT;
-+            break;
-+        case ATA_PORT_NSECT:
-+            val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_NSECT_BIT)) >> SATA_NSECT_BIT;
-+            break;
-+        case ATA_PORT_LBAL:
-+            val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAL_BIT)) >> SATA_LBAL_BIT;
-+            break;
-+        case ATA_PORT_LBAM:
-+            val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAM_BIT)) >> SATA_LBAM_BIT;
-+            break;
-+        case ATA_PORT_LBAH:
-+            val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAH_BIT)) >> SATA_LBAH_BIT;
-+            break;
-+        case ATA_PORT_DEVICE:
-+            val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_HOB_LBAH_BIT)) >> SATA_HOB_LBAH_BIT;
-+            val |= (*(sata_regs_base[device] + SATA_ORB1_OFF) & (0xFFUL << SATA_DEVICE_BIT)) >> SATA_DEVICE_BIT;
-+            break;
-+        case ATA_PORT_COMMAND:
-+            val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_COMMAND_BIT)) >> SATA_COMMAND_BIT;
-+            val |= ATA_STAT_DRQ ;
-+            break;
-+        default:
-+            printf("ide_inb() Unknown port = %d\n", port);
-+            break;
-+    }
-+
-+//    printf("inb: %d:%01x => %02x\n", device, port, val);
-+
-+    return val;
-+}
-+
-+/**
-+ * Possible that ATA status will not become no-error, so must have timeout
-+ * @returns An int which is zero on error
-+ */
-+static inline int wait_no_error(int device)
-+{
-+    int status = 0;
-+
-+	/* Check for ATA core error */
-+	if (*(sata_regs_base[device] + SATA_INT_STATUS_OFF) & (1 << SATA_INT_STATUS_ERROR_BIT)) {
-+		printf("wait_no_error() SATA core flagged error\n");
-+	} else {
-+		int loops = MAX_NO_ERROR_LOOPS;
-+		do {
-+			/* Check for ATA device error */
-+			if (!(oxnas_sata_inb(device, ATA_PORT_COMMAND) & (1 << ATA_STATUS_ERR_BIT))) {
-+				status = 1;
-+				break;
-+			}
-+			udelay(10);
-+		} while (--loops);
-+
-+		if (!loops) {
-+			printf("wait_no_error() Timed out of wait for SATA no-error condition\n");
-+		}
-+	}
-+
-+    return status;
-+}
-+
-+/**
-+ * Expect SATA command to always finish, perhaps with error
-+ * @returns An int which is zero on error
-+ */
-+static inline int wait_sata_command_not_busy(int device)
-+{
-+    /* Wait for data to be available */
-+    int status = 0;
-+    int loops = MAX_NOT_BUSY_LOOPS;
-+    do {
-+        if (!(*(sata_regs_base[device] + SATA_COMMAND_OFF) & (1 << SATA_CMD_BUSY_BIT) )) {
-+            status = 1;
-+            break;
-+        }
-+        udelay(100);
-+    } while (--loops);
-+
-+    if (!loops) {
-+        printf("wait_sata_command_not_busy() Timed out of wait for SATA command to finish\n");
-+    }
-+
-+    return status;
-+}
-+
-+void oxnas_sata_outb(int device, int port, unsigned char val)
-+{
-+    typedef enum send_method {
-+        SEND_NONE,
-+        SEND_SIMPLE,
-+        SEND_CMD,
-+        SEND_CTL,
-+    } send_method_t;
-+
-+    /* Only permit accesses to disks found to be present during ide_preinit() */
-+    if (!disk_present[device]) {
-+        return;
-+    }
-+    
-+//    printf("outb: %d:%01x <= %02x\n", device, port, val);
-+
-+    device_select(device);
-+
-+    send_method_t send_regs = SEND_NONE;
-+    switch (port) {
-+        case ATA_PORT_CTL:
-+            wr_sata_orb4[device] &= ~(0xFFUL << SATA_CTL_BIT);
-+            wr_sata_orb4[device] |= (val << SATA_CTL_BIT);
-+            send_regs = SEND_CTL;
-+            break;
-+        case ATA_PORT_FEATURE:
-+            wr_sata_orb2[device] &= ~(0xFFUL << SATA_FEATURE_BIT);
-+            wr_sata_orb2[device] |= (val << SATA_FEATURE_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_NSECT:
-+            wr_sata_orb2[device] &= ~(0xFFUL << SATA_NSECT_BIT);
-+            wr_sata_orb2[device] |= (val << SATA_NSECT_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_LBAL:
-+            wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAL_BIT);
-+            wr_sata_orb3[device] |= (val << SATA_LBAL_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_LBAM:
-+            wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAM_BIT);
-+            wr_sata_orb3[device] |= (val << SATA_LBAM_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_LBAH:
-+            wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAH_BIT);
-+            wr_sata_orb3[device] |= (val << SATA_LBAH_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_DEVICE:
-+            wr_sata_orb1[device] &= ~(0xFFUL << SATA_DEVICE_BIT);
-+            wr_sata_orb1[device] |= ((val & 0xf0) << SATA_DEVICE_BIT);
-+            wr_sata_orb3[device] &= ~(0xFFUL << SATA_HOB_LBAH_BIT);
-+            wr_sata_orb3[device] |= ((val & 0x0f) << SATA_HOB_LBAH_BIT);
-+            send_regs = SEND_SIMPLE;
-+            break;
-+        case ATA_PORT_COMMAND:
-+            wr_sata_orb2[device] &= ~(0xFFUL << SATA_COMMAND_BIT);
-+            wr_sata_orb2[device] |= (val << SATA_COMMAND_BIT);
-+            send_regs = SEND_CMD;
-+            break;
-+        default:
-+            printf("ide_outb() Unknown port = %d\n", port);
-+    }
-+
-+    u32 command;
-+    switch (send_regs) {
-+        case SEND_CMD:
-+            wait_sata_command_not_busy(device);
-+            command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
-+            command &= ~SATA_OPCODE_MASK;
-+            command |= SATA_CMD_WRITE_TO_ORB_REGS;
-+            xfer_wr_shadow_to_orbs(device);
-+            wait_sata_command_not_busy(device);
-+            *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
-+            if (!wait_no_error(device)) {
-+                printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
-+            }
-+            break;
-+        case SEND_CTL:
-+            wait_sata_command_not_busy(device);
-+            command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
-+            command &= ~SATA_OPCODE_MASK;
-+            command |= SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND;
-+            xfer_wr_shadow_to_orbs(device);
-+            wait_sata_command_not_busy(device);
-+            *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
-+            if (!wait_no_error(device)) {
-+                printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
-+            }
-+            break;
-+        default:
-+            break;
-+    }
-+}
-+
-+static u32 encode_start(u32 ctrl_status)
-+{
-+    return ctrl_status & ~DMA_CTRL_STATUS_PAUSE;
-+}
-+
-+static void dma_start(void)
-+{
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) =
-+        encode_start(*(DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)));
-+}
-+
-+static unsigned long encode_control_status(
-+    oxnas_dma_device_settings_t* src_settings,
-+    oxnas_dma_device_settings_t* dst_settings)
-+{
-+    unsigned long ctrl_status;
-+    oxnas_dma_transfer_direction_t direction;
-+
-+    ctrl_status  = DMA_CTRL_STATUS_PAUSE;                                       // Paused
-+    ctrl_status |= DMA_CTRL_STATUS_FAIR_SHARE_ARB;                              // High priority
-+    ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT);     // Dreq
-+    ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT);    // Dreq
-+    ctrl_status &= ~DMA_CTRL_STATUS_RESET;                                      // !RESET
-+
-+    // Use new interrupt clearing register
-+    ctrl_status |= DMA_CTRL_STATUS_INTR_CLEAR_ENABLE;
-+
-+    // Setup the transfer direction and burst/single mode for the two DMA busses
-+    if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+        // Set the burst/single mode for bus A based on src device's settings
-+        if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+            ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+        }
-+
-+        if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+            direction = OXNAS_DMA_A_TO_A;
-+        } else {
-+            direction = OXNAS_DMA_A_TO_B;
-+
-+            // Set the burst/single mode for bus B based on dst device's settings
-+            if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+                ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+            } else {
-+                ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+            }
-+        }
-+    } else {
-+        // Set the burst/single mode for bus B based on src device's settings
-+        if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+            ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+        }
-+
-+        if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+            direction = OXNAS_DMA_B_TO_A;
-+            
-+            // Set the burst/single mode for bus A based on dst device's settings
-+            if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+                ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+            } else {
-+                ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+            }
-+        } else {
-+            direction = OXNAS_DMA_B_TO_B;
-+        }
-+    }
-+    ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
-+
-+    // Setup source address mode fixed or increment
-+    if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+        // Fixed address
-+        ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
-+        
-+        // Set up whether fixed address is _really_ fixed
-+        if (src_settings->address_really_fixed_) {
-+            ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+        }        
-+    } else {
-+        // Incrementing address
-+        ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
-+        ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+    }
-+
-+    // Setup destination address mode fixed or increment
-+    if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+        // Fixed address
-+        ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
-+        
-+        // Set up whether fixed address is _really_ fixed
-+        if (dst_settings->address_really_fixed_) {
-+            ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+        } else {
-+            ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+        }
-+    } else {
-+        // Incrementing address
-+        ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
-+        ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+    }
-+
-+    // Set up the width of the transfers on the DMA buses
-+    ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
-+    ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
-+
-+    // Setup the priority arbitration scheme
-+    ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY;    // !Starve low priority
-+
-+    return ctrl_status;
-+}
-+
-+static u32 encode_final_eot(
-+    oxnas_dma_device_settings_t* src_settings,
-+    oxnas_dma_device_settings_t* dst_settings,
-+    unsigned long length)
-+{
-+    // Write the length, with EOT configuration for a final transfer
-+    unsigned long encoded = length;
-+    if (dst_settings->write_final_eot_) {
-+        encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
-+    } else {
-+        encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
-+    }
-+    if (src_settings->read_final_eot_) {
-+        encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
-+    } else {
-+        encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
-+    }
-+    return encoded;
-+}
-+
-+static void dma_start_write(ulong* buffer, int num_bytes)
-+{
-+    // Assemble complete memory settings
-+    oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
-+    mem_settings.address_ = (unsigned long)buffer;
-+    mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
-+
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)  = encode_control_status(&mem_settings, &oxnas_sata_dma_settings);
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = mem_settings.address_;
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = oxnas_sata_dma_settings.address_;
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT)     = encode_final_eot(&mem_settings, &oxnas_sata_dma_settings, num_bytes);
-+
-+    dma_start();
-+}
-+
-+static void dma_start_read(ulong* buffer, int num_bytes)
-+{
-+    // Assemble complete memory settings
-+    oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
-+    mem_settings.address_ = (unsigned long)buffer;
-+    mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
-+
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)  = encode_control_status(&oxnas_sata_dma_settings, &mem_settings);
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = oxnas_sata_dma_settings.address_;
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = mem_settings.address_;
-+    *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT)     = encode_final_eot(&oxnas_sata_dma_settings, &mem_settings, num_bytes);
-+
-+    dma_start();
-+}
-+
-+static inline int dma_busy(void)
-+{
-+    return (*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS;
-+}
-+
-+static int wait_dma_not_busy(int device)
-+{
-+    unsigned int cleanup_required = 0;
-+
-+	/* Poll for DMA completion */
-+	int loops = MAX_DMA_XFER_LOOPS;
-+	do {
-+		if (!dma_busy()) {
-+			break;
-+		}
-+		udelay(100);
-+	} while (--loops);
-+
-+	if (!loops) {
-+		printf("wait_dma_not_busy() Timed out of wait for DMA not busy\n");
-+		cleanup_required = 1;
-+	}
-+
-+    if (cleanup_required) {
-+        /* Abort DMA to make sure it has finished. */
-+        unsigned long ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
-+        ctrl_status |= DMA_CTRL_STATUS_RESET;
-+        *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
-+
-+        // Wait for the channel to become idle - should be quick as should
-+        // finish after the next AHB single or burst transfer
-+        loops = MAX_DMA_ABORT_LOOPS;
-+        do {
-+            if (!(*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) & DMA_CTRL_STATUS_IN_PROGRESS)) {
-+                break;
-+            }
-+            udelay(10);
-+        } while (--loops);
-+
-+        if (!loops) {
-+            printf("wait_dma_not_busy() Timed out of wait for DMA channel abort\n");
-+        } else {
-+			/* Successfully cleanup the DMA channel */
-+			cleanup_required = 0;
-+		}
-+
-+        // Deassert reset for the channel
-+        ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
-+        ctrl_status &= ~DMA_CTRL_STATUS_RESET;
-+        *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
-+    }
-+
-+	return !cleanup_required;
-+}
-+
-+/**
-+ * Possible that ATA status will not become not-busy, so must have timeout
-+ */
-+static unsigned int wait_not_busy(int device, unsigned long timeout_secs)
-+{
-+    int busy = 1;
-+    unsigned long loops = (timeout_secs * 1000) / 50;
-+    do {
-+        // Test the ATA status register BUSY flag
-+        if (!((*(sata_regs_base[device] + SATA_ORB2_OFF) >> SATA_COMMAND_BIT) & (1UL << ATA_STATUS_BSY_BIT))) {
-+            /* Not busy, so stop polling */
-+            busy = 0;
-+            break;
-+        }
-+
-+        // Wait for 50mS before sampling ATA status register again
-+        udelay(50000);
-+    } while (--loops);
-+
-+    return busy;
-+}
-+
-+void oxnas_sata_output_data(int device, ulong *sect_buf, int words)
-+{
-+    /* Only permit accesses to disks found to be present during ide_preinit() */
-+    if (!disk_present[device]) {
-+        return;
-+    }
-+
-+    /* Select the required internal SATA drive */
-+    device_select(device);
-+
-+    /* Start the DMA channel sending data from the passed buffer to the SATA core */
-+    dma_start_write(sect_buf, words << 2);
-+
-+	/* Don't know why we need this delay, but without it the wait for DMA not 
-+	   busy times soemtimes out, e.g. when saving environment to second disk */
-+	udelay(1000);
-+
-+    /* Wait for DMA to finish */
-+    if (!wait_dma_not_busy(device)) {
-+		printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
-+	}
-+
-+	/* Sata core should finish after DMA */
-+	if (wait_not_busy(device, 30)) {
-+		printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+	}
-+	if (!wait_no_error(device)) {
-+		printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
-+	}
-+}
-+
-+void oxnas_sata_input_data(int device, ulong *sect_buf, int words)
-+{
-+    /* Only permit accesses to disks found to be present during ide_preinit() */
-+    if (!disk_present[device]) {
-+        return;
-+    }
-+
-+    /* Select the required internal SATA drive */
-+    device_select(device);
-+
-+    /* Start the DMA channel receiving data from the SATA core into the passed buffer */
-+    dma_start_read(sect_buf, words << 2);
-+
-+	/* Sata core should finish before DMA */
-+	if (wait_not_busy(device, 30)) {
-+		printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+	}
-+	if (!wait_no_error(device)) {
-+		printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
-+	}
-+
-+    /* Wait for DMA to finish */
-+    if (!wait_dma_not_busy(device)) {
-+		printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
-+	}
-+}
-+
-+static u32 scr_read(int device, unsigned int sc_reg)
-+{
-+    /* Setup adr of required register. std regs start eight into async region */    
-+    *(sata_regs_base[device] + SATA_LINK_RD_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
-+
-+    /* Wait for data to be available */
-+    int loops = MAX_SRC_READ_LOOPS;
-+    do {
-+        if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
-+            break;
-+        }
-+        udelay(10);
-+    } while (--loops);
-+
-+    if (!loops) {
-+        printf("scr_read() Timed out of wait for read completion\n");
-+    }
-+
-+    /* Read the data from the async register */
-+    return *(sata_regs_base[device] + SATA_LINK_DATA);
-+}
-+
-+static void scr_write(int device, unsigned int sc_reg, u32 val)
-+{
-+    /* Setup the data for the write */
-+    *(sata_regs_base[device] + SATA_LINK_DATA) = val;
-+
-+    /* Setup adr of required register. std regs start eight into async region */    
-+    *(sata_regs_base[device] + SATA_LINK_WR_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
-+
-+    /* Wait for data to be written */
-+    int loops = MAX_SRC_WRITE_LOOPS;
-+    do {
-+        if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
-+            break;
-+        }
-+        udelay(10);
-+    } while (--loops);
-+
-+    if (!loops) {
-+        printf("scr_write() Timed out of wait for write completion\n");
-+    }
-+}
-+
-+#define PHY_LOOP_COUNT  25  /* Wait for upto 5 seconds for PHY to be found */
-+static int phy_reset(int device)
-+{
-+#ifdef FPGA
-+    /* The FPGA thinks it can do 3G when infact only 1.5G is possible, so limit
-+    it to Gen-1 SATA (1.5G) */ 
-+    scr_write(device, SATA_SCR_CONTROL, 0x311);  /* Issue phy wake & core reset */
-+    scr_read(device, SATA_SCR_STATUS);           /* Dummy read; flush */
-+    udelay(1000);
-+    scr_write(device, SATA_SCR_CONTROL, 0x310);  /* Issue phy wake & clear core reset */
-+#else
-+    scr_write(device, SATA_SCR_CONTROL, 0x301);  /* Issue phy wake & core reset */
-+    scr_read(device, SATA_SCR_STATUS);           /* Dummy read; flush */
-+    udelay(1000);
-+    scr_write(device, SATA_SCR_CONTROL, 0x300);  /* Issue phy wake & clear core reset */
-+#endif
-+    /* Wait for upto 5 seconds for PHY to become ready */
-+    int phy_status = 0;
-+    int loops = 0;
-+    do {
-+        udelay(200000);
-+        if ((scr_read(device, SATA_SCR_STATUS) & 0xf) != 1) {
-+            phy_status = 1;
-+            break;
-+        }
-+        printf("No SATA PHY found\n");
-+    } while (++loops < PHY_LOOP_COUNT);
-+
-+    if (phy_status) {
-+        udelay(500000); /* wait half a second */
-+    }
-+    return phy_status;
-+}
-+
-+#define FIS_LOOP_COUNT  25  /* Wait for upto 5 seconds for FIS to be received */
-+static int wait_FIS(int device)
-+{
-+    int status = 0;
-+    int loops = 0;
-+
-+    do {
-+        udelay(200000);
-+        if 	(oxnas_sata_inb(device, ATA_PORT_NSECT) > 0) {
-+            status = 1;
-+            break;
-+        }
-+    } while (++loops < FIS_LOOP_COUNT);
-+
-+    return status;
-+}
-+
-+int ide_preinit(void)
-+{
-+    int num_disks_found = 0;
-+
-+    /* Initialise records of which disks are present to all present */
-+    int i;
-+    for (i=0; i < CFG_IDE_MAXDEVICE; i++) {
-+        disk_present[i] = 1;
-+    }
-+
-+//udelay(1000000);
-+    /* Enable clocks to SATA and DMA cores */
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_SATA_BIT);
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_DMA_BIT);
-+    
-+    /* Block reset SATA and DMA cores */
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
-+                                              (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+                                              (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+                                              (1UL << SYS_CTRL_RSTEN_DMA_BIT);
-+    udelay(50);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT);
-+    udelay(50);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+                                              (1UL << SYS_CTRL_RSTEN_SATA_BIT);
-+    udelay(50);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_DMA_BIT);
-+    udelay(50);
-+//udelay(1000000);
-+
-+    /* disable and clear core interrupts */
-+    *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
-+    *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_CLR_OFF) = ~0UL;
-+
-+    int device;
-+    for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
-+        int found = 0;
-+        int retries = 1;
-+
-+        /* Disable SATA interrupts */
-+        *(sata_regs_base[device] + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
-+
-+        /* Clear any pending SATA interrupts */
-+        *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
-+
-+        do {
-+            /* clear sector count register for FIS detection */
-+            oxnas_sata_outb(device, ATA_PORT_NSECT, 0);
-+    
-+            /* Get the PHY working */
-+            if (!phy_reset(device)) {
-+                printf("SATA PHY not ready for device %d\n", device);
-+                break;
-+            }
-+
-+            if (!wait_FIS(device)) {
-+                printf("No FIS received from device %d\n", device);
-+            } else {
-+                if ((scr_read(device, SATA_SCR_STATUS) & 0xf) == 0x3) {
-+                    if (wait_not_busy(device, 30)) {
-+                        printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+                    } else {
-+                        ++num_disks_found;
-+                        found = 1;
-+                    }
-+                } else {
-+                    printf("No SATA device %d found, PHY status = 0x%08x\n",
-+                            device, scr_read(device, SATA_SCR_STATUS));
-+                }
-+                break;
-+            }
-+        } while (retries--) ;
-+
-+        /* Record whether disk is present, so won't attempt to access it later */
-+        disk_present[device] = found;
-+    }
-+
-+    /* post disk detection clean-up */
-+    for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
-+        if ( disk_present[device] ) {
-+            /* set as ata-5 (28-bit) */
-+            *(sata_regs_base[device] + SATA_DRIVE_CONTROL_OFF) = 0UL;
-+            
-+            /* clear phy/link errors */
-+            scr_write(device, SATA_SCR_ERROR, ~0);
-+            
-+            /* clear host errors */
-+            *(sata_regs_base[device] + SATA_CONTROL_OFF) |= SATA_SCTL_CLR_ERR;
-+            
-+            /* clear interrupt register as this clears the error bit in the IDE 
-+            status register */
-+            *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
-+        }
-+    }    
-+    
-+
-+    return !num_disks_found;
-+}
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/Makefile u-boot-1.1.2-oxe810/board/oxnas/Makefile
---- u-boot-1.1.2/board/oxnas/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/Makefile	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,51 @@
-+#
-+# (C) Copyright 2000-2004
-+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
-+#
-+# (C) Copyright 2004
-+# ARM Ltd.
-+# Philippe Robin, <philippe.robin at arm.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 $(TOPDIR)/config.mk
-+
-+LIB	= lib$(BOARD).a
-+
-+OBJS	:= oxnas.o eth.o ide-$(NAS_VERSION).o
-+SOBJS	:= platform-$(NAS_VERSION).o
-+
-+$(LIB):	$(OBJS) $(SOBJS)
-+	$(AR) crv $@ $^
-+
-+clean:
-+	rm -f $(SOBJS) $(OBJS)
-+
-+distclean:	clean
-+	rm -f $(LIB) core *.bak .depend
-+
-+#########################################################################
-+
-+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
-+		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-+
-+-include .depend
-+
-+#########################################################################
-diff -Nurd u-boot-1.1.2/board/oxnas/oxnas.c u-boot-1.1.2-oxe810/board/oxnas/oxnas.c
---- u-boot-1.1.2/board/oxnas/oxnas.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/oxnas.c	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,280 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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>
-+
-+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
-+void show_boot_progress(int progress)
-+{
-+    printf("Boot reached stage %d\n", progress);
-+}
-+#endif
-+
-+static inline void delay(unsigned long loops)
-+{
-+    __asm__ volatile ("1:\n"
-+        "subs %0, %1, #1\n"
-+        "bne 1b":"=r" (loops):"0" (loops));
-+}
-+
-+/*
-+ * Miscellaneous platform dependent initialisations
-+ */
-+
-+/** Expected Intel 28F320B3T CFI info */
-+//    mfr_id:			MANUFACTURER_INTEL, -> 0x0089
-+//    dev_id:			I28F320B3T,         -> 0x8896
-+//    name:			"Intel 28F320B3T",
-+//    DevSize:		SIZE_4MiB,              -> 22
-+//    CmdSet:			P_ID_INTEL_STD,     -> 0x0003
-+//    NumEraseRegions:	2,
-+//    regions: {                            -> #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
-+//        ERASEINFO(0x10000, 63),
-+//        ERASEINFO(0x02000, 8),
-+//    }
-+
-+#define FLASH_WORD_SIZE unsigned short
-+
-+int board_init(void)
-+{
-+    DECLARE_GLOBAL_DATA_PTR;
-+
-+    gd->bd->bi_arch_number = MACH_TYPE_OXNAS;
-+    gd->bd->bi_boot_params = PHYS_SDRAM_1_PA + 0x100;
-+    gd->flags = 0;
-+
-+    icache_enable();
-+
-+    /* Block reset Static core */
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
-+
-+    /* Enable clock to Static core */
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_STATIC_BIT);
-+
-+#ifdef CONFIG_OXNAS_ENABLE_PCI
-+    /* Block reset PCI core */
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+
-+    /* Enable clock to PCI core */
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+#endif // CONFIG_OXNAS_ENABLE_PCI
-+
-+#ifdef CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+    /* Assert manual static bus PCI arbitration request */
-+    *(volatile u32*)SYS_CTRL_PCI_CTRL1 |= (1UL << SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT);
-+#endif // CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+
-+#ifdef CONFIG_OXNAS_FEEDBACK_PCI_CLKS
-+    /* Set PCI feedback clk GPIO pin as an output */
-+    *(volatile u32*)GPIO_1_SET_OE |= 0x800;
-+
-+    /* Enable PCI feedback clk onto GPIO pin */
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x00000800;
-+#endif // CONFIG_OXNAS_FEEDBACK_PCI_CLKS
-+
-+#ifndef CFG_NO_FLASH
-+    /* Enable static bus onto GPIOs, only CS0 as CS1 conflicts with UART2 */
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x002FF000;
-+
-+    /* Setup the static bus CS0 to access FLASH */
-+    *(volatile u32*)STATIC_CONTROL_BANK0 = STATIC_BUS_FLASH_CONFIG;
-+#endif // !CFG_NO_FLASH
-+
-+    /* Set 33MHz PCI clock */
-+    *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR = 5;
-+    /* Enable full speed RPS clock */
-+    *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR &= ~(1UL << SYS_CTRL_CKCTRL_SLOW_BIT);
-+
-+#if (USE_EXTERNAL_UART == 0)
-+#ifdef CONFIG_OXNAS_UART1
-+    /* Block reset UART1 */
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+
-+    /* Setup pin mux'ing for first internal UART */
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x80000000;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x80000000; // Route UART1 SOUT onto external pins
-+
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1  &= ~0x00000001;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |=  0x00000001; // Route UART1 SIN onto external pins
-+
-+    *(volatile u32*)GPIO_1_SET_OE |= 0x80000000;                // Make UART1 SOUT an o/p
-+    *(volatile u32*)GPIO_2_CLR_OE |= 0x00000001;                // Make UART1 SIN an i/p
-+#endif // CONFIG_OXNAS_UART1
-+
-+#ifdef CONFIG_OXNAS_UART2
-+    // Block reset UART2
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+
-+    /* Setup pin mux'ing for second internal UART */
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x00500000;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x00500000; // Route UART2 SOUT and SIN onto external pins
-+
-+    *(volatile u32*)GPIO_1_SET_OE |= 0x00100000;                // Make UART2 SOUT an o/p
-+    *(volatile u32*)GPIO_1_CLR_OE |= 0x00400000;                // Make UART2 SIN an i/p
-+#endif // CONFIG_OXNAS_UART2
-+
-+#ifdef CONFIG_OXNAS_UART3
-+    // Block reset UART3
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+
-+    // Route UART3 SIN/SOUT onto external pin
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  &= ~0x000000C0;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |=  0x000000C0;
-+
-+    // Setup GPIO line directions for UART3 SIN/SOUT
-+    *(volatile u32*)GPIO_1_SET_OE   |= 0x00000080;
-+    *(volatile u32*)GPIO_1_CLR_OE |= 0x00000040;
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_OXNAS_UART4
-+    // Block reset UART4
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+
-+    // Enable UART4 to override PCI functions onto GPIOs
-+    *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
-+#endif // CONFIG_OXNAS_UART4
-+#endif // !USE_EXTERNAL_UART
-+
-+    return 0;
-+}
-+
-+int board_late_init()
-+{
-+    return 0;
-+}
-+
-+int misc_init_r(void)
-+{
-+    return 0;
-+}
-+
-+int dram_init(void)
-+{
-+#ifdef PROBE_MEM_SIZE
-+	/* Determine the amount of SDRAM the DDR controller is configured for */
-+	volatile unsigned long * const ddr_config_reg_adr = (volatile unsigned long *)(0x45800000);
-+	static const int DDR_SIZE_BIT = 17;
-+	static const int DDR_SIZE_NUM_BITS = 4;
-+	static const unsigned long DDR_SIZE_MASK = (((1UL << DDR_SIZE_NUM_BITS) - 1) << DDR_SIZE_BIT);
-+
-+	unsigned long ddr_config_reg = *ddr_config_reg_adr;
-+	int ddr_size_pow2 = (ddr_config_reg & DDR_SIZE_MASK) >> DDR_SIZE_BIT;
-+
-+    DECLARE_GLOBAL_DATA_PTR;
-+
-+    gd->bd->bi_dram[0].size  = (1 << ddr_size_pow2) * 1024 * 1024;
-+
-+	if ((gd->bd->bi_dram[0].size >> 20) == 256) {
-+		/* Do we really have 256M, or are we working around the DDR controller's
-+		 * problem with 128M size? */
-+		volatile unsigned long * const PROBE_ADR_1 = (volatile unsigned long * const)PHYS_SDRAM_1_PA;
-+		volatile unsigned long * const PROBE_ADR_2 = (volatile unsigned long * const)(PHYS_SDRAM_1_PA + (128*1024*1024));
-+		static const unsigned long PROBE_VAL_1 = 0xdeadbeef;
-+		static const unsigned long PROBE_VAL_2 = 0x12345678;
-+
-+		*PROBE_ADR_1 = PROBE_VAL_1;
-+		*PROBE_ADR_2 = PROBE_VAL_2;
-+		if (*PROBE_ADR_1 != PROBE_VAL_1) {
-+			gd->bd->bi_dram[0].size  = 128*1024*1024;
-+		}
-+	}
-+#else // PROBE_MEM_SIZE
-+    gd->bd->bi_dram[0].size = MEM_SIZE;
-+#endif // PROBE_MEM_SIZE
-+
-+    gd->bd->bi_dram[0].start = PHYS_SDRAM_1_PA;
-+
-+	gd->bd->bi_sramstart = CFG_SRAM_BASE;
-+	gd->bd->bi_sramsize = CFG_SRAM_SIZE;
-+
-+    return 0;
-+}
-+
-+int reset_cpu(void)
-+{
-+    printf("Resetting Oxsemi NAS...");
-+
-+    // Assert reset to cores as per power on defaults
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL =
-+        (1UL << SYS_CTRL_RSTEN_COPRO_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_USBHS_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
-+        (1UL << SYS_CTRL_RSTEN_MAC_BIT)      |
-+        (1UL << SYS_CTRL_RSTEN_PCI_BIT)      |
-+        (1UL << SYS_CTRL_RSTEN_DMA_BIT)      |
-+        (1UL << SYS_CTRL_RSTEN_DPE_BIT)      |
-+        (1UL << SYS_CTRL_RSTEN_SATA_BIT)     |
-+        (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+        (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+        (1UL << SYS_CTRL_RSTEN_STATIC_BIT)   |
-+        (1UL << SYS_CTRL_RSTEN_UART1_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_UART2_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_MISC_BIT)     |
-+        (1UL << SYS_CTRL_RSTEN_I2S_BIT)      |
-+        (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT)  |
-+        (1UL << SYS_CTRL_RSTEN_UART3_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_UART4_BIT)    |
-+        (1UL << SYS_CTRL_RSTEN_SGDMA_BIT);
-+
-+    // Release reset to cores as per power on defaults
-+    *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_GPIO_BIT);
-+
-+    // Disable clocks to cores as per power-on defaults
-+    *(volatile u32*)SYS_CTRL_CKEN_CLR_CTRL =
-+        (1UL << SYS_CTRL_CKEN_COPRO_BIT) |
-+        (1UL << SYS_CTRL_CKEN_DMA_BIT)   |
-+        (1UL << SYS_CTRL_CKEN_DPE_BIT)   |
-+        (1UL << SYS_CTRL_CKEN_SATA_BIT)  |
-+        (1UL << SYS_CTRL_CKEN_I2S_BIT)   |
-+        (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
-+        (1UL << SYS_CTRL_CKEN_MAC_BIT)   |
-+        (1UL << SYS_CTRL_CKEN_STATIC_BIT);
-+
-+    // Enable clocks to cores as per power-on defaults
-+    *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+
-+    // Set sys-control pin mux'ing as per power-on defaults
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 = 0x800UL;
-+    *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 = 0x0UL;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0  = 0x0UL;
-+    *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1  = 0x0UL;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 = 0x0UL;
-+    *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 = 0x0UL;
-+
-+    // No need to save any state, as the ROM loader can determine whether reset
-+    // is due to power cycling or programatic action, just hit the (self-
-+    // clearing) CPU reset bit of the block reset register
-+    *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL =  (1UL << SYS_CTRL_RSTEN_ARM_BIT);
-+
-+	return 0;
-+}
-diff -Nurd u-boot-1.1.2/board/oxnas/platform-800.S u-boot-1.1.2-oxe810/board/oxnas/platform-800.S
---- u-boot-1.1.2/board/oxnas/platform-800.S	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/platform-800.S	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,254 @@
-+/*
-+ * Board specific setup info
-+ *
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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>
-+
-+/* use estimate of processor speed to calculate number of cycles delay */
-+/* delay count is nominal (PLL200 frequency x delay time) / loop count 
-+ * expressing 200us as 200/1000000 and re-arranging gives the expression below
-+ */
-+ 
-+#define DELAY_200US   ((NOMINAL_ARMCLK / (5 * 1000000)) * 200) 
-+/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
-+#define DELAY_1S   ((DELAY_200US) * 5000)
-+#define DELAY_8       8
-+#define DELAY_200     200
-+
-+.globl platformsetup
-+platformsetup:
-+/* register allocations
-+ * r0 - delay counter and scratch
-+ * r1 - address register
-+ * r2 - data register
-+ * r3 - index to table pointer
-+ * r4 - iteration counter.
-+ * 
-+ * r5 - hold return address.
-+ * lr - (R14) link register
-+ * pc - (R15) program counter.
-+ */
-+
-+#ifdef INITIALISE_SDRAM
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+	adrl r0, platformsetup		/* Relative location of function start.*/
-+	ldr  r1, _platformsetup
-+	cmp  r0, r1
-+	moveq pc, lr
-+#else
-+	mov pc, lr
-+#endif
-+
-+	/* Establish a working setup for the SDRAM */
-+	mov r6, lr
-+
-+#ifdef OXNAS_OVERCLOCK
-+	/* Delay so the broken JTAG can get control */
-+	ldr r0, =DELAY_1S
-+	bl delay
-+
-+	/* Configure the PLL to run faster */
-+	ldr r1, =SYS_CTRL_PLLSYS_CTRL
-+	ldr r2, =SYS_CTRL_PLLSYS_KEY_CTRL
-+
-+	/* 0xBEADFACE -> PLL_KEY */
-+	/* Bypass PLL */
-+	ldr r3, [r1]
-+	ldr r5, =0x20000
-+	orr r3, r3, r5
-+	ldr r4, =0xbeadface
-+	str r4, [r2]
-+	str r3, [r1]
-+
-+	/* 0xBEADFACE -> PLL_KEY */
-+	/* Set m,p and s for PLL at 400MHz */
-+	ldr r5, =0xffff0000
-+	and r3, r3, r5
-+	ldr r5, =OXNAS_OVERCLOCK
-+	orr r3, r3, r5
-+	str r4, [r2]
-+	str r3, [r1]
-+
-+	/* Wait at least 300uS */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+	ldr r0, =DELAY_200US
-+	bl delay
-+
-+	/* 0xBEADFACE -> PLL_KEY */
-+	/* Disable PLL bypass */
-+	ldr r5, =0xfffdffff
-+	and r3, r3, r5
-+	str r4, [r2]
-+	str r3, [r1]
-+#endif // OXNAS_OVERCLOCK
-+
-+	/* Assert reset to the DDR core */
-+	ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+	ldr r1, =1
-+	ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+	mov r1, r1, LSL r2
-+	str r1, [r0]
-+
-+	/* Deassert reset to the DDR core */
-+	ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+	str r1, [r0]
-+
-+	/* Turn on the DDR core clock */
-+	ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+	ldr r1, =1
-+	ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+	mov r1, r1, LSL r2
-+	str r1, [r0]
-+
-+	/* Start using the initialisation value list */
-+	adrl r3, init_table
-+
-+	/* Copy next 6 entries from DDR init table*/
-+	ldr r4, =6
-+loop0:
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loop0
-+
-+	/* Delay for 200uS while DRAM controller stabilises. */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+
-+#if !TEST_BRD
-+	/* Copy next entry */
-+	ldr r4, =1
-+loopx:	
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loopx
-+
-+	/* Delay for 200uS while DRAM controller stabilises. */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+#endif // TEST_BRD
-+
-+	/* Copy next entry */
-+	ldr r4, =1
-+loop1:	
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loop1
-+
-+	/* Delay for 200uS while DRAM controller stabilises. */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+
-+	/* Copy next entry */
-+	ldr r4, =1
-+loop2:	
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loop2
-+
-+	/* Delay for 200uS while DRAM controller stabilises. */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+
-+	/* Copy next entry */
-+	ldr r4, =1
-+loop3:	
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loop3
-+
-+	/* Delay for 200uS while DRAM controller stabilises. */
-+	ldr r0, =DELAY_200US
-+	bl delay
-+
-+	/* Copy next 5 entries */
-+	ldr r4, =5
-+loop4:	
-+	ldmia r3!, {r1, r2}
-+	str r2, [r1]
-+	subs r4, r4, #1
-+	bne loop4
-+
-+	/* SDRAM initialised so now exit. */
-+	mov lr, r6
-+	mov pc, lr
-+
-+/*
-+ *  delay()
-+ *
-+ *  uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+	nop
-+	nop
-+	nop
-+	subs r0, r0, #1
-+	bne delay
-+	mov pc, lr
-+
-+_platformsetup:
-+	.word platformsetup
-+
-+init_table:
-+	/* Table of address, data for loading into the DRAM controller */
-+    	/* Configure for a single DDR device */
-+	.word 0x4500002C, 0x08
-+	.word 0x45000038, 0x400
-+	.word 0x45800000, 0x80100000
-+	.word 0x45800004, 0x8000ffff	// Enable DDR core and all clients
-+	.word 0x45800024, 0x1e4
-+	.word 0x45800014, 0xe0000001	// DLL to automatic with starting value=1
-+/* 200uS delay */
-+#if !TEST_BRD
-+	.word 0x45800014, 0xa0000003	// DLL to automatic with offset value=3
-+/* 200uS delay */
-+#endif // TEST_BRD
-+#if (MEM_SIZE == 32)
-+	.word 0x45800000, 0x801B030C
-+#else
-+	.word 0x45800000, 0x801D030C
-+#endif // MEM_SIZE
-+/* 200uS delay */
-+	.word 0x4580000c, 0x80280400
-+/* 200uS delay */
-+	.word 0x4580000c, 0x80210000
-+/* 200uS delay */
-+	.word 0x4580000c, 0x80200063
-+	.word 0x45800028, 0x0000001f	// Enable all arbiter features
-+	.word 0x45800018, 0x00000000	// Disable all monitoring
-+	.word 0x45800010, 0xffffffff	// Disable all read buffering, due to h/w bug
-+	.word 0x4580002C, 0x00000000	// Do NOT disable HPROT, ie want write coherency
-+
-+.ltorg
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/platform-810.S u-boot-1.1.2-oxe810/board/oxnas/platform-810.S
---- u-boot-1.1.2/board/oxnas/platform-810.S	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/platform-810.S	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,477 @@
-+/*
-+ * Board specific setup info
-+ *
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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>
-+
-+/* use estimate of processor speed to calculate number of cycles delay */
-+/* delay count is nominal (PLL200 frequency x delay time) / loop count 
-+ * expressing 200us as 200/1000000 and re-arranging gives the expression below
-+ */
-+ 
-+#define DELAY_200US   ((NOMINAL_ARMCLK  / (5 * 1000000)) * 200)  
-+#define DELAY_300US   ((NOMINAL_ARMCLK  / (5 * 1000000)) * 300)  
-+/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
-+#define DELAY_1S   ((DELAY_200US) * 5000)
-+#define DELAY_8       8
-+#define DELAY_200     200
-+
-+
-+.globl platformsetup
-+platformsetup:
-+/* register allocations
-+ * r0 - delay counter and scratch
-+ * r1 - address register
-+ * r2 - data register
-+ * r3 - index to table pointer
-+ * r4 - iteration counter.
-+ * 
-+ * r5 - hold return address.
-+ * lr - (R14) link register
-+ * pc - (R15) program counter.
-+ */
-+
-+#ifdef INITIALISE_SDRAM
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+    adrl r0, platformsetup      /* Relative location of function start.*/
-+    ldr  r1, _platformsetup
-+    cmp  r0, r1
-+    moveq pc, lr
-+#else
-+    mov pc, lr
-+#endif
-+
-+#if (FPGA == 1)
-+    /* Establish a working setup for the SDRAM */
-+    mov r6, lr
-+
-+    /* Assert reset to the DDR core */
-+    ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+
-+    /* Deassert reset to the DDR core */
-+    ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+    str r1, [r0]
-+
-+    /* Turn on the DDR core clock */
-+    ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+
-+    /* Start using the initialisation value list */
-+    adrl r3, init_table
-+
-+    /* Copy first 6 entries */
-+    ldr r4, =6
-+loop0:
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne loop0
-+
-+    /* Delay for 200uS while DRAM controller stabilises. */
-+    ldr r0, =DELAY_200US
-+    bl delay
-+
-+    /* Copy next 4 entries */
-+    ldr r4, =4
-+loop1:  
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne loop1
-+
-+    /* Wait at least 200 clock cycles. */
-+    ldr r0, =DELAY_200
-+    bl delay
-+
-+    /* Copy next 2 entries */
-+    ldr r4, =2
-+loop2:  
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne loop2
-+
-+    /* Wait at least 8 clock  cycles. */
-+    ldr r0, =DELAY_8
-+    bl delay
-+
-+    /* Copy next 9 entries */
-+    ldr r4, =9
-+loop3:  
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne loop3
-+
-+    /* SDRAM initialised so now exit. */
-+    mov lr, r6
-+    mov pc, lr
-+
-+/*
-+ *  delay()
-+ *
-+ *  uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+    nop
-+    nop
-+    nop
-+    subs r0, r0, #1
-+    bne delay
-+    mov pc, lr
-+
-+_platformsetup:
-+    .word platformsetup
-+#else // ASIC, (DDR-2)
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+    /* Establish a working setup for the SDRAM */
-+    mov r6, lr
-+
-+#ifdef OVERCLOCK
-+    /* 
-+      change clock speed on chip 
-+    */
-+    
-+    /* read SYS_CTRL_PLLSYS_CTRL into r3*/
-+    mov r5, #0x45000000
-+    ldr r3, [r5, #72]
-+    
-+    /* load the value at dllkey (0xbeadface) into r7 */
-+    adrl r7, dllkey
-+    ldr r7, [r7]
-+    
-+    /* pll_sys |= 0x20000; */
-+    orr r3, r3, #131072 /* 0x20000 */
-+    
-+    /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+    str r7, [r5, #108]
-+
-+    /* write pll_sys (bypass pll)*/
-+    str r3, [r5, #72]
-+    
-+    /* pll_sys &= 0xff000000; */
-+    mov r4, r3, lsr #16
-+    mov r4, r4, lsl #16
-+    
-+    /* pll_sys |= 0x00F00061  */
-+    orr r4, r4, #15728640   /* 0xf00000 */
-+    orr r4, r4, #97 /* 0x61 */
-+#if 0
-+    orr r4, r4, #7864320    /* 0x780000 */
-+    orr r4, r4, #96 /* 0x60 */
-+#endif
-+    
-+    /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+    str r7, [r5, #108]
-+
-+    /* write pll_sys (with new pll speeds) */    
-+    str r4, [r5, #72]
-+
-+    /* delay 300us */
-+    ldr r0, =DELAY_300US
-+    bl delay
-+
-+    /* clear bypass pll bit */
-+    bic r4, r4, #131072 /* 0x20000 */
-+
-+    /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+    str r7, [r5, #108]
-+
-+    /* write pll_sys (with new pll speeds and pll un-bypassed) */    
-+    str r4, [r5, #72]
-+#endif /* OVERCLOCK */
-+  
-+    /* Turn on the DDR core and phy clocks */
-+    ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_CKEN_DDR_PHY_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+
-+    /* Assert reset to the DDR core and phy */
-+    ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+
-+    /* Deassert reset to the DDR core and phy*/
-+    ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+    ldr r1, =1
-+    ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+    mov r1, r1, LSL r2
-+    str r1, [r0]
-+
-+    /* Start using the initialisation value list */
-+    adrl r3, init_table
-+
-+    /* Copy first 14 entries of DDR core setup (section A)*/
-+    ldr r4, =14
-+loop0:
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne loop0
-+
-+    /* Delay for 200uS while DDR controller stabilises. */
-+    ldr r0, =DELAY_200US
-+    bl delay
-+
-+    /* Copy next 13 entries of DDR device commands (section B)*/
-+    ldr r4, =13
-+loop1:
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+
-+    /* Wait at least 200 clock cycles between ram chip command writes */
-+    ldr r0, =DELAY_200
-+    bl delay
-+
-+    subs r4, r4, #1
-+    bne loop1
-+
-+    /* Copy final DDR controller setup to set memory size/banks (section C)*/
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+
-+#if (PROBE_MEM_SIZE == 1)
-+    /* Load the probe values into SDRAM */
-+    adrl r3, probe_table
-+    mov r4, #4
-+.globl pl1
-+pl1:
-+    ldmia r3!, {r1, r2}
-+    str r2, [r1]
-+    subs r4, r4, #1
-+    bne pl1
-+
-+    /* Get the current contents of the DDR controller core's config register */
-+    adrl r1, ddr_config_reg
-+    ldr r1, [r1]
-+    ldr r1, [r1]
-+
-+    /* Zero the number of banks field - bit 23*/
-+    mov r2, #1
-+    bic r1, r1, r2, lsl #23
-+
-+    /* Zero the size field - bits 17-20 inclusive */
-+    mov r2, #15
-+    bic r1, r1, r2, lsl #17
-+
-+    /* First probe location tells us the SDRAM size */
-+    adrl r3, probe_table
-+    ldr r0, [r3]
-+    ldr r0, [r0]
-+
-+    /* Is size 64MB? */
-+    ldr r2, [r3, #28]	/* Get probe value 4 */
-+    cmp r0, r2
-+    moveq r4, #6
-+    orreq r1, r1, r4, lsl #17
-+    beq pl2
-+
-+    /* Is 128M or 256M so set banks to 8 */
-+    mov r4, #1
-+    orr r1, r1, r4, lsl #23
-+
-+    /* Is size 128MB? */
-+    ldr r2, [r3, #20]	/* Get probe value 3 */
-+    cmp r0, r2
-+//    moveq r4, #7
-+    moveq r4, #8	/* DDR controller does not work at 128M, use 256M instead
-+    orreq r1, r1, r4, lsl #17
-+    beq pl2
-+
-+    /* Must be 256MB, or something is very wrong */
-+    mov r4, #8
-+    orr r1, r1, r4, lsl #17
-+
-+pl2:
-+    /* Write the revised contents to the DDR controller core's config register */
-+    adrl r2, ddr_config_reg
-+    ldr r2, [r2]
-+    str r1, [r2]
-+#endif
-+
-+    /* SDRAM setup complete */
-+    mov lr, r6
-+    mov pc, lr
-+
-+/*
-+ *  delay()
-+ *
-+ *  uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+    nop
-+    nop
-+    nop
-+    subs r0, r0, #1
-+    bne delay
-+    mov pc, lr
-+
-+_platformsetup:
-+    .word platformsetup
-+#endif
-+
-+
-+init_table:
-+#if (FPGA == 1)
-+    /* Table of address, data for loading into the DRAM controller on FPGA */
-+    .word 0x45800000, 0x000d0000    // Enable the DDR in SDR mode and width 32 bits
-+    .word 0x45800034, 0x04442032    // SDR mode timings - #0
-+    .word 0x45800038, 0x570A0907    // SDR mode timings - #1
-+    .word 0x4580003C, 0x00000002    // SDR mode timings - #2
-+    .word 0x45800004, 0x80000000    // Enable DDR core, but not clients yet
-+    .word 0x45800014, 0x80000001    // Enable CK and set DLL mode to manual
-+/* 200uS delay */
-+    .word 0x4580000c, 0x80200000    // Assert CKE for all further commands
-+    .word 0x4580000c, 0x80280400    // Issue precharge to all banks
-+    .word 0x4580000c, 0x80200000    // NOP, as only DDR has real command here
-+    .word 0x4580000c, 0x80200022    // Set burst length 4, sequential CAS 2
-+/* 200uS delay */
-+    .word 0x4580000c, 0x80280400    // Issue precharge to all banks
-+    .word 0x4580000c, 0x80240000    // Issue auto-refresh command, CKE not asserted
-+/* 200uS delay */
-+    .word 0x4580000c, 0x80240000    // Issue auto-refresh command, CKE not asserted
-+    .word 0x4580000c, 0x80200000    // Assert CKE for all further commands
-+    .word 0x4580000c, 0x80200022        // Set burst length 4, sequential CAS 2
-+    .word 0x45800000, 0x000d0186    // SDR, size and width and refresh rate, assuming
-+                        // 25Mhz clk to SDR, divide down to get 15.625uS
-+                    // refresh rate
-+    .word 0x45800024, 0x00000124    // Set I/O drive strengths
-+    .word 0x45800028, 0x0000001f    // Enable all arbiter features
-+    .word 0x45800018, 0x00000000    // Disable all monitoring
-+    .word 0x45800010, 0xFFFFFFFF    // Disable all read buffering
-+    .word 0x45800004, 0x800000ff    // Enable all client interfaces
-+#else   // ASIC DDR-2
-+    // SECTION A - DDR controller core configuration
-+    .word 0x45800000, 0x802d0591    // enable in ddr-2 mode 16 bit wide
-+    .word 0x45800034, 0x04442032    // ddr-2 mode timings 
-+    .word 0x45800038, 0x870f0b25    // ddr-2 mode timings
-+    .word 0x4580003c, 0x00000a23    // ddr-2 mode timings
-+    .word 0x45800054, 0x00072000    // phy-3 settings
-+    .word 0x45800050, 0x00022828    // phy-2 settings, start
-+    .word 0x45800050, 0x00032828    // phy-2 settings, on
-+    .word 0x45800028, 0x0000001f    // Enable all arbiter features
-+    .word 0x45800018, 0x00000000    // Disable all monitoring
-+    .word 0x45800010, 0xffff0000    // Enable all read buffering
-+    .word 0x4580002c, 0x00ff00fd    // no burst accl, no hprot on arm data
-+    .word 0x45800040, 0x00000000    // enable burst and read cache
-+    .word 0x45800044, 0xffff0000    // enable write behind prot, disable timeout     
-+    .word 0x45800004, 0x8000ffff    // Enable all client interfaces
-+/* 200uS delay after configuring DDR controller core */
-+
-+    // SECTION B - Memory device configuration
-+    .word 0x4580000c, 0x807c0000    // exit something or other
-+    .word 0x4580000c, 0x803c0000    // nop - wake up
-+    .word 0x4580000c, 0x80280400    // precharge all
-+    .word 0x4580000c, 0x80220000    // emr2
-+    .word 0x4580000c, 0x80230000    // emr3
-+
-+#if (MEM_ODT == 150)
-+    .word 0x4580000c, 0x80210042    // enable dll, odt to 150
-+#elif (MEM_ODT == 75)
-+    .word 0x4580000c, 0x80210006    // enable dll, odt to 75
-+#elif (MEM_ODT == 50)
-+    .word 0x4580000c, 0x80210046    // enable dll, odt to 50
-+#else
-+#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
-+#endif
-+
-+    .word 0x4580000c, 0x80200733    // set WR CL BL and reset dll
-+    .word 0x4580000c, 0x80280400    // precharge all
-+    .word 0x4580000c, 0x80240000    // auto refresh
-+    .word 0x4580000c, 0x80240000    // auto refresh
-+    .word 0x4580000c, 0x80200733    // set WR CL BL and reset dll
-+
-+#if (MEM_ODT == 150)
-+    .word 0x4580000c, 0x802103c2    // enable OCD
-+    .word 0x4580000c, 0x80210042    // disable OCD
-+#elif (MEM_ODT == 75)
-+    .word 0x4580000c, 0x80210386    // enable OCD
-+    .word 0x4580000c, 0x80210006    // disable OCD
-+#elif (MEM_ODT == 50)
-+    .word 0x4580000c, 0x802103c6    // enable OCD
-+    .word 0x4580000c, 0x80210046    // disable OCD
-+#else
-+#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
-+#endif
-+
-+    // SECTION C - Final memory size/bank configuration
-+#if (PROBE_MEM_SIZE == 1)
-+    .word 0x45800000, 0x80b10591    // 256M, 8 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 64)
-+    .word 0x45800000, 0x802d0591    // 64M,  4 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 128)
-+    .word 0x45800000, 0x80af0591    // 128M, 8 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 256)
-+    .word 0x45800000, 0x80b10591    // 256M, 8 banks, 1425 clocks for 7.8us refresh.
-+#else
-+#error Unsupported memory size, set MEM_SIZE to 64, 128 or 256
-+#endif
-+
-+#endif  // FPGA or ASIC
-+dllkey:
-+    .word 0xbeadface
-+
-+ddr_config_reg:
-+    .word 0x45800000
-+
-+probe_table:
-+    .word 0x48000000, 0x12345678
-+    .word 0x48000040, 0xdeadbeef
-+    .word 0x50000000, 0xfafafafa
-+    .word 0x50000040, 0xabcdef01
-+
-+.ltorg
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/u-boot.lds u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds
---- u-boot-1.1.2/board/oxnas/u-boot.lds	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds	2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * (C) Copyright 2002
-+ * Gary Jennejohn, DENX Software Engineering, <gj at 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/arm926ejs/start.o	(.text)
-+	  *(.text)
-+	}
-+	.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 : { *(.bss) }
-+	_end = .;
-+}
-diff -Nurd u-boot-1.1.2/common/cmd_ext2.c u-boot-1.1.2-oxe810/common/cmd_ext2.c
---- u-boot-1.1.2/common/cmd_ext2.c	2004-12-16 18:34:53.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ext2.c	2008-06-11 17:55:30.000000000 +0200
-@@ -223,7 +223,7 @@
- 	PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
- 
- 	if (part != 0) {
--		if (get_partition_info (&dev_desc[dev], part, &info)) {
-+		if (get_partition_info (dev_desc, part, &info)) {
- 			printf ("** Bad partition %d **\n", part);
- 			return(1);
- 		}
-diff -Nurd u-boot-1.1.2/common/cmd_ide.c u-boot-1.1.2-oxe810/common/cmd_ide.c
---- u-boot-1.1.2/common/cmd_ide.c	2004-12-31 10:32:50.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ide.c	2008-06-11 17:55:30.000000000 +0200
-@@ -193,6 +193,13 @@
- static void set_pcmcia_timing (int pmode);
- #endif
- 
-+#ifdef CONFIG_OXNAS
-+extern unsigned char oxnas_sata_inb(int dev, int port);
-+extern void oxnas_sata_outb(int dev, int port, unsigned char val);
-+extern void oxnas_sata_output_data(int dev, ulong *sect_buf, int words);
-+extern void oxnas_sata_input_data(int dev, ulong *sect_buf, int words);
-+#endif // CONFIG_OXNAS
-+
- /* ------------------------------------------------------------------------- */
- 
- int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-@@ -491,175 +498,103 @@
- 	return rcode;
- }
- 
--/* ------------------------------------------------------------------------- */
- 
--void ide_init (void)
-+static int ide_probe(int device)
- {
-+    int found = 0;
-+
-+    /* Select device */
-+    udelay(100000);	    /* 100 ms */
-+    ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-+    udelay(100000);     /* 100 ms */
- 
--#ifdef CONFIG_IDE_8xx_DIRECT
--	DECLARE_GLOBAL_DATA_PTR;
--	volatile immap_t *immr = (immap_t *)CFG_IMMR;
--	volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
--#endif
- 	unsigned char c;
--	int i, bus;
--#ifdef CONFIG_AMIGAONEG3SE
--	unsigned int max_bus_scan;
--	unsigned int ata_reset_time;
--	char *s;
-+    int i = 0;
-+    do {
-+        udelay(10000);  /* 10 ms */
-+
-+        c = ide_inb(device, ATA_STATUS);
-+        if (++i > (ATA_RESET_TIME * 100)) {
-+            PRINTF("ide_probe() timeout\n");
-+            ide_led((LED_IDE1 | LED_IDE2), 0);  /* LED's off */
-+            return found;
-+        }
-+        if ((i >= 100) && ((i%100) == 0)) {
-+            putc ('.');
-+        }
-+    } while (c & ATA_STAT_BUSY);
-+
-+    if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
-+        PRINTF("ide_probe() status = 0x%02X ", c);
-+#ifndef CONFIG_ATAPI    /* ATAPI Devices do not set DRDY */
-+    } else  if ((c & ATA_STAT_READY) == 0) {
-+        PRINTF("ide_probe() status = 0x%02X ", c);
- #endif
--#ifdef CONFIG_IDE_8xx_PCCARD
--	extern int pcmcia_on (void);
--	extern int ide_devices_found; /* Initialized in check_ide_device() */
--#endif	/* CONFIG_IDE_8xx_PCCARD */
-+    } else {
-+        found = 1;
-+    }
- 
--#ifdef CONFIG_IDE_PREINIT
--	extern int ide_preinit (void);
--	WATCHDOG_RESET();
-+    return found;
-+}
- 
--	if (ide_preinit ()) {
--		puts ("ide_preinit failed\n");
-+void ide_init(void)
-+{
-+	static int ide_init_called = 0;
-+	int i, bus;
-+
-+	if (ide_init_called) {
- 		return;
- 	}
--#endif	/* CONFIG_IDE_PREINIT */
--
--#ifdef CONFIG_IDE_8xx_PCCARD
--	extern int pcmcia_on (void);
--	extern int ide_devices_found; /* Initialized in check_ide_device() */
-+	ide_init_called = 1;
- 
-+#ifdef CONFIG_IDE_PREINIT
-+	extern int ide_preinit(void);
- 	WATCHDOG_RESET();
- 
--	ide_devices_found = 0;
--	/* initialize the PCMCIA IDE adapter card */
--	pcmcia_on();
--	if (!ide_devices_found)
-+    printf("Initialising disks\n");
-+	if (ide_preinit()) {
-+		puts ("ide_preinit failed\n");
- 		return;
--	udelay (1000000);	/* 1 s */
--#endif	/* CONFIG_IDE_8xx_PCCARD */
-+	}
-+#endif	/* CONFIG_IDE_PREINIT */
- 
- 	WATCHDOG_RESET();
- 
--#ifdef CONFIG_IDE_8xx_DIRECT
--	/* Initialize PIO timing tables */
--	for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
--	    pio_config_clk[i].t_setup  = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
--							    gd->bus_clk);
--	    pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
--							    gd->bus_clk);
--	    pio_config_clk[i].t_hold   = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
--							    gd->bus_clk);
--	    PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
--		    "  len=%3d ns/%d clk"
--		    "  hold=%2d ns/%d clk\n",
--		    i,
--		    pio_config_ns[i].t_setup,  pio_config_clk[i].t_setup,
--		    pio_config_ns[i].t_length, pio_config_clk[i].t_length,
--		    pio_config_ns[i].t_hold,   pio_config_clk[i].t_hold);
--	}
--#endif /* CONFIG_IDE_8xx_DIRECT */
--
- 	/* Reset the IDE just to be sure.
- 	 * Light LED's to show
- 	 */
--	ide_led ((LED_IDE1 | LED_IDE2), 1);		/* LED's on	*/
--	ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
--
--#ifdef CONFIG_IDE_8xx_DIRECT
--	/* PCMCIA / IDE initialization for common mem space */
--	pcmp->pcmc_pgcrb = 0;
--
--	/* start in PIO mode 0 - most relaxed timings */
--	pio_mode = 0;
--	set_pcmcia_timing (pio_mode);
--#endif /* CONFIG_IDE_8xx_DIRECT */
-+	ide_led((LED_IDE1 | LED_IDE2), 1);		/* LED's on	*/
-+	ide_reset(); /* ATAPI Drives seems to need a proper IDE Reset */
- 
- 	/*
- 	 * Wait for IDE to get ready.
- 	 * According to spec, this can take up to 31 seconds!
- 	 */
--#ifndef CONFIG_AMIGAONEG3SE
--	for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) {
--		int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
--#else
--	s = getenv("ide_maxbus");
--	if (s)
--	    max_bus_scan = simple_strtol(s, NULL, 10);
--	else
--	    max_bus_scan = CFG_IDE_MAXBUS;
--
--	for (bus=0; bus<max_bus_scan; ++bus) {
--		int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
--#endif
--
--#ifdef CONFIG_IDE_8xx_PCCARD
--		/* Skip non-ide devices from probing */
--		if ((ide_devices_found & (1 << bus)) == 0) {
--			ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
--			continue;
--		}
--#endif
--		printf ("Bus %d: ", bus);
--
--		ide_bus_ok[bus] = 0;
--
--		/* Select device
--		 */
--		udelay (100000);		/* 100 ms */
--		ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
--		udelay (100000);		/* 100 ms */
--#ifdef CONFIG_AMIGAONEG3SE
--		ata_reset_time = ATA_RESET_TIME;
--		s = getenv("ide_reset_timeout");
--		if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10);
--#endif
--		i = 0;
--		do {
--			udelay (10000);		/* 10 ms */
--
--			c = ide_inb (dev, ATA_STATUS);
--			i++;
--#ifdef CONFIG_AMIGAONEG3SE
--			if (i > (ata_reset_time * 100)) {
--#else
--			if (i > (ATA_RESET_TIME * 100)) {
--#endif
--				puts ("** Timeout **\n");
--				ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
--#ifdef CONFIG_AMIGAONEG3SE
--				/* If this is the second bus, the first one was OK */
--				if (bus != 0) {
--				    ide_bus_ok[bus] = 0;
--				    goto skip_bus;
--				}
--#endif
--				return;
--			}
--			if ((i >= 100) && ((i%100)==0)) {
--				putc ('.');
--			}
--		} while (c & ATA_STAT_BUSY);
-+    printf("Detecting SATA busses:\n");
-+    for (bus=0; bus < CFG_IDE_MAXBUS; ++bus) {
-+        printf("Bus %d: ", bus);
- 
--		if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
--			puts ("not available  ");
--			PRINTF ("Status = 0x%02X ", c);
--#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
--		} else  if ((c & ATA_STAT_READY) == 0) {
--			puts ("not available  ");
--			PRINTF ("Status = 0x%02X ", c);
--#endif
--		} else {
--			puts ("OK ");
--			ide_bus_ok[bus] = 1;
--		}
--		WATCHDOG_RESET();
--	}
-+        /* Try to discover if bus is present by probing first device on bus */
-+        int device = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
-+        ide_bus_ok[bus] = ide_probe(device);
-+        if (ide_bus_ok[bus]) {
-+            puts("Found first device OK\n");
-+        } else {
-+            WATCHDOG_RESET();
-+        
-+            /* Try second device on bus */
-+            ide_bus_ok[bus] = ide_probe(++device);
-+            if (ide_bus_ok[bus]) {
-+                puts("Found second device OK\n");
-+            } else {
-+                puts("No devices found\n");
-+            }
-+        }
- 
--#ifdef CONFIG_AMIGAONEG3SE
--      skip_bus:
--#endif
--	putc ('\n');
-+        WATCHDOG_RESET();
-+    }
- 
--	ide_led ((LED_IDE1 | LED_IDE2), 0);	/* LED's off	*/
-+	ide_led((LED_IDE1 | LED_IDE2), 0);	/* LED's off	*/
- 
- 	curr_device = -1;
- 	for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
-@@ -675,13 +610,12 @@
- 		ide_dev_desc[i].block_read=ide_read;
- 		if (!ide_bus_ok[IDE_BUS(i)])
- 			continue;
--		ide_led (led, 1);		/* LED on	*/
-+		ide_led(led, 1);		/* LED on	*/
- 		ide_ident(&ide_dev_desc[i]);
--		ide_led (led, 0);		/* LED off	*/
-+		ide_led(led, 0);		/* LED off	*/
- 		dev_print(&ide_dev_desc[i]);
--/*		ide_print (i); */
- 		if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
--			init_part (&ide_dev_desc[i]);			/* initialize partition type */
-+			init_part(&ide_dev_desc[i]);    /* initialize partition type */
- 			if (curr_device < 0)
- 				curr_device = i;
- 		}
-@@ -689,6 +623,11 @@
- 	WATCHDOG_RESET();
- }
- 
-+int is_device_present(int device_number)
-+{
-+    return ide_dev_desc[device_number].part_type != PART_TYPE_UNKNOWN;
-+}
-+
- /* ------------------------------------------------------------------------- */
- 
- block_dev_desc_t * ide_get_dev(int dev)
-@@ -798,6 +737,11 @@
- 	EIEIO;
- 	*((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
- }
-+#elif defined(CONFIG_OXNAS)
-+static void __inline__ ide_outb(int dev, int port, unsigned char val)
-+{
-+    oxnas_sata_outb(dev, port, val);
-+}
- #else	/* ! __PPC__ */
- static void __inline__
- ide_outb(int dev, int port, unsigned char val)
-@@ -819,6 +763,11 @@
- 		dev, port, (ATA_CURR_BASE(dev)+port), val);
- 	return (val);
- }
-+#elif defined(CONFIG_OXNAS)
-+static unsigned char __inline__ ide_inb(int dev, int port)
-+{
-+    return oxnas_sata_inb(dev, port);
-+}
- #else	/* ! __PPC__ */
- static unsigned char __inline__
- ide_inb(int dev, int port)
-@@ -921,6 +870,11 @@
- 	}
- #endif	/* CONFIG_HMI10 */
- }
-+#elif defined(CONFIG_OXNAS)
-+static void output_data(int dev, ulong *sect_buf, int words)
-+{
-+    oxnas_sata_output_data(dev, sect_buf, words);
-+}
- #else	/* ! __PPC__ */
- static void
- output_data(int dev, ulong *sect_buf, int words)
-@@ -968,6 +922,11 @@
- 	}
- #endif	/* CONFIG_HMI10 */
- }
-+#elif defined(CONFIG_OXNAS)
-+static void input_data(int dev, ulong *sect_buf, int words)
-+{
-+    oxnas_sata_input_data(dev, sect_buf, words);
-+}
- #else	/* ! __PPC__ */
- static void
- input_data(int dev, ulong *sect_buf, int words)
-@@ -1001,10 +960,36 @@
- 
- /* -------------------------------------------------------------------------
-  */
-+#ifdef CONFIG_OXNAS
-+static void byte_swap_and_trim(char* buf)
-+{
-+    char *src = buf;
-+
-+    // Swap bytes in 16-bit words
-+    while ((*src != '\0') && (*(src+1) != '\0')) {
-+        char tmp = *(src+1);
-+        *(src+1) = *src;
-+        *src = tmp;
-+        src += 2;
-+    }
-+
-+    // Trim leading spaces
-+    src = buf;
-+    while (*src == ' ') {
-+        ++src;
-+    }
-+    if (src != buf) {
-+        memcpy(buf, src, strlen(src));
-+        buf[strlen(buf) - (src-buf)] = '\0';
-+    }
-+}
-+#endif // CONFIG_OXNAS
-+
- static void ide_ident (block_dev_desc_t *dev_desc)
- {
- 	ulong iobuf[ATA_SECTORWORDS];
- 	unsigned char c;
-+    unsigned int i;
- 	hd_driveid_t *iop = (hd_driveid_t *)iobuf;
- 
- #ifdef CONFIG_AMIGAONEG3SE
-@@ -1023,6 +1008,10 @@
- 	device=dev_desc->dev;
- 	printf ("  Device %d: ", device);
- 
-+    for ( i=0; i < ATA_SECTORWORDS; ++i) {
-+        iobuf[i] = 0;
-+    }
-+    
- #ifdef CONFIG_AMIGAONEG3SE
- 	s = getenv("ide_maxbus");
- 	if (s) {
-@@ -1110,20 +1099,22 @@
- 
- 	input_swap_data (device, iobuf, ATA_SECTORWORDS);
- 
--	ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
--	ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
--	ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
-+	ident_cpy(dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
-+	ident_cpy(dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
-+	ident_cpy(dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
-+
- #ifdef __LITTLE_ENDIAN
- 	/*
--	 * firmware revision and model number have Big Endian Byte
-+	 * firmware revision, model number and product have Big Endian Byte
- 	 * order in Word. Convert both to little endian.
- 	 *
- 	 * See CF+ and CompactFlash Specification Revision 2.0:
- 	 * 6.2.1.6: Identfy Drive, Table 39 for more details
- 	 */
- 
--	strswab (dev_desc->revision);
--	strswab (dev_desc->vendor);
-+	byte_swap_and_trim(dev_desc->revision);
-+	byte_swap_and_trim(dev_desc->vendor);
-+	byte_swap_and_trim(dev_desc->product);
- #endif /* __LITTLE_ENDIAN */
- 
- 	if ((iop->config & 0x0080)==0x0080)
-diff -Nurd u-boot-1.1.2/common/cmd_ledfail.c u-boot-1.1.2-oxe810/common/cmd_ledfail.c
---- u-boot-1.1.2/common/cmd_ledfail.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ledfail.c	2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,58 @@
-+
-+#include <common.h>
-+#include <command.h>
-+
-+#if (CONFIG_COMMANDS & CFG_CMD_LEDFAIL)
-+#define FAILURE_LED (1 << (34-32))
-+
-+#define GPIO_B	0x44100000
-+#define WARN_GPIO_OUT_REG			(GPIO_B + 0x10)
-+#define WARN_GPIO_OUT_ENABLE_SET	(GPIO_B + 0x1C)
-+#define WARN_GPIO_OUT_ENABLE_CLR	(GPIO_B + 0x20)
-+
-+static void ledfail_light(void)
-+{
-+	printf("Light LED\n");
-+	/* Light the failure LED - assumes active low drive */
-+	u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
-+	led_state = led_state & ~FAILURE_LED;
-+	*((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
-+
-+	/* Enable GPIO for output */
-+	*((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_SET) = FAILURE_LED;
-+}
-+
-+static void ledfail_extinguish(void)
-+{
-+	printf("Extinguish LED\n");
-+	/* Extinguish the failure LED - assumes active low drive */
-+	u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
-+	led_state = led_state | FAILURE_LED;
-+	*((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
-+
-+    /* Clear the failure bit output enable in GPIO's */
-+	*((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_CLR) = FAILURE_LED;
-+}
-+
-+int do_ledfail(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-+{
-+	if (argc != 2) {
-+		printf ("Usage:\n%s\n", cmdtp->usage);
-+		return 1;
-+	}
-+
-+	ulong arg = simple_strtoul(argv[1], NULL, 10);
-+	switch (arg) {
-+		case 0:
-+			ledfail_extinguish();
-+			break;
-+		case 1:
-+			ledfail_light();
-+			break;
-+	}
-+
-+	return 0;
-+}
-+
-+U_BOOT_CMD(ledfail, 2, 2, do_ledfail, "ledfail - Extinguish (0) or light (1) failure LED\n", NULL);
-+#endif	/* CFG_CMD_LEDFAIL */
-diff -Nurd u-boot-1.1.2/common/cmd_mem.c u-boot-1.1.2-oxe810/common/cmd_mem.c
---- u-boot-1.1.2/common/cmd_mem.c	2004-12-16 18:42:39.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_mem.c	2008-06-11 17:55:30.000000000 +0200
-@@ -731,13 +731,17 @@
- 	if (argc > 1) {
- 		start = (ulong *)simple_strtoul(argv[1], NULL, 16);
- 	} else {
--		start = (ulong *)CFG_MEMTEST_START;
-+		DECLARE_GLOBAL_DATA_PTR;
-+
-+		start = (ulong *)(gd->bd->bi_dram[0].start);
- 	}
- 
- 	if (argc > 2) {
- 		end = (ulong *)simple_strtoul(argv[2], NULL, 16);
- 	} else {
--		end = (ulong *)(CFG_MEMTEST_END);
-+		DECLARE_GLOBAL_DATA_PTR;
-+
-+		end = (ulong *)(start + gd->bd->bi_dram[0].size);
- 	}
- 
- 	if (argc > 3) {
-diff -Nurd u-boot-1.1.2/common/cmd_nvedit.c u-boot-1.1.2-oxe810/common/cmd_nvedit.c
---- u-boot-1.1.2/common/cmd_nvedit.c	2004-09-30 00:55:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/cmd_nvedit.c	2008-06-11 17:55:30.000000000 +0200
-@@ -55,8 +55,9 @@
-     !defined(CFG_ENV_IS_IN_FLASH)	&& \
-     !defined(CFG_ENV_IS_IN_DATAFLASH)	&& \
-     !defined(CFG_ENV_IS_IN_NAND)	&& \
-+    !defined(CFG_ENV_IS_IN_DISK)	&& \
-     !defined(CFG_ENV_IS_NOWHERE)
--# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|NOWHERE}
-+# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|DISK|NOWHERE}
- #endif
- 
- #define XMK_STR(x)	#x
-@@ -483,7 +484,7 @@
-  * or NULL if not found
-  */
- 
--char *getenv (uchar *name)
-+char *getenv (const uchar *name)
- {
- 	int i, nxt;
- 
-@@ -530,7 +531,9 @@
- 	return (-1);
- }
- 
--#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
-+#if defined(CFG_ENV_IS_IN_NVRAM) || \
-+    defined(CFG_ENV_IS_IN_EEPROM) || \
-+    defined(CFG_ENV_IS_IN_DISK) || \
-     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
-       (CFG_CMD_ENV|CFG_CMD_FLASH))
- int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-@@ -586,7 +589,9 @@
- 	"    - delete environment variable 'name'\n"
- );
- 
--#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
-+#if defined(CFG_ENV_IS_IN_NVRAM) || \
-+    defined(CFG_ENV_IS_IN_EEPROM) || \
-+    defined(CFG_ENV_IS_IN_DISK) || \
-     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
-       (CFG_CMD_ENV|CFG_CMD_FLASH))
- U_BOOT_CMD(
-diff -Nurd u-boot-1.1.2/common/env_common.c u-boot-1.1.2-oxe810/common/env_common.c
---- u-boot-1.1.2/common/env_common.c	2004-06-09 16:58:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/env_common.c	2008-06-11 17:55:30.000000000 +0200
-@@ -42,7 +42,7 @@
- 	extern void disable_nvram(void);
- #endif
- 
--#undef DEBUG_ENV
-+//#undef DEBUG_ENV
- #ifdef DEBUG_ENV
- #define DEBUGF(fmt,args...) printf(fmt ,##args)
- #else
-diff -Nurd u-boot-1.1.2/common/env_disk.c u-boot-1.1.2-oxe810/common/env_disk.c
---- u-boot-1.1.2/common/env_disk.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/env_disk.c	2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,152 @@
-+/*
-+ * (C) Copyright 2006
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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>
-+
-+#if defined(CFG_ENV_IS_IN_DISK)
-+
-+#include <command.h>
-+#include <environment.h>
-+#include <ide.h>
-+
-+extern int is_device_present(int device_number);
-+
-+/* Point to the environment as held in SRAM */
-+env_t *env_ptr = NULL;
-+
-+char *env_name_spec = "Disk";
-+
-+/* The default environment compiled into U-Boot */
-+extern uchar default_environment[];
-+
-+uchar env_get_char_spec(int index)
-+{
-+    DECLARE_GLOBAL_DATA_PTR;
-+
-+    return *((uchar *)(gd->env_addr + index));
-+}
-+
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+
-+void env_relocate_spec(void)
-+{
-+    /* Compute the CRC of the environment in SRAM, copied from disk at boot */
-+    env_t *sram_env = (env_t*)CFG_ENV_ADDR;
-+    ulong  crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+    /* Copy the SRAM environment and CRC to the working environment */
-+    memcpy(env_ptr->data, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+    env_ptr->crc = crc;
-+}
-+
-+int saveenv(void)
-+{
-+    /* Compute the CRC of the working environment */
-+    env_ptr->crc = crc32(0, env_ptr->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+    /* Copy the working environment to the reserved area on each disk device */
-+    int status = 1;
-+    int i;
-+    for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
-+        if (!is_device_present(i)) {
-+            continue;
-+        }
-+
-+		/* Write environment to the main environment area on disk */
-+        unsigned long written = ide_write(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
-+        if (written != CFG_ENV_SIZE/512) {
-+			printf("Saving environment to disk %d primary image failed\n", i);
-+            status = 0;
-+        } else {
-+			/* Write environment to the redundant environment area on disk */
-+			written = ide_write(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
-+			if (written != CFG_ENV_SIZE/512) {
-+				printf("Saving environment to disk %d secondary image failed\n", i);
-+				status = 0;
-+			}
-+		}
-+    }
-+
-+    return status;
-+}
-+
-+static int check_sram_env_integrity(void)
-+{
-+    DECLARE_GLOBAL_DATA_PTR;
-+
-+	env_t *sram_env = (env_t*)CFG_ENV_ADDR;
-+	ulong crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+	if (crc == sram_env->crc) {
-+		gd->env_addr  = (ulong)sram_env->data;
-+		gd->env_valid = 1;
-+	}
-+
-+	return gd->env_valid;
-+}
-+
-+int env_init(void)
-+{
-+    DECLARE_GLOBAL_DATA_PTR;
-+
-+	/* Have not yet found a valid environment */
-+	gd->env_valid = 0;
-+
-+	/* Need SATA available to load environment from alternate disk locations */
-+	ide_init();
-+
-+	int i;
-+    for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
-+        if (!is_device_present(i)) {
-+            continue;
-+        }
-+
-+		/* Read environment from the primary environment area on disk */
-+        unsigned long read = ide_read(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
-+        if (read == CFG_ENV_SIZE/512) {
-+			/* Check integrity of primary environment data */
-+			if (check_sram_env_integrity()) {
-+				printf("Environment successfully read from disk %d primary image\n", i);
-+				break;
-+			}
-+        }
-+
-+		/* Read environment from the secondary environment area on disk */
-+		read = ide_read(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
-+		if (read == CFG_ENV_SIZE/512) {
-+			/* Check integrity of secondary environment data */
-+			if (check_sram_env_integrity()) {
-+				printf("Environment successfully read from disk %d secondary image\n", i);
-+				break;
-+			}
-+		}
-+	}
-+
-+	if (!gd->env_valid) {
-+		printf("Failed to read valid environment from disk, using built-in default\n");
-+        gd->env_addr  = (ulong)default_environment;
-+        gd->env_valid = 0;
-+	}
-+
-+    return 0;
-+}
-+#endif // CFG_ENV_IS_IN_DISK
-diff -Nurd u-boot-1.1.2/common/main.c u-boot-1.1.2-oxe810/common/main.c
---- u-boot-1.1.2/common/main.c	2004-04-23 22:32:06.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/main.c	2008-06-11 17:55:30.000000000 +0200
-@@ -182,7 +182,7 @@
- 			else {
- 				for (i = 0; i < presskey_max - 1; i ++)
- 					presskey [i] = presskey [i + 1];
--
-+do_recovery
- 				presskey [i] = getc();
- 			}
- 		}
-@@ -369,6 +369,149 @@
- 	install_auto_complete();
- #endif
- 
-+
-+#if defined(CONFIG_OXNAS)
-+	/* Set the memory size given to Linux */
-+	{
-+		DECLARE_GLOBAL_DATA_PTR;
-+
-+		/* Get a copy of the bootargs string from the runtime environment */
-+		char tempBuf[1024];
-+		char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+
-+		/* Find the extent of memory token in the bootargs string */
-+		char* mem_token = strstr(cmd_string, "mem=");
-+		char* mem_token_end = mem_token;
-+		while ((*mem_token_end != ' ') &&
-+			   (*mem_token_end != '\0')) {
-+			++mem_token_end;
-+		}
-+
-+		if ((*mem_token_end == '\0') && (mem_token != mem_token_end)) {
-+			/* Memory token is last in bootargs string */
-+			if (mem_token != cmd_string) {
-+				/* Is not the only token, so erase token and previous space" */
-+				*(mem_token-1) = '\0';
-+			} else {
-+				/* Is the only token, so no previous space to erase */
-+				*mem_token = '\0';
-+			}
-+		} else {
-+			/* Memory token is at intermediate location in bootargs string */
-+			if (*mem_token_end == ' ') {
-+				++mem_token_end;
-+			}
-+
-+			/* Form the bootargs string without the memory token present */
-+			strcpy(mem_token, mem_token_end);
-+		}
-+
-+		/* How many MB of SDRAM are present */
-+		int megabytes = gd->bd->bi_dram[0].size >> 20;
-+
-+		/* Append the memory token to the bootargs string */
-+		switch (megabytes) {
-+			case 64:
-+				cmd_string = strcat(cmd_string, " mem=64M");
-+				break;
-+			case 128:
-+				cmd_string = strcat(cmd_string, " mem=128M");
-+				break;
-+			case 256:
-+				cmd_string = strcat(cmd_string, " mem=256M");
-+				break;
-+			default:
-+				printf("Unsupported memory size, defaulting to 64M\n");
-+				cmd_string = strcat(cmd_string, " mem=64M");
-+		}
-+
-+		/* Save the revised bootargs string to the runtime environment */
-+		setenv("bootargs", cmd_string);
-+	}
-+
-+/* Upgrade, recovery and power button monitor code
-+*/
-+    int do_recovery = 0; /* default no recovery */
-+
-+    /* Read the upgrade flag from disk into memory */
-+    ide_init();
-+    run_command("ide read 48700000 ff 1", 0);
-+
-+    char upgrade_mode = *(volatile char*)0x48700000;
-+    char recovery_mode = *(volatile char*)0x48700001;
-+    char controlled_pd_mode = *(volatile char*)0x48700002;
-+
-+	if (recovery_mode == RECOVERY_MAGIC) {
-+		do_recovery = 1; /* perform recovery */
-+	} 
-+
-+	if (controlled_pd_mode == CONTROLLED_POWER_DOWN_MAGIC) {
-+		/* System in controlled pwer down mode */
-+
-+		/* Read the SRAM location for normal boot flag */
-+		char sram_data = *(volatile char*)(CFG_SRAM_BASE + CFG_SRAM_SIZE - POWER_ON_FLAG_SRAM_OFFSET);
-+		char tempBuf[1024];
-+		char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+
-+		if (sram_data == CONTROLLED_POWER_UP_MAGIC) {
-+			/* The system has to remain in power down state */
-+
-+			/* Set appropriate boot args */
-+			cmd_string = strcat(cmd_string, " powermode=controlledpup");
-+			printf("Controlled Power UP requested\n");
-+		} else {
-+			/* The system is moving to power up state from power down state */
-+			cmd_string = strcat(cmd_string, " powermode=controlledpdown");
-+			printf("Controlled Power DOWN requested\n");
-+		}
-+		setenv("bootargs", cmd_string);
-+	}
-+
-+    /* branch off inot recovery or upadate */
-+    if (upgrade_mode == UPGRADE_MAGIC) {
-+        /* Script to select first disk */
-+        parse_string_outer("set select0 ide dev 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script to select second disk */
-+        parse_string_outer("set select1 ide dev 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script for loading 256KB of upgrade rootfs image from hidden sectors */
-+        parse_string_outer("set loadf ide read 48700000 1770 200", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script for loading 2MB of upgrade kernel image from hidden sectors */
-+        parse_string_outer("set loadk ide read 48800000 1970 1000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script to light failure LED */
-+        parse_string_outer("set lightled ledfail 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script to extinguish failure LED */
-+        parse_string_outer("set extinguishled ledfail 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Script for booting Linux kernel image with mkimage-wrapped initrd */
-+        parse_string_outer("set boot bootm 48800000 48700000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Set Linux bootargs to use rootfs in initial ramdisk */
-+        parse_string_outer("set bootargs mem=32M console=ttyS0,115200 root=/dev/ram0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+        /* Validate, load and boot the first validate set of initrd and kernel 
-+           Theres alot of combos here due to disk/backup/fk arrangments, it'll
-+           no doubt work on the first or second one though. */
-+        parse_string_outer("run          select0 loadf          loadk                boot || "
-+                           "run lightled select1 loadf          loadk  extinguishled boot || "
-+                           "run lightled select0 loadf  select1 loadk  extinguishled boot || "
-+                           "run lightled select1 loadf  select0 loadk  extinguishled boot || "
-+						    "run lightled ", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+    } else if (do_recovery) {
-+		printf ("\nRecovery mode selected\n");
-+
-+		char tempBuf[1024];
-+		char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+		cmd_string = strcat(cmd_string, " adminmode=recovery");
-+		setenv("bootargs", cmd_string);
-+    } 
-+
-+#endif // CONFIG_OXNAS
-+
- #ifdef CONFIG_PREBOOT
- 	if ((p = getenv ("preboot")) != NULL) {
- # ifdef CONFIG_AUTOBOOT_KEYED
-diff -Nurd u-boot-1.1.2/common/Makefile u-boot-1.1.2-oxe810/common/Makefile
---- u-boot-1.1.2/common/Makefile	2004-12-16 18:35:57.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/Makefile	2008-06-11 17:55:30.000000000 +0200
-@@ -40,9 +40,10 @@
- 	  cmd_nand.o cmd_net.o cmd_nvedit.o \
- 	  cmd_pci.o cmd_pcmcia.o cmd_portio.o \
- 	  cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o \
-+	  cmd_ledfail.o \
- 	  command.o console.o devices.o dlmalloc.o docecc.o \
- 	  environment.o env_common.o \
--	  env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
-+	  env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o env_disk.o exports.o \
- 	  flash.o fpga.o \
- 	  hush.o kgdb.o lcd.o lists.o lynxkdi.o \
- 	  memsize.o miiphybb.o miiphyutil.o \
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/config.mk u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk
---- u-boot-1.1.2/cpu/arm926ejs/config.mk	2003-08-30 00:00:47.000000000 +0200
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk	2008-06-11 17:55:03.000000000 +0200
-@@ -21,7 +21,6 @@
- # MA 02111-1307 USA
- #
- 
--PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
--	-mshort-load-bytes -msoft-float
-+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8
- 
--PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4
-+PLATFORM_CPPFLAGS += -march=armv5te
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/interrupts.c u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c
---- u-boot-1.1.2/cpu/arm926ejs/interrupts.c	2004-03-23 22:43:08.000000000 +0100
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c	2008-06-11 17:55:03.000000000 +0200
-@@ -41,7 +41,12 @@
- #include <asm/proc-armv/ptrace.h>
- 
- extern void reset_cpu(ulong addr);
-+
-+#ifdef CONFIG_OXNAS
-+#define TIMER_LOAD_VAL 0xffffUL
-+#else // CONFIG_OXNAS
- #define TIMER_LOAD_VAL 0xffffffff
-+#endif // CONFIG_OXNAS
- 
- /* macro to read the 32 bit timer */
- #ifdef CONFIG_OMAP
-@@ -53,6 +58,9 @@
- #ifdef CONFIG_VERSATILE
- #define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4))
- #endif
-+#ifdef CONFIG_OXNAS
-+#define READ_TIMER ((*(volatile ushort *)(CFG_TIMERBASE+4)) & 0xFFFFUL)  /* RPS timer value register has only 16 defined bits */
-+#endif
- 
- #ifdef CONFIG_USE_IRQ
- /* enable IRQ interrupts */
-@@ -212,6 +220,16 @@
- 	*(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD;	/* TimerValue */
- 	*(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C;
- #endif	/* CONFIG_VERSATILE */
-+#ifdef CONFIG_OXNAS
-+    // Setup timer 1 load value
-+    *(volatile ulong*)(CFG_TIMERBASE + 0) = TIMER_LOAD_VAL;
-+
-+    // Setup timer 1 prescaler, periodic operation and start it
-+    *(volatile ulong*)(CFG_TIMERBASE + 8) =
-+        (TIMER_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+        (TIMER_MODE_PERIODIC << TIMER_MODE_BIT) |
-+        (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
-+#endif	/* CONFIG_OXNAS */
- 
- 	/* init the timestamp and lastdec value */
- 	reset_timer_masked();
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/start.S u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S
---- u-boot-1.1.2/cpu/arm926ejs/start.S	2004-06-09 02:11:01.000000000 +0200
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S	2008-06-11 17:55:03.000000000 +0200
-@@ -94,6 +94,11 @@
- _TEXT_BASE:
- 	.word	TEXT_BASE
- 
-+#ifdef CONFIG_OXNAS
-+_EXCEPTION_BASE:
-+	.word	EXCEPTION_BASE
-+#endif
-+
- .globl _armboot_start
- _armboot_start:
- 	.word _start
-@@ -135,6 +140,18 @@
- 	orr	r0,r0,#0xd3
- 	msr	cpsr,r0
- 
-+#ifdef CONFIG_OXNAS
-+	/*
-+	 * Copy exception table to relocated address in internal SRAM
-+	 */
-+	adr	r0, _start				/* Address of exception table in flash */
-+	ldr	r1, _EXCEPTION_BASE		/* Relocated address of exception table */
-+	ldmia	r0!, {r3-r10}		/* Copy exception table and jump values from */
-+	stmia	r1!, {r3-r10}		/* FLASH to relocated address */
-+	ldmia	r0!, {r3-r10}
-+	stmia	r1!, {r3-r10}
-+#endif
-+
- 	/*
- 	 * we do sys-critical inits only at reboot,
- 	 * not when booting from ram!
-@@ -143,21 +160,21 @@
- 	bl	cpu_init_crit
- #endif
- 
--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
-+relocate:					/* relocate U-Boot to RAM */
-+	adr	r0, _start			/* current position of code */
-+	ldr	r1, _TEXT_BASE		/* relocated position of code */
-+	cmp	r0, r1
-+	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         */
-+	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]    */
-+	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
- 
- 	/* Set up the stack						    */
-@@ -212,7 +229,7 @@
- 	mrc	p15, 0, r0, c1, c0, 0
- 	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
- 	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
--	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
-+	orr	r0, r0, #0x00000002	/* set bit 1 (A) Align */
- 	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
- 	mcr	p15, 0, r0, c1, c0, 0
- 
-@@ -391,6 +408,7 @@
- 
- #endif
- 
-+#ifndef CONFIG_OXNAS
- 	.align	5
- .globl reset_cpu
- reset_cpu:
-@@ -405,3 +423,4 @@
- 
- rstctl1:
- 	.word	0xfffece10
-+#endif // !CONFIG_OXNAS
-diff -Nurd u-boot-1.1.2/drivers/cfi_flash.c u-boot-1.1.2-oxe810/drivers/cfi_flash.c
---- u-boot-1.1.2/drivers/cfi_flash.c	2004-12-18 23:35:45.000000000 +0100
-+++ u-boot-1.1.2-oxe810/drivers/cfi_flash.c	2008-06-11 17:55:31.000000000 +0200
-@@ -1056,7 +1056,11 @@
- 			}
- 			tmp = flash_read_long (info, 0,
- 					       FLASH_OFFSET_ERASE_REGIONS +
-+#ifdef FORCE_TOP_BOOT_FLASH
-+					       (num_erase_regions - 1 - i) * 4);
-+#else
- 					       i * 4);
-+#endif
- 			erase_region_size =
- 				(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
- 			tmp >>= 16;
-@@ -1104,6 +1108,7 @@
- 	cfiptr_t ctladdr;
- 	cfiptr_t cptr;
- 	int flag;
-+	ulong start;
- 
- 	ctladdr.cp = flash_make_addr (info, 0, 0);
- 	cptr.cp = (uchar *) dest;
-@@ -1151,6 +1156,15 @@
- 		break;
- 	case FLASH_CFI_16BIT:
- 		cptr.wp[0] = cword.w;
-+		/* Wait for write to complete */
-+		start = get_timer (0);
-+		while (cptr.wp[0] != cword.w) {
-+			printf(".");
-+			if (get_timer (start) > info->erase_blk_tout * CFG_HZ) {
-+				printf ("Flash write timeout!");;
-+			}
-+		}
-+		printf("\n");
- 		break;
- 	case FLASH_CFI_32BIT:
- 		cptr.lp[0] = cword.l;
-diff -Nurd u-boot-1.1.2/drivers/ns16550.c u-boot-1.1.2-oxe810/drivers/ns16550.c
---- u-boot-1.1.2/drivers/ns16550.c	2004-06-07 01:13:57.000000000 +0200
-+++ u-boot-1.1.2-oxe810/drivers/ns16550.c	2008-06-11 17:55:31.000000000 +0200
-@@ -14,8 +14,25 @@
- #define MCRVAL (MCR_DTR | MCR_RTS)			/* RTS/DTR */
- #define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR)	/* Clear & enable FIFOs */
- 
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+static int oxnas_fractional_divider(NS16550_t com_port, int baud_divisor)
-+{
-+	// Baud rate is passed around x16
-+	int real_divisor = baud_divisor >> 4;
-+	// Top three bits of 8-bit dlf register hold the number of eigths
-+	// for the fractional part of the divide ratio
-+	com_port->dlf = (unsigned char)(((baud_divisor - (real_divisor << 4)) << 4) & 0xFF);
-+	// Return the x1 divider for the normal divider register
-+	return real_divisor;
-+}
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- void NS16550_init (NS16550_t com_port, int baud_divisor)
- {
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+	baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- 	com_port->ier = 0x00;
- #ifdef CONFIG_OMAP1510
- 	com_port->mdr1 = 0x7;	/* mode select reset TL16C750*/
-@@ -33,6 +50,10 @@
- 
- void NS16550_reinit (NS16550_t com_port, int baud_divisor)
- {
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+	baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- 	com_port->ier = 0x00;
- 	com_port->lcr = LCR_BKSE;
- 	com_port->dll = baud_divisor & 0xff;
-diff -Nurd u-boot-1.1.2/drivers/serial.c u-boot-1.1.2-oxe810/drivers/serial.c
---- u-boot-1.1.2/drivers/serial.c	2003-08-30 00:00:47.000000000 +0200
-+++ u-boot-1.1.2-oxe810/drivers/serial.c	2008-06-11 17:55:31.000000000 +0200
-@@ -59,7 +59,13 @@
- 		return (26);		/* return 26 for base divisor */
- 	}
- #endif
--	return (CFG_NS16550_CLK / 16 / gd->baudrate);
-+
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+	return (((CFG_NS16550_CLK << 4) / gd->baudrate) + 8) >> 4;	
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
-+    // Round to nearest integer
-+    return (((CFG_NS16550_CLK / gd->baudrate) + 8 ) / 16);
- }
- 
- int serial_init (void)
-diff -Nurd u-boot-1.1.2/examples/Makefile u-boot-1.1.2-oxe810/examples/Makefile
---- u-boot-1.1.2/examples/Makefile	2004-10-10 23:27:33.000000000 +0200
-+++ u-boot-1.1.2-oxe810/examples/Makefile	2008-06-11 17:55:30.000000000 +0200
-@@ -30,7 +30,8 @@
- endif
- 
- ifeq ($(ARCH),arm)
--LOAD_ADDR = 0xc100000
-+#LOAD_ADDR = 0xc100000
-+LOAD_ADDR = 0x4C004000
- endif
- 
- ifeq ($(ARCH),mips)
-@@ -58,6 +59,11 @@
- SREC	= hello_world.srec
- BIN	= hello_world.bin hello_world
- 
-+ifeq ($(ARCH),arm)
-+SREC   += mem_test.srec
-+BIN    += mem_test.bin mem_test
-+endif
-+
- ifeq ($(ARCH),i386)
- SREC   += 82559_eeprom.srec
- BIN    += 82559_eeprom.bin 82559_eeprom
-@@ -115,10 +121,10 @@
- 	$(LD) -g $(EX_LDFLAGS) -Ttext $(LOAD_ADDR) \
- 		-o $@ -e $(<:.o=) $< $(LIB) \
- 		-L$(gcclibdir) -lgcc
--%.srec:	%
-+%.srec:	%.o
- 	$(OBJCOPY) -O srec $< $@ 2>/dev/null
- 
--%.bin:	%
-+%.bin:	%.o
- 	$(OBJCOPY) -O binary $< $@ 2>/dev/null
- 
- #########################################################################
-diff -Nurd u-boot-1.1.2/examples/mem_test.c u-boot-1.1.2-oxe810/examples/mem_test.c
---- u-boot-1.1.2/examples/mem_test.c	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/examples/mem_test.c	2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,1322 @@
-+/*
-+ * (C) Copyright 2006
-+ * Oxford Semiconductor Ltd, www.oxsemi.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
-+ */
-+
-+/********************* OPTIONS ********************************************************/
-+
-+#define ARM
-+/*
-+#define QUIET
-+#define SHORT
-+*/
-+
-+/********************* TEST DEFINITIONS ********************************************************/
-+
-+
-+#define NUM_PATTYPES 5
-+#define PATTYPE_A5     0
-+#define PATTYPE_5A     1
-+#define PATTYPE_NO_FF  2
-+#define PATTYPE_INCR   3
-+#define PATTYPE_DECR   4
-+
-+/* Number of words in a block (to ensure that neither data not ~data is 0xFFxx) */
-+
-+#ifdef SHORT
-+    #define BLOCKWORDS (254*4)
-+    #define BLOCKSIZE  (256*4)
-+#else
-+    #define BLOCKWORDS (254*256*4)
-+    #define BLOCKSIZE  (256*256*4)
-+#endif
-+
-+#ifdef ARM
-+    #include <common.h>
-+    #include <exports.h>
-+
-+    #define SDRAM_BASE  0x48000000
-+    #define SDRAM_TOP   0x49000000
-+    #define SDRAM_BLOCK 0x10000
-+//    #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR));
-+//    #define SDRAM_READ(ADDR, VAR) printf("Read from 0x%08x\n", (ADDR));
-+//    #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR)); (*((volatile unsigned int *)(ADDR)) = (DATA))
-+//    #define SDRAM_READ(ADDR, VAR)  printf("Read from 0x%08x\n", (ADDR)); (*(VAR) = *((volatile unsigned int *)(ADDR)))
-+    #define SDRAM_WRITE(ADDR, DATA) (*((volatile unsigned int *)(ADDR)) = (DATA))
-+    #define SDRAM_READ(ADDR, VAR)  (*(VAR) = *((volatile unsigned int *)(ADDR)))
-+#else
-+    #include <stdio.h>
-+    #include <stdlib.h>
-+    /* Not so much space - just 2 blocks from addr 0... */
-+    #define SDRAM_BASE  0
-+    #define SDRAM_TOP   (2 * BLOCKSIZE)
-+    #define SDRAM_BLOCK 0x10000
-+    #ifdef QUIET
-+        #define SDRAM_WRITE(ADDR, DATA)      array[ADDR] = (DATA)
-+        #define SDRAM_READ(ADDR, VAR)        *((volatile unsigned int *)(VAR)) = array[ADDR]
-+    #else
-+        #define SDRAM_WRITE(ADDR, DATA)      printf("WRITE(%08x)=%08x\n", ADDR, DATA); array[ADDR] = (DATA)
-+        #define SDRAM_READ(ADDR, VAR)        printf("READ (%08x)=%08x\n", ADDR, array[ADDR]); *((volatile unsigned int *)(VAR)) = array[ADDR]
-+    #endif
-+    unsigned volatile int array[SDRAM_TOP];
-+#endif
-+
-+
-+#define SYSCTRL_PRIMSEL_LO      0x4500000C
-+#define SYSCTRL_SECSEL_LO       0x45000014
-+#define SYSCTRL_TERSEL_LO       0x4500008C
-+#define SYSCTRL_PRIMSEL_HI      0x45000010
-+#define SYSCTRL_SECSEL_HI       0x45000018
-+#define SYSCTRL_TERSEL_HI       0x45000090
-+
-+/* GPIO */
-+#define GPIOB_IO_VAL       0x44100000
-+#define GPIOB_OE_VAL       0x44100004
-+#define GPIOB_SET_OE       0x4410001C
-+#define GPIOB_CLEAR_OE     0x44100020
-+#define GPIOB_OUTPUT_VAL   0x44100010
-+#define GPIOB_SET_OUTPUT   0x44100014
-+#define GPIOB_CLEAR_OUTPUT 0x44100018
-+#define GPIOB_BIT_34       0x00000004
-+
-+void configure_caches(void);
-+void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration);
-+
-+/********************* TYPES.H ********************************************************/
-+
-+typedef unsigned int    UINT,  *PUINT;
-+/*
-+#ifndef __MY_BASIC_TYPES_H
-+#define __MY_BASIC_TYPES_H
-+
-+typedef signed char     CHAR,  *PCHAR;
-+typedef unsigned char   BYTE,   UCHAR,  *PBYTE, *PUCHAR;
-+typedef signed short    SHORT, *PSHORT;
-+typedef unsigned short  WORD,   USHORT, *PWORD, *PUSHORT;
-+typedef signed long     LONG,  *PLONG;
-+typedef unsigned long   DWORD, *PDWORD;
-+typedef int             BOOL,  *PBOOL;
-+typedef unsigned int    UINT,  *PUINT;
-+typedef void            VOID,  *PVOID;
-+
-+typedef float           SINGLE,*PSINGLE;
-+typedef double          DOUBLE,*PDOUBLE;
-+
-+
-+#define FALSE 0
-+#define TRUE  1
-+
-+#endif
-+*/
-+
-+/********************* CHIP.H ********************************************************/
-+
-+// Address Map
-+#define BOOT_ROM_BASE       0x00000000
-+#define USBHS_BASE          0x00200000
-+#define GMAC_BASE           0x00400000
-+#define PCI_BASE            0x00600000
-+#define PCI_DATA_BASE       0x00800000
-+#define STATIC0_BASE        0x01000000
-+#define STATIC1_BASE        0x01400000
-+#define STATIC2_BASE        0x01800000
-+#define STATIC_BASE         0x01C00000
-+#define SATA_DATA_BASE      0x02000000
-+#define DPE_DATA_BASE       0x03000000
-+#define GPIOA_BASE          0x04000000
-+#define GPIOB_BASE          0x04100000
-+#define UARTA_BASE          0x04200000
-+#define UARTB_BASE          0x04300000
-+#define I2C_MASTER_BASE     0x04400000
-+#define AUDIO_BASE          0x04500000
-+#define FAN_BASE            0x04600000
-+#define PWM_BASE            0x04700000
-+#define IR_RX_BASE          0x04800000
-+#define UARTC_BASE          0x04900000
-+#define UARTD_BASE          0x04A00000
-+#define SYS_CTRL_BASE       0x05000000
-+#define RPSA_BASE           0x05300000
-+#define  ARM_RPS_BASE  RPSA_BASE 
-+#define RPSC_BASE           0x05400000
-+#define AHB_MON_BASE        0x05500000
-+#define DMA_BASE            0x05600000
-+#define DPE_BASE            0x05700000
-+#define IBIW_BASE           0x05780000
-+#define DDR_BASE            0x05800000
-+#define SATA0_BASE          0x05900000
-+#define SATA1_BASE          0x05980000
-+#define DMA_CHKSUM_BASE     0x05A00000
-+#define COPRO_BASE          0x05B00000
-+#define SGDMA_BASE          0x05C00000
-+#define DDR_DATA_BASE       0x08000000
-+#define SRAM_BASE           0x0C000000
-+#define SRAM0_BASE          0x0C000000
-+#define SRAM1_BASE          0x0C002000
-+#define SRAM2_BASE          0x0C004000
-+#define SRAM3_BASE          0x0C006000
-+
-+// Virtual peripheral for TB sync
-+#define TB_SYNC_BASE        0x05F00100
-+
-+
-+/********************* DMA.H ********************************************************/
-+
-+
-+// DMA Control register settings
-+
-+#define DMA_FAIR_SHARE                  (1<<0)
-+#define DMA_IN_PROGRESS                 (1<<1)
-+
-+#define DMA_SDREQ_SATA                  (0<<2)
-+#define DMA_SDREQ_DPE_OUT               (2<<2)
-+#define DMA_SDREQ_UARTA_RX              (4<<2)
-+#define DMA_SDREQ_AUDIO_RX              (6<<2)
-+#define DMA_SDREQ_MEM                   (0xF<<2)
-+
-+#define DMA_DDREQ_SATA                  (0<<6)
-+#define DMA_DDREQ_DPE_IN                (1<<6)
-+#define DMA_DDREQ_UARTA_TX              (3<<6)
-+#define DMA_DDREQ_AUDIO_TX              (5<<6)
-+#define DMA_DDREQ_MEM                   (0xF<<6)
-+
-+#define DMA_INTERRUPT                   (1 << 10)
-+#define DMA_NEXT_FREE                   (1 << 11)
-+#define DMA_CH_RESET                    (1 << 12)
-+
-+#define DMA_DIR_ATOA                    (0 << 13)
-+#define DMA_DIR_BTOA                    (1 << 13)
-+#define DMA_DIR_ATOB                    (2 << 13)
-+#define DMA_DIR_BTOB                    (3 << 13)
-+
-+#define DMA_BURST_A                     (1 << 17)
-+#define DMA_BURST_B                     (1 << 18)
-+
-+#define DMA_SWIDTH_8                    (0 << 19)
-+#define DMA_SWIDTH_16                   (1 << 19)
-+#define DMA_SWIDTH_32                   (2 << 19)
-+
-+#define DMA_DWIDTH_8                    (0 << 22)
-+#define DMA_DWIDTH_16                   (1 << 22)
-+#define DMA_DWIDTH_32                   (2 << 22)
-+
-+#define DMA_PAUSE                       (1 << 25)
-+#define DMA_INT_ENABLE                  (1 << 26)
-+#define DMA_STARVE_LO_PRIORITY          (1 << 29)
-+#define DMA_NEW_INT_CLEAR               (1 << 30)
-+
-+#define DMA_FIXED_SADDR                 ((0 << 15) | (1 << 27))
-+#define DMA_INCR_SADDR                  ((1 << 15) | (0 << 27))
-+#define DMA_SEMI_FIXED_SADDR            ((0 << 15) | (0 << 27))
-+
-+#define DMA_FIXED_DADDR                 ((0 << 16) | (1 << 28))
-+#define DMA_INCR_DADDR                  ((1 << 16) | (0 << 28))
-+#define DMA_SEMI_FIXED_DADDR            ((0 << 16) | (0 << 28))
-+
-+#define DMA_BASE_CTRL                   (DMA_BURST_A | DMA_BURST_B | DMA_INT_ENABLE | DMA_NEW_INT_CLEAR)
-+
-+// Common base setups
-+
-+#define DMA_CTRL_A32TOA32               ( DMA_BASE_CTRL | DMA_DIR_ATOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOA32               ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_A32TOB32               ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOB32               ( DMA_BASE_CTRL | DMA_DIR_BTOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+
-+#define DMA_CTRL_A8TOB32                ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_8  | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOA8                ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_8  )
-+#define DMA_CTRL_A32TOB8                ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_8  )
-+
-+// Most likely transactions
-+
-+#define DMA_CTRL_MEM_TO_MEM_AA          ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_AB          ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_BB          ( DMA_CTRL_B32TOB32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_BA          ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM             ( DMA_CTRL_MEM_TO_MEM_AB ) 
-+
-+//DMA A-A
-+#define DMA_CTRL_SATA_TO_MEM_AA         ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA     | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_SATA_AA         ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_SATA     | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+
-+#define DMA_CTRL_SATA_TO_MEM            ( DMA_CTRL_A32TOB32 | DMA_SDREQ_SATA     | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_SATA            ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_SATA     | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_SATA_TO_DPE            ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA     | DMA_DDREQ_DPE_IN   | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_DPE_TO_SATA            ( DMA_CTRL_A32TOA32 | DMA_SDREQ_DPE_OUT  | DMA_DDREQ_SATA     | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_DPE             ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_DPE_IN   | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_DPE_TO_MEM             ( DMA_CTRL_A32TOB32 | DMA_SDREQ_DPE_OUT  | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_PCI_TO_MEM             ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+
-+#define DMA_CTRL_MEM_TO_PCI             ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_MEM      | DMA_INCR_SADDR       | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_AUDIO           ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM      | DMA_DDREQ_AUDIO_TX | DMA_INCR_SADDR       | DMA_FIXED_DADDR )
-+#define DMA_CTRL_AUDIO_TO_MEM           ( DMA_CTRL_A32TOB32 | DMA_SDREQ_AUDIO_RX | DMA_DDREQ_MEM      | DMA_FIXED_SADDR      | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_UART            ( DMA_CTRL_B32TOA8  | DMA_SDREQ_MEM      | DMA_DDREQ_UARTA_TX | DMA_INCR_SADDR       | DMA_FIXED_DADDR )
-+#define DMA_CTRL_UART_TO_MEM            ( DMA_CTRL_A8TOB32  | DMA_SDREQ_UARTA_RX | DMA_DDREQ_MEM      | DMA_FIXED_SADDR      | DMA_INCR_DADDR )
-+
-+// Byte count register flags
-+
-+#define DMA_HBURST_EN                   (1<<28)
-+#define DMA_WR_BUFFERABLE               (1<<29)
-+#define DMA_WR_EOT                      (1<<30)
-+#define DMA_RD_EOT                      (1<<31)
-+
-+
-+// Pause the DMA channel specified
-+void PauseDMA( UINT channel );
-+
-+// UnPause the DMA channel specified
-+void UnPauseDMA( UINT channel );
-+
-+// Configure a DMA
-+void SetupDMA( UINT channel,
-+               UINT src_addr,
-+               UINT dest_addr,
-+               UINT byte_count,
-+               UINT control,
-+               UINT flags );
-+
-+// Wait while the given DMA channel is busy
-+void WaitWhileDMABusy( UINT channel );
-+
-+// Perform a memory to memory copy
-+void DMAMemCopy ( UINT channel,
-+                  UINT src_addr,
-+                  UINT dest_addr,
-+                  UINT byte_count );
-+
-+
-+/****************************** MAIN ***********************************************/
-+#ifdef ARM
-+int mem_test(int argc, char* argv[])
-+#else
-+int main(int argc, char* argv[])
-+#endif
-+{
-+    unsigned int i;
-+    unsigned int iteration;
-+    unsigned int block_base;
-+    unsigned int datapattern;
-+    unsigned int correct_data;
-+    unsigned volatile int read_data;
-+    unsigned int pattype, starting_pattype;
-+    unsigned int end_addr;
-+    unsigned int row, col, bank;
-+
-+#ifdef ARM
-+    /* Print the ABI version */
-+    app_startup(argv);
-+    printf ("Example expects ABI version %d\n", XF_VERSION);
-+    printf ("Actual U-Boot ABI version %d\n", (int)get_version());
-+
-+    printf("GPIO34 is output, low\n");
-+    * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+    * (volatile unsigned int *) GPIOB_SET_OE       = GPIOB_BIT_34;
-+#endif
-+
-+//    configure_caches();
-+//printf("Caches enabled\n");
-+
-+    /* ******************************************************************* */
-+    printf("DMA TEST.\n" );
-+    /* ******************************************************************* */
-+
-+
-+    #define DMA0_CTRL_STAT    0x45A00000
-+    #define DMA0_SRC_BASE     0x45A00004
-+    #define DMA0_DEST_BASE    0x45A00008
-+    #define DMA0_BYTE_COUNT   0x45A0000C
-+    #define DMA0_CURRENT_BYTE 0x45A00018
-+
-+    printf("Test to top of 1st SDRAM" );
-+    #define BLOCK_BYTES 0x20000
-+    #define SDRAM_STOP SDRAM_TOP
-+
-+    for (iteration=0; 1; iteration++) {
-+
-+        if ((iteration % 5)==0)
-+            printf("Iteration %d\n", iteration );
-+
-+//        printf("Write pattern into first block.\n" );
-+        end_addr = SDRAM_BASE + BLOCK_BYTES;
-+        for (i=SDRAM_BASE; i < end_addr; i=i+4) {
-+            SDRAM_WRITE( i, i);
-+        }
-+
-+//        printf("Clear last block and a few blocks more - easy to see on LA.\n" );
-+        end_addr = SDRAM_BASE + (BLOCK_BYTES << 3);
-+        for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
-+            SDRAM_WRITE( i, 0);
-+        }
-+
-+        end_addr = SDRAM_STOP - BLOCK_BYTES;
-+        for (i=SDRAM_BASE; i < end_addr; i=i+BLOCK_BYTES) {
-+
-+//            printf("DMA transfer from %08x to %08x.\n", i, i + BLOCK_BYTES );
-+#ifdef ARM
-+            DMAMemCopy ( 0, i, i + BLOCK_BYTES, BLOCK_BYTES );
-+#endif
-+//            printf("...pending.\n" );
-+#ifdef ARM
-+            WaitWhileDMABusy( 0 );
-+#endif
-+//            printf("...complete.\n" );
-+        }
-+
-+//        printf("Verify pattern in last block.\n" );
-+        end_addr = SDRAM_STOP;
-+        correct_data = SDRAM_BASE;
-+        for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
-+            SDRAM_READ( i, &read_data);
-+            if (read_data != correct_data)
-+            {
-+            /* Expand out the report_err function to avoid the stack operations. */
-+            #ifdef ARM
-+                /* ASSERT GPIO */
-+                * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
-+            #endif
-+
-+                /* REPORT ERROR */
-+                printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", i, read_data, correct_data, iteration );
-+
-+                /* WRITE TO ANOTHER LOCATION */
-+                SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+                /* READ AGAIN */
-+                SDRAM_READ(i, &read_data);
-+                if (read_data != correct_data)
-+                    printf("Again 1  [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+                /* WRITE TO ANOTHER LOCATION */
-+                SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+                /* READ AGAIN */
-+                SDRAM_READ(i, &read_data);
-+                if (read_data != correct_data)
-+                    printf("Again 2  [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+                /* WRITE TO ANOTHER LOCATION */
-+                SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+                /* READ AGAIN */
-+                SDRAM_READ(i, &read_data);
-+                if (read_data != correct_data)
-+                    printf("Again 3  [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+                row = (((i >> 26) & 0x1) << 13) | (((i >> 23) & 0x3) << 11) | ((i >> 10) & 0x7FF); /* [26], [24:23], [20:10]*/
-+                col = (((i >> 27) & 0x1) << 10) | (((i >> 25) & 0x1) << 9) | (((i >> 22) & 0x1) << 8); /* [27], [25], [22]... */
-+                col |= (((i >> 6) & 0xF) << 4) | (((i >> 21) & 0x1) << 3) | (((i >> 1) & 0x3) << 1); /* ...[9:8], [21], [3:2], '0' */
-+                col |= 0x800; /* bit 11 set for auto-precharge */
-+                bank = (i >> 4) & 0x3; /* [5:4] */
-+                printf("Bank   %08x\n", bank );
-+                printf("Row    %08x\n", row );
-+                printf("Column %08x\n", col );
-+            #ifdef ARM
-+                /* DEASSERT GPIO */
-+                * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+            #endif
-+            }
-+
-+
-+            correct_data += 4;
-+        }
-+    }
-+
-+
-+    /* ******************************************************************* */
-+    printf("MEM_TEST2\n");
-+    /* ******************************************************************* */
-+
-+
-+    pattype=0;
-+    iteration=0;
-+
-+    for (;;) { 
-+        /* FOR EACH 64Kword==256KB BLOCK IN 16Mword=64MB (2 OFF 16M16) MEMORY... */
-+
-+#ifdef SHORT
-+        if ((iteration % 5)==0)
-+            printf("Iteration %d\n", iteration );
-+#else
-+        if ((iteration % 1000)==0)
-+            printf("Iteration %d\n", iteration );
-+#endif
-+
-+        /* WRITE DATA BLOCKS */
-+        starting_pattype = pattype; /* Record for later */
-+
-+        for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
-+	    switch (pattype) {
-+	    case PATTYPE_A5 :
-+                /* Write alternating 1s and 0s... */
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_WRITE( i, 0xaa55aa55);
-+                }
-+                break;
-+	    case PATTYPE_5A :
-+                /* Write alternating 1s and 0s (inverse of above)... */
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_WRITE( i, 0x55aa55aa);
-+                }
-+                break;
-+	    case PATTYPE_NO_FF : 
-+                /* Write data=address with bit[n+16]=~bit[n]... */
-+                datapattern = 0x0100FEFF;
-+                /* In range 0x0100...0xFEFF so that
-+                    a. temp[15:8] is never 0xFF
-+                    b. Inverse of temp[15:8] is never 0xFF
-+                */
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_WRITE( i, datapattern);
-+                    datapattern = datapattern + 0xFFFF;
-+                }
-+                break;
-+	    case PATTYPE_INCR : 
-+                /* Write data=address... */
-+                end_addr = block_base + BLOCKSIZE;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_WRITE( i, i);
-+                }
-+                break;
-+	    case PATTYPE_DECR : 
-+                /* Write data=~address... */
-+                end_addr = block_base + BLOCKSIZE;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_WRITE( i, ~i);
-+                }
-+                break;
-+            }
-+        }
-+
-+        /* VERIFY DATA BLOCKS */
-+        pattype = starting_pattype; /* Reset to same as for writes */
-+
-+        for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
-+	    switch (pattype) {
-+	    case PATTYPE_A5 :
-+                correct_data = 0xaa55aa55;
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_READ( i, &read_data);
-+                    if (read_data != correct_data)
-+                        report_err(i, read_data, correct_data, iteration);
-+                }
-+                break;
-+	    case PATTYPE_5A :
-+                correct_data = 0x55aa55aa;
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_READ( i, &read_data);
-+                    if (read_data != correct_data)
-+                        report_err(i, read_data, correct_data, iteration);
-+                }
-+                break;
-+	    case PATTYPE_NO_FF :
-+                correct_data = 0x0100FEFF;
-+                end_addr = block_base + BLOCKWORDS;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_READ( i, &read_data);
-+                    if (read_data != correct_data)
-+                        report_err(i, read_data, correct_data, iteration);
-+                    correct_data = correct_data + 0xFFFF;
-+                }
-+                break;
-+	    case PATTYPE_INCR :
-+                end_addr = block_base + BLOCKSIZE;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_READ( i, &read_data);
-+                    if (read_data != i)
-+                        report_err(i, read_data, i, iteration);
-+                }
-+                break;
-+	    case PATTYPE_DECR :
-+                end_addr = block_base + BLOCKSIZE;
-+                for (i=block_base; i < end_addr; i=i+4) {
-+                    SDRAM_READ( i, &read_data);
-+                    if (read_data != ~i)
-+                        report_err(i, read_data, ~i, iteration);
-+                }
-+                break;
-+            }
-+        }
-+
-+	pattype = pattype + 1;
-+	if (pattype >= NUM_PATTYPES) { pattype = 0; }
-+        ++iteration;
-+    }
-+
-+    return 0;
-+}
-+
-+/********************* REPORT ERROR FUNC ********************************************************/
-+
-+void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration)
-+{
-+    volatile unsigned int readvalue;
-+
-+#ifdef ARM
-+    /* ASSERT GPIO */
-+    * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
-+#endif
-+
-+    /* REPORT ERROR */
-+    printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", address, bad_data, correct_data, iteration );
-+
-+    /* WRITE TO ANOTHER LOCATION */
-+    SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+    /* READ AGAIN */
-+    SDRAM_READ(address, &readvalue);
-+    if (readvalue != correct_data)
-+        printf("Again 1  [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+    /* WRITE TO ANOTHER LOCATION */
-+    SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+    /* READ AGAIN */
-+    SDRAM_READ(address, &readvalue);
-+    if (readvalue != correct_data)
-+        printf("Again 2  [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+    /* WRITE TO ANOTHER LOCATION */
-+    SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+    /* READ AGAIN */
-+    SDRAM_READ(address, &readvalue);
-+    if (readvalue != correct_data)
-+        printf("Again 3  [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+#ifdef ARM
-+    /* DEASSERT GPIO */
-+    * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+#endif
-+
-+} /* end of report_err */
-+
-+
-+
-+
-+/********************* DMA.C FUNCTIONS ********************************************************/
-+
-+void ResetDMA( UINT channel ) {
-+    
-+    // Clear and abort the dma channel
-+    
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    dma[0] =  (1 << 12);
-+    dma[0] &=  ~(1 << 12);
-+}
-+
-+
-+
-+
-+void PauseDMA( UINT channel ) {
-+    
-+    // Pause the DMA channel specified
-+    
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    UINT  rd;
-+    
-+    rd = dma[0];
-+    
-+    rd |= DMA_PAUSE;
-+    
-+    dma[0] = rd;
-+}
-+
-+
-+
-+
-+void UnPauseDMA( UINT channel ) {
-+    
-+    // UnPause the DMA channel specified
-+    
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    UINT  rd;
-+    
-+    rd = dma[0];
-+    
-+    rd &= ~DMA_PAUSE;
-+    
-+    dma[0] = rd;
-+}
-+
-+
-+
-+
-+void SetupDMA( UINT channel,
-+               UINT src_addr,
-+               UINT dest_addr,
-+               UINT byte_count,
-+               UINT control,
-+               UINT flags ) {
-+
-+    // Configure a DMA
-+    
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    
-+    dma[0] = control;
-+    dma[1] = src_addr;
-+    dma[2] = dest_addr;
-+    dma[3] = byte_count | (flags & 0xF0000000);
-+}
-+
-+// EXAMPLE:
-+//
-+// DMA 2kB from SRAM to SATA core with a write EOT set, and HBURST enabled, using DMA channel 2
-+// Then wait for the DMA to complete
-+//
-+//   SetupDMA ( 2 , 0x4C001100, BASE_SATA, 2048, DMA_CTRL_MEM_TO_SATA, WR_EOT | DMA_HBURST_EN );
-+//   WaitWhileDMABusy( 2 );
-+
-+int DMABusy(UINT channel)
-+{
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    return (dma[0] & DMA_IN_PROGRESS ? 1 : 0);
-+}
-+
-+
-+void WaitWhileDMABusy( UINT channel ) // Wait while the given DMA channel is busy
-+{
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    while (dma[0] & DMA_IN_PROGRESS) ; // Do Nothing
-+}
-+
-+void DMAClearIRQ(UINT channel) 
-+{
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    dma[4] = 1; // write any value to offset 0x10 (16 / 4 => 4) 
-+
-+}
-+
-+void DMAMemCopy ( UINT channel,
-+                  UINT src_addr,
-+                  UINT dest_addr,
-+                  UINT byte_count ) {
-+    
-+    // Perform a memory to memory copy
-+    
-+    volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+    
-+    // Choose fastest configuration possible for required transfer
-+    
-+    if (src_addr < SRAM_BASE) {
-+        if (dest_addr < SRAM_BASE) {
-+            dma[0] = DMA_CTRL_MEM_TO_MEM_AA; // Src and Dest must use A
-+        } else {
-+            dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // Src must use A
-+        }
-+    } else {
-+        if (dest_addr < SRAM_BASE) {
-+            dma[0] = DMA_CTRL_MEM_TO_MEM_BA; // Dest must use A
-+        } else {
-+            dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // No restriction
-+        }
-+    }
-+    
-+    dma[1] = src_addr;
-+    dma[2] = dest_addr;
-+    dma[3] = byte_count | DMA_WR_BUFFERABLE | DMA_HBURST_EN;
-+    
-+    WaitWhileDMABusy( channel );
-+}
-+ 
-+
-+
-+
-+
-+
-+
-+#define CP15R1_M_ENABLE 0x0001 // MMU Enable
-+#define CP15R1_A_ENABLE 0x0002 // Address alignment fault enable
-+#define CP15R1_C_ENABLE 0x0004 // (data) cache enable
-+#define CP15R1_W_ENABLE 0x0008 // write buffer enable
-+#define CP15R1_PROG32   0x0010 // PROG32
-+#define CP15R1_DATA32   0x0020 // DATA32
-+#define CP15R1_L_ENABLE 0x0040 // Late abort on earlier CPUs
-+#define CP15R1_BIGEND   0x0080 // Big-endian (=1), little-endian (=0)
-+#define CP15R1_SYSTEM   0x0100 // System bit, modifies MMU protections
-+#define CP15R1_ROM      0x0200 // ROM bit, modifies MMU protections
-+#define CP15R1_F        0x0400 // Should Be Zero
-+#define CP15R1_Z_ENABLE 0x0800 // Branch prediction enable on 810
-+#define CP15R1_I_ENABLE 0x1000 // Instruction cache enable
-+#define CP15R1_RESERVED 0x00000078
-+#define CP15R2_RESERVED 0xFFFFC000
-+
-+#define NUM_DOMAINS 16
-+
-+#define DAV_NO_ACCESS 0
-+#define DAV_CLIENT    1
-+#define DAV_RESERVED  2
-+#define DAV_MANAGER   3
-+#define NUM_DOMAIN_ACCESS_VALUES 4
-+
-+#define AP_LEVEL_0 0
-+#define AP_LEVEL_1 0
-+#define AP_LEVEL_2 0
-+#define AP_LEVEL_3 0
-+#define NUM_ACCESS_PERMISSIONS 4
-+
-+#define FAULT_ID 0
-+
-+#define FLD_COURSE_ID  1
-+#define FLD_SECTION_ID 2
-+#define FLD_FINE_ID    3
-+
-+#define FD_USER_DATA_BIT 2
-+
-+#define FD_USER_DATA_NUM_BITS 30
-+
-+#define SD_BUFFERABLE_BIT 2
-+#define SD_CACHEABLE_BIT  3
-+#define SD_IMP_BIT        4
-+#define SD_DOMAIN_BIT     5
-+#define SD_AP_BIT         10
-+#define SD_ADDRESS_BIT    20
-+
-+#define SD_DOMAIN_NUM_BITS  4
-+#define SD_AP_NUM_BITS      2
-+
-+void CoPro15Regs_SetCP15Reg1(const unsigned long mask) {
-+    asm volatile(
-+        "MOV  r0, %0;"
-+        "MRC  p15, 0, r1, c1, c0, 0;"
-+        "ORR  r1,r1,r0;"
-+        "MCR  p15, 0, r1, c1, c0, 0;"
-+        :
-+        : "r" (mask | CP15R1_RESERVED)
-+        : "r0","r1");
-+}
-+
-+void CoPro15Regs_ClearCP15Reg1(const unsigned long mask) {
-+    asm volatile(
-+        "MOV  r0, %0;"
-+        "MRC  p15, 0, r1, c1, c0, 0;"
-+        "BIC  r1,r1,r0;"
-+        "MCR  p15, 0, r1, c1, c0, 0;"
-+        :
-+        : "r" (mask)
-+        : "r0","r1");
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg1(const unsigned long mask) {
-+    unsigned long value;
-+    asm volatile(
-+        "MRC  p15, 0, r1, c1, c0, 0;"
-+        "MOV  r0, %1;"
-+        "BIC  %0,r1,r0; "
-+        : "=r" (value)
-+        : "r" (mask)
-+        : "r0","r1");
-+    return value;
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg2(void) {
-+    unsigned long value;
-+    asm volatile(
-+        "MRC  p15, 0, r0, c2, c0, 0;"
-+        "MOV  %0, r0;"
-+        : "=r" (value)
-+        :
-+        : "r0");
-+    return value & CP15R2_RESERVED;
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg3(void) {
-+    unsigned long value;
-+    asm volatile(
-+        "MRC  p15, 0, r0, c3, c0, 0;"
-+        "MOV  %0, r0;"
-+        : "=r" (value)
-+        :
-+        : "r0");
-+    return value;
-+}
-+
-+void CoPro15Regs_SetCP15Reg3(unsigned long value) {
-+    asm volatile(
-+        "MOV  r0, %0;"
-+        "MCR  p15, 0, r0, c3, c0, 0;"
-+        :
-+        : "r" (value)
-+        : "r0");
-+}
-+
-+void CoPro15Regs_SetCP15Reg2(unsigned long value) {
-+    asm volatile(
-+        "MOV  r0, %0;"
-+        "MCR  p15, 0, r0, c2, c0, 0;"
-+        :
-+        : "r" (value & CP15R2_RESERVED)
-+        : "r0");
-+}
-+
-+void Cache_CleanDataCache(void)
-+{
-+    // Clean the data cache - usually precedes a data cache invalidation.
-+    // Forces the data cache content to be written to main memory - only
-+    // required if using write-back data cache
-+    asm volatile(
-+        "MOV  r3,pc;"
-+        "LDR  r1, =0;"
-+        "  MOV  r4,pc;"
-+        "  LDR  r0, =0;"
-+        "    ORR  r2, r1, r0;"
-+        "    MCR  p15, 0, r2, c7, c10, 2 ;"     // I (BHC) think that this should be c10, 2 not c14, 1 -- See ARM ARM
-+        "    ADD  r0, r0, #0x10;"
-+        "    CMP  r0,#0x40;"
-+        "  BXNE  r4;"
-+        "  ADD  r1, r1, #0x04000000;"
-+        "  CMP  r1, #0x0;"
-+        "BXNE  r3;"
-+        :
-+        :
-+        : "r0","r1","r2","r3","r4");
-+}
-+
-+void Cache_DrainWriteBuffer(void)
-+{
-+    // Forces the write buffer to update to main memory
-+    asm volatile(
-+        "LDR  r1, =0;"
-+        "MCR  p15, 0, r1, c7, c10, 4 ;"
-+        :
-+        :
-+        : "r1");
-+}
-+
-+void Cache_FlushPrefetchBuffer(void)
-+{
-+    // Forces the CPU to flush the instruction prefetch buffer
-+    asm volatile(
-+        "LDR  r1, =0;"
-+        "MCR  p15, 0, r1, c7, c5, 4 ;"
-+        :
-+        :
-+        : "r1");
-+}
-+
-+void Cache_InvalidateDataCache(void)
-+{
-+    asm volatile(
-+        "LDR  r1, =0;"
-+        "MCR  p15, 0, r1, c7, c6, 0;"
-+        :
-+        :
-+        : "r1");
-+}
-+
-+void Cache_InvalidateInstructionCache(void)
-+{
-+    asm volatile(
-+        "LDR  r1, =0;"
-+        "MCR  p15, 0, r1, c7, c5, 0;"
-+        :
-+        :
-+        : "r1");
-+}
-+
-+void Cache_InstOn(void)
-+{
-+    // Invalidate the instruction cache, in case there's anything
-+    // left from when it was last enabled
-+    Cache_InvalidateInstructionCache();
-+
-+    // Enable the instruction cache
-+    CoPro15Regs_SetCP15Reg1(CP15R1_I_ENABLE);
-+}
-+
-+void Cache_InstOff(void)
-+{
-+    // Disable the instruction cache
-+    CoPro15Regs_ClearCP15Reg1(CP15R1_I_ENABLE);
-+}
-+
-+void Cache_DataOn(void)
-+{
-+    // Invalidate the data cache, in case there's anything left from when
-+    // it was last enabled
-+    Cache_InvalidateDataCache();
-+
-+    // Enable the data cache
-+    CoPro15Regs_SetCP15Reg1(CP15R1_C_ENABLE);
-+}
-+
-+void Cache_DataOff(void)
-+{
-+    // Ensure all data in data cache or write buffer is written to memory
-+    Cache_CleanDataCache();
-+    Cache_DrainWriteBuffer();
-+
-+    // Disable the data cache
-+    CoPro15Regs_ClearCP15Reg1(CP15R1_C_ENABLE);
-+}
-+
-+void Cache_WriteBufferOn(void)
-+{
-+    // Enable the write buffer
-+    CoPro15Regs_SetCP15Reg1(CP15R1_W_ENABLE);
-+}
-+
-+void Cache_WriteBufferOff(void)
-+{
-+    // Ensure all data in the write buffer is written to memory
-+    Cache_DrainWriteBuffer();
-+
-+    // Disable the write buffer
-+    CoPro15Regs_ClearCP15Reg1(CP15R1_W_ENABLE);
-+}
-+
-+int MMU_SetDomainAccessValue(
-+    int domainNumber,
-+    int value) {
-+    int status = 0;
-+    if ((value < NUM_DOMAIN_ACCESS_VALUES) && (domainNumber < NUM_DOMAINS))
-+    {
-+        // Insert the 2-bit domain field into the slot for the specified domain
-+        unsigned long registerContents = CoPro15Regs_GetCP15Reg3();
-+        registerContents &= ~(3UL << (2*domainNumber));
-+        registerContents |= ((unsigned long)value << (2*domainNumber));
-+        CoPro15Regs_SetCP15Reg3(registerContents);
-+        status = 1;
-+    }
-+    return status;
-+}
-+
-+void MMU_SetAlignmentChecked(int alignmentChecked) {
-+    alignmentChecked ? CoPro15Regs_SetCP15Reg1(CP15R1_A_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_A_ENABLE);
-+}
-+
-+void MMU_SetEnabled(int enabled) {
-+    enabled ? CoPro15Regs_SetCP15Reg1(CP15R1_M_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_M_ENABLE);
-+}
-+void MMU_InvalidateDataTLB(void)
-+{
-+    asm volatile(
-+        "MCR  p15, 0, r0, c8, c6, 0;"
-+        :
-+        :
-+        : "r0");
-+}
-+
-+void MMU_InvalidateInstructionTLB(void)
-+{
-+    asm volatile(
-+        "MCR  p15, 0, r0, c8, c5, 0;"
-+        :
-+        :
-+        : "r0");
-+}
-+
-+void MMU_SetROMPermission(int rOM_Permitted) {
-+    rOM_Permitted ? CoPro15Regs_SetCP15Reg1(CP15R1_ROM) : CoPro15Regs_ClearCP15Reg1(CP15R1_ROM);
-+}
-+
-+void MMU_SetSystemPermission(int systemPermitted) {
-+    systemPermitted ? CoPro15Regs_SetCP15Reg1(CP15R1_SYSTEM) : CoPro15Regs_ClearCP15Reg1(CP15R1_SYSTEM);
-+}
-+
-+void MMU_SetTranslationTableBaseAddress(unsigned long *baseAddress) {
-+    CoPro15Regs_SetCP15Reg2((unsigned long)baseAddress);
-+}
-+
-+unsigned long SetBit(
-+    unsigned long source,
-+    int           state,
-+    int           offset)
-+{
-+    source = state ? (source | (1UL << offset)) :
-+                     (source & ~(1UL << offset));
-+    return source;
-+}
-+
-+unsigned long SetField(
-+    unsigned long source,
-+    unsigned long newFieldContents,
-+    int           offset,
-+    int           length)
-+{
-+    unsigned long mask = (1UL << length) - 1;
-+    source &= ~(mask << offset);
-+    source |= ((newFieldContents & mask) << offset);
-+    return source;
-+}
-+
-+unsigned long FD_SetUserData(
-+    unsigned long userData,
-+    unsigned long descriptor)
-+{
-+    return SetField(descriptor, userData, FD_USER_DATA_BIT, FD_USER_DATA_NUM_BITS);
-+}
-+
-+unsigned long FLPT_CreateFaultDescriptor(unsigned long userData)
-+{
-+    unsigned long descriptor = FAULT_ID;
-+    descriptor = FD_SetUserData(userData, descriptor);
-+    return descriptor;
-+}
-+
-+void FLPT_InsertFaultDescriptor(
-+    unsigned long *tableBaseAdr,
-+    int            index,
-+    unsigned long  descriptor)
-+{
-+    *(tableBaseAdr + index) = descriptor;
-+}
-+
-+unsigned long SD_SetAccessPermission(
-+    int           ap,
-+    unsigned long descriptor)
-+{
-+    return SetField(descriptor, ap, SD_AP_BIT, SD_AP_NUM_BITS);
-+}
-+
-+unsigned long SD_SetBaseAddress(
-+    unsigned long baseAddress,
-+    unsigned long descriptor)
-+{
-+    unsigned long mask = ~0UL << SD_ADDRESS_BIT;
-+    baseAddress &= mask;
-+    descriptor &= ~mask;
-+    descriptor |= baseAddress;
-+    return descriptor;
-+}
-+
-+unsigned long SD_SetBufferable(
-+    int           bufferable,
-+    unsigned long descriptor)
-+{
-+    return SetBit(descriptor, bufferable, SD_BUFFERABLE_BIT);
-+}
-+
-+unsigned long SD_SetCacheable(
-+    int           cacheable,
-+    unsigned long descriptor)
-+{
-+    return SetBit(descriptor, cacheable, SD_CACHEABLE_BIT);
-+}
-+
-+unsigned long SD_SetDomain(
-+    int           domain,
-+    unsigned long descriptor)
-+{
-+    return SetField(descriptor, domain, SD_DOMAIN_BIT, SD_DOMAIN_NUM_BITS);
-+}
-+
-+unsigned long SD_SetImplementationDefined(
-+    unsigned long implementationDefined,
-+    unsigned long descriptor)
-+{
-+    return SetBit(descriptor, implementationDefined, SD_IMP_BIT);
-+}
-+
-+unsigned long FLPT_CreateSectionDescriptor(
-+    unsigned long baseAddress,
-+    unsigned char domain,
-+    int           implementationDefined,
-+    int           ap,
-+    int           bufferable,
-+    int           cacheable)
-+{
-+    unsigned long descriptor = FLD_SECTION_ID;
-+    descriptor = SD_SetAccessPermission(ap, descriptor);
-+    descriptor = SD_SetBaseAddress(baseAddress, descriptor);
-+    descriptor = SD_SetBufferable(bufferable, descriptor);
-+    descriptor = SD_SetCacheable(cacheable, descriptor);
-+    descriptor = SD_SetDomain(domain, descriptor);
-+    descriptor = SD_SetImplementationDefined(implementationDefined, descriptor);
-+    return descriptor;
-+}
-+
-+void FLPT_InsertSectionDescriptor(
-+    unsigned long *tableBaseAdr,
-+    int            index,
-+    unsigned long  descriptor)
-+{
-+    *(tableBaseAdr + index) = descriptor;
-+}
-+
-+void FLPT_Zeroise(
-+    unsigned long *base_adr,
-+    int            numberOfdescriptors) {
-+    unsigned long faultDescriptor = FLPT_CreateFaultDescriptor(0);
-+    int i;
-+    for (i=0; i < numberOfdescriptors; i++) {
-+        FLPT_InsertFaultDescriptor(base_adr, i, faultDescriptor);
-+    }
-+}
-+
-+void configure_caches(void)
-+{
-+    // Disable caches
-+//    Cache_DataOff();
-+printf("1");
-+    Cache_InstOff();
-+//    Cache_WriteBufferOff();
-+
-+    // Disable MMU
-+printf("2");
-+    MMU_SetEnabled(0);
-+printf("3");
-+    MMU_InvalidateDataTLB();
-+printf("4");
-+    MMU_InvalidateInstructionTLB();
-+
-+    // Setup the MMU
-+printf("5");
-+    MMU_SetAlignmentChecked(1);
-+printf("6");
-+    MMU_SetROMPermission(0);
-+printf("7");
-+    MMU_SetSystemPermission(1);
-+
-+    // Allow client access to all protection domains
-+    int i;
-+    for (i=0; i < NUM_DOMAINS; i++) {
-+        MMU_SetDomainAccessValue(i, DAV_CLIENT);
-+    }
-+printf("8");
-+
-+    // Allocate first level page table, which we'll populate only with section
-+    // descriptors, which cover 1MB each. Table must be aligned to a 16KB
-+    // boundary.
-+    // We'll put it 4KB into the SRAM and it will occupy:
-+    //   64 entries for SDRAM
-+    //   1  entry for SRAM
-+    //   16 entries for APB bridge A
-+    //   16 entries for APB bridge B
-+    // The largest memory address we need to map is that of the SRAM at
-+    // 0x4c000000 -> (4c000000/2^20)*4 = offset 1300h from table start ->
-+    // require at least 1300h/4 +1 entries in table = 1217
-+    unsigned long *firstLevelPageTableBaseAdr = (unsigned long*)SRAM_BASE;
-+    FLPT_Zeroise(firstLevelPageTableBaseAdr, 4096);
-+printf("9");
-+
-+    // Map entire adr space uncached, unbuffered, read/write, virtual == physical
-+    unsigned megabytesPresent = 4096;
-+    unsigned index = 0;
-+    for (i=0; i < megabytesPresent; i++) {
-+        FLPT_InsertSectionDescriptor(
-+            firstLevelPageTableBaseAdr,
-+            index,
-+            FLPT_CreateSectionDescriptor(
-+                index * 1024 * 1024,    // Base address
-+                0,                      // Domain number
-+                0,                      // Implementation defined
-+                AP_LEVEL_1,             // Access permissions
-+                0,                      // Bufferable
-+                0));                    // Cacheable
-+
-+        ++index;
-+    }
-+printf("10");
-+
-+    // Map SDRAM as cached and buffered, read/write, virtual == physical
-+    megabytesPresent = 64;
-+    index = PHYS_SDRAM_1_PA / (1024 * 1024);
-+    for (i=0; i < megabytesPresent; i++) {
-+        FLPT_InsertSectionDescriptor(
-+            firstLevelPageTableBaseAdr,
-+            index,
-+            FLPT_CreateSectionDescriptor(
-+                index * 1024 * 1024,    // Base address
-+                0,                      // Domain number
-+                0,                      // Implementation defined
-+                AP_LEVEL_1,             // Access permissions
-+                1,                      // Bufferable
-+                1));                    // Cacheable
-+
-+        ++index;
-+    }
-+printf("11");
-+
-+    // Map SRAM as cached and buffered, read/write, virtual == physical
-+    megabytesPresent = 1;   // Actually only 32KB
-+    index = SRAM_BASE / (1024 * 1024);
-+    for (i=0; i < megabytesPresent; i++) {
-+        FLPT_InsertSectionDescriptor(
-+            firstLevelPageTableBaseAdr,
-+            index,
-+            FLPT_CreateSectionDescriptor(
-+                index * 1024 * 1024,    // Base address
-+                0,                      // Domain number
-+                0,                      // Implementation defined
-+                AP_LEVEL_1,             // Access permissions
-+                1,                      // Bufferable
-+                1));                    // Cacheable
-+
-+        ++index;
-+    }
-+printf("12");
-+
-+    // Map APB bridge A address space as uncached, unbuffered, read/write,
-+    // virtual == physical
-+    megabytesPresent = 16;
-+    index = APB_BRIDGE_A_BASE_PA / (1024 * 1024);
-+    for (i=0; i < megabytesPresent; i++) {
-+        FLPT_InsertSectionDescriptor(
-+            firstLevelPageTableBaseAdr,
-+            index,
-+            FLPT_CreateSectionDescriptor(
-+                index * 1024 * 1024,    // Base address
-+                0,                      // Domain number
-+                0,                      // Implementation defined
-+                AP_LEVEL_1,             // Access permissions
-+                0,                      // Bufferable
-+                0));                    // Cacheable
-+
-+        ++index;
-+    }
-+printf("13");
-+
-+    // Map APB bridge B address space as uncached, unbuffered, read/write,
-+    // virtual == physical
-+    megabytesPresent = 16;
-+    index = APB_BRIDGE_B_BASE_PA / (1024 * 1024);
-+    for (i=0; i < megabytesPresent; i++) {
-+        FLPT_InsertSectionDescriptor(
-+            firstLevelPageTableBaseAdr,
-+            index,
-+            FLPT_CreateSectionDescriptor(
-+                index * 1024 * 1024,    // Base address
-+                0,                      // Domain number
-+                0,                      // Implementation defined
-+                AP_LEVEL_1,             // Access permissions
-+                0,                      // Bufferable
-+                0));                    // Cacheable
-+
-+        ++index;
-+    }
-+printf("14");
-+
-+    // Load base address of first level page table
-+    MMU_SetTranslationTableBaseAddress(firstLevelPageTableBaseAdr);
-+printf("15");
-+
-+    // Enable MMU
-+    MMU_SetEnabled(1);
-+printf("16");
-+
-+    // Enable caches
-+    Cache_DataOn();
-+printf("17");
-+    Cache_InstOn();
-+printf("18");
-+    Cache_WriteBufferOn();
-+printf("19");
-+}
-+
-diff -Nurd u-boot-1.1.2/include/asm-arm/barrier.h u-boot-1.1.2-oxe810/include/asm-arm/barrier.h
---- u-boot-1.1.2/include/asm-arm/barrier.h	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/asm-arm/barrier.h	2008-06-11 17:55:08.000000000 +0200
-@@ -0,0 +1,25 @@
-+#if !defined(__BARRIER_H__)
-+#define __BARRIER_H__
-+
-+static inline void rmb(void)
-+{
-+    asm volatile ("" : : : "memory");
-+}
-+
-+/*
-+ * wmb() Would normally need to ensure shared memory regions are marked as
-+ *       non-cacheable and non-bufferable, then the work to be done by wmb() is
-+ *       to ensure the compiler and any possible CPU out of order writes are
-+ *       flushed to memory, however we have no data cache and as far as I'm
-+ *       aware we can't use the MMU to set page properties, so in our case wmb()
-+ *       must cause the compiler to flush.
-+ */
-+
-+static inline void wmb(void)
-+{
-+    // Cause the compiler to flush any registers containing pending write data
-+    // to memory
-+    asm volatile ("" : : : "memory");
-+
-+}
-+#endif        //  #if !defined(__BARRIER_H__)
-diff -Nurd u-boot-1.1.2/include/asm-arm/global_data.h u-boot-1.1.2-oxe810/include/asm-arm/global_data.h
---- u-boot-1.1.2/include/asm-arm/global_data.h	2003-10-10 12:05:43.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/asm-arm/global_data.h	2008-06-11 17:55:08.000000000 +0200
-@@ -61,6 +61,7 @@
- #define	GD_FLG_DEVINIT	0x00002		/* Devices have been initialized	*/
- #define	GD_FLG_SILENT	0x00004		/* Silent mode				*/
- 
--#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
-+#define DECLARE_GLOBAL_DATA_PTR     register gd_t* volatile gd asm ("r8");
- 
- #endif /* __ASM_GBL_DATA_H */
-+
-diff -Nurd u-boot-1.1.2/include/asm-arm/mach-types.h u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h
---- u-boot-1.1.2/include/asm-arm/mach-types.h	2004-10-10 20:41:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h	2008-06-11 17:55:08.000000000 +0200
-@@ -624,6 +624,7 @@
- #define MACH_TYPE_RMS100               611
- #define MACH_TYPE_KB9200               612
- #define MACH_TYPE_SX1                  613
-+#define MACH_TYPE_OXNAS                1152
- 
- #ifdef CONFIG_ARCH_EBSA110
- # ifdef machine_arch_type
-@@ -7945,6 +7946,18 @@
- # define machine_is_sx1()	(0)
- #endif
- 
-+#ifdef CONFIG_MACH_OXNAS
-+# ifdef machine_arch_type
-+#  undef machine_arch_type
-+#  define machine_arch_type	__machine_arch_type
-+# else
-+#  define machine_arch_type	MACH_TYPE_OXNAS
-+# endif
-+# define machine_is_oxnas()	(machine_arch_type == MACH_TYPE_OXNAS)
-+#else
-+# define machine_is_oxnas()	(0)
-+#endif
-+
- /*
-  * These have not yet been registered
-  */
-diff -Nurd u-boot-1.1.2/include/asm-arm/u-boot.h u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h
---- u-boot-1.1.2/include/asm-arm/u-boot.h	2002-11-03 01:33:10.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h	2008-06-11 17:55:08.000000000 +0200
-@@ -41,6 +41,8 @@
- 	ulong start;
- 	ulong size;
-     } 			bi_dram[CONFIG_NR_DRAM_BANKS];
-+	unsigned long	bi_sramstart;	/* start of SRAM memory */
-+	unsigned long	bi_sramsize;	/* size	 of SRAM memory */
- } bd_t;
- 
- #define bi_env_data bi_env->data
-diff -Nurd u-boot-1.1.2/include/ata.h u-boot-1.1.2-oxe810/include/ata.h
---- u-boot-1.1.2/include/ata.h	2004-03-14 23:25:50.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/ata.h	2008-06-11 17:55:11.000000000 +0200
-@@ -80,7 +80,12 @@
- /*
-  * Device / Head Register Bits
-  */
-+#ifdef CONFIG_OXNAS
-+#define ATA_DEVICE(x) (0)
-+#else
- #define ATA_DEVICE(x)	((x & 1)<<4)
-+#endif // CONFIG_OXNAS
-+
- #define ATA_LBA		0xE0
- 
- /*
-diff -Nurd u-boot-1.1.2/include/cmd_confdefs.h u-boot-1.1.2-oxe810/include/cmd_confdefs.h
---- u-boot-1.1.2/include/cmd_confdefs.h	2004-12-16 18:59:53.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/cmd_confdefs.h	2008-06-11 17:55:11.000000000 +0200
-@@ -92,6 +92,7 @@
- #define CFG_CMD_XIMG	0x0400000000000000ULL	/* Load part of Multi Image	*/
- #define CFG_CMD_UNIVERSE 0x0800000000000000ULL	/* Tundra Universe Support      */
- #define CFG_CMD_EXT2    0x1000000000000000ULL	/* EXT2 Support                 */
-+#define CFG_CMD_LEDFAIL 0x2000000000000000ULL	/* OXNAS Failure LED support */
- 
- #define CFG_CMD_ALL	0xFFFFFFFFFFFFFFFFULL	/* ALL commands			*/
- 
-diff -Nurd u-boot-1.1.2/include/common.h u-boot-1.1.2-oxe810/include/common.h
---- u-boot-1.1.2/include/common.h	2004-12-13 10:49:01.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/common.h	2008-06-11 17:55:11.000000000 +0200
-@@ -204,7 +204,7 @@
- /* common/cmd_nvedit.c */
- int	env_init     (void);
- void	env_relocate (void);
--char	*getenv	     (uchar *);
-+char	*getenv	     (const uchar *);
- int	getenv_r     (uchar *name, uchar *buf, unsigned len);
- int	saveenv	     (void);
- #ifdef CONFIG_PPC		/* ARM version to be fixed! */
-diff -Nurd u-boot-1.1.2/include/configs/oxnas.h u-boot-1.1.2-oxe810/include/configs/oxnas.h
---- u-boot-1.1.2/include/configs/oxnas.h	1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/configs/oxnas.h	2008-06-12 13:57:57.000000000 +0200
-@@ -0,0 +1,593 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * 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
-+
-+#define readb(p)  (*(volatile u8 *)(p))
-+#define readl(p)  (*(volatile u32 *)(p))
-+#define writeb(v, p) (*(volatile u8 *)(p)= (v))
-+#define writel(v, p) (*(volatile u32*)(p)=(v))
-+
-+#define CFG_FLASH_EMPTY_INFO
-+
-+/**
-+ * Architecture
-+ */
-+#define CONFIG_ARM926EJS    1
-+#define CONFIG_OXNAS        1
-+#define CONFIG_OXNAS_ENABLE_PCI         /* Enables PCI clock and takes out of reset - needed if require access to static bus */
-+#define CONFIG_OXNAS_FEEDBACK_PCI_CLKS  /* Feedback PCI clock out 3 to drive PCI core clock - needed if require access to static bus */
-+#define CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+#if (USE_SATA == 1)
-+#define CONFIG_OXNAS_USE_SATA           /* Define to include support for SATA disks */
-+#if (USE_SATA_ENV == 1)
-+#define ENV_ON_SATA                     /* Define to have the U-Boot env. stored on SATA disk */
-+#endif // USE_SATA_ENV
-+#endif // USE_SATA
-+#if (USE_FLASH == 0)
-+#define CFG_NO_FLASH                    /* Define to NOT include flash support on static bus*/
-+#endif //USE_FLASH
-+
-+/* Won't be using any interrupts */
-+#undef CONFIG_USE_IRQ
-+
-+/* Everything, incl board info, in Hz */
-+#undef CFG_CLKS_IN_HZ
-+
-+#define CFG_HUSH_PARSER		1
-+#define CFG_PROMPT_HUSH_PS2	"> "
-+
-+/* Miscellaneous configurable options */
-+#define CFG_LONGHELP				/* undef to save memory		*/
-+#ifdef CFG_HUSH_PARSER
-+#define CFG_PROMPT		"$ "		/* Monitor Command Prompt */
-+#else
-+#define CFG_PROMPT		"# "		/* Monitor Command Prompt */
-+#endif
-+#define CFG_CBSIZE      256             /* Console I/O Buffer Size  */
-+
-+/* Print Buffer Size */
-+#define CFG_PBSIZE      ((CFG_CBSIZE)+sizeof(CFG_PROMPT)+16)
-+#define CFG_MAXARGS     16              /* max number of command args   */
-+#define CFG_BARGSIZE    (CFG_CBSIZE)    /* Boot Argument Buffer Size    */
-+
-+#define CONFIG_CMDLINE_TAG          1   /* enable passing of ATAGs  */
-+#define CONFIG_SETUP_MEMORY_TAGS    1
-+#define CONFIG_MISC_INIT_R          1   /* call misc_init_r during start up */
-+#define CONFIG_INITRD_TAG           1   /* allow initrd tag to be generated */
-+
-+/* May want to do some setup prior to relocation */
-+#define CONFIG_INIT_CRITICAL
-+
-+/* ARM specific late initialisation */
-+#define BOARD_LATE_INIT
-+
-+/**
-+ * 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
-+
-+/**
-+ * RAM
-+ */
-+#define CONFIG_NR_DRAM_BANKS    1           /* We have 1 bank of SDRAM */
-+#define PHYS_SDRAM_1_PA         0x48000000  /* SDRAM Bank #1 */
-+#if (NAS_VERSION == 810)
-+#define PHYS_SDRAM_1_MAX_SIZE	 (256 * 1024 * 1024)
-+#endif // NAS_VERSION
-+#define CFG_SRAM_BASE           ((PHYS_SDRAM_1_PA) + (PHYS_SDRAM_1_MAX_SIZE))
-+#if (NAS_VERSION == 810)
-+#define CFG_SRAM_SIZE			 (128 * 1024)
-+#endif // NAS_VERSION
-+
-+#define INITIALISE_SDRAM
-+
-+/* Default location from which bootm etc will load */
-+#define CFG_LOAD_ADDR   (PHYS_SDRAM_1_PA)
-+
-+/**
-+ * Core addresses
-+ */
-+#define MAC_BASE_PA             0x40400000
-+#define STATIC_CS0_BASE_PA      0x41000000
-+#define STATIC_CS1_BASE_PA      0x41400000
-+#define STATIC_CS2_BASE_PA      0x41800000
-+#define STATIC_CONTROL_BASE_PA  0x41C00000
-+#define SATA_DATA_BASE_PA       0x42000000
-+
-+#define APB_BRIDGE_A_BASE_PA    0x44000000
-+#define APB_BRIDGE_B_BASE_PA    0x45000000
-+
-+#define GPIO_1_PA               ((APB_BRIDGE_A_BASE_PA) + 0x0)
-+#define GPIO_2_PA               ((APB_BRIDGE_A_BASE_PA) + 0x100000)
-+
-+#define SYS_CONTROL_BASE_PA     ((APB_BRIDGE_B_BASE_PA) + 0x0)
-+#define DMA_BASE_PA             ((APB_BRIDGE_B_BASE_PA) + 0x600000)
-+#define RPS_BASE                ((APB_BRIDGE_B_BASE_PA) + 0x300000)
-+
-+/* Static bus registers */
-+#define STATIC_CONTROL_VERSION  ((STATIC_CONTROL_BASE_PA) + 0x0)
-+#define STATIC_CONTROL_BANK0    ((STATIC_CONTROL_BASE_PA) + 0x4)
-+#define STATIC_CONTROL_BANK1    ((STATIC_CONTROL_BASE_PA) + 0x8)
-+#define STATIC_CONTROL_BANK2    ((STATIC_CONTROL_BASE_PA) + 0xC)
-+
-+/* Clock to the ARM/DDR */
-+#if (FPGA == 0)
-+#define NOMINAL_ARMCLK  ((PLL400) / 2)
-+#define NOMINAL_SYSCLK  ((PLL400) / 4)
-+#else // !FPGA
-+#define NOMINAL_ARMCLK  (FPGA_ARM_CLK)
-+#define NOMINAL_SYSCLK  ((PLL400) / 4)
-+#endif // !FPGA
-+
-+/**
-+ * Timer
-+ */
-+#define CFG_TIMERBASE            ((RPS_BASE) + 0x200)
-+#define TIMER_PRESCALE_BIT       2
-+#define TIMER_PRESCALE_1_ENUM    0
-+#define TIMER_PRESCALE_16_ENUM   1
-+#define TIMER_PRESCALE_256_ENUM  2
-+#define TIMER_MODE_BIT           6
-+#define TIMER_MODE_FREE_RUNNING  0
-+#define TIMER_MODE_PERIODIC      1
-+#define TIMER_ENABLE_BIT         7
-+#define TIMER_ENABLE_DISABLE     0
-+#define TIMER_ENABLE_ENABLE      1
-+
-+#define TIMER_PRESCALE_ENUM      (TIMER_PRESCALE_256_ENUM)
-+#define CFG_HZ                   ((RPSCLK) / 256)
-+
-+/**
-+ * GPIO
-+ */
-+#define GPIO_1_OE       ((GPIO_1_PA) + 0x4)
-+#define GPIO_1_SET_OE   ((GPIO_1_PA) + 0x1C)
-+#define GPIO_1_CLR_OE   ((GPIO_1_PA) + 0x20)
-+
-+#define GPIO_2_OE       ((GPIO_2_PA) + 0x4)
-+#define GPIO_2_SET_OE   ((GPIO_2_PA) + 0x1C)
-+#define GPIO_2_CLR_OE   ((GPIO_2_PA) + 0x20)
-+
-+/**
-+ * Serial Configuration
-+ */
-+#define EXT_UART_BASE       0x28000000
-+
-+#define UART_1_BASE (APB_BRIDGE_A_BASE_PA + 0x200000)
-+#define UART_2_BASE (APB_BRIDGE_A_BASE_PA + 0x300000)
-+#define UART_3_BASE (APB_BRIDGE_A_BASE_PA + 0x900000) 
-+#define UART_4_BASE (APB_BRIDGE_A_BASE_PA + 0xA00000) 
-+
-+#define CFG_NS16550          1
-+#define CFG_NS16550_SERIAL   1
-+#define CFG_NS16550_REG_SIZE 1
-+
-+#if (USE_EXTERNAL_UART != 0)
-+#define CFG_NS16550_CLK      16000000
-+#define CFG_NS16550_COM1     (EXT_UART_BASE)
-+#else // USE_EXTERNAL_UART
-+#define CFG_NS16550_CLK      (NOMINAL_SYSCLK)
-+#define USE_UART_FRACTIONAL_DIVIDER
-+#if (INTERNAL_UART == 1)
-+#define CONFIG_OXNAS_UART1
-+#define CFG_NS16550_COM1     (UART_1_BASE)
-+#elif (INTERNAL_UART == 2)
-+#define CONFIG_OXNAS_UART2
-+#define CFG_NS16550_COM1     (UART_2_BASE)
-+#elif (INTERNAL_UART == 3)
-+#define CONFIG_OXNAS_UART3
-+#define CFG_NS16550_COM1     (UART_3_BASE)
-+#else
-+#define CONFIG_OXNAS_UART4
-+#define CFG_NS16550_COM1     (UART_4_BASE)
-+#endif // CONFIG_OXNAS_UART
-+#endif // USE_EXTERNAL_UART
-+
-+#define CONFIG_CONS_INDEX    1
-+#define CONFIG_BAUDRATE      115200
-+#define CFG_BAUDRATE_TABLE   { 9600, 19200, 38400, 57600, 115200 }
-+
-+/**
-+ * Monitor commands
-+ */
-+#define BASE_COMMANDS (CFG_CMD_IMI    | \
-+                       CFG_CMD_IMLS   | \
-+                       CFG_CMD_BDI    | \
-+                       CFG_CMD_NET    | \
-+                       CFG_CMD_PING   | \
-+                       CFG_CMD_ENV    | \
-+                       CFG_CMD_RUN    | \
-+                       CFG_CMD_MEMORY)
-+
-+#ifdef CFG_NO_FLASH
-+#define FLASH_COMMANDS (BASE_COMMANDS)
-+#else
-+#define FLASH_COMMANDS (BASE_COMMANDS | CFG_CMD_FLASH)
-+#endif // CFG_NO_FLASH
-+
-+#ifdef CONFIG_OXNAS_USE_SATA
-+#define SATA_COMMANDS (FLASH_COMMANDS | CFG_CMD_IDE | CFG_CMD_EXT2 | CFG_CMD_LEDFAIL)
-+#else
-+#define SATA_COMMANDS (FLASH_COMMANDS)
-+#endif // CONFIG_OXNAS_USE_SATA
-+
-+#define CONFIG_COMMANDS SATA_COMMANDS
-+
-+/* This must be included AFTER the definition of CONFIG_COMMANDS */
-+#include <cmd_confdefs.h>
-+
-+/**
-+ * Booting
-+ */
-+#if (LINUX_ROOT_RAIDED == 1)
-+#define LINUX_ROOT_DEVICE "root=/dev/md1"
-+#else
-+#define LINUX_ROOT_DEVICE "root=/dev/sda1"
-+#endif
-+#define CONFIG_BOOTARGS LINUX_ROOT_DEVICE " console=ttyS0,115200 elevator=cfq gmac.mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01"
-+
-+#ifdef CONFIG_OXNAS_USE_SATA
-+#define CONFIG_BOOTDELAY	2
-+#define CONFIG_BOOTCOMMAND	"run select0 load boot || run select0 load2 boot || run lightled select1 load extinguishled boot || run lightled select1 load2 extinguishled boot || lightled"
-+#define CONFIG_EXTRA_ENV_SETTINGS \
-+    "select0=ide dev 0\0" \
-+    "select1=ide dev 1\0" \
-+    "load=ide read 0x48500000 12c 1644\0" \
-+    "load2=ide read 0x48500000 2a6e 1644\0" \
-+	"lightled=ledfail 1\0" \
-+	"extinguishled=ledfail 0\0" \
-+    "boot=bootm 48500000\0"
-+#else // CONFIG_OXNAS_USE_SATA
-+#define CONFIG_BOOTDELAY	15
-+#define CONFIG_BOOTCOMMAND	"bootm 0x41020000"
-+#endif // CONFIG_OXNAS_USE_SATA
-+
-+//#define CONFIG_SHOW_BOOT_PROGRESS   1
-+
-+/**
-+ * Networking
-+ */
-+#define CONFIG_ETHADDR      00:30:e0:00:00:01
-+#define CONFIG_NETMASK      255.255.0.0
-+#define CONFIG_IPADDR       172.31.0.128
-+#define CONFIG_SERVERIP     172.31.0.100
-+#define CONFIG_BOOTFILE     "uImage"
-+#define CFG_AUTOLOAD        "n"
-+#define CONFIG_NET_RETRY_COUNT 30
-+
-+/**
-+ * Flash support
-+ */
-+#ifndef CFG_NO_FLASH
-+
-+#define FORCE_TOP_BOOT_FLASH	1
-+
-+#define CFG_FLASH_CFI			1
-+#define CFG_FLASH_CFI_DRIVER	1
-+
-+#define NUM_FLASH_MAIN_BLOCKS   63          /* For Intel 28F320B3T */
-+#define NUM_FLASH_PARAM_BLOCKS  8           /* For Intel 28F320B3T */
-+#define FLASH_MAIN_BLOCK_SIZE   (64*1024)   /* For Intel 28F320B3T family */
-+#define FLASH_PARAM_BLOCK_SIZE  (8*1024)    /* For Intel 28F320B3T family */
-+
-+/* Assuming counts main blocks and parameter blocks, as the Intel/AMD detection */
-+/* I'm intending to copy would seem to indicate */
-+#define CFG_MAX_FLASH_SECT      (NUM_FLASH_MAIN_BLOCKS + NUM_FLASH_PARAM_BLOCKS)
-+
-+#define CFG_MAX_FLASH_BANKS     1           /* Assume counts flash devices */
-+#define FLASH_BASE_OFF          0
-+#define CFG_FLASH_BASE          ((STATIC_CS0_BASE_PA) + (FLASH_BASE_OFF))
-+#define PHYS_FLASH_1            (CFG_FLASH_BASE)
-+
-+#define CFG_FLASH_ERASE_TOUT    (20*CFG_HZ)	/* Timeout for Flash Erase */
-+#define CFG_FLASH_WRITE_TOUT    (20*CFG_HZ)	/* Timeout for Flash Write */
-+#define CFG_FLASH_WRITE_ATTEMPTS 5
-+
-+#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f3f  /* Slow ASIC settings */
-+
-+#endif // !CFG_NO_FLASH
-+
-+/**
-+ * Environment organization
-+ */
-+#ifdef ENV_ON_SATA
-+
-+/* Environment on SATA disk */
-+#define SIZE_TO_SECTORS(x) ((x) / 512)
-+#define CFG_ENV_IS_IN_DISK
-+#define CFG_ENV_SIZE			(8*1024)
-+#define ENVIRONMENT_OFFSET		((CFG_SRAM_SIZE) - (CFG_ENV_SIZE) - 1024)
-+#define CFG_ENV_ADDR			((CFG_SRAM_BASE) + (ENVIRONMENT_OFFSET))
-+#define ROM_LOADER_LOAD_START_SECTOR 1
-+#define CFG_ENV_DISK_SECTOR 	((ROM_LOADER_LOAD_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
-+#define ROM_LOADER_LOAD_REDUNDANT_START_SECTOR 10608
-+#define CFG_ENV_DISK_REDUNDANT_SECTOR ((ROM_LOADER_LOAD_REDUNDANT_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
-+
-+#else
-+/** Flash based environment
-+ *
-+ *  It appears that all flash env start/size info. has to be pre-defined. How
-+ *  this is supposed to work when the flash detection code could cope with all
-+ *  sorts of different flash is hard to see.
-+ *  It appears from the README that with bottom/top boot flashes with smaller
-+ *  parameter blocks available, the environment code will only use a single
-+ *  one of these smaller sectors for the environment, i.e. CFG_ENV_SECT_SIZE
-+ *  is the size of the environment. I hope this isn't really true. The defines
-+ *  below may well not work if this is the truth
-+ */
-+#define CFG_ENV_IS_IN_FLASH
-+/* Environment in flash device parameter blocks */
-+#define CFG_ENV_SECT_SIZE   (8*1024)
-+/* First parameter block for environment */
-+#define CFG_ENV_SIZE        CFG_ENV_SECT_SIZE
-+/* Second parameter block for backup environment */
-+#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE)
-+/* Main environment occupies first parameter block */
-+#define CFG_ENV_ADDR        ((CFG_FLASH_BASE)+((NUM_FLASH_MAIN_BLOCKS)*(FLASH_MAIN_BLOCK_SIZE)))
-+/* Backup environment occupies second parameter block */
-+#define CFG_ENV_ADDR_REDUND ((CFG_ENV_ADDR)+(CFG_ENV_SIZE))
-+
-+#endif // ENV_ON_SATA
-+
-+#define CONFIG_ENV_OVERWRITE
-+
-+/* Magic number that indicates rebooting into upgrade mode */
-+#define UPGRADE_MAGIC 0x31	/* ASCII '1' */
-+
-+/* Magic number that indicates user recovery on reboot */
-+/* Also defined in oxnas_user_recovery.agent */
-+#define RECOVERY_MAGIC 0x31    /* ASCII '1' */
-+
-+/* Magic number that indicates controlled power down on reboot */
-+/* Also defined in controlled_power_down.sh in init.d */
-+#define CONTROLLED_POWER_DOWN_MAGIC 0x31  /* ASCII '1' */
-+
-+/* This flag is set in SRAM location by Co Proc */
-+#define CONTROLLED_POWER_UP_MAGIC  0x31 /* ASCII '1' */
-+/* 9k + a quad from top */
-+/* Be carefule on changing the location of this flag
-+ * u-boot has other things to write in SRAM too
-+ */
-+#define POWER_ON_FLAG_SRAM_OFFSET 	9220
-+
-+/* Size of malloc() pool */
-+#define CFG_MALLOC_LEN      (CFG_ENV_SIZE + 128*1024)
-+#define CFG_GBL_DATA_SIZE   128 /* size in bytes reserved for initial data */
-+
-+/**
-+ * ASM startup control
-+ */
-+/* Start of address within SRAM of loader's exception table. */
-+/* ROM-based exception table will redirect to here */
-+#define EXCEPTION_BASE  (CFG_SRAM_BASE)
-+
-+/**
-+ * Disk related stuff
-+ */
-+#define CONFIG_LBA48
-+#define CONFIG_DOS_PARTITION
-+#define CFG_IDE_MAXDEVICE   2
-+#define CFG_IDE_MAXBUS      1
-+#define CONFIG_IDE_PREINIT
-+#undef CONFIG_IDE_RESET
-+#undef CONFIG_IDE_LED
-+#define CFG_ATA_DATA_OFFSET 0
-+#define CFG_ATA_REG_OFFSET  0
-+#define CFG_ATA_ALT_OFFSET  0
-+
-+/**
-+ * System block reset and clock control
-+ */
-+#define SYS_CTRL_USB11_CTRL           (SYS_CONTROL_BASE_PA + 0x00)
-+#define SYS_CTRL_PCI_CTRL0            (SYS_CONTROL_BASE_PA + 0x04)
-+#define SYS_CTRL_PCI_CTRL1            (SYS_CONTROL_BASE_PA + 0x08)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0  (SYS_CONTROL_BASE_PA + 0x0C)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1  (SYS_CONTROL_BASE_PA + 0x10)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_0   (SYS_CONTROL_BASE_PA + 0x14)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_1   (SYS_CONTROL_BASE_PA + 0x18)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_0  (SYS_CONTROL_BASE_PA + 0x8C)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_1  (SYS_CONTROL_BASE_PA + 0x90)
-+#define SYS_CTRL_USB11_STAT           (SYS_CONTROL_BASE_PA + 0x1c)
-+#define SYS_CTRL_PCI_STAT             (SYS_CONTROL_BASE_PA + 0x20)
-+#define SYS_CTRL_CKEN_SET_CTRL        (SYS_CONTROL_BASE_PA + 0x2C)
-+#define SYS_CTRL_CKEN_CLR_CTRL        (SYS_CONTROL_BASE_PA + 0x30)
-+#define SYS_CTRL_RSTEN_SET_CTRL       (SYS_CONTROL_BASE_PA + 0x34)
-+#define SYS_CTRL_RSTEN_CLR_CTRL       (SYS_CONTROL_BASE_PA + 0x38)
-+#define SYS_CTRL_PLLSYS_CTRL          (SYS_CONTROL_BASE_PA + 0x48)
-+#define SYS_CTRL_PLLSYS_KEY_CTRL      (SYS_CONTROL_BASE_PA + 0x6C)
-+#define SYS_CTRL_GMAC_CTRL            (SYS_CONTROL_BASE_PA + 0x78)
-+#define SYS_CTRL_UART_CTRL            (SYS_CONTROL_BASE_PA + 0x94)
-+
-+#define SYS_CTRL_CKEN_COPRO_BIT  0
-+#define SYS_CTRL_CKEN_DMA_BIT    1
-+#define SYS_CTRL_CKEN_DPE_BIT    2
-+#define SYS_CTRL_CKEN_DDR_BIT    3
-+#define SYS_CTRL_CKEN_SATA_BIT   4
-+#define SYS_CTRL_CKEN_I2S_BIT    5
-+#define SYS_CTRL_CKEN_USBHS_BIT  6
-+#define SYS_CTRL_CKEN_MAC_BIT    7
-+#define SYS_CTRL_CKEN_PCI_BIT    8
-+#define SYS_CTRL_CKEN_STATIC_BIT 9
-+#define SYS_CTRL_CKEN_DDR_PHY_BIT 10
-+
-+#define SYS_CTRL_RSTEN_ARM_BIT          0
-+#define SYS_CTRL_RSTEN_COPRO_BIT        1
-+#define SYS_CTRL_RSTEN_USBHS_BIT        4
-+#define SYS_CTRL_RSTEN_USBHSPHY_BIT     5
-+#define SYS_CTRL_RSTEN_MAC_BIT          6
-+#define SYS_CTRL_RSTEN_PCI_BIT          7
-+#define SYS_CTRL_RSTEN_DMA_BIT          8
-+#define SYS_CTRL_RSTEN_DPE_BIT          9
-+#define SYS_CTRL_RSTEN_DDR_BIT          10
-+#define SYS_CTRL_RSTEN_SATA_BIT         11
-+#define SYS_CTRL_RSTEN_SATA_LINK_BIT    12
-+#define SYS_CTRL_RSTEN_SATA_PHY_BIT     13
-+#define SYS_CTRL_RSTEN_STATIC_BIT       15
-+#define SYS_CTRL_RSTEN_GPIO_BIT         16
-+#define SYS_CTRL_RSTEN_UART1_BIT        17
-+#define SYS_CTRL_RSTEN_UART2_BIT        18
-+#define SYS_CTRL_RSTEN_MISC_BIT         19
-+#define SYS_CTRL_RSTEN_I2S_BIT          20
-+#define SYS_CTRL_RSTEN_AHB_MON_BIT      21
-+#define SYS_CTRL_RSTEN_UART3_BIT        22
-+#define SYS_CTRL_RSTEN_UART4_BIT        23
-+#define SYS_CTRL_RSTEN_SGDMA_BIT        24
-+#define SYS_CTRL_RSTEN_DDR_PHY_BIT      25
-+#define SYS_CTRL_RSTEN_BUS_BIT          31
-+
-+#define SYS_CTRL_GMAC_RGMII         2
-+#define SYS_CTRL_GMAC_SIMPLE_MAX    1
-+#define SYS_CTRL_GMAC_CKEN_GTX      0
-+
-+#define SYS_CTRL_CKCTRL_CTRL_ADDR     (SYS_CONTROL_BASE_PA + 0x64)
-+
-+#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0
-+#define SYS_CTRL_CKCTRL_SLOW_BIT    8
-+
-+#define SYS_CTRL_UART2_DEQ_EN       0
-+#define SYS_CTRL_UART3_DEQ_EN       1
-+#define SYS_CTRL_UART3_IQ_EN        2
-+#define SYS_CTRL_UART4_IQ_EN        3
-+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
-+
-+#define SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT 11
-+
-+/**
-+ * SATA related definitions
-+ */
-+#define ATA_PORT_CTL        0
-+#define ATA_PORT_FEATURE    1
-+#define ATA_PORT_NSECT      2
-+#define ATA_PORT_LBAL       3
-+#define ATA_PORT_LBAM       4
-+#define ATA_PORT_LBAH       5
-+#define ATA_PORT_DEVICE     6
-+#define ATA_PORT_COMMAND    7
-+
-+#define SATA_0_REGS_BASE    (APB_BRIDGE_B_BASE_PA + 0x900000)
-+#define SATA_1_REGS_BASE    (APB_BRIDGE_B_BASE_PA + 0x910000)
-+#define SATA_HOST_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x9e0000)
-+
-+/* The offsets to the SATA registers */
-+#define SATA_ORB1_OFF           0
-+#define SATA_ORB2_OFF           1
-+#define SATA_ORB3_OFF           2
-+#define SATA_ORB4_OFF           3
-+#define SATA_ORB5_OFF           4
-+
-+#define SATA_FIS_ACCESS         11
-+#define SATA_INT_STATUS_OFF     12  /* Read only */
-+#define SATA_INT_CLR_OFF        12  /* Write only */
-+#define SATA_INT_ENABLE_OFF     13  /* Read only */
-+#define SATA_INT_ENABLE_SET_OFF 13  /* Write only */
-+#define SATA_INT_ENABLE_CLR_OFF 14  /* Write only */
-+#define SATA_VERSION_OFF        15
-+#define SATA_CONTROL_OFF        23
-+#define SATA_COMMAND_OFF        24
-+#define SATA_PORT_CONTROL_OFF   25
-+#define SATA_DRIVE_CONTROL_OFF  26
-+
-+/* The offsets to the link registers that are access in an asynchronous manner */
-+#define SATA_LINK_DATA     28
-+#define SATA_LINK_RD_ADDR  29
-+#define SATA_LINK_WR_ADDR  30
-+#define SATA_LINK_CONTROL  31
-+
-+/* SATA interrupt status register fields */
-+#define SATA_INT_STATUS_EOC_RAW_BIT     ( 0 + 16) 
-+#define SATA_INT_STATUS_ERROR_BIT       ( 2 + 16)
-+#define SATA_INT_STATUS_EOADT_RAW_BIT   ( 1 + 16)
-+
-+/* SATA core command register commands */
-+#define SATA_CMD_WRITE_TO_ORB_REGS              2
-+#define SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND   4
-+
-+#define SATA_CMD_BUSY_BIT 7
-+
-+#define SATA_SCTL_CLR_ERR 0x00000316UL
-+
-+#define SATA_OPCODE_MASK 0x3
-+
-+#define SATA_LBAL_BIT    0
-+#define SATA_LBAM_BIT    8
-+#define SATA_LBAH_BIT    16
-+#define SATA_HOB_LBAH_BIT 24
-+#define SATA_DEVICE_BIT  24
-+#define SATA_NSECT_BIT   0
-+#define SATA_FEATURE_BIT 16
-+#define SATA_COMMAND_BIT 24
-+#define SATA_CTL_BIT     24
-+
-+/* ATA status (7) register field definitions */
-+#define ATA_STATUS_BSY_BIT     7
-+#define ATA_STATUS_DRDY_BIT    6
-+#define ATA_STATUS_DF_BIT      5
-+#define ATA_STATUS_DRQ_BIT     3
-+#define ATA_STATUS_ERR_BIT     0
-+
-+/* ATA device (6) register field definitions */
-+#define ATA_DEVICE_FIXED_MASK 0xA0
-+#define ATA_DEVICE_DRV_BIT 4
-+#define ATA_DEVICE_DRV_NUM_BITS 1
-+#define ATA_DEVICE_LBA_BIT 6
-+
-+/* ATA control (0) register field definitions */
-+#define ATA_CTL_SRST_BIT   2
-+
-+/* ATA Command register initiated commands */
-+#define ATA_CMD_INIT    0x91
-+#define ATA_CMD_IDENT   0xEC
-+
-+#define SATA_STD_ASYNC_REGS_OFF 0x20
-+#define SATA_SCR_STATUS      0
-+#define SATA_SCR_ERROR       1
-+#define SATA_SCR_CONTROL     2
-+#define SATA_SCR_ACTIVE      3
-+#define SATA_SCR_NOTIFICAION 4
-+
-+#define SATA_BURST_BUF_FORCE_EOT_BIT        0
-+#define SATA_BURST_BUF_DATA_INJ_ENABLE_BIT  1
-+#define SATA_BURST_BUF_DIR_BIT              2
-+#define SATA_BURST_BUF_DATA_INJ_END_BIT     3
-+#define SATA_BURST_BUF_FIFO_DIS_BIT         4
-+#define SATA_BURST_BUF_DIS_DREQ_BIT         5
-+#define SATA_BURST_BUF_DREQ_BIT             6
-+
-+/* Button on GPIO 32 */
-+#define RECOVERY_BUTTON         (0x00000001 << 0)
-+#define RECOVERY_PRISEL_REG     SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define RECOVERY_SECSEL_REG     SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define RECOVERY_TERSEL_REG     SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define RECOVERY_CLR_OE_REG     GPIO_2_CLR_OE
-+#define RECOVERY_DEBOUNCE_REG   GPIO_2_INPUT_DEBOUNCE_ENABLE
-+#define RECOVERY_DATA           GPIO_2_PA
-+
-+#endif // CONFIG_H
-diff -Nurd u-boot-1.1.2/include/_exports.h u-boot-1.1.2-oxe810/include/_exports.h
---- u-boot-1.1.2/include/_exports.h	2003-09-12 17:35:33.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/_exports.h	2008-06-11 17:55:11.000000000 +0200
-@@ -12,6 +12,7 @@
- EXPORT_FUNC(get_timer)
- EXPORT_FUNC(vprintf)
- EXPORT_FUNC(do_reset)
-+EXPORT_FUNC(raise)
- #if (CONFIG_COMMANDS & CFG_CMD_I2C)
- EXPORT_FUNC(i2c_write)
- EXPORT_FUNC(i2c_read)
-diff -Nurd u-boot-1.1.2/include/flash.h u-boot-1.1.2-oxe810/include/flash.h
---- u-boot-1.1.2/include/flash.h	2004-12-16 19:01:48.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/flash.h	2008-06-11 17:55:11.000000000 +0200
-@@ -207,6 +207,7 @@
- #define ATM_ID_BV1614	0x000000C0	/* 49BV1614  ID */
- #define ATM_ID_BV1614A	0x000000C8	/* 49BV1614A ID */
- #define ATM_ID_BV6416	0x000000D6	/* 49BV6416  ID */
-+#define ATM_ID_BV322    0x000000c9      /* 49BV322A  ID */
- 
- #define FUJI_ID_29F800BA  0x22582258	/* MBM29F800BA ID  (8M) */
- #define FUJI_ID_29F800TA  0x22D622D6	/* MBM29F800TA ID  (8M) */
-@@ -405,6 +406,7 @@
- #define FLASH_MAN_INTEL 0x00300000
- #define FLASH_MAN_MT	0x00400000
- #define FLASH_MAN_SHARP 0x00500000
-+#define FLASH_MAN_ATM   0x00070000      /* Atmel */
- 
- 
- #define FLASH_TYPEMASK	0x0000FFFF	/* extract FLASH type	information	*/
-diff -Nurd u-boot-1.1.2/include/ns16550.h u-boot-1.1.2-oxe810/include/ns16550.h
---- u-boot-1.1.2/include/ns16550.h	2004-06-07 01:13:57.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/ns16550.h	2008-06-11 17:55:11.000000000 +0200
-@@ -19,6 +19,10 @@
- 	unsigned char lsr;		/* 5 */
- 	unsigned char msr;		/* 6 */
- 	unsigned char scr;		/* 7 */
-+#if defined(CONFIG_OXNAS)
-+	unsigned char ext;		/* 8 */
-+	unsigned char dlf;		/* 9 */
-+#endif
- #if defined(CONFIG_OMAP730)
- 	unsigned char mdr1;		/* 8 */
- 	unsigned char reg9;		/* 9 */
-diff -Nurd u-boot-1.1.2/lib_arm/board.c u-boot-1.1.2-oxe810/lib_arm/board.c
---- u-boot-1.1.2/lib_arm/board.c	2004-08-02 00:48:22.000000000 +0200
-+++ u-boot-1.1.2-oxe810/lib_arm/board.c	2008-06-11 17:55:06.000000000 +0200
-@@ -39,6 +39,9 @@
- #include "../drivers/lan91c96.h"
- #endif
- 
-+DECLARE_GLOBAL_DATA_PTR
-+
-+
- #if (CONFIG_COMMANDS & CFG_CMD_NAND)
- void nand_init (void);
- #endif
-@@ -106,7 +109,6 @@
- 
- static int init_baudrate (void)
- {
--	DECLARE_GLOBAL_DATA_PTR;
- 
- 	uchar tmp[64];	/* long enough for environment variables */
- 	int i = getenv_r ("baudrate", tmp, sizeof (tmp));
-@@ -142,16 +144,18 @@
-  */
- static int display_dram_config (void)
- {
--	DECLARE_GLOBAL_DATA_PTR;
- 	int i;
- 
- 	puts ("RAM Configuration:\n");
- 
- 	for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
--		printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
-+		printf ("\tBank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
- 		print_size (gd->bd->bi_dram[i].size, "\n");
- 	}
- 
-+	puts("SRAM Configuration:\n");
-+	printf("\t%dKB at 0x%08x\n", gd->bd->bi_sramsize >> 10, gd->bd->bi_sramstart);
-+
- 	return (0);
- }
- 
-@@ -191,6 +195,12 @@
- 	cpu_init,		/* basic cpu dependent setup */
- 	board_init,		/* basic board dependent setup */
- 	interrupt_init,		/* set up exceptions */
-+#ifdef CONFIG_OXNAS
-+	/* Need early console to see SATA env. load messages */
-+	init_baudrate,		/* initialze baudrate settings */
-+	serial_init,		/* serial communications setup */
-+	console_init_f,		/* stage 1 init of console */
-+#endif // CONFIG_OXNAS
- 	env_init,		/* initialize environment */
- 	init_baudrate,		/* initialze baudrate settings */
- 	serial_init,		/* serial communications setup */
-@@ -206,7 +216,6 @@
- 
- void start_armboot (void)
- {
--	DECLARE_GLOBAL_DATA_PTR;
- 
- 	ulong size;
- 	init_fnc_t **init_fnc_ptr;
-@@ -232,9 +241,11 @@
- 		}
- 	}
- 
-+#ifndef CFG_NO_FLASH
- 	/* configure available FLASH banks */
- 	size = flash_init ();
- 	display_flash_config (size);
-+#endif // CFG_NO_FLASH
- 
- #ifdef CONFIG_VFD
- #	ifndef PAGE_SIZE
-@@ -354,6 +365,12 @@
- {
- 	puts ("### ERROR ### Please RESET the board ###\n");
- 	for (;;);
-+}
-+
-+void raise (int n)
-+{
-+	puts ("### ERROR ### Please RESET the board ###\n");
-+	for (;;);
- }
- 
- #ifdef CONFIG_MODEM_SUPPORT
-diff -Nurd u-boot-1.1.2/MAKEALL u-boot-1.1.2-oxe810/MAKEALL
---- u-boot-1.1.2/MAKEALL	2004-12-31 10:32:48.000000000 +0100
-+++ u-boot-1.1.2-oxe810/MAKEALL	2008-06-11 17:55:31.000000000 +0200
-@@ -154,7 +154,7 @@
- 	lpd7a400	mx1ads		mx1fs2		omap1510inn	\
- 	omap1610h2	omap1610inn	omap730p2	scb9328		\
- 	smdk2400	smdk2410	trab		VCMA9		\
--	versatile							\
-+	versatile	oxnas	\
- "
- 
- #########################################################################
-diff -Nurd u-boot-1.1.2/Makefile u-boot-1.1.2-oxe810/Makefile
---- u-boot-1.1.2/Makefile	2004-12-19 10:58:11.000000000 +0100
-+++ u-boot-1.1.2-oxe810/Makefile	2008-06-11 17:55:31.000000000 +0200
-@@ -1296,6 +1296,9 @@
- SX1_config :		unconfig
- 	@./mkconfig $(@:_config=) arm arm925t sx1
- 
-+oxnas_config :	unconfig
-+	@./mkconfig $(@:_config=) arm arm926ejs oxnas
-+
- # TRAB default configuration:	8 MB Flash, 32 MB RAM
- trab_config \
- trab_bigram_config \
-@@ -1561,11 +1564,12 @@
- clean:
- 	find . -type f \
- 		\( -name 'core' -o -name '*.bak' -o -name '*~' \
--		-o -name '*.o'  -o -name '*.a'  \) -print \
-+		-o -name '*.o'  -o -name '*.a' -o -name '.depend' \) -print \
- 		| xargs rm -f
- 	rm -f examples/hello_world examples/timer \
- 	      examples/eepro100_eeprom examples/sched \
--	      examples/mem_to_mem_idma2intr examples/82559_eeprom
-+	      examples/mem_to_mem_idma2intr examples/82559_eeprom \
-+              examples/mem_test
- 	rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr
- 	rm -f tools/mpc86x_clk tools/ncb
- 	rm -f tools/easylogo/easylogo tools/bmp_logo
-diff -Nurd u-boot-1.1.2/net/net.c u-boot-1.1.2-oxe810/net/net.c
---- u-boot-1.1.2/net/net.c	2004-10-12 00:51:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/net/net.c	2008-06-11 17:55:11.000000000 +0200
-@@ -225,7 +225,7 @@
- 		return;
- 
- 	t = get_timer(0);
--
-+	
- 	/* check for arp timeout */
- 	if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
- 		NetArpWaitTry++;
-@@ -235,6 +235,7 @@
- 			NetArpWaitTry = 0;
- 			NetStartAgain();
- 		} else {
-+			puts ("\nARP Resend request\n");
- 			NetArpWaitTimerStart = t;
- 			ArpRequest();
- 		}
-@@ -738,7 +739,7 @@
- #if defined(CONFIG_NET_MULTI)
- 	printf ("Using %s device\n", eth_get_name());
- #endif	/* CONFIG_NET_MULTI */
--	NetSetTimeout (10 * CFG_HZ, PingTimeout);
-+	NetSetTimeout (30 * CFG_HZ, PingTimeout);
- 	NetSetHandler (PingHandler);
- 
- 	PingSend();
-@@ -1384,7 +1385,7 @@
- 				 */
- 				/* XXX point to ip packet */
- 				(*packetHandler)((uchar *)ip, 0, 0, 0);
--				break;
-+				return;/**break; BHC Changed to remove second invocation of ping handler below */
- #endif
- 			default:
- 				return;
-@@ -1492,10 +1493,11 @@
- NetCksum(uchar * ptr, int len)
- {
- 	ulong	xsum;
-+	ushort *s = ptr;
- 
- 	xsum = 0;
- 	while (len-- > 0)
--		xsum += *((ushort *)ptr)++;
-+		xsum += *s++;
- 	xsum = (xsum & 0xffff) + (xsum >> 16);
- 	xsum = (xsum & 0xffff) + (xsum >> 16);
- 	return (xsum & 0xffff);
-diff -Nurd u-boot-1.1.2/net/tftp.c u-boot-1.1.2-oxe810/net/tftp.c
---- u-boot-1.1.2/net/tftp.c	2004-04-15 23:48:55.000000000 +0200
-+++ u-boot-1.1.2-oxe810/net/tftp.c	2008-06-11 17:55:11.000000000 +0200
-@@ -106,6 +106,7 @@
- 	volatile uchar *	pkt;
- 	volatile uchar *	xp;
- 	int			len = 0;
-+	volatile ushort *	s;
- 
- 	/*
- 	 *	We will always be sending some sort of packet, so
-@@ -117,7 +118,9 @@
- 
- 	case STATE_RRQ:
- 		xp = pkt;
--		*((ushort *)pkt)++ = htons(TFTP_RRQ);
-+		s = (ushort *)pkt;
-+		*s++ = htons(TFTP_RRQ);
-+		pkt = (uchar *)s;
- 		strcpy ((char *)pkt, tftp_filename);
- 		pkt += strlen(tftp_filename) + 1;
- 		strcpy ((char *)pkt, "octet");
-@@ -135,15 +138,19 @@
- 	case STATE_DATA:
- 	case STATE_OACK:
- 		xp = pkt;
--		*((ushort *)pkt)++ = htons(TFTP_ACK);
--		*((ushort *)pkt)++ = htons(TftpBlock);
-+		s = (ushort *)pkt;
-+		*s++ = htons(TFTP_ACK);
-+		*s++ = htons(TftpBlock);
-+		pkt = (uchar *)s;
- 		len = pkt - xp;
- 		break;
- 
- 	case STATE_TOO_LARGE:
- 		xp = pkt;
--		*((ushort *)pkt)++ = htons(TFTP_ERROR);
--		*((ushort *)pkt)++ = htons(3);
-+		s = (ushort *)pkt;
-+		*s++ = htons(TFTP_ERROR);
-+		*s++ = htons(3);
-+		pkt = (uchar *)s;
- 		strcpy ((char *)pkt, "File too large");
- 		pkt += 14 /*strlen("File too large")*/ + 1;
- 		len = pkt - xp;
-@@ -151,8 +158,10 @@
- 
- 	case STATE_BAD_MAGIC:
- 		xp = pkt;
--		*((ushort *)pkt)++ = htons(TFTP_ERROR);
--		*((ushort *)pkt)++ = htons(2);
-+		s = (ushort *)pkt;
-+		*s++ = htons(TFTP_ERROR);
-+		*s++ = htons(2);
-+		pkt = (uchar *)s;
- 		strcpy ((char *)pkt, "File has bad magic");
- 		pkt += 18 /*strlen("File has bad magic")*/ + 1;
- 		len = pkt - xp;
-@@ -167,6 +176,7 @@
- TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
- {
- 	ushort proto;
-+	ushort *s;
- 
- 	if (dest != TftpOurPort) {
- 		return;
-@@ -180,7 +190,9 @@
- 	}
- 	len -= 2;
- 	/* warning: don't use increment (++) in ntohs() macros!! */
--	proto = *((ushort *)pkt)++;
-+	s = (ushort *)pkt;
-+	proto = *s++;
-+	pkt = (uchar *)s;
- 	switch (ntohs(proto)) {
- 
- 	case TFTP_RRQ:
diff --git a/recipes/u-boot/u-boot_1.1.2.bb b/recipes/u-boot/u-boot_1.1.2.bb
index c83e31f..8287d35 100644
--- a/recipes/u-boot/u-boot_1.1.2.bb
+++ b/recipes/u-boot/u-boot_1.1.2.bb
@@ -13,7 +13,6 @@ SRC_URI_append_mnci   = "file://mnci.patch;patch=1 \
                          file://command-names.patch;patch=1"
 
 SRC_URI_append_magicbox  = "file://u-boot-emetec.patch;patch=1 "
-SRC_URI_append_oxnas     = "file://oxnas.patch;patch=1 "
 
 
 # TODO: SRC_URI_append_rt3000
@@ -23,7 +22,6 @@ TARGET_LDFLAGS = ""
 UBOOT_MACHINE_mnci   = "mnci_config"
 UBOOT_MACHINE_vibren = "pxa255_idp_config"
 UBOOT_MACHINE_magicbox = "EMETEC405_config"
-UBOOT_MACHINE_oxnas  = "oxnas_config"
 
 inherit base
 
-- 
1.6.4.2





More information about the Openembedded-devel mailing list