diff options
author | ssz <sledz@BFG9000.(none)> | 2009-02-09 09:45:51 +0100 |
---|---|---|
committer | ssz <sledz@BFG9000.(none)> | 2009-02-09 09:45:51 +0100 |
commit | 414f12a48b7da397b2064b4b2bccac52e1e7a387 (patch) | |
tree | 1ccbbea7d009e100949426bd48279ac3406a3f69 /packages/linux/linux-2.6.24/oxe810 | |
parent | 40a3369fd8275701ff98918f66bb95e297d52c42 (diff) |
machines: oxe810 renamed to oxnas
- avoid future confusions (oxe810 is just the processor, oxnas is the
official name of the device)
- affects machine conf, linux kernel, and u-boot
Diffstat (limited to 'packages/linux/linux-2.6.24/oxe810')
-rw-r--r-- | packages/linux/linux-2.6.24/oxe810/defconfig | 1232 | ||||
-rw-r--r-- | packages/linux/linux-2.6.24/oxe810/oxe810.diff | 57804 |
2 files changed, 0 insertions, 59036 deletions
diff --git a/packages/linux/linux-2.6.24/oxe810/defconfig b/packages/linux/linux-2.6.24/oxe810/defconfig deleted file mode 100644 index 5382e30f85..0000000000 --- a/packages/linux/linux-2.6.24/oxe810/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/packages/linux/linux-2.6.24/oxe810/oxe810.diff b/packages/linux/linux-2.6.24/oxe810/oxe810.diff deleted file mode 100644 index 04ff1a670b..0000000000 --- a/packages/linux/linux-2.6.24/oxe810/oxe810.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@google.com> --Adam Oldham <oldhamca@gmail.com> --Adam Radford <aradford@gmail.com> --Adrian Bunk <bunk@stusta.de> --Alan Cox <alan@lxorguk.ukuu.org.uk> --Alan Cox <root@hraefn.swansea.linux.org.uk> --Aleksey Gorelov <aleksey_gorelov@phoenix.com> --Al Viro <viro@ftp.linux.org.uk> --Al Viro <viro@zenIV.linux.org.uk> --Andreas Herrmann <aherrman@de.ibm.com> --Andrew Morton <akpm@osdl.org> --Andrew Vasquez <andrew.vasquez@qlogic.com> --Andy Adamson <andros@citi.umich.edu> --Arnaud Patard <arnaud.patard@rtp-net.org> --Arnd Bergmann <arnd@arndb.de> --Axel Dyks <xl@xlsigned.net> --Ben Gardner <bgardner@wabtec.com> --Ben M Cahill <ben.m.cahill@intel.com> --Björn Steinbrink <B.Steinbrink@gmx.de> --Brian Avery <b.avery@hp.com> --Brian King <brking@us.ibm.com> --Christoph Hellwig <hch@lst.de> --Corey Minyard <minyard@acm.org> --David Brownell <david-b@pacbell.net> --David Woodhouse <dwmw2@shinybook.infradead.org> --Domen Puncer <domen@coderock.org> --Douglas Gilbert <dougg@torque.net> --Ed L. Cashin <ecashin@coraid.com> --Evgeniy Polyakov <johnpol@2ka.mipt.ru> --Felipe W Damasio <felipewd@terra.com.br> --Felix Kuhling <fxkuehl@gmx.de> --Felix Moeller <felix@derklecks.de> --Filipe Lautert <filipe@icewall.org> --Franck Bui-Huu <vagabon.xyz@gmail.com> --Frank Zago <fzago@systemfabricworks.com> --Greg Kroah-Hartman <greg@echidna.(none)> --Greg Kroah-Hartman <gregkh@suse.de> --Greg Kroah-Hartman <greg@kroah.com> --Henk Vergonet <Henk.Vergonet@gmail.com> --Henrik Kretzschmar <henne@nachtwindheim.de> --Herbert Xu <herbert@gondor.apana.org.au> --Jacob Shin <Jacob.Shin@amd.com> --James Bottomley <jejb@mulgrave.(none)> --James Bottomley <jejb@titanic.il.steeleye.com> --James E Wilson <wilson@specifix.com> --James Ketrenos <jketreno@io.(none)> --Jean Tourrilhes <jt@hpl.hp.com> --Jeff Garzik <jgarzik@pretzel.yyz.us> --Jens Axboe <axboe@suse.de> --Jens Osterkamp <Jens.Osterkamp@de.ibm.com> --John Stultz <johnstul@us.ibm.com> --Juha Yrjola <at solidboot.com> --Juha Yrjola <juha.yrjola@nokia.com> --Juha Yrjola <juha.yrjola@solidboot.com> --Kay Sievers <kay.sievers@vrfy.org> --Kenneth W Chen <kenneth.w.chen@intel.com> --Koushik <raghavendra.koushik@neterion.com> --Leonid I Ananiev <leonid.i.ananiev@intel.com> --Linas Vepstas <linas@austin.ibm.com> --Matthieu CASTET <castet.matthieu@free.fr> --Michael Buesch <mb@bu3sch.de> --Michael Buesch <mbuesch@freenet.de> --Michel Dänzer <michel@tungstengraphics.com> --Mitesh shah <mshah@teja.com> --Morten Welinder <terra@gnome.org> --Morten Welinder <welinder@anemone.rentec.com> --Morten Welinder <welinder@darter.rentec.com> --Morten Welinder <welinder@troll.com> --Nguyen Anh Quynh <aquynh@gmail.com> --Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> --Patrick Mochel <mochel@digitalimplant.org> --Peter A Jonsson <pj@ludd.ltu.se> --Praveen BP <praveenbp@ti.com> --Rajesh Shah <rajesh.shah@intel.com> --Ralf Baechle <ralf@linux-mips.org> --Ralf Wildenhues <Ralf.Wildenhues@gmx.de> --Rémi Denis-Courmont <rdenis@simphalempin.com> --Rudolf Marek <R.Marek@sh.cvut.cz> --Rui Saraiva <rmps@joel.ist.utl.pt> --Sachin P Sant <ssant@in.ibm.com> --Sam Ravnborg <sam@mars.ravnborg.org> --Simon Kelley <simon@thekelleys.org.uk> --Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> --Stephen Hemminger <shemminger@osdl.org> --Tejun Heo <htejun@gmail.com> --Thomas Graf <tgraf@suug.ch> --Tony Luck <tony.luck@intel.com> --Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> --Valdis Kletnieks <Valdis.Kletnieks@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(©_mutex)); -+ -+ // Get kernel mappings for the user pages -+ down_read(¤t->mm->mmap_sem); -+ pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 0, 0, pages, NULL); -+ up_read(¤t->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(©_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(©_mutex)); -+// -+// // Get kernel mappings for the user pages -+// down_read(¤t->mm->mmap_sem); -+// pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 1, 0, pages, NULL); -+// up_read(¤t->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(©_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, ðtool_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@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@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@80000000/ide@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(¤t->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@davemloft.net) -+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@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, ®); -+ 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, ®); -+ 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@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@saout.de> -+ * Copyright (C) 2004 Clemens Fruhwirth <clemens@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, ®s->CAMCR); -- -- writeb(0, ®s->CAMADDR); -- -- /* read mask */ -- for (i = 0; i < 8; i++) -- *mask++ = readb(&(regs->MARCAM[i])); -- -- /* disable CAMEN */ -- writeb(0, ®s->CAMADDR); -- -- /* Select mar */ -- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -- -- writeb(CAMADDR_CAMEN, ®s->CAMADDR); -- -- for (i = 0; i < 8; i++) { -- writeb(*mask++, &(regs->MARCAM[i])); -- } -- /* disable CAMEN */ -- writeb(0, ®s->CAMADDR); -- -- /* Select mar */ -- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -- -- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR); -- -- for (i = 0; i < 8; i++) { -- writeb(*mask++, &(regs->MARCAM[i])); -- } -- /* disable CAMEN */ -- writeb(0, ®s->CAMADDR); -- -- /* Select mar */ -- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -- -- idx &= (64 - 1); -- -- writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); -- -- for (i = 0; i < 6; i++) { -- writeb(*addr++, &(regs->MARCAM[i])); -- } -- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->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, ®s->CAMADDR); -+#define VELOCITY_DESC_IN_SRAM - -- /* Select mar */ -- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -- -- idx &= (64 - 1); -- -- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); -- writew(*((u16 *) addr), ®s->MARCAM[0]); -- -- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR); -- -- udelay(10); -- -- writeb(0, ®s->CAMADDR); -- -- /* Select mar */ -- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->STICKHW); -- /* clear sticky bits */ -- BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); -- -- BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR); -- BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); -- /* disable force PME-enable */ -- writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr); -- /* disable power-event config bit */ -- writew(0xFFFF, ®s->WOLCRClr); -- /* clear power status */ -- writew(0xFFFF, ®s->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, ®s->MCFG); - WORD_REG_BITS_ON(MCFG_VIDFR, ®s->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, ®s->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, ®s->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, ®s->CR0Clr); -- writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), -+ writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), - ®s->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, ®s->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(®s->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, ®s->TXESR); - writew(TRDCSR_RUN, ®s->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, ®s->MARCAM[0]); -+ writel(0x0, ®s->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, ®s->MARCAM[0]); -+ writel(0xffffffff, ®s->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, ®s->MARCAM[0]); -- writel(0xffffffff, ®s->MARCAM[4]); -- rx_mode = (RCR_AM | RCR_AB | RCR_PROM); -- } else if ((dev->mc_count > vptr->multicast_limit) -- || (dev->flags & IFF_ALLMULTI)) { -- writel(0xffffffff, ®s->MARCAM[0]); -- writel(0xffffffff, ®s->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, ®s->RCR); -- -+ BYTE_REG_BITS_SET(rx_mode, RCR_AM | RCR_AB | RCR_PROM | RCR_AL | RCR_AP, ®s->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(®s->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, ®s->CAMCR); -+ -+ if (cam_type == VELOCITY_VLAN_ID_CAM) -+ writeb(CAMADDR_VCAMSL, ®s->CAMADDR); -+ else -+ writeb(0, ®s->CAMADDR); -+ -+ /* read mask */ -+ for (i = 0; i < 8; i++) -+ *mask++ = readb(&(regs->MARCAM[i])); -+ -+ /* disable CAMEN */ -+ writeb(0, ®s->CAMADDR); -+ -+ /* Select mar */ -+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -+ -+ if (cam_type == VELOCITY_VLAN_ID_CAM) -+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR); -+ else -+ writeb(CAMADDR_CAMEN, ®s->CAMADDR); -+ -+ for (i = 0; i < 8; i++) { -+ writeb(*mask++, &(regs->MARCAM[i])); -+ } -+ /* disable CAMEN */ -+ writeb(0, ®s->CAMADDR); -+ -+ /* Select mar */ -+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -+ -+ idx &= (64 - 1); -+ -+ if (cam_type == VELOCITY_VLAN_ID_CAM) -+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); -+ else -+ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); -+ -+ if (cam_type == VELOCITY_VLAN_ID_CAM) -+ writew(*((u16 *) addr), ®s->MARCAM[0]); -+ else { -+ for (i = 0; i < 6; i++) { -+ writeb(*addr++, &(regs->MARCAM[i])); -+ } -+ } -+ BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR); -+ -+ udelay(10); -+ -+ writeb(0, ®s->CAMADDR); -+ -+ /* Select mar */ -+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->CAMCR); -+ -+ idx &= (64 - 1); -+ -+ if (cam_type == VELOCITY_VLAN_ID_CAM) -+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); -+ else -+ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); -+ -+ BYTE_REG_BITS_ON(CAMCR_CAMRD, ®s->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, ®s->CAMADDR); -+ -+ /* Select mar */ -+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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, ®s->STICKHW); -+ /* clear sticky bits */ -+ BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); -+ -+ BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR); -+ BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); -+ /* disable force PME-enable */ -+ writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr); -+ /* disable power-event config bit */ -+ writew(0xFFFF, ®s->WOLCRClr); -+ /* clear power status */ -+ writew(0xFFFF, ®s->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@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@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@gmx.net> - * and Olaf Hering <olh@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(<p->bestcount, 1); -+ be32_add_cpu(<p->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(<p->bestcount, -(db - i)); -+ be32_add_cpu(<p->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(<p->bestcount, -1); -+ be32_add_cpu(<p->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@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 -+ = ¤t_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 = ¤t_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@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@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@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@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@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@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; - } |