diff -urN orig/linux-2.6.35.9//acme_config relase/linux-2.6.35.9//acme_config --- orig/linux-2.6.35.9//acme_config 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//acme_config 2010-09-29 17:22:41.000000000 +0200 @@ -0,0 +1,3029 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.35.4 +# Tue Sep 21 10:13:28 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_ARCH_USES_GETTIMEOFFSET=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_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_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +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_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# 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_VEXPRESS is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X 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_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +CONFIG_HAVE_AT91_USART3=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_HAVE_AT91_USART5=y + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +CONFIG_ARCH_AT91SAM9G20=y +# CONFIG_ARCH_AT91SAM9G45 is not set +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT572D940HF is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9G20 Board Type +# +# CONFIG_MACH_AT91SAM9G20EK is not set +# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set +# CONFIG_MACH_CPU9G20 is not set +# CONFIG_MACH_PORTUXG20 is not set +# CONFIG_MACH_STAMP9G20 is not set +CONFIG_MACH_FOXG20=y + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_AT91_TIMER_HZ=100 +# CONFIG_AT91_EARLY_DBGU is not set +CONFIG_AT91_EARLY_USART0=y +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=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_ARM_L1_CACHE_SHIFT=5 + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rw rootwait init=/sbin/init" +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_NVS=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_APM_EMULATION=m +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_PHONET=m +CONFIG_IEEE802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +# CONFIG_MKISS is not set +# CONFIG_6PACK is not set +# CONFIG_BPQETHER is not set +# CONFIG_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_BAYCOM_PAR is not set +# CONFIG_BAYCOM_EPP is not set +# CONFIG_YAM is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_DEV is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +# CONFIG_BT_L2CAP_EXT_FEATURES is not set +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +# CONFIG_BT_ATH3K is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_1284 is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_BLK_DEV=y +# CONFIG_PARIDE 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_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_OSD 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=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +# CONFIG_ICS932S401 is not set +CONFIG_ATMEL_SSC=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +CONFIG_SENSORS_TSL2550=m +CONFIG_DS1682=m +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +CONFIG_IWMC3200TOP=m +# CONFIG_IWMC3200TOP_DEBUG is not set +# CONFIG_IWMC3200TOP_DEBUGFS is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m +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=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FC_TGT_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_ATA is not set +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_SRP_TGT_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +# CONFIG_SATA_AHCI_PLATFORM is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_SATA_MV=m + +# +# PATA SFF controllers with BMDMA +# + +# +# PIO-only SFF controllers +# +CONFIG_PATA_AT91=m +CONFIG_PATA_PLATFORM=m + +# +# Generic fallback / legacy drivers +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_AT76C50X_USB=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8187=m +CONFIG_MAC80211_HWSIM=m +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH9K_HTC is not set +CONFIG_AR9170_USB=m +CONFIG_B43=m +# CONFIG_B43_SDIO is not set +CONFIG_B43_PIO=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_IWM=m +# CONFIG_IWM_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_MESH is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_SPI=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT30XX=y +# CONFIG_RT2800USB_RT35XX is not set +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL12XX is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO 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=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=m +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_CDC_PHONET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set +CONFIG_IEEE802154_DRIVERS=m +# CONFIG_IEEE802154_FAKEHARD is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +CONFIG_PHONE=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_APMPOWER=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADP5588=m +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_QT2160 is not set +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_TCA6416 is not set +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_LM8323=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +# CONFIG_JOYSTICK_IFORCE_USB is not set +# CONFIG_JOYSTICK_IFORCE_232 is not set +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +# CONFIG_JOYSTICK_XPAD_FF is not set +# CONFIG_JOYSTICK_XPAD_LEDS is not set +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879=m +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC5UH=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_W90X900=m +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_SI is not set +# CONFIG_IPMI_WATCHDOG is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_NVRAM=m +CONFIG_R3964=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB 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_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +CONFIG_SPI_BITBANG=m +# CONFIG_SPI_BUTTERFLY is not set +CONFIG_SPI_GPIO=m +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_TLE62X0=m + +# +# PPS support +# +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_W1=y +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=y + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=y +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_APM_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91SAM9X_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TC35892 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB8500_CORE is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_IR_CORE=m +CONFIG_VIDEO_IR=m +CONFIG_RC_MAP=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +# CONFIG_IR_IMON is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_AU0828=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +# CONFIG_SOC_CAMERA_MT9T112 is not set +CONFIG_SOC_CAMERA_MT9V022=m +# CONFIG_SOC_CAMERA_RJ54N1 is not set +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_OV772X=m +# CONFIG_SOC_CAMERA_OV9640 is not set +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +# CONFIG_USB_GSPCA_BENQ is not set +CONFIG_USB_GSPCA_CONEX=m +# CONFIG_USB_GSPCA_CPIA1 is not set +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +# CONFIG_USB_GSPCA_OV534_9 is not set +CONFIG_USB_GSPCA_PAC207=m +# CONFIG_USB_GSPCA_PAC7302 is not set +CONFIG_USB_GSPCA_PAC7311=m +# CONFIG_USB_GSPCA_SN9C2028 is not set +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_STK014=m +# CONFIG_USB_GSPCA_STV0680 is not set +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +# CONFIG_VIDEO_TLG2300 is not set +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_DSBR=m +# CONFIG_RADIO_SI470X is not set +CONFIG_USB_MR800=m +CONFIG_RADIO_TEA5764=m +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_FRIIO=m +# CONFIG_DVB_USB_EC168 is not set +# CONFIG_DVB_USB_AZ6027 is not set +CONFIG_SMS_SIANO_MDTV=m + +# +# Siano module components +# +CONFIG_SMS_USB_DRV=m +CONFIG_SMS_SDIO_DRV=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_STB6100=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=m +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +CONFIG_LCD_LMS283GF05=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +CONFIG_LCD_PLATFORM=m +# CONFIG_LCD_S6E63M0 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP8860 is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_MPU401_UART=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_ARM=y + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_AC97C is not set +CONFIG_SND_SPI=y +CONFIG_SND_AT73C213=m +CONFIG_SND_AT73C213_TARGET_BITRATE=48000 +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +CONFIG_SND_USB_CAIAQ=m +# CONFIG_SND_USB_CAIAQ_INPUT is not set +CONFIG_SND_SOC=m +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_ATMEL_SOC_SSC=m +CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_WM_HUBS=m +CONFIG_SND_SOC_AD1836=m +CONFIG_SND_SOC_AD193X=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_ADS117X=m +CONFIG_SND_SOC_AK4104=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK4671=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_DA7210=m +CONFIG_SND_SOC_L3=m +CONFIG_SND_SOC_PCM3008=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320DAC33=m +CONFIG_SND_SOC_UDA134X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8727=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8940=m +CONFIG_SND_SOC_WM8955=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8961=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8988=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SOC_WM8993=m +CONFIG_SND_SOC_WM9081=m +CONFIG_SND_SOC_MAX9877=m +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_WM2000=m +CONFIG_SND_SOC_WM9090=m +CONFIG_SOUND_PRIME=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +# CONFIG_HID_CANDO is not set +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_PRODIKEYS is not set +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +# CONFIG_DRAGONRISE_FF is not set +# CONFIG_HID_EGALAX is not set +CONFIG_HID_EZKEY=m +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MICROSOFT=m +# CONFIG_HID_MOSART is not set +CONFIG_HID_MONTEREY=m +CONFIG_HID_NTRIG=m +# CONFIG_HID_ORTEK is not set +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_ROCCAT_KONE is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +# CONFIG_HID_STANTUM is not set +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=m +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_WACOM=m +# CONFIG_HID_WACOM_POWER_SUPPLY is not set +CONFIG_HID_ZEROPLUS=m +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=m +# CONFIG_USB_ULPI is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_AT91=y +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_DAC124S085=m +CONFIG_LEDS_BD2802=m +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_DEBUG=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 +# CONFIG_DMADEVICES is not set +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_STAGING 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_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +# CONFIG_GFS2_FS_LOCKING_DLM is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_NILFS2_FS=m +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=m +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m + +# +# Caches +# +CONFIG_FSCACHE=m +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_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_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTRS is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_EXOFS_FS=m +# CONFIG_EXOFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_FSCACHE is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +# CONFIG_AFS_FSCACHE 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=y +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_PCOMP=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MANAGER_TESTS=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=m +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -urN orig/linux-2.6.35.9//arch/arm/boot/compressed/head.S relase/linux-2.6.35.9//arch/arm/boot/compressed/head.S --- orig/linux-2.6.35.9//arch/arm/boot/compressed/head.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/boot/compressed/head.S 2011-03-15 10:56:25.869702441 +0100 @@ -1064,6 +1064,15 @@ mov pc, r10 #endif +#ifdef CONFIG_IPIPE_TRACE_MCOUNT + .text + .align 0 + .type mcount %function + .global mcount +mcount: + mov pc, lr @ just return +#endif + .ltorg reloc_end: diff -urN orig/linux-2.6.35.9//arch/arm/common/it8152.c relase/linux-2.6.35.9//arch/arm/common/it8152.c --- orig/linux-2.6.35.9//arch/arm/common/it8152.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/common/it8152.c 2011-03-15 10:56:25.873702441 +0100 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -119,21 +120,21 @@ bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1); while (bits_pd) { i = __ffs(bits_pd); - generic_handle_irq(IT8152_PD_IRQ(i)); + ipipe_handle_chained_irq(IT8152_PD_IRQ(i)); bits_pd &= ~(1 << i); } bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1); while (bits_lp) { i = __ffs(bits_lp); - generic_handle_irq(IT8152_LP_IRQ(i)); + ipipe_handle_chained_irq(IT8152_LP_IRQ(i)); bits_lp &= ~(1 << i); } bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1); while (bits_ld) { i = __ffs(bits_ld); - generic_handle_irq(IT8152_LD_IRQ(i)); + ipipe_handle_chained_irq(IT8152_LD_IRQ(i)); bits_ld &= ~(1 << i); } } diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/assembler.h relase/linux-2.6.35.9//arch/arm/include/asm/assembler.h --- orig/linux-2.6.35.9//arch/arm/include/asm/assembler.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/assembler.h 2011-03-15 10:56:25.873702441 +0100 @@ -81,6 +81,18 @@ .macro enable_irq_notrace cpsie i .endm + + .macro disable_irq_cond +#ifdef CONFIG_IPIPE + cpsid i +#endif /* CONFIG_IPIPE */ + .endm + + .macro enable_irq_cond +#ifdef CONFIG_IPIPE + cpsie i +#endif /* CONFIG_IPIPE */ + .endm #else .macro disable_irq_notrace msr cpsr_c, #PSR_I_BIT | SVC_MODE @@ -89,6 +101,18 @@ .macro enable_irq_notrace msr cpsr_c, #SVC_MODE .endm + + .macro disable_irq_cond +#ifdef CONFIG_IPIPE + msr cpsr_c, #PSR_I_BIT | SVC_MODE +#endif /* CONFIG_IPIPE */ + .endm + + .macro enable_irq_cond +#ifdef CONFIG_IPIPE + msr cpsr_c, #SVC_MODE +#endif /* CONFIG_IPIPE */ + .endm #endif .macro asm_trace_hardirqs_off diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/atomic.h relase/linux-2.6.35.9//arch/arm/include/asm/atomic.h --- orig/linux-2.6.35.9//arch/arm/include/asm/atomic.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/atomic.h 2011-03-15 10:56:25.873702441 +0100 @@ -158,10 +158,10 @@ unsigned long flags; int val; - raw_local_irq_save(flags); + local_irq_save_hw(flags); val = v->counter; v->counter = val += i; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return val; } @@ -172,10 +172,10 @@ unsigned long flags; int val; - raw_local_irq_save(flags); + local_irq_save_hw(flags); val = v->counter; v->counter = val -= i; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return val; } @@ -186,11 +186,11 @@ int ret; unsigned long flags; - raw_local_irq_save(flags); + local_irq_save_hw(flags); ret = v->counter; if (likely(ret == old)) v->counter = new; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return ret; } @@ -199,9 +199,9 @@ { unsigned long flags; - raw_local_irq_save(flags); + local_irq_save_hw(flags); *addr &= ~mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); } #endif /* __LINUX_ARM_ARCH__ */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/bitops.h relase/linux-2.6.35.9//arch/arm/include/asm/bitops.h --- orig/linux-2.6.35.9//arch/arm/include/asm/bitops.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/bitops.h 2011-03-15 10:56:25.873702441 +0100 @@ -41,9 +41,9 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); *p |= mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); } static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p) @@ -53,9 +53,9 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); *p &= ~mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); } static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p) @@ -65,9 +65,9 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); *p ^= mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); } static inline int @@ -79,10 +79,10 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); res = *p; *p = res | mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return (res & mask) != 0; } @@ -96,10 +96,10 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); res = *p; *p = res & ~mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return (res & mask) != 0; } @@ -113,10 +113,10 @@ p += bit >> 5; - raw_local_irq_save(flags); + local_irq_save_hw(flags); res = *p; *p = res ^ mask; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); return (res & mask) != 0; } diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/cacheflush.h relase/linux-2.6.35.9//arch/arm/include/asm/cacheflush.h --- orig/linux-2.6.35.9//arch/arm/include/asm/cacheflush.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/cacheflush.h 2011-03-15 10:56:25.873702441 +0100 @@ -16,6 +16,7 @@ #include #include #include +#include #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) @@ -276,6 +277,27 @@ #endif +#ifdef CONFIG_ARM_FCSE +#define FCSE_CACHE_MASK (~(L1_CACHE_BYTES - 1)) +#define FCSE_CACHE_ALIGN(addr) (((addr) + ~FCSE_CACHE_MASK) & FCSE_CACHE_MASK) + +static inline void +fcse_flush_cache_user_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (cache_is_vivt() + && fcse_mm_in_cache(vma->vm_mm)) { + start = fcse_va_to_mva(vma->vm_mm, start & FCSE_CACHE_MASK); + end = fcse_va_to_mva(vma->vm_mm, FCSE_CACHE_ALIGN(end)); + __cpuc_flush_user_range(start, end, vma->vm_flags); + } +} +#undef FCSE_CACHE_MASK +#undef FCSE_CACHE_ALIGN +#else /* ! CONFIG_ARM_FCSE */ +#define fcse_flush_cache_user_range(vma, start, end) do { } while (0) +#endif /* ! CONFIG_ARM_FCSE */ + /* * Copy user data from/to a page which is mapped into a different * processes address space. Really, we want to allow our "user @@ -283,9 +305,10 @@ */ extern void copy_to_user_page(struct vm_area_struct *, struct page *, unsigned long, void *, const void *, unsigned long); -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - do { \ - memcpy(dst, src, len); \ +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + fcse_flush_cache_user_range(vma, vaddr, vaddr + len); \ + memcpy(dst, src, len); \ } while (0) /* @@ -295,23 +318,29 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm) { - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) + if (fcse_mm_in_cache(mm)) { + unsigned seq = fcse_flush_all_start(); __cpuc_flush_user_all(); + fcse_flush_all_done(seq, 1); + } } static inline void vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) - __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), - vma->vm_flags); + if (fcse_mm_in_cache(vma->vm_mm)) { + start = fcse_va_to_mva(vma->vm_mm, start & PAGE_MASK); + end = fcse_va_to_mva(vma->vm_mm, PAGE_ALIGN(end)); + __cpuc_flush_user_range(start, end, vma->vm_flags); + } } static inline void vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) { - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { - unsigned long addr = user_addr & PAGE_MASK; + if (fcse_mm_in_cache(vma->vm_mm)) { + unsigned long addr; + addr = fcse_va_to_mva(vma->vm_mm, user_addr) & PAGE_MASK; __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); } } @@ -336,14 +365,22 @@ * Harvard caches are synchronised for the user space address range. * This is used for the ARM private sys_cacheflush system call. */ -#define flush_cache_user_range(vma,start,end) \ - __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) +#define flush_cache_user_range(vma, start, end) \ + ({ \ + struct mm_struct *_mm = (vma)->vm_mm; \ + unsigned long _start, _end; \ + _start = fcse_va_to_mva(_mm, start) & PAGE_MASK; \ + _end = PAGE_ALIGN(fcse_va_to_mva(_mm, end)); \ + __cpuc_coherent_user_range(_start, _end); \ + }) /* * Perform necessary cache operations to ensure that data previously * stored within this range of addresses can be executed by the CPU. */ -#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) +#define flush_icache_range(s,e) \ + __cpuc_coherent_kern_range(fcse_va_to_mva(current->mm, (s)), \ + fcse_va_to_mva(current->mm, (e))) /* * Perform necessary cache operations to ensure that the TLB will @@ -399,7 +436,8 @@ extern void __flush_anon_page(struct vm_area_struct *vma, struct page *, unsigned long); if (PageAnon(page)) - __flush_anon_page(vma, page, vmaddr); + __flush_anon_page(vma, page, + fcse_va_to_mva(vma->vm_mm, vmaddr)); } #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE @@ -433,9 +471,11 @@ */ static inline void flush_cache_vmap(unsigned long start, unsigned long end) { - if (!cache_is_vipt_nonaliasing()) + if (!cache_is_vipt_nonaliasing()) { + unsigned seq = fcse_flush_all_start(); flush_cache_all(); - else + fcse_flush_all_done(seq, 1); + } else /* * set_pte_at() called from vmap_pte_range() does not * have a DSB after cleaning the cache line. @@ -445,8 +485,11 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { - if (!cache_is_vipt_nonaliasing()) + if (!cache_is_vipt_nonaliasing()) { + unsigned seq = fcse_flush_all_start(); flush_cache_all(); + fcse_flush_all_done(seq, 1); + } } #endif diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/cpu-multi32.h relase/linux-2.6.35.9//arch/arm/include/asm/cpu-multi32.h --- orig/linux-2.6.35.9//arch/arm/include/asm/cpu-multi32.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/cpu-multi32.h 2011-03-15 10:56:25.873702441 +0100 @@ -52,7 +52,13 @@ /* * Set the page table */ +#ifndef CONFIG_ARM_FCSE_BEST_EFFORT void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm); +#else /* !CONFIG_ARM_FCSE_BEST_EFFORT */ + void (*switch_mm)(unsigned long pgd_phys, + struct mm_struct *mm, unsigned flush); +#endif /* !CONFIG_ARM_FCSE_BEST_EFFORT */ + /* * Set a possibly extended PTE. Non-extended PTEs should * ignore 'ext'. @@ -66,4 +72,8 @@ #define cpu_do_idle() processor._do_idle() #define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz) #define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext) +#ifndef CONFIG_ARM_FCSE_BEST_EFFORT #define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm) +#else /* !CONFIG_ARM_FCSE_BEST_EFFORT */ +#define cpu_do_switch_mm(pgd,mm,flush) processor.switch_mm(pgd,mm,flush) +#endif /* !CONFIG_ARM_FCSE_BEST_EFFORT */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/cpu-single.h relase/linux-2.6.35.9//arch/arm/include/asm/cpu-single.h --- orig/linux-2.6.35.9//arch/arm/include/asm/cpu-single.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/cpu-single.h 2011-03-15 10:56:25.873702441 +0100 @@ -39,6 +39,11 @@ extern void cpu_proc_fin(void); extern int cpu_do_idle(void); extern void cpu_dcache_clean_area(void *, int); +#ifndef CONFIG_ARM_FCSE_BEST_EFFORT extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); +#else /* !CONFIG_ARM_FCSE_BEST_EFFORT */ +extern void cpu_do_switch_mm(unsigned long pgd_phys, + struct mm_struct *mm, unsigned flush); +#endif /* !CONFIG_ARM_FCSE_BEST_EFFORT */ extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/fcse.h relase/linux-2.6.35.9//arch/arm/include/asm/fcse.h --- orig/linux-2.6.35.9//arch/arm/include/asm/fcse.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/fcse.h 2011-03-15 10:56:25.873702441 +0100 @@ -0,0 +1,181 @@ +/* + * arch/arm/include/asm/fcse.h + * + * Helper header for using the ARM Fast Context Switch Extension with + * processors supporting it, lifted from the Fast Address Space + * Switching (FASS) patch for ARM Linux. + * + * Copyright (C) 2001, 2002 Adam Wiggins + * Copyright (C) 2007 Sebastian Smolorz + * Copyright (C) 2008 Richard Cochran + * Copyright (C) 2009-2011 Gilles Chanteperdrix + * + * 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_FCSE_H +#define __ASM_ARM_FCSE_H + +#ifdef CONFIG_ARM_FCSE + +#include /* For struct mm_struct */ +#include +#include + +#include +#include + +#define FCSE_PID_SHIFT 25 + +/* Size of PID relocation area */ +#define FCSE_PID_TASK_SIZE (1UL << FCSE_PID_SHIFT) + +/* Mask to get rid of PID from relocated address */ +#define FCSE_PID_MASK (FCSE_PID_TASK_SIZE - 1) + +#define FCSE_PID_INVALID (~0 << FCSE_PID_SHIFT) +extern unsigned long fcse_pids_cache_dirty[]; + +#ifdef CONFIG_ARM_FCSE_DEBUG +#define FCSE_BUG_ON(expr) BUG_ON(expr) +#else /* !CONFIG_ARM_FCSE_DEBUG */ +#define FCSE_BUG_ON(expr) do { } while(0) +#endif /* !CONFIG_ARM_FCSE_DEBUG */ + +#if defined(CONFIG_ARM_FCSE_DYNPID) && defined(CONFIG_PREEMPT) +#define fcse_check_context(mm) \ + FCSE_BUG_ON(!in_atomic() \ + && (mm)->context.fcse.active \ + && atomic_read(&(mm)->mm_users) \ + && !(mm)->core_state \ + && !rwsem_is_locked(&(mm)->mmap_sem) \ + && !irqs_disabled_hw()); +#else /* !CONFIG_ARM_FCSE_DYNPID */ +#define fcse_check_context(mm) do { (void)(mm); } while(0) +#endif /* !CONFIG_ARM_FCSE_DYNPID */ + +int fcse_pid_alloc(struct mm_struct *mm); +void fcse_pid_free(struct mm_struct *mm); +unsigned fcse_flush_all_start(void); +void fcse_flush_all_done(unsigned seq, unsigned dirty); +unsigned long +fcse_check_mmap_inner(struct mm_struct *mm, unsigned long start_addr, + unsigned long addr, unsigned long len, unsigned long fl); + +/* Sets the CPU's PID Register */ +static inline void fcse_pid_set(unsigned long pid) +{ + __asm__ __volatile__ ("mcr p15, 0, %0, c13, c0, 0" + : /* */: "r" (pid) : "cc", "memory"); +} + +static inline unsigned long +fcse_va_to_mva(struct mm_struct *mm, unsigned long va) +{ + if (cache_is_vivt() && va < FCSE_PID_TASK_SIZE) { + fcse_check_context(mm); + return mm->context.fcse.pid | va; + } + return va; +} + +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +struct fcse_user { + struct mm_struct *mm; + unsigned count; +}; +extern struct fcse_user fcse_pids_user[]; +int fcse_switch_mm_inner(struct mm_struct *prev, struct mm_struct *next); +void fcse_pid_reference(unsigned pid); + +static inline int fcse_switch_mm(struct mm_struct *prev, struct mm_struct *next) +{ + if (!cache_is_vivt()) + return 0; + + return fcse_switch_mm_inner(prev, next); +} + +static inline int fcse_mm_in_cache(struct mm_struct *mm) +{ + unsigned fcse_pid = mm->context.fcse.pid >> FCSE_PID_SHIFT; + int res; + fcse_check_context(mm); + res = test_bit(fcse_pid, fcse_pids_cache_dirty) + && fcse_pids_user[fcse_pid].mm == mm; + return res; +} + +static inline unsigned long +fcse_check_mmap_addr(struct mm_struct *mm, unsigned long start_addr, + unsigned long addr, unsigned long len, unsigned long fl) +{ + const unsigned long stack_base = ALIGN(mm->start_stack, PAGE_SIZE) + - current->signal->rlim[RLIMIT_STACK].rlim_cur; + + if (addr + len <= stack_base) + return addr; + + return fcse_check_mmap_inner(mm, start_addr, addr, len, fl); +} + +#else /* CONFIG_ARM_FCSE_GUARANTEED */ +static inline int +fcse_switch_mm(struct mm_struct *prev, struct mm_struct *next) +{ + unsigned fcse_pid; + + if (!cache_is_vivt()) + return 0; + + fcse_pid = next->context.fcse.pid >> FCSE_PID_SHIFT; + set_bit(fcse_pid, fcse_pids_cache_dirty); + fcse_pid_set(next->context.fcse.pid); + return 0; +} + +static inline int fcse_mm_in_cache(struct mm_struct *mm) +{ + unsigned fcse_pid = mm->context.fcse.pid >> FCSE_PID_SHIFT; + return test_bit(fcse_pid, fcse_pids_cache_dirty); +} + +static inline unsigned long +fcse_check_mmap_addr(struct mm_struct *mm, unsigned long start_addr, + unsigned long addr, unsigned long len, unsigned long fl) +{ + if (addr + len <= FCSE_TASK_SIZE) + return addr; + + return fcse_check_mmap_inner(mm, start_addr, addr, len, fl); +} +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ + +static inline void fcse_mark_dirty(struct mm_struct *mm) +{ + if (cache_is_vivt()) { + set_bit(mm->context.fcse.pid >> FCSE_PID_SHIFT, + fcse_pids_cache_dirty); + FCSE_BUG_ON(!fcse_mm_in_cache(mm)); + } +} + +#else /* ! CONFIG_ARM_FCSE */ +#define fcse_switch_mm(prev, next) do { } while (0) +#define fcse_va_to_mva(mm, x) ({ (void)(mm); (x); }) +#define fcse_mark_dirty(mm) do { (void)(mm); } while(0) +#define fcse_flush_all_start() (0) +#define fcse_flush_all_done(seq, dirty) do { (void)(seq); } while (0) +#define fcse_mm_in_cache(mm) \ + (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) +#endif /* ! CONFIG_ARM_FCSE */ + +#ifdef CONFIG_ARM_FCSE_MESSAGES +void fcse_notify_segv(struct mm_struct *mm, + unsigned long addr, struct pt_regs *regs); +#else /* !FCSE_MESSAGES */ +#define fcse_notify_segv(mm, addr, regs) do { } while(0) +#endif /* !FCSE_MESSAGES */ + +#endif /* __ASM_ARM_FCSE_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/ipipe_base.h relase/linux-2.6.35.9//arch/arm/include/asm/ipipe_base.h --- orig/linux-2.6.35.9//arch/arm/include/asm/ipipe_base.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/ipipe_base.h 2011-03-15 10:56:25.873702441 +0100 @@ -0,0 +1,136 @@ +/* -*- linux-c -*- + * arch/arm/include/asm/ipipe_base.h + * + * Copyright (C) 2007 Gilles Chanteperdrix. + * Copyright (C) 2010 Philippe Gerum (SMP port). + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ARM_IPIPE_BASE_H +#define __ARM_IPIPE_BASE_H + +#include +#include +#include +#include +#include /* For __IPIPE_FEATURE_PIC_MUTE */ + +#define IPIPE_NR_XIRQS NR_IRQS + +/* ARM traps */ +#define IPIPE_TRAP_ACCESS 0 /* Data or instruction access exception */ +#define IPIPE_TRAP_SECTION 1 /* Section fault */ +#define IPIPE_TRAP_DABT 2 /* Generic data abort */ +#define IPIPE_TRAP_UNKNOWN 3 /* Unknown exception */ +#define IPIPE_TRAP_BREAK 4 /* Instruction breakpoint */ +#define IPIPE_TRAP_FPU 5 /* Floating point exception */ +#define IPIPE_TRAP_VFP 6 /* VFP floating point exception */ +#define IPIPE_TRAP_UNDEFINSTR 7 /* Undefined instruction */ +#define IPIPE_TRAP_ALIGNMENT 8 /* Unaligned access exception */ +#define IPIPE_NR_FAULTS 9 + +/* Pseudo-vectors used for kernel events */ +#define IPIPE_FIRST_EVENT IPIPE_NR_FAULTS +#define IPIPE_EVENT_SYSCALL (IPIPE_FIRST_EVENT) +#define IPIPE_EVENT_SCHEDULE (IPIPE_FIRST_EVENT + 1) +#define IPIPE_EVENT_SIGWAKE (IPIPE_FIRST_EVENT + 2) +#define IPIPE_EVENT_SETSCHED (IPIPE_FIRST_EVENT + 3) +#define IPIPE_EVENT_INIT (IPIPE_FIRST_EVENT + 4) +#define IPIPE_EVENT_EXIT (IPIPE_FIRST_EVENT + 5) +#define IPIPE_EVENT_CLEANUP (IPIPE_FIRST_EVENT + 6) +#define IPIPE_EVENT_RETURN (IPIPE_FIRST_EVENT + 7) +#define IPIPE_LAST_EVENT IPIPE_EVENT_RETURN +#define IPIPE_NR_EVENTS (IPIPE_LAST_EVENT + 1) + +#ifndef __ASSEMBLY__ + +#include + +#ifdef CONFIG_SMP + +#define IPIPE_FIRST_IPI IPIPE_VIRQ_BASE + +#define IPIPE_CRITICAL_IPI IPIPE_FIRST_IPI +#define IPIPE_SERVICE_IPI0 (IPIPE_CRITICAL_IPI + 1) +#define IPIPE_SERVICE_IPI1 (IPIPE_CRITICAL_IPI + 2) +#define IPIPE_SERVICE_IPI2 (IPIPE_CRITICAL_IPI + 3) +#define IPIPE_SERVICE_IPI3 (IPIPE_CRITICAL_IPI + 4) +#define IPIPE_SERVICE_VNMI (IPIPE_CRITICAL_IPI + 5) + +#define IPIPE_LAST_IPI IPIPE_SERVICE_VNMI + +#define ipipe_ipi_p(ipi) \ + ((ipi) >= IPIPE_SERVICE_IPI0 && (ipi) <= IPIPE_SERVICE_IPI3) + +void __ipipe_stall_root(void); + +unsigned long __ipipe_test_and_stall_root(void); + +unsigned long __ipipe_test_root(void); + +#else /* !CONFIG_SMP */ + +#if __GNUC__ >= 4 +/* Alias to ipipe_root_cpudom_var(status) */ +extern unsigned long __ipipe_root_status; +#else +extern unsigned long *const __ipipe_root_status_addr; +#define __ipipe_root_status (*__ipipe_root_status_addr) +#endif + +static inline void __ipipe_stall_root(void) +{ + unsigned long flags; + + local_irq_save_hw(flags); + __ipipe_root_status |= 1; + local_irq_restore_hw(flags); +} + +static inline unsigned __ipipe_test_root(void) +{ + return __ipipe_root_status & 1; +} + +static inline unsigned __ipipe_test_and_stall_root(void) +{ + unsigned long flags, res; + + local_irq_save_hw(flags); + res = __ipipe_root_status; + __ipipe_root_status = res | 1; + local_irq_restore_hw(flags); + + return res & 1; +} + +#endif /* CONFIG_SMP */ + +#define __IPIPE_FEATURE_PREEMPTIBLE_SWITCH 1 +#define __IPIPE_FEATURE_SYSINFO_V2 1 + +#ifdef CONFIG_VFP +#define __IPIPE_FEATURE_VFP_SAFE 1 +#endif + +#ifdef CONFIG_IPIPE_ARM_KUSER_TSC +#define __IPIPE_FEATURE_KUSER_TSC +#endif + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ARM_IPIPE_BASE_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/ipipe.h relase/linux-2.6.35.9//arch/arm/include/asm/ipipe.h --- orig/linux-2.6.35.9//arch/arm/include/asm/ipipe.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/ipipe.h 2011-03-15 10:56:25.873702441 +0100 @@ -0,0 +1,340 @@ +/* -*- linux-c -*- + * arch/arm/include/asm/ipipe.h + * + * Copyright (C) 2002-2005 Philippe Gerum. + * Copyright (C) 2005 Stelian Pop. + * Copyright (C) 2006-2008 Gilles Chanteperdrix. + * Copyright (C) 2010 Philippe Gerum (SMP port). + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ARM_IPIPE_H +#define __ARM_IPIPE_H + +#ifdef CONFIG_IPIPE + +#include +#include + +#define IPIPE_ARCH_STRING "1.18-01" +#define IPIPE_MAJOR_NUMBER 1 +#define IPIPE_MINOR_NUMBER 18 +#define IPIPE_PATCH_NUMBER 1 + +#ifdef CONFIG_SMP +#define ipipe_processor_id() hard_smp_processor_id() +#else /* !CONFIG_SMP */ +#define ipipe_processor_id() 0 +#endif /* CONFIG_SMP */ + +#define smp_processor_id_hw() ipipe_processor_id() + +#if defined(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH) || defined(CONFIG_SMP) + +#define prepare_arch_switch(next) \ + do { \ + local_irq_enable_hw(); \ + ipipe_schedule_notify(current, next); \ + } while(0) + +#define task_hijacked(p) \ + ({ \ + int __x__ = ipipe_root_domain_p; \ + !__x__; \ + }) + +#define ipipe_mm_switch_protect(flags) \ + do { \ + (void)(flags); \ + } while(0) + +#define ipipe_mm_switch_unprotect(flags) \ + do { \ + (void)(flags); \ + } while(0) + +#else /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && !SMP */ + +#define prepare_arch_switch(next) \ + do { \ + ipipe_schedule_notify(current ,next); \ + local_irq_disable_hw(); \ + } while(0) + +#define task_hijacked(p) \ + ({ \ + int __x__ = __ipipe_root_domain_p; \ + if (__x__) local_irq_enable_hw(); \ + !__x__; \ + }) + +#define ipipe_mm_switch_protect(flags) \ + local_irq_save_hw_cond(flags) + +#define ipipe_mm_switch_unprotect(flags) \ + local_irq_restore_hw_cond(flags) + +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && !SMP */ + +extern unsigned long arm_return_addr(int level); + +#define BROKEN_BUILTIN_RETURN_ADDRESS +#define __BUILTIN_RETURN_ADDRESS0 arm_return_addr(0) +#define __BUILTIN_RETURN_ADDRESS1 arm_return_addr(1) + +struct ipipe_domain; + +#define IPIPE_TSC_TYPE_NONE 0 +#define IPIPE_TSC_TYPE_FREERUNNING 1 +#define IPIPE_TSC_TYPE_DECREMENTER 2 +#define IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN 3 + +/* tscinfo, exported to user-space */ +struct __ipipe_tscinfo { + unsigned type; + unsigned freq; + unsigned long counter_vaddr; + union { + struct { + unsigned long counter_paddr; + unsigned mask; + }; + struct { + unsigned *counter; /* Hw counter physical address */ + unsigned mask; /* Significant bits in the hw counter. */ + unsigned long long *tsc; /* 64 bits tsc value. */ + } fr; + struct { + unsigned *counter; /* Hw counter physical address */ + unsigned mask; /* Significant bits in the hw counter. */ + unsigned *last_cnt; /* Counter value when updating + tsc value. */ + unsigned long long *tsc; /* 64 bits tsc value. */ + } dec; + } u; +}; + +struct ipipe_sysinfo { + int sys_nr_cpus; /* Number of CPUs on board */ + int sys_hrtimer_irq; /* hrtimer device IRQ */ + u64 sys_hrtimer_freq; /* hrtimer device frequency */ + u64 sys_hrclock_freq; /* hrclock device frequency */ + u64 sys_cpu_freq; /* CPU frequency (Hz) */ + struct __ipipe_tscinfo arch_tsc; /* exported data for u.s. tsc */ +}; + +DECLARE_PER_CPU(struct mm_struct *,ipipe_active_mm); +/* arch specific stuff */ +extern char __ipipe_tsc_area[]; +extern int __ipipe_mach_timerstolen; +extern unsigned int __ipipe_mach_ticks_per_jiffy; +extern void __ipipe_mach_acktimer(void); +extern void __ipipe_mach_set_dec(unsigned long); +extern void __ipipe_mach_release_timer(void); +extern unsigned long __ipipe_mach_get_dec(void); +void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info); +int __ipipe_check_tickdev(const char *devname); + +#ifdef CONFIG_IPIPE_ARM_KUSER_TSC +unsigned long long __ipipe_tsc_get(void) __attribute__((long_call)); +void __ipipe_tsc_register(struct __ipipe_tscinfo *info); +void __ipipe_tsc_update(void); +#else /* ! generic tsc */ +unsigned long long __ipipe_mach_get_tsc(void); +#define __ipipe_tsc_get() __ipipe_mach_get_tsc() +#endif /* ! generic tsc */ + +#ifndef __ipipe_cpu_freq +#define __ipipe_cpu_freq (HZ * __ipipe_mach_ticks_per_jiffy) +#endif +#ifndef __ipipe_mach_hrtimer_freq +#define __ipipe_mach_hrtimer_freq __ipipe_cpu_freq +#endif +#ifndef __ipipe_mach_hrclock_freq +#define __ipipe_mach_hrclock_freq __ipipe_mach_hrtimer_freq +#endif +#ifndef __ipipe_mach_hrtimer_irq +/* + * hrtimer IRQ advertised to domains. Defaults to the contents of the + * __ipipe_mach_timerint variable found in legacy platform supports. + * May be overridden on SMP platforms with distinct per-CPU timer + * interrupts. + */ +extern int __ipipe_mach_timerint; +#define __ipipe_mach_hrtimer_irq __ipipe_mach_timerint +#endif +#ifndef __ipipe_mach_ext_hrtimer +/* + * hrtimer external IRQ number for the given CPU. Same as the internal + * hrtimer IRQ number by default. + */ +#define __ipipe_mach_ext_hrtimer(cpu) \ + ({ \ + (void)(cpu); \ + __ipipe_mach_hrtimer_irq; \ + }) +#define __ipipe_mach_ext_hrtimer_p(irq) \ + ((irq) == __ipipe_mach_hrtimer_irq) +#endif +#ifndef __ipipe_mach_localtimer +/* + * Some SMP platforms may use different IRQ numbers depending on the + * CPU, remapping them to a single virq to advertise a common local + * timer interrupt to domains. The macro below provides the hrtimer + * IRQ number after remapping, if any. By default, there is no + * remapping. + */ +#define __ipipe_mach_localtimer(ext_irq) (ext_irq) +#endif +#ifndef __ipipe_mach_doirq +#define __ipipe_mach_doirq(irq) __ipipe_do_IRQ +#endif +#ifndef __ipipe_mach_ackirq +#define __ipipe_mach_ackirq(irq) \ + ({ \ + __ipipe_mach_ext_hrtimer_p(irq) \ + ? __ipipe_ack_timerirq \ + : __ipipe_ack_irq; \ + }) +#endif +#ifndef __ipipe_mach_hrtimer_debug +#define __ipipe_mach_hrtimer_debug(irq) do { } while (0) +#endif + +#define ipipe_read_tsc(t) do { t = __ipipe_tsc_get(); } while (0) +#define __ipipe_read_timebase() __ipipe_tsc_get() + +#define ipipe_tsc2ns(t) \ +({ \ + unsigned long long delta = (t)*1000; \ + do_div(delta, __ipipe_cpu_freq / 1000000 + 1); \ + (unsigned long)delta; \ +}) +#define ipipe_tsc2us(t) \ +({ \ + unsigned long long delta = (t); \ + do_div(delta, __ipipe_cpu_freq / 1000000 + 1); \ + (unsigned long)delta; \ +}) + +/* Private interface -- Internal use only */ + +#define __ipipe_check_platform() do { } while(0) + +#define __ipipe_enable_irq(irq) irq_desc[irq].chip->enable(irq) + +#define __ipipe_disable_irq(irq) irq_desc[irq].chip->disable(irq) + +#ifdef CONFIG_SMP +void __ipipe_init_platform(void); +void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd); +void __ipipe_root_ipi(unsigned int irq, struct pt_regs *regs); +void __ipipe_root_localtimer(unsigned int irq, struct pt_regs *regs); +void __ipipe_send_vnmi(void (*fn)(void *), cpumask_t cpumask, void *arg); +void __ipipe_do_vnmi(unsigned int irq, void *cookie); +#else /* !CONFIG_SMP */ +#define __ipipe_init_platform() do { } while(0) +#define __ipipe_hook_critical_ipi(ipd) do { } while(0) +#endif /* !CONFIG_SMP */ +#ifndef __ipipe_mach_init_platform +#define __ipipe_mach_init_platform() do { } while(0) +#endif + +void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq); + +#ifndef __IPIPE_FEATURE_PIC_MUTE +#define __ipipe_disable_irqdesc(ipd, irq) do { } while (0) +#else /* __IPIPE_FEATURE_PIC_MUTE */ + +typedef unsigned long +__ipipe_irqbits_t[(NR_IRQS + BITS_PER_LONG - 1) / BITS_PER_LONG]; +extern __ipipe_irqbits_t __ipipe_irqbits; + +void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq); + +void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq); + +void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq); + +void ipipe_mute_pic(void); + +void ipipe_unmute_pic(void); +#endif /* __IPIPE_FEATURE_PIC_MUTE */ + +void __ipipe_enable_pipeline(void); + +void __ipipe_do_critical_sync(unsigned irq, void *cookie); + +DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs); + +void __ipipe_grab_irq(int irq, struct pt_regs *regs); + +void __ipipe_exit_irq(struct pt_regs *regs); + +void __ipipe_handle_irq(int irq, struct pt_regs *regs); + +static inline void ipipe_handle_chained_irq(unsigned int irq) +{ + struct pt_regs regs; /* dummy */ + + ipipe_trace_irq_entry(irq); + __ipipe_handle_irq(irq, ®s); + ipipe_trace_irq_exit(irq); +} + +#define ipipe_update_tick_evtdev(evtdev) do { } while (0) + +static inline unsigned long __ipipe_ffnz(unsigned long ul) +{ + return ffs(ul) - 1; +} + +#define __ipipe_syscall_watched_p(p, sc) \ + (ipipe_notifier_enabled_p(p) || (unsigned long)sc >= __ARM_NR_BASE + 64) + +#define __ipipe_root_tick_p(regs) (!raw_irqs_disabled_flags(regs->ARM_cpsr)) + +#else /* !CONFIG_IPIPE */ + +#define task_hijacked(p) 0 + +#define ipipe_update_tick_evtdev(evtdev) do { } while (0) + +#define smp_processor_id_hw() smp_processor_id() + +#define ipipe_handle_chained_irq(irq) generic_handle_irq(irq) + +#define ipipe_mm_switch_protect(flags) \ + do { \ + (void) (flags); \ + } while (0) + +#define ipipe_mm_switch_unprotect(flags) \ + do { \ + (void) (flags); \ + } while (0) + +#endif /* CONFIG_IPIPE */ + +#if defined (CONFIG_IPIPE_DEBUG) && \ + (defined(CONFIG_DEBUG_LL) || defined(CONFIG_SERIAL_8250_CONSOLE)) +void __ipipe_serial_debug(const char *fmt, ...); +#else +#define __ipipe_serial_debug(fmt, args...) do { } while (0) +#endif + +#endif /* !__ARM_IPIPE_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/irqflags.h relase/linux-2.6.35.9//arch/arm/include/asm/irqflags.h --- orig/linux-2.6.35.9//arch/arm/include/asm/irqflags.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/irqflags.h 2011-03-15 10:56:25.873702441 +0100 @@ -10,30 +10,30 @@ */ #if __LINUX_ARM_ARCH__ >= 6 -#define raw_local_irq_save(x) \ +#define local_irq_save_hw_notrace(x) \ ({ \ __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ + "mrs %0, cpsr @ local_irq_save_hw\n" \ "cpsid i" \ : "=r" (x) : : "memory", "cc"); \ }) -#define raw_local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") -#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") -#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") -#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") +#define local_irq_enable_hw_notrace() __asm__("cpsie i @ __sti" : : : "memory", "cc") +#define local_irq_disable_hw_notrace() __asm__("cpsid i @ __cli" : : : "memory", "cc") +#define local_fiq_enable_hw_notrace() __asm__("cpsie f @ __stf" : : : "memory", "cc") +#define local_fiq_disable_hw_notrace() __asm__("cpsid f @ __clf" : : : "memory", "cc") #else /* * Save the current interrupt enable state & disable IRQs */ -#define raw_local_irq_save(x) \ +#define local_irq_save_hw_notrace(x) \ ({ \ unsigned long temp; \ (void) (&temp == &x); \ __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ + "mrs %0, cpsr @ local_irq_save_hw\n" \ " orr %1, %0, #128\n" \ " msr cpsr_c, %1" \ : "=r" (x), "=r" (temp) \ @@ -44,11 +44,11 @@ /* * Enable IRQs */ -#define raw_local_irq_enable() \ +#define local_irq_enable_hw_notrace() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_enable\n" \ + "mrs %0, cpsr @ local_irq_enable_hw\n" \ " bic %0, %0, #128\n" \ " msr cpsr_c, %0" \ : "=r" (temp) \ @@ -59,11 +59,11 @@ /* * Disable IRQs */ -#define raw_local_irq_disable() \ +#define local_irq_disable_hw_notrace() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_disable\n" \ + "mrs %0, cpsr @ local_irq_disable_hw\n" \ " orr %0, %0, #128\n" \ " msr cpsr_c, %0" \ : "=r" (temp) \ @@ -74,7 +74,7 @@ /* * Enable FIQs */ -#define local_fiq_enable() \ +#define local_fiq_enable_hw_notrace() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ @@ -89,7 +89,7 @@ /* * Disable FIQs */ -#define local_fiq_disable() \ +#define local_fiq_disable_hw_notrace() \ ({ \ unsigned long temp; \ __asm__ __volatile__( \ @@ -106,19 +106,19 @@ /* * Save the current interrupt enable state. */ -#define raw_local_save_flags(x) \ +#define local_save_flags_hw(x) \ ({ \ __asm__ __volatile__( \ - "mrs %0, cpsr @ local_save_flags" \ + "mrs %0, cpsr @ local_save_flags_hw" \ : "=r" (x) : : "memory", "cc"); \ }) /* * restore saved IRQ & FIQ state */ -#define raw_local_irq_restore(x) \ +#define local_irq_restore_hw_notrace(x) \ __asm__ __volatile__( \ - "msr cpsr_c, %0 @ local_irq_restore\n" \ + "msr cpsr_c, %0 @ local_irq_restore_hw\n" \ : \ : "r" (x) \ : "memory", "cc") @@ -128,5 +128,99 @@ (int)((flags) & PSR_I_BIT); \ }) +#define irqs_disabled_hw() \ +({ \ + unsigned long flags; \ + local_save_flags_hw(flags); \ + raw_irqs_disabled_flags(flags); \ +}) + +static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) +{ + /* Merge virtual and real interrupt mask bits into a single + 32bit word. */ + return (real & ~(1L << 8)) | ((virt != 0) << 8); +} + +static inline int raw_demangle_irq_bits(unsigned long *x) +{ + int virt = (*x & (1 << 8)) != 0; + *x &= ~(1L << 8); + return virt; +} + +#ifdef CONFIG_IPIPE + +void __ipipe_unstall_root(void); +void __ipipe_restore_root(unsigned long flags); + +/* PSR_I_BIT is bit no. 7 and is set if interrupts are _disabled_ */ +#define raw_local_irq_save(flags) ((flags) = __ipipe_test_and_stall_root() << 7) +#define raw_local_irq_enable() __ipipe_unstall_root() +#define raw_local_irq_disable() __ipipe_stall_root() +#define local_fiq_enable() __ipipe_unstall_root() +#define local_fiq_disable() __ipipe_stall_root() +#define raw_local_save_flags(flags) ((flags) = __ipipe_test_root() << 7) +#define raw_local_irq_restore(flags) __ipipe_restore_root(flags & (1 << 7)) + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + +#include + +#define local_irq_disable_hw() do { \ + if (!irqs_disabled_hw()) { \ + local_irq_disable_hw_notrace(); \ + ipipe_trace_begin(0x80000000); \ + } \ +} while (0) +#define local_irq_enable_hw() do { \ + if (irqs_disabled_hw()) { \ + ipipe_trace_end(0x80000000); \ + local_irq_enable_hw_notrace(); \ + } \ +} while (0) +#define local_irq_save_hw(x) do { \ + local_save_flags_hw(x); \ + if (!raw_irqs_disabled_flags(x)) { \ + local_irq_disable_hw_notrace(); \ + ipipe_trace_begin(0x80000001); \ + } \ +} while (0) +#define local_irq_restore_hw(x) do { \ + if (!raw_irqs_disabled_flags(x)) \ + ipipe_trace_end(0x80000001); \ + local_irq_restore_hw_notrace(x); \ +} while (0) + +#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */ + +#define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags) +#define local_irq_enable_hw() local_irq_enable_hw_notrace() +#define local_irq_disable_hw() local_irq_disable_hw_notrace() +#define local_fiq_enable_hw() local_fiq_enable_hw_notrace() +#define local_fiq_disable_hw() local_fiq_disable_hw_notrace() +#define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags) + +#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ + +#else /* !CONFIG_IPIPE */ + +#define raw_local_irq_save(flags) local_irq_save_hw_notrace(flags) +#define raw_local_irq_enable() local_irq_enable_hw_notrace() +#define raw_local_irq_disable() local_irq_disable_hw_notrace() +#define local_fiq_enable() local_fiq_enable_hw_notrace() +#define local_fiq_disable() local_fiq_disable_hw_notrace() +#define raw_local_save_flags(flags) local_save_flags_hw(flags) +#define raw_local_irq_restore(flags) local_irq_restore_hw_notrace(flags) + +#define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags) +#define local_irq_enable_hw() local_irq_enable_hw_notrace() +#define local_irq_disable_hw() local_irq_disable_hw_notrace() +#define local_fiq_enable_hw() local_fiq_enable_hw_notrace() +#define local_fiq_disable_hw() local_fiq_disable_hw_notrace() +#define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags) + +#endif /* CONFIG_IPIPE */ + #endif #endif diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/memory.h relase/linux-2.6.35.9//arch/arm/include/asm/memory.h --- orig/linux-2.6.35.9//arch/arm/include/asm/memory.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/memory.h 2011-03-15 10:56:25.873702441 +0100 @@ -33,7 +33,12 @@ */ #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000)) +#ifndef CONFIG_ARM_FCSE #define TASK_UNMAPPED_BASE (UL(CONFIG_PAGE_OFFSET) / 3) +#else /* CONFIG_ARM_FCSE */ +#define TASK_UNMAPPED_BASE UL(0x00800000) +#define FCSE_TASK_SIZE UL(0x02000000) +#endif /* CONFIG_ARM_FCSE */ /* * The maximum size of a 26-bit user space task. diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/mmu_context.h relase/linux-2.6.35.9//arch/arm/include/asm/mmu_context.h --- orig/linux-2.6.35.9//arch/arm/include/asm/mmu_context.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/mmu_context.h 2011-03-15 10:56:25.877702441 +0100 @@ -19,6 +19,7 @@ #include #include #include +#include void __check_kvm_seq(struct mm_struct *mm); @@ -79,11 +80,58 @@ #endif } -#define init_new_context(tsk,mm) 0 +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ +#ifdef CONFIG_ARM_FCSE + int fcse_pid; + +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + if (!mm->context.fcse.large) { + fcse_pid = fcse_pid_alloc(mm); + mm->context.fcse.pid = fcse_pid << FCSE_PID_SHIFT; + } else { + /* We are normally forking a process vith a virtual address + space larger than 32 MB, so its pid should be 0. */ + FCSE_BUG_ON(mm->context.fcse.pid); + fcse_pid_reference(0); + } + /* If we are forking, set_pte_at will restore the correct high pages + count, and shared writable pages are write-protected again. */ + mm->context.fcse.shared_dirty_pages = 0; + mm->context.fcse.high_pages = 0; + mm->context.fcse.active = 0; +#else /* CONFIG_ARM_FCSE_GUARANTEED */ + fcse_pid = fcse_pid_alloc(mm); + if (fcse_pid < 0) { + /* + * Set mm pid to FCSE_PID_INVALID, as even when + * init_new_context fails, destroy_context is called. + */ + mm->context.fcse.pid = FCSE_PID_INVALID; + return fcse_pid; + } + mm->context.fcse.pid = fcse_pid << FCSE_PID_SHIFT; +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ + FCSE_BUG_ON(fcse_mm_in_cache(mm)); +#endif /* CONFIG_ARM_FCSE */ + + return 0; +} #endif -#define destroy_context(mm) do { } while(0) +static inline void destroy_context(struct mm_struct *mm) +{ +#ifdef CONFIG_ARM_FCSE +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + FCSE_BUG_ON(mm->context.fcse.shared_dirty_pages); + FCSE_BUG_ON(mm->context.fcse.high_pages); +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ + if (mm->context.fcse.pid != FCSE_PID_INVALID) + fcse_pid_free(mm); +#endif /* CONFIG_ARM_FCSE */ +} /* * This is called when "tsk" is about to enter lazy TLB mode. @@ -106,11 +154,11 @@ * actually changed. */ static inline void -switch_mm(struct mm_struct *prev, struct mm_struct *next, +__switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { #ifdef CONFIG_MMU - unsigned int cpu = smp_processor_id(); + unsigned int cpu = ipipe_processor_id(); #ifdef CONFIG_SMP /* check for possible thread migration */ @@ -121,17 +169,76 @@ if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { #ifdef CONFIG_SMP struct mm_struct **crt_mm = &per_cpu(current_mm, cpu); - *crt_mm = next; #endif - check_context(next); - cpu_switch_mm(next->pgd, next); - if (cache_is_vivt()) +#if defined(CONFIG_IPIPE) + if (ipipe_root_domain_p) { + /* mark mm state as undefined. */ + per_cpu(ipipe_active_mm, cpu) = NULL; + barrier(); +#ifdef CONFIG_SMP + *crt_mm = next; +#endif + check_context(next); + cpu_switch_mm(next->pgd, next, + fcse_switch_mm(prev, next)); + barrier(); + per_cpu(ipipe_active_mm, cpu) = next; + while (test_and_clear_thread_flag(TIF_MMSWITCH_INT)) { + /* mark mm state as undefined. */ + per_cpu(ipipe_active_mm, cpu) = NULL; + barrier(); +#ifdef CONFIG_SMP + *crt_mm = next; +#endif + check_context(next); + cpu_switch_mm(next->pgd, next, + fcse_switch_mm(NULL, next)); + barrier(); + per_cpu(ipipe_active_mm, cpu) = next; + } + } else +#endif /* CONFIG_IPIPE */ + { + check_context(next); + cpu_switch_mm(next->pgd, next, + fcse_switch_mm(prev, next)); + } +#if defined(CONFIG_IPIPE) && defined(CONFIG_ARM_FCSE) + if (tsk) + set_tsk_thread_flag(tsk, TIF_SWITCHED); +#endif /* CONFIG_IPIPE && CONFIG_ARM_FCSE */ + if (cache_is_vivt() && prev) cpumask_clear_cpu(cpu, mm_cpumask(prev)); - } + } else + fcse_mark_dirty(next); #endif } +static inline void +switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ +#if !defined(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH) && !defined(CONFIG_SMP) + unsigned long flags; + local_irq_save_hw(flags); +#endif /* !(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && SMP) */ + __switch_mm(prev, next, tsk); +#if !defined(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH) && !defined(CONFIG_SMP) + local_irq_restore_hw(flags); +#endif /* !(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && SMP) */ +} + #define deactivate_mm(tsk,mm) do { } while (0) + +#ifndef CONFIG_ARM_FCSE_BEST_EFFORT #define activate_mm(prev,next) switch_mm(prev, next, NULL) +#else +#define activate_mm(prev,next) \ + ({ \ + switch_mm(prev, next, NULL); \ + next->context.fcse.active = 1; \ + FCSE_BUG_ON(current->mm == next && !fcse_mm_in_cache(next)); \ + }) +#endif #endif diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/mmu.h relase/linux-2.6.35.9//arch/arm/include/asm/mmu.h --- orig/linux-2.6.35.9//arch/arm/include/asm/mmu.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/mmu.h 2011-03-15 10:56:25.873702441 +0100 @@ -6,8 +6,19 @@ typedef struct { #ifdef CONFIG_CPU_HAS_ASID unsigned int id; - spinlock_t id_lock; + ipipe_spinlock_t id_lock; #endif +#ifdef CONFIG_ARM_FCSE + struct { + unsigned long pid; +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + unsigned shared_dirty_pages; + unsigned active : 1; + unsigned large : 1; + unsigned high_pages; +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ + } fcse; +#endif /* CONFIG_ARM_FCSE */ unsigned int kvm_seq; } mm_context_t; diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/percpu.h relase/linux-2.6.35.9//arch/arm/include/asm/percpu.h --- orig/linux-2.6.35.9//arch/arm/include/asm/percpu.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/percpu.h 2011-03-15 10:56:25.877702441 +0100 @@ -1,6 +1,10 @@ #ifndef __ARM_PERCPU #define __ARM_PERCPU +#if defined(CONFIG_IPIPE) && defined(CONFIG_SMP) +#define __my_cpu_offset per_cpu_offset(hard_smp_processor_id()) +#endif + #include #endif diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/pgtable.h relase/linux-2.6.35.9//arch/arm/include/asm/pgtable.h --- orig/linux-2.6.35.9//arch/arm/include/asm/pgtable.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/pgtable.h 2011-03-15 10:56:25.877702441 +0100 @@ -112,6 +112,8 @@ #define LIBRARY_TEXT_START 0x0c000000 #ifndef __ASSEMBLY__ +#include + extern void __pte_error(const char *file, int line, unsigned long val); extern void __pmd_error(const char *file, int line, unsigned long val); extern void __pgd_error(const char *file, int line, unsigned long val); @@ -248,6 +250,40 @@ #define __S111 __PAGE_SHARED_EXEC #ifndef __ASSEMBLY__ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +#define fcse_account_page_removal(mm, addr, val) do { \ + struct mm_struct *_mm = (mm); \ + unsigned long _addr = (addr); \ + unsigned long _val = (val); \ + if (pte_present(_val) && ((_val) & L_PTE_SHARED)) \ + --_mm->context.fcse.shared_dirty_pages; \ + if (pte_present(_val) && _addr < TASK_SIZE) { \ + if (_addr >= FCSE_TASK_SIZE) \ + --_mm->context.fcse.high_pages; \ + } \ +} while (0) + +#define fcse_account_page_addition(mm, addr, val) ({ \ + struct mm_struct *_mm = (mm); \ + unsigned long _addr = (addr); \ + unsigned long _val = (val); \ + if (pte_present(_val) && (_val & L_PTE_SHARED)) { \ + if ((_val & (PTE_CACHEABLE | L_PTE_WRITE | L_PTE_DIRTY)) \ + != (PTE_CACHEABLE | L_PTE_WRITE | L_PTE_DIRTY)) \ + _val &= ~L_PTE_SHARED; \ + else \ + ++_mm->context.fcse.shared_dirty_pages; \ + } \ + if (pte_present(_val) \ + && _addr < TASK_SIZE && _addr >= FCSE_TASK_SIZE) \ + ++_mm->context.fcse.high_pages; \ + _val; \ +}) +#else /* CONFIG_ARM_FCSE_GUARANTEED || !CONFIG_ARM_FCSE */ +#define fcse_account_page_removal(mm, addr, val) do { } while (0) +#define fcse_account_page_addition(mm, addr, val) (val) +#endif /* CONFIG_ARM_FCSE_GUARANTEED || !CONFIG_ARM_FCSE */ + /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. @@ -259,7 +295,10 @@ #define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) #define pte_none(pte) (!pte_val(pte)) -#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) +#define pte_clear(mm,addr,ptep) do { \ + fcse_account_page_removal(mm, addr, pte_val(*ptep)); \ + set_pte_ext(ptep, __pte(0), 0); \ +} while (0) #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) @@ -278,8 +317,11 @@ #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) -#define set_pte_at(mm,addr,ptep,pteval) do { \ - set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \ +#define set_pte_at(mm,addr,ptep,pteval) do { \ + pte_t _pteval = pte_val(pteval); \ + fcse_account_page_removal(mm, addr, pte_val(*ptep)); \ + _pteval = fcse_account_page_addition(mm, addr, _pteval); \ + set_pte_ext(ptep, _pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \ } while (0) /* @@ -372,10 +414,14 @@ /* to find an entry in a page-table-directory */ #define pgd_index(addr) ((addr) >> PGDIR_SHIFT) -#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr)) +#define pgd_offset(mm, addr) \ + ({ \ + struct mm_struct *_mm = (mm); \ + (_mm->pgd + pgd_index(fcse_va_to_mva(_mm, (addr)))); \ + }) /* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) +#define pgd_offset_k(addr) (init_mm.pgd + pgd_index(addr)) /* Find an entry in the second-level page table.. */ #define pmd_offset(dir, addr) ((pmd_t *)(dir)) diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/processor.h relase/linux-2.6.35.9//arch/arm/include/asm/processor.h --- orig/linux-2.6.35.9//arch/arm/include/asm/processor.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/processor.h 2011-03-15 10:56:25.877702441 +0100 @@ -23,9 +23,14 @@ #include #ifdef __KERNEL__ +#ifndef CONFIG_ARM_FCSE #define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ TASK_SIZE : TASK_SIZE_26) #define STACK_TOP_MAX TASK_SIZE +#else /* CONFIG_ARM_FCSE */ +#define STACK_TOP FCSE_TASK_SIZE +#define STACK_TOP_MAX FCSE_TASK_SIZE +#endif /* CONFIG_ARM_FCSE */ #endif union debug_insn { diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/proc-fns.h relase/linux-2.6.35.9//arch/arm/include/asm/proc-fns.h --- orig/linux-2.6.35.9//arch/arm/include/asm/proc-fns.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/proc-fns.h 2011-03-15 10:56:25.877702441 +0100 @@ -261,12 +261,21 @@ #ifdef CONFIG_MMU -#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) +#ifndef CONFIG_ARM_FCSE_BEST_EFFORT +#define cpu_switch_mm(pgd,mm,fcse_switch) \ + ({ \ + fcse_switch; \ + cpu_do_switch_mm(virt_to_phys(pgd), (mm)); \ + }) +#else /* CONFIG_ARM_FCSE_BEST_EFFORT */ +#define cpu_switch_mm(pgd,mm,fcse_switch) \ + cpu_do_switch_mm(virt_to_phys(pgd), (mm), (fcse_switch)) +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ #define cpu_get_pgd() \ ({ \ unsigned long pg; \ - __asm__("mrc p15, 0, %0, c2, c0, 0" \ + __asm__ __volatile__ ("mrc p15, 0, %0, c2, c0, 0" \ : "=r" (pg) : : "cc"); \ pg &= ~0x3fff; \ (pgd_t *)phys_to_virt(pg); \ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/resource.h relase/linux-2.6.35.9//arch/arm/include/asm/resource.h --- orig/linux-2.6.35.9//arch/arm/include/asm/resource.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/resource.h 2011-03-15 10:56:25.877702441 +0100 @@ -1,6 +1,16 @@ #ifndef _ARM_RESOURCE_H #define _ARM_RESOURCE_H +/* + * When FCSE is enabled, reduce the default stack size to 1MB, and maximum + * to 16MB, the address space is only 32MB. + */ +#ifdef CONFIG_ARM_FCSE +#define _STK_LIM (1024*1024) + +#define _STK_LIM_MAX (16*1024*1024) +#endif /* CONFIG_ARM_FCSE */ + #include #endif diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/system.h relase/linux-2.6.35.9//arch/arm/include/asm/system.h --- orig/linux-2.6.35.9//arch/arm/include/asm/system.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/system.h 2011-03-15 10:56:25.877702441 +0100 @@ -221,10 +221,19 @@ */ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); +#if defined(CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH) || defined(CONFIG_SMP) #define switch_to(prev,next,last) \ do { \ + local_irq_disable_hw_cond(); \ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ + local_irq_enable_hw_cond(); \ } while (0) +#else /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && !SMP */ +#define switch_to(prev,next,last) \ +do { \ + last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ +} while (0) +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH && !SMP */ #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) /* @@ -285,17 +294,17 @@ #error SMP is not supported on this platform #endif case 1: - raw_local_irq_save(flags); + local_irq_save_hw(flags); ret = *(volatile unsigned char *)ptr; *(volatile unsigned char *)ptr = x; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); break; case 4: - raw_local_irq_save(flags); + local_irq_save_hw(flags); ret = *(volatile unsigned long *)ptr; *(volatile unsigned long *)ptr = x; - raw_local_irq_restore(flags); + local_irq_restore_hw(flags); break; #else case 1: diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/thread_info.h relase/linux-2.6.35.9//arch/arm/include/asm/thread_info.h --- orig/linux-2.6.35.9//arch/arm/include/asm/thread_info.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/thread_info.h 2011-03-15 10:56:25.877702441 +0100 @@ -144,6 +144,12 @@ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_FREEZE 19 #define TIF_RESTORE_SIGMASK 20 +#ifdef CONFIG_IPIPE +#define TIF_MMSWITCH_INT 21 +#ifdef CONFIG_ARM_FCSE +#define TIF_SWITCHED 22 +#endif /* CONFIG_ARM_FCSE */ +#endif /* CONFIG_IPIPE */ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -153,6 +159,12 @@ #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) +#ifdef CONFIG_IPIPE +#define _TIF_MMSWITCH_INT (1 << TIF_MMSWITCH_INT) +#ifdef CONFIG_ARM_FCSE +#define _TIF_SWITCHED (1 << TIF_SWITCHED) +#endif /* CONFIG_ARM_FCSE */ +#endif /* CONFIG_IPIPE */ /* * Change these and you break ASM code in entry-common.S diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/tlbflush.h relase/linux-2.6.35.9//arch/arm/include/asm/tlbflush.h --- orig/linux-2.6.35.9//arch/arm/include/asm/tlbflush.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/tlbflush.h 2011-03-15 10:56:25.877702441 +0100 @@ -213,6 +213,7 @@ #ifndef __ASSEMBLY__ #include +#include struct cpu_tlb_fns { void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); @@ -403,7 +404,8 @@ const int zero = 0; const unsigned int __tlb_flag = __cpu_tlb_flags; - uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); + uaddr = (fcse_va_to_mva(vma->vm_mm, uaddr) & PAGE_MASK) + | ASID(vma->vm_mm); if (tlb_flag(TLB_WB)) dsb(); @@ -540,7 +542,15 @@ /* * Convert calls to our calling convention. */ -#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) +#define local_flush_tlb_range(vma, start, end) \ + ({ \ + struct mm_struct *_mm = (vma)->vm_mm; \ + unsigned long _start, _end; \ + _start = fcse_va_to_mva(_mm, start); \ + _end = fcse_va_to_mva(_mm, end); \ + __cpu_flush_user_tlb_range(_start, _end, vma); \ + }) + #define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) #ifndef CONFIG_SMP diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/arith.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/arith.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/arith.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/arith.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,125 @@ +#ifndef _XENO_ASM_ARM_ARITH_H +#define _XENO_ASM_ARM_ARITH_H + +#include + +#if __LINUX_ARM_ARCH__ >= 4 +static inline __attribute__((__const__)) unsigned long long +rthal_arm_nodiv_ullimd(const unsigned long long op, + const unsigned long long frac, + const unsigned rhs_integ); + +#define rthal_nodiv_ullimd(op, frac, integ) \ + rthal_arm_nodiv_ullimd((op), (frac), (integ)) + +static inline __attribute__((__const__)) long long +rthal_arm_nodiv_llimd(const long long op, + const unsigned long long frac, + const unsigned rhs_integ); + +#define rthal_nodiv_llimd(op, frac, integ) \ + rthal_arm_nodiv_llimd((op), (frac), (integ)) +#else /* arm <= v3 */ +#define __rthal_add96and64(l0, l1, l2, s0, s1) \ + do { \ + __asm__ ("adds %2, %2, %4\n\t" \ + "adcs %1, %1, %3\n\t" \ + "adc %0, %0, #0\n\t" \ + : "+r"(l0), "+r"(l1), "+r"(l2) \ + : "r"(s0), "r"(s1): "cc"); \ + } while (0) +#endif /* arm <= v3 */ + +#include + +#if __LINUX_ARM_ARCH__ >= 4 +#define rthal_arm_nodiv_ullimd_str \ + "umull %[tl], %[rl], %[opl], %[fracl]\n\t" \ + "umull %[rm], %[rh], %[oph], %[frach]\n\t" \ + "adds %[rl], %[rl], %[tl], lsr #31\n\t" \ + "adcs %[rm], %[rm], #0\n\t" \ + "adc %[rh], %[rh], #0\n\t" \ + "umull %[tl], %[th], %[oph], %[fracl]\n\t" \ + "adds %[rl], %[rl], %[tl]\n\t" \ + "adcs %[rm], %[rm], %[th]\n\t" \ + "adc %[rh], %[rh], #0\n\t" \ + "umull %[tl], %[th], %[opl], %[frach]\n\t" \ + "adds %[rl], %[rl], %[tl]\n\t" \ + "adcs %[rm], %[rm], %[th]\n\t" \ + "adc %[rh], %[rh], #0\n\t" \ + "umlal %[rm], %[rh], %[opl], %[integ]\n\t" \ + "mla %[rh], %[oph], %[integ], %[rh]\n\t" + +static inline __attribute__((__const__)) unsigned long long +rthal_arm_nodiv_ullimd(const unsigned long long op, + const unsigned long long frac, + const unsigned rhs_integ) +{ + register unsigned rl __asm__("r5"); + register unsigned rm __asm__("r0"); + register unsigned rh __asm__("r1"); + register unsigned fracl __asm__ ("r2"); + register unsigned frach __asm__ ("r3"); + register unsigned integ __asm__("r4") = rhs_integ; + register unsigned opl __asm__ ("r6"); + register unsigned oph __asm__ ("r7"); + register unsigned tl __asm__("r8"); + register unsigned th __asm__("r9"); + + __rthal_u64tou32(op, oph, opl); + __rthal_u64tou32(frac, frach, fracl); + + __asm__ (rthal_arm_nodiv_ullimd_str + : [rl]"=r"(rl), [rm]"=r"(rm), [rh]"=r"(rh), + [tl]"=r"(tl), [th]"=r"(th) + : [opl]"r"(opl), [oph]"r"(oph), + [fracl]"r"(fracl), [frach]"r"(frach), + [integ]"r"(integ) + : "cc"); + + return __rthal_u64fromu32(rh, rm); +} + +static inline __attribute__((__const__)) long long +rthal_arm_nodiv_llimd(const long long op, + const unsigned long long frac, + const unsigned rhs_integ) +{ + register unsigned rl __asm__("r5"); + register unsigned rm __asm__("r0"); + register unsigned rh __asm__("r1"); + register unsigned fracl __asm__ ("r2"); + register unsigned frach __asm__ ("r3"); + register unsigned integ __asm__("r4") = rhs_integ; + register unsigned opl __asm__ ("r6"); + register unsigned oph __asm__ ("r7"); + register unsigned tl __asm__("r8"); + register unsigned th __asm__("r9"); + register unsigned s __asm__("r10"); + + __rthal_u64tou32(op, oph, opl); + __rthal_u64tou32(frac, frach, fracl); + + __asm__ ("movs %[s], %[oph], lsr #30\n\t" + "beq 1f\n\t" + "rsbs %[opl], %[opl], #0\n\t" + "sbc %[oph], %[oph], %[oph], lsl #1\n" + "1:\t" + rthal_arm_nodiv_ullimd_str + "teq %[s], #0\n\t" + "beq 2f\n\t" + "rsbs %[rm], %[rm], #0\n\t" + "sbc %[rh], %[rh], %[rh], lsl #1\n" + "2:\t" + : [rl]"=r"(rl), [rm]"=r"(rm), [rh]"=r"(rh), + [tl]"=r"(tl), [th]"=r"(th), [s]"=r"(s) + : [opl]"r"(opl), [oph]"r"(oph), + [fracl]"r"(fracl), [frach]"r"(frach), + [integ]"r"(integ) + : "cc"); + + return __rthal_u64fromu32(rh, rm); +} +#endif /* arm >= v4 */ + +#endif /* _XENO_ASM_ARM_ARITH_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/atomic.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/atomic.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/atomic.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/atomic.h 2011-03-06 19:30:24.000000000 +0100 @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_ATOMIC_H +#define _XENO_ASM_ARM_ATOMIC_H + +#include + +typedef struct { unsigned long counter; } xnarch_atomic_t; +typedef xnarch_atomic_t atomic_counter_t; + +#define xnarch_atomic_get(v) (*(volatile unsigned long *)(&(v)->counter)) +static __inline__ void +xnarch_atomic_set(xnarch_atomic_t *ptr, unsigned long val) +{ + ptr->counter = val; +} + +extern void __xnarch_xchg_called_with_bad_pointer(void); + +#define xnarch_read_memory_barrier() xnarch_memory_barrier() +#define xnarch_write_memory_barrier() xnarch_memory_barrier() + +#if __LINUX_ARM_ARCH__ >= 6 +#ifndef CONFIG_SMP +#define xnarch_memory_barrier() \ + __asm__ __volatile__ ("": /* */ : /* */ :"memory") +#else /* SMP */ +#if __LINUX_ARM_ARCH__ >= 7 +#define xnarch_memory_barrier() \ + __asm__ __volatile__ ("dmb" : /* */ : /* */ : "memory") +#else /* __LINUX_ARM_ARCH == 6 */ +#define xnarch_memory_barrier() \ + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : /* */ : "r" (0) : "memory") +#endif /* __LINUX_ARM_ARCH == 6 */ +#endif /* CONFIG_SMP */ + +#ifndef __KERNEL__ +#define cpu_relax() xnarch_memory_barrier() +#endif /* __KERNEL__ */ + +static inline unsigned long +__xnarch_xchg(volatile void *ptr, unsigned long x, int size) +{ + unsigned long ret; + unsigned long tmp; + + xnarch_memory_barrier(); + + switch (size) { + case 1: + asm volatile("@ __xchg1\n" + "1: ldrexb %0, [%4]\n" + " strexb %1, %3, [%4]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp), + "+Qo" (*(char *)ptr) + : "r" (x), "r" (ptr) + : "cc"); + break; + case 4: + asm volatile("@ __xchg4\n" + "1: ldrex %0, [%4]\n" + " strex %1, %3, [%4]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp), + "+Qo" (*(unsigned *)ptr) + : "r" (x), "r" (ptr) + : "cc"); + break; + default: + __xnarch_xchg_called_with_bad_pointer(), ret = 0; + break; + } + xnarch_memory_barrier(); + + return ret; +} + +#define xnarch_atomic_xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) \ + __xnarch_xchg((ptr),(unsigned long)_x_, sizeof(*(ptr))); \ + }) + +static inline void xnarch_atomic_inc(xnarch_atomic_t *v) +{ + unsigned long tmp; + unsigned long result; + + __asm__ __volatile__("@ atomic_add\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (1) + : "cc"); +} + +static inline void xnarch_atomic_dec(xnarch_atomic_t *v) +{ + unsigned long tmp; + unsigned long result; + + __asm__ __volatile__("@ atomic_sub\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (1) + : "cc"); +} + +static inline void +xnarch_atomic_set_mask(unsigned long *addr, unsigned long mask) +{ + unsigned long tmp, tmp2; + + __asm__ __volatile__("@ atomic_set_mask\n" +"1: ldrex %0, [%3]\n\t" +" orr %0, %0, %4\n\t" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr) + : "r" (addr), "Ir" (mask) + : "cc"); +} + +static inline void +xnarch_atomic_clear_mask(unsigned long *addr, unsigned long mask) +{ + unsigned long tmp, tmp2; + + __asm__ __volatile__("@ atomic_clear_mask\n" +"1: ldrex %0, [%3]\n" +" bic %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr) + : "r" (addr), "Ir" (mask) + : "cc"); +} + +static inline unsigned long +xnarch_atomic_cmpxchg(xnarch_atomic_t *ptr, + unsigned long oldval, unsigned long newval) +{ + unsigned long curval, res; + + xnarch_memory_barrier(); + + do { + __asm__ __volatile__("@ atomic_cmpxchg\n" + "ldrex %1, [%3]\n" + "mov %0, #0\n" + "teq %1, %4\n" + "strexeq %0, %5, [%3]\n" + : "=&r" (res), "=&r" (curval), "+Qo" (ptr->counter) + : "r" (&ptr->counter), "Ir" (oldval), "r" (newval) + : "cc"); + } while (res); + + xnarch_memory_barrier(); + + return curval; +} + +static inline int xnarch_atomic_inc_and_test(xnarch_atomic_t *v) +{ + unsigned long tmp; + unsigned long result; + + xnarch_memory_barrier(); + + __asm__ __volatile__("@ atomic_add_return\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (1) + : "cc"); + + xnarch_memory_barrier(); + + return result == 0; +} + +static inline int xnarch_atomic_dec_and_test(xnarch_atomic_t *v) +{ + unsigned long tmp; + unsigned long result; + + xnarch_memory_barrier(); + + __asm__ __volatile__("@ atomic_sub_return\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (1) + : "cc"); + + xnarch_memory_barrier(); + + return result == 0; +} +#else /* ARM arch <= 5 */ + +#ifdef __KERNEL__ + +#include +#include +#include + +static inline void +xnarch_atomic_set_mask(unsigned long *addr, unsigned long mask) +{ + unsigned long flags; + + local_irq_save_hw(flags); + *addr |= mask; + local_irq_restore_hw(flags); +} + +#define xnarch_memory_barrier() smp_mb() +#define xnarch_atomic_xchg(ptr,x) xchg(ptr,x) +#define xnarch_atomic_inc(pcounter) \ + atomic_inc((atomic_t *)pcounter) +#define xnarch_atomic_dec(pcounter) \ + atomic_dec((atomic_t *)pcounter) +#define xnarch_atomic_clear_mask(addr, mask) \ + atomic_clear_mask((mask), (addr)) +#define xnarch_atomic_cmpxchg(pcounter, oldval, newval) \ + atomic_cmpxchg((atomic_t *)(pcounter), (oldval), (newval)) +#define xnarch_atomic_inc_and_test(pcounter) \ + atomic_inc_and_test((atomic_t *)pcounter) +#define xnarch_atomic_dec_and_test(pcounter) \ + atomic_dec_and_test((atomic_t *)pcounter) + +#else /* !__KERNEL__ */ + +#include +#include + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid xchg(). + */ +static __inline__ unsigned long +__xchg(volatile void *ptr, unsigned long x, unsigned int size) +{ + unsigned long ret; + + if (size != 4) { + __xnarch_xchg_called_with_bad_pointer(); + return 0; + } + +#if defined(CONFIG_XENO_ARM_SA1100) + XENOMAI_SYSCALL5(__xn_sys_arch, + XENOMAI_SYSARCH_XCHG, ptr, x, size, &ret); +#else + asm volatile("@ __xchg4\n" +" swp %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); +#endif + return ret; +} + +#define xnarch_atomic_xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ + }) + + +#ifdef CONFIG_SMP +static __inline__ unsigned long +xnarch_atomic_add_return(int i, xnarch_atomic_t *v) +{ + unsigned long ret; + + XENOMAI_SYSCALL4(__xn_sys_arch, + XENOMAI_SYSARCH_ATOMIC_ADD_RETURN, i, v, &ret); + return ret; +} + +static __inline__ unsigned long +xnarch_atomic_sub_return(int i, xnarch_atomic_t *v) +{ + unsigned long ret; + + XENOMAI_SYSCALL4(__xn_sys_arch, + XENOMAI_SYSARCH_ATOMIC_ADD_RETURN, -i, v, &ret); + return ret; +} + +static inline void +xnarch_atomic_set_mask(unsigned long *addr, unsigned long mask) +{ + XENOMAI_SYSCALL3(__xn_sys_arch, + XENOMAI_SYSARCH_ATOMIC_SET_MASK, mask, addr); +} + +static inline void +xnarch_atomic_clear_mask(unsigned long *addr, unsigned long mask) +{ + XENOMAI_SYSCALL3(__xn_sys_arch, + XENOMAI_SYSARCH_ATOMIC_CLEAR_MASK, mask, addr); +} +#else /* ARM_ARCH <= 5 && !CONFIG_SMP */ + +static __inline__ unsigned long +xnarch_atomic_cmpxchg(xnarch_atomic_t *ptr, + unsigned long oldval, unsigned long newval) +{ + register unsigned long asm_old asm("r0") = oldval; + register unsigned long asm_new asm("r1") = newval; + register unsigned long *asm_ptr asm("r2") = + (unsigned long *)&ptr->counter; + register unsigned long asm_lr asm("lr"); + register unsigned long asm_tmp asm("r3"); + + do { + asm volatile ( + "mov %1, #0xffff0fff\n\t" + "mov lr, pc\n\t" + "add pc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" + : "+r"(asm_old), "=&r"(asm_tmp), "=r"(asm_lr) + : "r"(asm_new), "r"(asm_ptr) + : "ip", "cc", "memory"); + if (likely(!asm_old)) + return oldval; + } while ((asm_old = *asm_ptr) == oldval); + return asm_old; +} + +static __inline__ unsigned long +xnarch_atomic_add_return(int i, xnarch_atomic_t *v) +{ + register unsigned long asm_old asm("r0"); + register unsigned long asm_new asm("r1"); + register unsigned long *asm_ptr asm("r2") = + (unsigned long *)&v->counter; + register unsigned long asm_lr asm("lr"); + register unsigned long asm_tmp asm("r3"); + + asm volatile ( \ + "1: @ xnarch_atomic_add\n\t" + "ldr %0, [%4]\n\t" + "mov %1, #0xffff0fff\n\t" + "add lr, pc, #4\n\t" + "add %3, %0, %5\n\t" + "add pc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" + "bcc 1b" + : "=&r" (asm_old), "=&r"(asm_tmp), "=r"(asm_lr), "=r"(asm_new) + : "r" (asm_ptr), "rIL"(i) + : "ip", "cc", "memory"); + return asm_new; +} + +static __inline__ unsigned long +xnarch_atomic_sub_return(int i, xnarch_atomic_t *v) +{ + register unsigned long asm_old asm("r0"); + register unsigned long asm_new asm("r1"); + register unsigned long *asm_ptr asm("r2") = + (unsigned long *)&v->counter; + register unsigned long asm_lr asm("lr"); + register unsigned long asm_tmp asm("r3"); + + asm volatile ( \ + "1: @ xnarch_atomic_sub\n\t" + "ldr %0, [%4]\n\t" + "mov %1, #0xffff0fff\n\t" + "add lr, pc, #4\n\t" + "sub %3, %0, %5\n\t" + "add pc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" + "bcc 1b" + : "=&r" (asm_old), "=&r"(asm_tmp), "=r"(asm_lr), "=r"(asm_new) + : "r" (asm_ptr), "rIL"(i) + : "ip", "cc", "memory"); + return asm_new; +} + +static __inline__ void +xnarch_atomic_set_mask(xnarch_atomic_t *v, long mask) +{ + register unsigned long asm_old asm("r0"); + register unsigned long asm_new asm("r1"); + register unsigned long *asm_ptr asm("r2") = + (unsigned long *)&v->counter; + register unsigned long asm_lr asm("lr"); + register unsigned long asm_tmp asm("r3"); + + asm volatile ( \ + "1: @ xnarch_atomic_set_mask\n\t" \ + "ldr %0, [%4]\n\t" \ + "mov %1, #0xffff0fff\n\t" \ + "add lr, pc, #4\n\t" \ + "orr %3, %0, %5\n\t"\ + "add pc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" \ + "bcc 1b" \ + : "=&r" (asm_old), "=&r"(asm_tmp), "=r"(asm_lr), "=r"(asm_new) \ + : "r" (asm_ptr), "rIL"(mask) \ + : "ip", "cc", "memory"); +} + +static __inline__ void +xnarch_atomic_clear_mask(xnarch_atomic_t *v, long mask) +{ + register unsigned long asm_old asm("r0"); + register unsigned long asm_new asm("r1"); + register unsigned long *asm_ptr asm("r2") = + (unsigned long *)&v->counter; + register unsigned long asm_lr asm("lr"); + register unsigned long asm_tmp asm("r3"); + + asm volatile ( \ + "1: @ xnarch_atomic_clear_mask\n\t" \ + "ldr %0, [%4]\n\t" \ + "mov %1, #0xffff0fff\n\t" \ + "add lr, pc, #4\n\t" \ + "bic %3, %0, %5\n\t" \ + "add pc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" \ + "bcc 1b" \ + : "=&r" (asm_old), "=&r"(asm_tmp), "=r"(asm_lr), "=r"(asm_new) \ + : "r" (asm_ptr), "rIL"(mask) \ + : "ip", "cc", "memory"); +} + + +#endif /* ARM_ARCH <= 5 && !CONFIG_SMP */ + +#if defined(CONFIG_SMP) && defined(CONFIG_XENO_CPU_XSC3) +#define xnarch_memory_barrier() \ + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : /* */ : "r" (0) : "memory") +#else /* !XSC3 || !SMP */ +#define xnarch_memory_barrier() \ + __asm__ __volatile__ ("": /* */ : /* */ :"memory") +#endif /* !XSC3 || !SMP */ + +#define cpu_relax() xnarch_memory_barrier() + +#define xnarch_atomic_inc(pcounter) (void) xnarch_atomic_add_return(1, pcounter) +#define xnarch_atomic_dec_and_test(pcounter) (xnarch_atomic_sub_return(1, pcounter) == 0) +#endif /* __KERNEL__ */ +#endif /* ARM arch <= 5 */ + +typedef unsigned long atomic_flags_t; + +#endif /* !_XENO_ASM_ARM_ATOMIC_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/bind.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/bind.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/bind.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/bind.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,111 @@ +#ifndef _XENO_ASM_ARM_BIND_H +#define _XENO_ASM_ARM_BIND_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +__attribute__((weak)) struct __xn_tscinfo __xn_tscinfo = { + type: -1 +}; + +static inline void xeno_arm_features_check(void) +{ +#ifdef XNARCH_ARM_TSC_TYPE + unsigned page_size; + int err, fd; + void *addr; + + if (__xn_tscinfo.type != -1) + return; + + err = XENOMAI_SYSCALL2(__xn_sys_arch, + XENOMAI_SYSARCH_TSCINFO, &__xn_tscinfo); + if (err) { + error: + fprintf(stderr, "Xenomai: Your board/configuration does not" + " allow tsc emulation in user-space: %d\n", err); + exit(EXIT_FAILURE); + } + + fd = open("/dev/mem", O_RDONLY | O_SYNC); + if (fd == -1) { + perror("Xenomai init: open(/dev/mem)"); + exit(EXIT_FAILURE); + } + + page_size = sysconf(_SC_PAGESIZE); + + switch(__xn_tscinfo.type) { +#if XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING \ + || XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING_COUNTDOWN \ + || XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING_FAST_WRAP + case __XN_TSC_TYPE_FREERUNNING: + case __XN_TSC_TYPE_FREERUNNING_COUNTDOWN: { + unsigned long phys_addr; + + phys_addr = (unsigned long) __xn_tscinfo.u.fr.counter; + addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, + fd, phys_addr & ~(page_size - 1)); + if (addr == MAP_FAILED) { + perror("Xenomai init: mmap(/dev/mem)"); + exit(EXIT_FAILURE); + } + + __xn_tscinfo.u.fr.counter = + ((volatile unsigned *) + ((char *) addr + (phys_addr & (page_size - 1)))); +#if XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING_FAST_WRAP + if (__xn_tscinfo.u.fr.mask >= ((1 << 28) - 1)) { + fprintf(stderr, "Hardware tsc is not a fast wrapping" + " one, select the correct platform, or fix\n" + "configure.in\n"); + exit(EXIT_FAILURE); + } +#endif /* __XN_TSC_TYPE_FREERUNNING_FAST_WRAP */ + break; + } +#elif XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_DECREMENTER + case __XN_TSC_TYPE_DECREMENTER: { + unsigned long phys_addr; + + phys_addr = (unsigned long) __xn_tscinfo.u.dec.counter; + addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, + fd, phys_addr & ~(page_size - 1)); + if (addr == MAP_FAILED) { + perror("Xenomai init: mmap(/dev/mem)"); + exit(EXIT_FAILURE); + } + + __xn_tscinfo.u.dec.counter = + ((volatile unsigned *) + ((char *) addr + (phys_addr & (page_size - 1)))); + break; + } +#endif /* XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_DECREMENTER */ + case __XN_TSC_TYPE_NONE: + goto error; + + default: + fprintf(stderr, + "Xenomai: kernel/user tsc emulation mismatch.\n"); + exit(EXIT_FAILURE); + } + + if (close(fd)) { + perror("Xenomai init: close(/dev/mem)"); + exit(EXIT_FAILURE); + } +#endif /* XNARCH_ARM_TSC_TYPE */ +} +#define xeno_arch_features_check() xeno_arm_features_check() + +#endif /* _XENO_ASM_ARM_BIND_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/heap.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/heap.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/heap.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/heap.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_HEAP_H +#define _XENO_ASM_ARM_BITS_HEAP_H + +#include + +#endif /* !_XENO_ASM_ARM_BITS_HEAP_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/init.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/init.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/init.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/init.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_INIT_H +#define _XENO_ASM_ARM_BITS_INIT_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include +#include +#include + +int xnarch_escalation_virq; + +int xnpod_trap_fault(xnarch_fltinfo_t *fltinfo); + +void xnpod_schedule_handler(void); + +static rthal_trap_handler_t xnarch_old_trap_handler; + +static int xnarch_trap_fault(unsigned event, unsigned domid, void *data) +{ + xnarch_fltinfo_t fltinfo; + fltinfo.exception = event; + fltinfo.regs = (struct pt_regs *)data; + return xnpod_trap_fault(&fltinfo); +} + +unsigned long xnarch_calibrate_timer(void) +{ + /* Compute the time needed to program the decrementer in aperiodic + mode. The return value is expressed in timebase ticks. */ + return rthal_timer_calibrate() ? : 1; +} + +int xnarch_calibrate_sched(void) +{ + nktimerlat = xnarch_calibrate_timer(); + + if (!nktimerlat) + return -ENODEV; + + nklatency = xnarch_ns_to_tsc(xnarch_get_sched_latency()) + nktimerlat; + + return 0; +} + +static inline int xnarch_init(void) +{ + int ret; + + ret = rthal_init(); + if (ret) + return ret; + +#if defined(CONFIG_SMP) && defined(MODULE) + /* + * Make sure the init sequence is kept on the same CPU when + * running as a module. + */ + set_cpus_allowed(current, cpumask_of_cpu(0)); +#endif /* CONFIG_SMP && MODULE */ + + xnarch_init_timeconv(RTHAL_CLOCK_FREQ); + + ret = xnarch_calibrate_sched(); + if (ret) + return ret; + + xnarch_escalation_virq = rthal_alloc_virq(); + if (xnarch_escalation_virq == 0) + return -ENOSYS; + + rthal_virtualize_irq(&rthal_domain, + xnarch_escalation_virq, + (rthal_irq_handler_t) &xnpod_schedule_handler, + NULL, NULL, IPIPE_HANDLE_MASK | IPIPE_WIRED_MASK); + + xnarch_old_trap_handler = rthal_trap_catch(&xnarch_trap_fault); + + return 0; +} + +static inline void xnarch_exit(void) +{ + rthal_trap_catch(xnarch_old_trap_handler); + rthal_free_virq(xnarch_escalation_virq); + rthal_exit(); +} + +#endif /* !_XENO_ASM_ARM_BITS_INIT_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/intr.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/intr.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/intr.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/intr.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_INTR_H +#define _XENO_ASM_ARM_BITS_INTR_H + +#include + +static inline void xnarch_relay_tick(void) +{ + rthal_irq_host_pend(RTHAL_TIMER_IRQ); +} + +static inline void xnarch_announce_tick(void) +{ + /* empty */ +} + +#endif /* !_XENO_ASM_ARM_BITS_INTR_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/pod.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/pod.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/pod.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/pod.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_POD_H +#define _XENO_ASM_ARM_BITS_POD_H + +#include + +void xnpod_welcome_thread(struct xnthread *, int); + +void xnpod_delete_thread(struct xnthread *); + +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#define xnarch_start_timer(tick_handler, cpu) \ + rthal_timer_request(tick_handler, xnarch_switch_htick_mode, xnarch_next_htick_shot, cpu) +#else +#define xnarch_start_timer(tick_handler, cpu) \ + rthal_timer_request(tick_handler, cpu) +#endif + +#define xnarch_stop_timer(cpu) rthal_timer_release(cpu) + +static inline void xnarch_leave_root(xnarchtcb_t * rootcb) +{ + rthal_mute_pic(); + /* Remember the preempted Linux task pointer. */ + rootcb->user_task = rootcb->active_task = current; + rootcb->mm = rootcb->active_mm = rthal_get_active_mm(); + rootcb->tip = current_thread_info(); +#ifdef CONFIG_XENO_HW_FPU +#ifdef CONFIG_VFP + rootcb->fpup = rthal_get_fpu_owner(); +#else /* !CONFIG_VFP */ + rootcb->user_fpu_owner = rthal_get_fpu_owner(rootcb->user_task); + /* So that xnarch_save_fpu() will operate on the right FPU area. */ + rootcb->fpup = (rootcb->user_fpu_owner + ? rthal_task_fpenv(rootcb->user_fpu_owner) : NULL); +#endif /* !CONFIG_VFP */ +#endif /* CONFIG_XENO_HW_FPU */ +} + +static inline void xnarch_enter_root(xnarchtcb_t * rootcb) +{ +#ifdef TIF_MMSWITCH_INT + if (!rootcb->mm) + set_ti_thread_flag(rootcb->tip, TIF_MMSWITCH_INT); +#endif /* TIF_MMSWITCH_INT */ + rthal_unmute_pic(); +} + +static inline void xnarch_switch_to(xnarchtcb_t *out_tcb, xnarchtcb_t *in_tcb) +{ + struct task_struct *prev = out_tcb->active_task; + struct mm_struct *prev_mm = out_tcb->active_mm; + struct task_struct *next = in_tcb->user_task; + + if (likely(next != NULL)) { + in_tcb->active_task = next; + in_tcb->active_mm = in_tcb->mm; + rthal_clear_foreign_stack(&rthal_domain); + } else { + in_tcb->active_task = prev; + in_tcb->active_mm = prev_mm; + rthal_set_foreign_stack(&rthal_domain); + } + + if (prev_mm != in_tcb->active_mm) { + /* Switch to new user-space thread? */ + if (in_tcb->active_mm) + switch_mm(prev_mm, in_tcb->active_mm, next); + if (!next->mm) + enter_lazy_tlb(prev_mm, next); + } + + /* Kernel-to-kernel context switch. */ + rthal_thread_switch(prev, out_tcb->tip, in_tcb->tip); +} + +asmlinkage static void xnarch_thread_trampoline(xnarchtcb_t * tcb) +{ + xnpod_welcome_thread(tcb->self, tcb->imask); + tcb->entry(tcb->cookie); + xnpod_delete_thread(tcb->self); +} + +static inline void xnarch_init_thread(xnarchtcb_t * tcb, + void (*entry) (void *), + void *cookie, + int imask, + struct xnthread *thread, char *name) +{ + unsigned long flags; + struct cpu_context_save *regs; + + rthal_local_irq_flags_hw(flags); + + regs = &tcb->ti.cpu_context; + memset(regs, 0, sizeof(*regs)); + regs->pc = (unsigned long)&rthal_thread_trampoline; + regs->r4 = (unsigned long)&xnarch_thread_trampoline; + regs->r5 = (unsigned long)tcb; + regs->sp = (unsigned long)tcb->stackbase + tcb->stacksize; + + tcb->entry = entry; + tcb->cookie = cookie; + tcb->self = thread; + tcb->imask = imask; + tcb->name = name; +} + +/* No lazy FPU init on ARM. */ +#define xnarch_fpu_init_p(task) (1) + +static inline void xnarch_enable_fpu(xnarchtcb_t *tcb) +{ +#ifdef CONFIG_XENO_HW_FPU +#ifdef CONFIG_VFP + /* If we are restoring the Linux current thread which does not own the + FPU context, we keep FPU disabled, so that a fault will occur if the + newly switched thread uses the FPU, to allow the kernel handler to + pick the correct FPU context. + */ + if (likely(!tcb->is_root)) { + rthal_enable_fpu(); + /* No exception should be pending, since it should have caused + a trap earlier. + */ + } else if (tcb->fpup && tcb->fpup == rthal_task_fpenv(tcb->user_task)) { + unsigned fpexc = rthal_enable_fpu(); +#ifndef CONFIG_SMP + if (likely(!(fpexc & RTHAL_VFP_ANY_EXC) + && !(rthal_vfp_fmrx(FPSCR) & FPSCR_IXE))) + return; + /* + If current process has pending exceptions it is + illegal to restore the FPEXC register with them, we must + save the fpu state and disable them, to get linux + fpu fault handler take care of them correctly. + */ +#endif + /* + On SMP systems, if we are restoring the root + thread, running the task holding the FPU context at + the time when we switched to real-time domain, + forcibly save the FPU context. It seems to fix SMP + systems for still unknown reasons. + */ + rthal_save_fpu(tcb->fpup, fpexc); + last_VFP_context[rthal_processor_id()] = NULL; + rthal_disable_fpu(); + } +#else /* !CONFIG_VFP */ + if (!tcb->user_task) + rthal_enable_fpu(); +#endif /* !CONFIG_VFP */ +#endif /* CONFIG_XENO_HW_FPU */ +} + +static inline void xnarch_init_fpu(xnarchtcb_t * tcb) +{ +#ifdef CONFIG_XENO_HW_FPU + /* Initialize the FPU for an emerging kernel-based RT thread. This + must be run on behalf of the emerging thread. */ + memset(&tcb->fpuenv, 0, sizeof(tcb->fpuenv)); + rthal_init_fpu(&tcb->fpuenv); +#ifdef CONFIG_VFP + rthal_enable_fpu(); + rthal_restore_fpu(&tcb->fpuenv); +#endif /* CONFIG_VFP */ +#endif /* CONFIG_XENO_HW_FPU */ +} + +static inline void xnarch_save_fpu(xnarchtcb_t * tcb) +{ +#ifdef CONFIG_XENO_HW_FPU +#ifdef CONFIG_VFP + if (tcb->fpup) + rthal_save_fpu(tcb->fpup, rthal_enable_fpu()); +#else /* !CONFIG_VFP */ + if (tcb->fpup) { + rthal_save_fpu(tcb->fpup); + + if (tcb->user_fpu_owner && task_thread_info(tcb->user_fpu_owner)) { + task_thread_info(tcb->user_fpu_owner)->used_cp[1] = 0; + task_thread_info(tcb->user_fpu_owner)->used_cp[2] = 0; + } + } +#endif /* !CONFIG_VFP */ +#endif /* CONFIG_XENO_HW_FPU */ +} + +static inline void xnarch_restore_fpu(xnarchtcb_t * tcb) +{ +#ifdef CONFIG_XENO_HW_FPU +#ifdef CONFIG_VFP + if (likely(!tcb->is_root)) { + rthal_enable_fpu(); + rthal_restore_fpu(tcb->fpup); + } else { + /* We are restoring the Linux current thread which does not own the FPU + context, so the FPU must be disabled, so that a fault will occur if + the newly switched thread uses the FPU, to allow the kernel handler + to pick the correct FPU context. + + Further set last_VFP_context to NULL to avoid the Linux kernel to + save, when the fault occur, the current FPU context, the one of an RT + task, into the FPU area of the last non RT task which used the FPU + before the preemption by Xenomai. + */ + last_VFP_context[rthal_processor_id()] = NULL; + rthal_disable_fpu(); + } +#else /* !CONFIG_VFP */ + if (tcb->fpup) { + rthal_restore_fpu(tcb->fpup); + + if (tcb->user_fpu_owner && task_thread_info(tcb->user_fpu_owner)) { + task_thread_info(tcb->user_fpu_owner)->used_cp[1] = 1; + task_thread_info(tcb->user_fpu_owner)->used_cp[2] = 1; + } + } + + /* FIXME: We restore FPU "as it was" when Xenomai preempted Linux, + whereas we could be much lazier. */ + if (tcb->user_task) + rthal_disable_fpu(); +#endif /* !CONFIG_VFP */ +#endif /* CONFIG_XENO_HW_FPU */ +} + +static inline int xnarch_escalate(void) +{ + extern int xnarch_escalation_virq; + + if (rthal_current_domain == rthal_root_domain) { + rthal_trigger_irq(xnarch_escalation_virq); + return 1; + } + + return 0; +} + +#endif /* !_XENO_ASM_ARM_BITS_POD_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/sched.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/sched.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/sched.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/sched.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_SCHED_H +#define _XENO_ASM_ARM_BITS_SCHED_H + +static inline void xnarch_init_root_tcb(xnarchtcb_t * tcb, + struct xnthread *thread, + const char *name) +{ + tcb->user_task = current; + tcb->active_task = NULL; + tcb->mm = current->mm; + tcb->active_mm = NULL; + tcb->tip = &tcb->ti; +#ifdef CONFIG_XENO_HW_FPU + tcb->user_fpu_owner = NULL; + tcb->fpup = NULL; + tcb->is_root = 1; +#endif /* CONFIG_XENO_HW_FPU */ + tcb->entry = NULL; + tcb->cookie = NULL; + tcb->self = thread; + tcb->imask = 0; + tcb->name = name; +} + +#endif /* !_XENO_ASM_ARM_BITS_SCHED_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/shadow.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/shadow.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/shadow.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/shadow.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_SHADOW_H +#define _XENO_ASM_ARM_BITS_SHADOW_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include + +static inline void xnarch_init_shadow_tcb(xnarchtcb_t * tcb, + struct xnthread *thread, + const char *name) +{ + struct task_struct *task = current; + + tcb->user_task = task; + tcb->active_task = NULL; + tcb->mm = task->mm; + tcb->active_mm = NULL; + tcb->tip = task_thread_info(task); +#ifdef CONFIG_XENO_HW_FPU + tcb->user_fpu_owner = task; + tcb->fpup = (rthal_fpenv_t *) & task_thread_info(task)->used_cp[0]; +#endif /* CONFIG_XENO_HW_FPU */ + tcb->entry = NULL; + tcb->cookie = NULL; + tcb->self = thread; + tcb->imask = 0; + tcb->name = name; +} + +static inline int xnarch_local_syscall(struct pt_regs *regs) +{ + int error = 0; + + switch (__xn_reg_arg1(regs)) { + case XENOMAI_SYSARCH_ATOMIC_ADD_RETURN:{ + int i; + atomic_t *v, val; + int ret; + unsigned long flags; + + local_irq_save_hw(flags); + __xn_get_user(i, (int *)__xn_reg_arg2(regs)); + __xn_get_user(v, (atomic_t **) __xn_reg_arg3(regs)); + if (__xn_copy_from_user(&val, v, sizeof(atomic_t))) { + error = -EFAULT; + goto unlock; + } + ret = atomic_add_return(i, &val); + if (__xn_copy_to_user(v, &val, sizeof(atomic_t))) { + error = -EFAULT; + goto unlock; + } + __xn_put_user(ret, (int *)__xn_reg_arg4(regs)); + unlock: + local_irq_restore_hw(flags); + break; + } + case XENOMAI_SYSARCH_ATOMIC_SET_MASK:{ + unsigned long mask; + unsigned long *addr, val; + unsigned long flags; + + local_irq_save_hw(flags); + __xn_get_user(mask, (unsigned long *)__xn_reg_arg2(regs)); + __xn_get_user(addr, (unsigned long **)__xn_reg_arg3(regs)); + __xn_get_user(val, (unsigned long *)addr); + val |= mask; + __xn_put_user(val, (unsigned long *)addr); + local_irq_restore_hw(flags); + break; + } + case XENOMAI_SYSARCH_ATOMIC_CLEAR_MASK:{ + unsigned long mask; + unsigned long *addr, val; + unsigned long flags; + + local_irq_save_hw(flags); + __xn_get_user(mask, (unsigned long *)__xn_reg_arg2(regs)); + __xn_get_user(addr, (unsigned long **)__xn_reg_arg3(regs)); + __xn_get_user(val, (unsigned long *)addr); + val &= ~mask; + __xn_put_user(val, (unsigned long *)addr); + local_irq_restore_hw(flags); + break; + } + case XENOMAI_SYSARCH_XCHG:{ + void *ptr; + unsigned long x; + unsigned int size; + unsigned long ret = 0; + unsigned long flags; + + local_irq_save_hw(flags); + __xn_get_user(ptr, (unsigned char **)__xn_reg_arg2(regs)); + __xn_get_user(x, (unsigned long *)__xn_reg_arg3(regs)); + __xn_get_user(size, (unsigned int *)__xn_reg_arg4(regs)); + if (size == 4) { + unsigned long val; + __xn_get_user(val, (unsigned long *)ptr); + ret = xnarch_atomic_xchg(&val, x); + } else + error = -EINVAL; + __xn_put_user(ret, (unsigned long *)__xn_reg_arg5(regs)); + local_irq_restore_hw(flags); + break; + } + +/* If I-pipe supports user-space tsc emulation, add a syscall for retrieving tsc + infos. */ +#ifdef IPIPE_TSC_TYPE_NONE + case XENOMAI_SYSARCH_TSCINFO:{ + struct ipipe_sysinfo ipipe_info; + struct __xn_tscinfo info; + + error = ipipe_get_sysinfo(&ipipe_info); + if (error) + return error; + + switch (RTHAL_TSC_INFO(&ipipe_info).type) { + case IPIPE_TSC_TYPE_FREERUNNING: + info.type = __XN_TSC_TYPE_FREERUNNING, + info.u.fr.counter = RTHAL_TSC_INFO(&ipipe_info).u.fr.counter; + info.u.fr.mask = RTHAL_TSC_INFO(&ipipe_info).u.fr.mask; + info.u.fr.tsc = RTHAL_TSC_INFO(&ipipe_info).u.fr.tsc; + break; + case IPIPE_TSC_TYPE_DECREMENTER: + info.type = __XN_TSC_TYPE_DECREMENTER, + info.u.dec.counter = RTHAL_TSC_INFO(&ipipe_info).u.dec.counter; + info.u.dec.mask = RTHAL_TSC_INFO(&ipipe_info).u.dec.mask; + info.u.dec.last_cnt = RTHAL_TSC_INFO(&ipipe_info).u.dec.last_cnt; + info.u.dec.tsc = RTHAL_TSC_INFO(&ipipe_info).u.dec.tsc; + break; +#ifdef IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN + case IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN: + info.type = __XN_TSC_TYPE_FREERUNNING_COUNTDOWN, + info.u.fr.counter = RTHAL_TSC_INFO(&ipipe_info).u.fr.counter; + info.u.fr.mask = RTHAL_TSC_INFO(&ipipe_info).u.fr.mask; + info.u.fr.tsc = RTHAL_TSC_INFO(&ipipe_info).u.fr.tsc; + break; +#endif /* IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN */ + case IPIPE_TSC_TYPE_NONE: + return -ENOSYS; + + default: + return -EINVAL; + } + + if (__xn_copy_to_user((void *)__xn_reg_arg2(regs), + &info, sizeof(info))) + return -EFAULT; + break; + } +#endif /* IPIPE_TSC_TYPE_NONE */ + + default: + error = -EINVAL; + } + return error; +} + +#define xnarch_schedule_tail(prev) do { } while(0) + +#ifdef XNARCH_HAVE_MAYDAY + +static inline void xnarch_setup_mayday_page(void *page) +{ + /* + * We want this code to appear at the top of the MAYDAY page: + * + * ifdef ARM_EABI + * + * e3a00f8a mov r0, #552 ; 0x228 + * e28003c3 add r0, r0, #201326595 ; 0xc000003 + * e3a0780f mov r7, #983040 ; 0xf0000 + * e2877042 add r7, r7, #66 ; 0x42 + * e3a06000 mov r6, #0 + * ef000000 svc 0x00000000 + * e3a00000 mov r0, #0 + * e5800000 str r0, [r0] ; + * + * elif ARM_OABI + * + * e3a00f8a mov r0, #552 ; 0x228 + * e28003c3 add r0, r0, #201326595 ; 0xc000003 + * e3a06000 mov r6, #0 + * ef9f0042 swi 0x009f0042 + * e3a00000 mov r0, #0 + * e5800000 str r0, [r0] ; + * + * endif + * + * 32bit instruction words will be laid out by the compiler as + * the target endianness requires. + * + * We don't mess with CPSR here, so no need to save/restore it + * in handle/fixup code. + */ +#ifdef CONFIG_XENO_ARM_EABI + static const struct { + u32 mov_muxl; + u32 add_muxh; + u32 mov_sysh; + u32 add_sysl; + u32 mov_sigp; + u32 swi_0; + u32 mov_r0; + u32 str_r0; + } code = { + .mov_muxl = 0xe3a00f8a, + .add_muxh = 0xe28003c3, + .mov_sysh = 0xe3a0780f, + .add_sysl = 0xe2877042, + .mov_sigp = 0xe3a06000, + .swi_0 = 0xef000000, + .mov_r0 = 0xe3a00000, + .str_r0 = 0xe5800000 + }; +#else /* OABI */ + static const struct { + u32 mov_muxl; + u32 add_muxh; + u32 mov_sigp; + u32 swi_syscall; + u32 mov_r0; + u32 str_r0; + } code = { + .mov_muxl = 0xe3a00f8a, + .add_muxh = 0xe28003c3, + .mov_sigp = 0xe3a06000, + .swi_syscall = 0x009f0042, + .mov_r0 = 0xe3a00000, + .str_r0 = 0xe5800000 + }; +#endif /* OABI */ + + memcpy(page, &code, sizeof(code)); + + flush_dcache_page(vmalloc_to_page(page)); +} + +static inline void xnarch_call_mayday(struct task_struct *p) +{ + rthal_return_intercept(p); +} + +static inline void xnarch_handle_mayday(struct xnarchtcb *tcb, + struct pt_regs *regs, + unsigned long tramp) +{ + tcb->mayday.pc = regs->ARM_pc; + tcb->mayday.r0 = regs->ARM_r0; + tcb->mayday.r6 = regs->ARM_r6; +#ifdef CONFIG_XENO_ARM_EABI + tcb->mayday.r7 = regs->ARM_r7; +#endif + regs->ARM_pc = tramp; +} + +static inline void xnarch_fixup_mayday(struct xnarchtcb *tcb, + struct pt_regs *regs) +{ + regs->ARM_pc = tcb->mayday.pc; + regs->ARM_r0 = tcb->mayday.r0; + regs->ARM_r6 = tcb->mayday.r6; +#ifdef CONFIG_XENO_ARM_EABI + regs->ARM_r7 = tcb->mayday.r7; +#endif +} + +#endif /* XNARCH_HAVE_MAYDAY */ + +#endif /* !_XENO_ASM_ARM_BITS_SHADOW_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/thread.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/thread.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/thread.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/thread.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_THREAD_H +#define _XENO_ASM_ARM_BITS_THREAD_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +static inline unsigned long xnarch_current_domain_access_control(void) +{ + unsigned long domain_access_control; + asm("mrc p15, 0, %0, c3, c0":"=r"(domain_access_control)); + return domain_access_control; +} + +static inline void xnarch_init_tcb(xnarchtcb_t * tcb) +{ + + tcb->user_task = NULL; + tcb->active_task = NULL; + tcb->mm = NULL; + tcb->active_mm = NULL; + tcb->tip = &tcb->ti; + tcb->ti.tp_value = 0; + tcb->ti.cpu_domain = xnarch_current_domain_access_control(); +#ifdef CONFIG_XENO_HW_FPU + tcb->user_fpu_owner = NULL; + tcb->fpup = &tcb->fpuenv; + tcb->is_root = 0; +#endif /* CONFIG_XENO_HW_FPU */ + /* Must be followed by xnarch_init_thread(). */ +} + +#define xnarch_alloc_stack(tcb,stacksize) \ +({ \ + int __err; \ + (tcb)->stacksize = stacksize; \ + if (stacksize == 0) { \ + (tcb)->stackbase = NULL; \ + __err = 0; \ + } else { \ + (tcb)->stackbase = xnheap_alloc(&kstacks, stacksize); \ + __err = (tcb)->stackbase ? 0 : -ENOMEM; \ + } \ + __err; \ +}) + +#define xnarch_free_stack(tcb) \ +do { \ + if ((tcb)->stackbase) \ + xnheap_free(&kstacks, (tcb)->stackbase); \ +} while(0) + +#endif /* !_XENO_ASM_ARM_BITS_THREAD_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/timer.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/timer.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/timer.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/bits/timer.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_BITS_TIMER_H +#define _XENO_ASM_ARM_BITS_TIMER_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include + +extern rthal_u32frac_t rthal_tsc_to_timer; + +static inline void xnarch_program_timer_shot(unsigned long delay) +{ + rthal_timer_program_shot(rthal_nodiv_imuldiv_ceil(delay, + rthal_tsc_to_timer)); +} + +static inline int xnarch_send_timer_ipi(xnarch_cpumask_t mask) +{ + return 0; +} + +#endif /* !_XENO_ASM_ARM_BITS_TIMER_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/calibration.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/calibration.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/calibration.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/calibration.h 2011-03-06 19:30:24.000000000 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_CALIBRATION_H +#define _XENO_ASM_ARM_CALIBRATION_H + +#ifndef _XENO_ASM_ARM_BITS_INIT_H +#error "please don't include asm/calibration.h directly" +#endif + +static inline unsigned long xnarch_get_sched_latency (void) +{ +#if CONFIG_XENO_OPT_TIMING_SCHEDLAT != 0 + return CONFIG_XENO_OPT_TIMING_SCHEDLAT; +#else +#if defined(CONFIG_ARCH_AT91RM9200) + return 8500; +#elif defined(CONFIG_ARCH_AT91SAM9263) + return 11000; +#elif defined(CONFIG_ARCH_OMAP3) + return 5000; +#elif defined(CONFIG_ARCH_MX51) + return 5000; +#else + return 9500; /* XXX sane ? */ +#endif +#endif +} + +#endif /* !_XENO_ASM_ARM_CALIBRATION_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/features.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/features.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/features.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/features.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _XENO_ASM_ARM_FEATURES_H +#define _XENO_ASM_ARM_FEATURES_H + +#include + +#ifdef __KERNEL__ + +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +#define CONFIG_XENO_ARM_SA1000 1 +#endif + +#ifdef CONFIG_AEABI +#define CONFIG_XENO_ARM_EABI 1 +#endif + +#define CONFIG_XENO_ARM_HW_DIRECT_TSC 1 + +#else /* !__KERNEL__ */ +#define __LINUX_ARM_ARCH__ CONFIG_XENO_ARM_ARCH +#endif /* __KERNEL__ */ + +#define __xn_feat_arm_atomic_xchg 0x00000001 +#define __xn_feat_arm_atomic_atomic 0x00000002 +#define __xn_feat_arm_eabi 0x00000004 +#define __xn_feat_arm_tsc 0x00000008 + +/* The ABI revision level we use on this arch. */ +#define XENOMAI_ABI_REV 3UL + +#if __LINUX_ARM_ARCH__ >= 6 +/* ARMv6 has both atomic xchg and atomic_inc/dec etc. */ +#define __xn_feat_arm_atomic_xchg_mask __xn_feat_arm_atomic_xchg +#define __xn_feat_arm_atomic_atomic_mask __xn_feat_arm_atomic_atomic +#else +/* ARM < v6 has only atomic xchg, except on SA1000 where it is buggy */ +#ifdef CONFIG_XENO_ARM_SA1100 +#define __xn_feat_arm_atomic_xchg_mask 0 +#else +#define __xn_feat_arm_atomic_xchg_mask __xn_feat_arm_atomic_xchg +#endif +#define __xn_feat_arm_atomic_atomic_mask 0 +#endif +#define __xn_feat_arm_eabi_mask __xn_feat_arm_eabi + +#ifdef CONFIG_XENO_ARM_HW_DIRECT_TSC +#define __xn_feat_arm_tsc_mask __xn_feat_arm_tsc +#else /* !CONFIG_XENO_ARM_HW_DIRECT_TSC */ +#define __xn_feat_arm_tsc_mask 0 +#endif /* !CONFIG_XENO_ARM_HW_DIRECT_TSC */ + +#define XENOMAI_FEAT_DEP ( __xn_feat_generic_mask | \ + __xn_feat_arm_atomic_xchg_mask | \ + __xn_feat_arm_atomic_atomic_mask | \ + __xn_feat_arm_eabi_mask | \ + __xn_feat_arm_tsc_mask) + +#define XENOMAI_FEAT_MAN __xn_feat_generic_man_mask + +static inline int check_abi_revision(unsigned long abirev) +{ + return abirev == XENOMAI_ABI_REV; +} + +static inline const char *get_feature_label (unsigned feature) +{ + switch (feature) { + case __xn_feat_arm_atomic_xchg: + return "sa1100"; + case __xn_feat_arm_atomic_atomic: + return "v6"; + case __xn_feat_arm_eabi: + return "eabi"; + case __xn_feat_arm_tsc: + return "tsc"; + default: + return get_generic_feature_label(feature); + } +} + +#define XNARCH_HAVE_LLMULSHFT 1 +#define XNARCH_HAVE_NODIV_LLIMD 1 + +#endif /* !_XENO_ASM_ARM_FEATURES_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/fptest.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/fptest.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/fptest.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/fptest.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,95 @@ +#ifndef _XENO_ASM_ARM_FPTEST_H +#define _XENO_ASM_ARM_FPTEST_H + +#ifdef __KERNEL__ +#include +#include + +#ifdef CONFIG_VFP +#define have_vfp (elf_hwcap & HWCAP_VFP) +#else /* !CONFIG_VFP */ +#define have_vfp (0) +#endif /* !CONFIG_VFP */ + +static inline int fp_kernel_supported(void) +{ + return 1; +} + +static inline int fp_linux_begin(void) +{ + return -ENOSYS; +} + +static inline void fp_linux_end(void) +{ +} + +#else /* !__KERNEL__ */ +#include +#include +#define printk(fmt, args...) fprintf(stderr, fmt, ## args) + +static int have_vfp; + +static void __attribute__((constructor)) fp_init(void) +{ + char buffer[1024]; + FILE *f = fopen("/proc/cpuinfo", "r"); + if(!f) + return; + + while(fgets(buffer, sizeof(buffer), f)) { + if(strncmp(buffer, "Features", sizeof("Features") - 1)) + continue; + + if (strstr(buffer, "vfp")) { + have_vfp = 1; + break; + } + } + + fclose(f); +} + +#endif /* !__KERNEL__ */ + +static inline void fp_regs_set(unsigned val) +{ + if (have_vfp) { + unsigned long long e[16]; + unsigned i; + + for (i = 0; i < 16; i++) + e[i] = val; + + /* vldm %0!, {d0-d15}, + AKA fldmiax %0!, {d0-d15} */ + __asm__ __volatile__("ldc p11, cr0, [%0],#32*4": + "=r"(i): "0"(&e[0]): "memory"); + } +} + +static inline unsigned fp_regs_check(unsigned val) +{ + unsigned result = val; + + if (have_vfp) { + unsigned long long e[16]; + unsigned i; + + /* vstm %0!, {d0-d15}, + AKA fstmiax %0!, {d0-d15} */ + __asm__ __volatile__("stc p11, cr0, [%0],#32*4": + "=r"(i): "0"(&e[0]): "memory"); + + for (i = 0; i < 16; i++) + if (e[i] != val) { + printk("d%d: %llu != %u\n", i, e[i], val); + result = e[i]; + } + } + + return result; +} +#endif /* _XENO_ASM_ARM_FPTEST_H */ diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/hal.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/hal.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/hal.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/hal.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,334 @@ +/** + * @ingroup hal + * @file + * + * Real-Time Hardware Abstraction Layer for ARM. + * + * Copyright © 2002-2004 Philippe Gerum. + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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, Inc., 675 Mass Ave, + * Cambridge MA 02139, USA; either version 2 of the License, or (at + * your option) any later version. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_HAL_H +#define _XENO_ASM_ARM_HAL_H + +#include /* Read the generic bits. */ +#include + +#ifdef CONFIG_VFP +#if defined(CONFIG_XENO_HW_FPU) && !__IPIPE_FEATURE_VFP_SAFE +#error "Xenomai requires a more recent I-pipe patch to use VFP hardware" +#endif /* defined(CONFIG_XENO_HW_FPU) && !__IPIPE_FEATURE_VFP_SAFE */ +#include +#endif /* CONFIG_VFP */ + +#if defined(CONFIG_ARCH_AT91) +#include +#define RTHAL_TIMER_DEVICE "at91_tc" __stringify(CONFIG_IPIPE_AT91_TC) +#define RTHAL_CLOCK_DEVICE "at91_tc" __stringify(CONFIG_IPIPE_AT91_TC) +#elif defined(CONFIG_ARCH_IMX) +#define RTHAL_TIMER_DEVICE "imx_timer1" +#define RTHAL_CLOCK_DEVICE "imx_timer1" +#elif defined(CONFIG_ARCH_IMX21) +#define RTHAL_TIMER_DEVICE "TCMP" +#define RTHAL_CLOCK_DEVICE "TCN" +#elif defined(CONFIG_ARCH_INTEGRATOR) +#define RTHAL_TIMER_DEVICE "TIMER1" +#define RTHAL_CLOCK_DEVICE "TIMER1" +#elif defined(CONFIG_ARCH_IXP4XX) +#define RTHAL_TIMER_DEVICE "ixp4xx timer1" +#define RTHAL_CLOCK_DEVICE "OSTS" +#elif defined(CONFIG_ARCH_MXC) +#define RTHAL_TIMER_DEVICE "mxc_timer1" +#define RTHAL_CLOCK_DEVICE "mxc_timer1" +#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +#define RTHAL_TIMER_DEVICE "gp timer" +#define RTHAL_CLOCK_DEVICE "gp timer" +#elif defined(CONFIG_ARCH_PXA) +#define RTHAL_TIMER_DEVICE "osmr0" +#define RTHAL_CLOCK_DEVICE "oscr0" +#elif defined(CONFIG_ARCH_S3C2410) +#define RTHAL_TIMER_DEVICE "TCNTB4" +#define RTHAL_CLOCK_DEVICE "TCNTO3" +#elif defined(CONFIG_ARCH_SA1100) +#define RTHAL_TIMER_DEVICE "osmr0" +#define RTHAL_CLOCK_DEVICE "oscr0" +#elif defined(CONFIG_PLAT_ORION) +#define RTHAL_TIMER_DEVICE "orion_tick" +#define RTHAL_CLOCK_DEVICE "orion_clocksource" +#else +#error "Unsupported ARM machine" +#endif /* CONFIG_ARCH_SA1100 */ + +typedef unsigned long long rthal_time_t; + +#if __LINUX_ARM_ARCH__ < 5 +static inline __attribute_const__ unsigned long ffnz (unsigned long x) +{ + int r = 0; + + if (!x) + return 0; + if (!(x & 0xffff)) { + x >>= 16; + r += 16; + } + if (!(x & 0xff)) { + x >>= 8; + r += 8; + } + if (!(x & 0xf)) { + x >>= 4; + r += 4; + } + if (!(x & 3)) { + x >>= 2; + r += 2; + } + if (!(x & 1)) { + x >>= 1; + r += 1; + } + return r; +} +#else +static inline __attribute_const__ unsigned long ffnz (unsigned long ul) +{ + int __r; + __asm__("clz\t%0, %1" : "=r" (__r) : "r"(ul & (-ul)) : "cc"); + return 31 - __r; +} +#endif + +#ifndef __cplusplus +#include +#include +#include +#include +#include +#include +#include + +#ifndef RTHAL_TIMER_IRQ +/* + * Default setting, unless pre-set in the machine-dependent section. + */ +#ifdef __IPIPE_FEATURE_SYSINFO_V2 +#define RTHAL_TIMER_IRQ __ipipe_mach_hrtimer_irq +#else +#define RTHAL_TIMER_IRQ __ipipe_mach_timerint +#endif /* __IPIPE_FEATURE_SYSINFO_V2 */ +#endif /* RTHAL_TIMER_IRQ */ + +#ifdef __IPIPE_FEATURE_SYSINFO_V2 +#define RTHAL_TSC_INFO(p) ((p)->arch_tsc) +#else +#define RTHAL_TSC_INFO(p) ((p)->archdep.tsc) +#endif /* __IPIPE_FEATURE_SYSINFO_V2 */ + +#ifdef CONFIG_XENO_OPT_PERVASIVE +#define RTHAL_SHARED_HEAP_FLAGS (cache_is_vivt() ? XNHEAP_GFP_NONCACHED : 0) +#else /* !CONFIG_XENO_OPT_PERVASIVE */ +#define RTHAL_SHARED_HEAP_FLAGS 0 +#endif /* !CONFIG_XENO_OPT_PERVASIVE */ + +#define rthal_grab_control() do { } while(0) +#define rthal_release_control() do { } while(0) + +static inline unsigned long long rthal_rdtsc (void) +{ + unsigned long long t; + rthal_read_tsc(t); + return t; +} + +static inline struct task_struct *rthal_current_host_task (int cpuid) +{ + return current; +} + +static inline void rthal_timer_program_shot (unsigned long delay) +{ + if(!delay) + rthal_schedule_irq_head(RTHAL_TIMER_IRQ); + else + __ipipe_mach_set_dec(delay); +} + +static inline struct mm_struct *rthal_get_active_mm(void) +{ +#ifdef TIF_MMSWITCH_INT + return per_cpu(ipipe_active_mm, smp_processor_id()); +#else /* !TIF_MMSWITCH_INT */ + return current->active_mm; +#endif /* !TIF_MMSWITCH_INT */ +} + +/* Private interface -- Internal use only */ + +asmlinkage void rthal_thread_switch(struct task_struct *prev, + struct thread_info *out, + struct thread_info *in); + +asmlinkage void rthal_thread_trampoline(void); + +#ifdef CONFIG_XENO_HW_FPU + +typedef struct rthal_fpenv { + + /* + * This layout must follow exactely the definition of the FPU + * area in the ARM thread_info structure. 'tp_value' is also + * saved even if it is not needed, but it shouldn't matter. + */ + __u8 used_cp[16]; /* thread used copro */ + unsigned long tp_value; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + struct crunch_state crunchstate; +#endif /* Linux version >= 2.6.18 */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) + union fp_state fpstate; +#else /* Linux version >= 2.6.16 */ + union fp_state fpstate __attribute__((aligned(8))); +#endif /* Linux version >= 2.6.16 */ + union vfp_state vfpstate; +} rthal_fpenv_t; + +static inline void rthal_init_fpu(rthal_fpenv_t *fpuenv) +{ + fp_init(&fpuenv->fpstate); +#if defined(CONFIG_VFP) + /* vfpstate has already been zeroed by xnarch_init_fpu */ + fpuenv->vfpstate.hard.fpexc = FPEXC_EN; + fpuenv->vfpstate.hard.fpscr = FPSCR_ROUND_NEAREST; +#endif +} + +#define rthal_task_fpenv(task) \ + ((rthal_fpenv_t *) &task_thread_info(task)->used_cp[0]) + +#ifdef CONFIG_VFP +asmlinkage void rthal_vfp_save(union vfp_state *vfp, unsigned fpexc); + +asmlinkage void rthal_vfp_load(union vfp_state *vfp); + +static inline void rthal_save_fpu(rthal_fpenv_t *fpuenv, unsigned fpexc) +{ + rthal_vfp_save(&fpuenv->vfpstate, fpexc); +} + +static inline void rthal_restore_fpu(rthal_fpenv_t *fpuenv) +{ + rthal_vfp_load(&fpuenv->vfpstate); +} + +#define rthal_vfp_fmrx(_vfp_) ({ \ + u32 __v; \ + asm volatile("mrc p10, 7, %0, " __stringify(_vfp_) \ + ", cr0, 0 @ fmrx %0, " #_vfp_: \ + "=r" (__v)); \ + __v; \ + }) + +#define rthal_vfp_fmxr(_vfp_,_var_) \ + asm volatile("mcr p10, 7, %0, " __stringify(_vfp_) \ + ", cr0, 0 @ fmxr " #_vfp_ ", %0": \ + /* */ : "r" (_var_)) + +extern union vfp_state *last_VFP_context[NR_CPUS]; +static inline rthal_fpenv_t *rthal_get_fpu_owner(void) +{ + union vfp_state *vfp_owner; +#ifdef CONFIG_SMP + unsigned fpexc; + + fpexc = rthal_vfp_fmrx(FPEXC); + if (!(fpexc & FPEXC_EN)) + return NULL; +#endif + + vfp_owner = last_VFP_context[ipipe_processor_id()]; + if (!vfp_owner) + return NULL; + + return container_of(vfp_owner, rthal_fpenv_t, vfpstate); +} + +#define rthal_disable_fpu() \ + rthal_vfp_fmxr(FPEXC, rthal_vfp_fmrx(FPEXC) & ~FPEXC_EN) + +#define RTHAL_VFP_ANY_EXC \ + (FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK) + +#define rthal_enable_fpu() \ + ({ \ + unsigned _fpexc = rthal_vfp_fmrx(FPEXC) | FPEXC_EN; \ + rthal_vfp_fmxr(FPEXC, _fpexc & ~RTHAL_VFP_ANY_EXC); \ + _fpexc; \ + }) + +#else /* !CONFIG_VFP */ +static inline void rthal_save_fpu(rthal_fpenv_t *fpuenv) +{ +} + +static inline void rthal_restore_fpu(rthal_fpenv_t *fpuenv) +{ +} + +#define rthal_get_fpu_owner(cur) ({ \ + struct task_struct * _cur = (cur); \ + ((task_thread_info(_cur)->used_cp[1] | task_thread_info(_cur)->used_cp[2]) \ + ? _cur : NULL); \ +}) + +#define rthal_disable_fpu() \ + task_thread_info(current)->used_cp[1] = task_thread_info(current)->used_cp[2] = 0; + +#define rthal_enable_fpu() \ + task_thread_info(current)->used_cp[1] = task_thread_info(current)->used_cp[2] = 1; + +#endif /* !CONFIG_VFP */ + +#endif /* CONFIG_XENO_HW_FPU */ + +void __rthal_arm_fault_range(struct vm_area_struct *vma); +#define rthal_fault_range(vma) __rthal_arm_fault_range(vma) + +static const char *const rthal_fault_labels[] = { + [IPIPE_TRAP_ACCESS] = "Data or instruction access", + [IPIPE_TRAP_SECTION] = "Section fault", + [IPIPE_TRAP_DABT] = "Generic data abort", + [IPIPE_TRAP_UNKNOWN] = "Unknown exception", + [IPIPE_TRAP_BREAK] = "Instruction breakpoint", + [IPIPE_TRAP_FPU] = "Floating point exception", + [IPIPE_TRAP_VFP] = "VFP Floating point exception", + [IPIPE_TRAP_UNDEFINSTR] = "Undefined instruction", +#ifdef IPIPE_TRAP_ALIGNMENT + [IPIPE_TRAP_ALIGNMENT] = "Unaligned access exception", +#endif /* IPIPE_TRAP_ALIGNMENT */ + [IPIPE_NR_FAULTS] = NULL +}; + +#endif /* !__cplusplus */ + +#endif /* !_XENO_ASM_ARM_HAL_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/syscall.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/syscall.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/syscall.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/syscall.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Copyright (C) 2007 Sebastian Smolorz + * Support for TSC emulation in user space for decrementing counters + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_SYSCALL_H +#define _XENO_ASM_ARM_SYSCALL_H + +#include +#include + +#define __xn_mux_code(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id(id) ((id << 16) & 0xff0000) + +#define XENO_ARM_SYSCALL 0x000F0042 /* carefully chosen... */ + +#ifdef __KERNEL__ + +#include +#include +#include + +/* Register mapping for accessing syscall args. */ + +#define __xn_reg_mux(regs) ((regs)->ARM_ORIG_r0) +#define __xn_reg_rval(regs) ((regs)->ARM_r0) +#define __xn_reg_arg1(regs) ((regs)->ARM_r1) +#define __xn_reg_arg2(regs) ((regs)->ARM_r2) +#define __xn_reg_arg3(regs) ((regs)->ARM_r3) +#define __xn_reg_arg4(regs) ((regs)->ARM_r4) +#define __xn_reg_arg5(regs) ((regs)->ARM_r5) +#define __xn_reg_sigp(regs) ((regs)->ARM_r6) + +/* In OABI_COMPAT mode, handle both OABI and EABI userspace syscalls */ +#ifdef CONFIG_OABI_COMPAT +#define __xn_reg_mux_p(regs) ( ((regs)->ARM_r7 == __NR_OABI_SYSCALL_BASE + XENO_ARM_SYSCALL) || \ + ((regs)->ARM_r7 == __NR_SYSCALL_BASE + XENO_ARM_SYSCALL) ) +#define __xn_linux_mux_p(regs, nr) \ + ( ((regs)->ARM_r7 == __NR_OABI_SYSCALL_BASE + (nr)) || \ + ((regs)->ARM_r7 == __NR_SYSCALL_BASE + (nr)) ) +#else /* !CONFIG_OABI_COMPAT */ +#define __xn_reg_mux_p(regs) ((regs)->ARM_r7 == __NR_SYSCALL_BASE + XENO_ARM_SYSCALL) +#define __xn_linux_mux_p(regs, nr) ((regs)->ARM_r7 == __NR_SYSCALL_BASE + (nr)) +#endif /* !CONFIG_OABI_COMPAT */ + +#define __xn_mux_id(regs) ((__xn_reg_mux(regs) >> 16) & 0xff) +#define __xn_mux_op(regs) ((__xn_reg_mux(regs) >> 24) & 0xff) + +/* Purposedly used inlines and not macros for the following routines + so that we don't risk spurious side-effects on the value arg. */ + +static inline void __xn_success_return(struct pt_regs *regs, int v) +{ + __xn_reg_rval(regs) = v; +} + +static inline void __xn_error_return(struct pt_regs *regs, int v) +{ + __xn_reg_rval(regs) = v; +} + +static inline void __xn_status_return(struct pt_regs *regs, int v) +{ + __xn_reg_rval(regs) = v; +} + +static inline int __xn_interrupted_p(struct pt_regs *regs) +{ + return __xn_reg_rval(regs) == -EINTR; +} + +#else /* !__KERNEL__ */ + +#include /* For -ERESTART */ + +/* + * Some of the following macros have been adapted from Linux's + * implementation of the syscall mechanism in : + * + * The following code defines an inline syscall mechanism used by + * Xenomai's real-time interfaces to invoke the skin module + * services in kernel space. + */ + +#if defined(HAVE___THREAD) && __GNUC__ == 4 && __GNUC_MINOR__ >= 3 +#error __thread is too buggy with gcc 4.3 and later, please do not pass --with-__thread to configure +#endif + +#define LOADARGS_0(muxcode, sigp, dummy...) \ + __a0 = (unsigned long) (muxcode); \ + __a6 = (unsigned long) (sigp) +#define LOADARGS_1(muxcode, sigp, arg1) \ + LOADARGS_0(muxcode, sigp); \ + __a1 = (unsigned long) (arg1) +#define LOADARGS_2(muxcode, sigp, arg1, arg2) \ + LOADARGS_1(muxcode, sigp, arg1); \ + __a2 = (unsigned long) (arg2) +#define LOADARGS_3(muxcode, sigp, arg1, arg2, arg3) \ + LOADARGS_2(muxcode, sigp, arg1, arg2); \ + __a3 = (unsigned long) (arg3) +#define LOADARGS_4(muxcode, sigp, arg1, arg2, arg3, arg4) \ + LOADARGS_3(muxcode, sigp, arg1, arg2, arg3); \ + __a4 = (unsigned long) (arg4) +#define LOADARGS_5(muxcode, sigp, arg1, arg2, arg3, arg4, arg5) \ + LOADARGS_4(muxcode, sigp, arg1, arg2, arg3, arg4); \ + __a5 = (unsigned long) (arg5) + +#define CLOBBER_REGS_0 "r0", "r6" +#define CLOBBER_REGS_1 CLOBBER_REGS_0, "r1" +#define CLOBBER_REGS_2 CLOBBER_REGS_1, "r2" +#define CLOBBER_REGS_3 CLOBBER_REGS_2, "r3" +#define CLOBBER_REGS_4 CLOBBER_REGS_3, "r4" +#define CLOBBER_REGS_5 CLOBBER_REGS_4, "r5" + +#define LOADREGS_0 __r0 = __a0; __r6 = __a6 +#define LOADREGS_1 LOADREGS_0; __r1 = __a1 +#define LOADREGS_2 LOADREGS_1; __r2 = __a2 +#define LOADREGS_3 LOADREGS_2; __r3 = __a3 +#define LOADREGS_4 LOADREGS_3; __r4 = __a4 +#define LOADREGS_5 LOADREGS_4; __r5 = __a5 + +#define ASM_INDECL_0 \ + unsigned long __a0; register unsigned long __r0 __asm__ ("r0"); \ + unsigned long __a6; register unsigned long __r6 __asm__ ("r6") +#define ASM_INDECL_1 ASM_INDECL_0; \ + unsigned long __a1; register unsigned long __r1 __asm__ ("r1") +#define ASM_INDECL_2 ASM_INDECL_1; \ + unsigned long __a2; register unsigned long __r2 __asm__ ("r2") +#define ASM_INDECL_3 ASM_INDECL_2; \ + unsigned long __a3; register unsigned long __r3 __asm__ ("r3") +#define ASM_INDECL_4 ASM_INDECL_3; \ + unsigned long __a4; register unsigned long __r4 __asm__ ("r4") +#define ASM_INDECL_5 ASM_INDECL_4; \ + unsigned long __a5; register unsigned long __r5 __asm__ ("r5") + +#define ASM_INPUT_0 "0" (__r0), "r" (__r6) +#define ASM_INPUT_1 ASM_INPUT_0, "r" (__r1) +#define ASM_INPUT_2 ASM_INPUT_1, "r" (__r2) +#define ASM_INPUT_3 ASM_INPUT_2, "r" (__r3) +#define ASM_INPUT_4 ASM_INPUT_3, "r" (__r4) +#define ASM_INPUT_5 ASM_INPUT_4, "r" (__r5) + +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifdef CONFIG_XENO_ARM_EABI +#define __SYS_REG , "r7" +#define __SYS_REG_DECL register unsigned long __r7 __asm__ ("r7") +#define __SYS_REG_SET __r7 = XENO_ARM_SYSCALL +#define __SYS_REG_INPUT ,"r" (__r7) +#define __xn_syscall "swi\t0" +#else +#define __SYS_REG +#define __SYS_REG_DECL +#define __SYS_REG_SET +#define __SYS_REG_INPUT +#define __NR_OABI_SYSCALL_BASE 0x900000 +#define __xn_syscall "swi\t" __sys1(__NR_OABI_SYSCALL_BASE + XENO_ARM_SYSCALL) "" +#endif + +#define XENOMAI_DO_SYSCALL_INNER(nr, shifted_id, op, args...) \ + ({ \ + ASM_INDECL_##nr; \ + __SYS_REG_DECL; \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ + __asm__ __volatile__ ("" : /* */ : /* */ : \ + CLOBBER_REGS_##nr __SYS_REG); \ + LOADREGS_##nr; \ + __SYS_REG_SET; \ + __asm__ __volatile__ ( \ + __xn_syscall \ + : "=r" (__r0) \ + : ASM_INPUT_##nr __SYS_REG_INPUT \ + : "memory"); \ + (int) __r0; \ + }) + +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + ({ \ + int err, res = -ERESTART; \ + struct xnsig sigs; \ + \ + do { \ + sigs.nsigs = 0; \ + err = XENOMAI_DO_SYSCALL_INNER(nr, shifted_id, \ + op, &sigs, args); \ + res = xnsig_dispatch(&sigs, res, err); \ + } while (res == -ERESTART); \ + res; \ + }) + +#define XENOMAI_SYSCALL0(op) \ + XENOMAI_DO_SYSCALL(0,0,op) +#define XENOMAI_SYSCALL1(op,a1) \ + XENOMAI_DO_SYSCALL(1,0,op,a1) +#define XENOMAI_SYSCALL2(op,a1,a2) \ + XENOMAI_DO_SYSCALL(2,0,op,a1,a2) +#define XENOMAI_SYSCALL3(op,a1,a2,a3) \ + XENOMAI_DO_SYSCALL(3,0,op,a1,a2,a3) +#define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) \ + XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4) +#define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) \ + XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5) +#define XENOMAI_SYSBIND(a1,a2,a3,a4) \ + XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4) +#define XENOMAI_SYSSIGS(sigs) \ + XENOMAI_DO_SYSCALL_INNER(0, 0, __xn_sys_get_next_sigs, sigs) + +#define XENOMAI_SKINCALL0(id,op) \ + XENOMAI_DO_SYSCALL(0,id,op) +#define XENOMAI_SKINCALL1(id,op,a1) \ + XENOMAI_DO_SYSCALL(1,id,op,a1) +#define XENOMAI_SKINCALL2(id,op,a1,a2) \ + XENOMAI_DO_SYSCALL(2,id,op,a1,a2) +#define XENOMAI_SKINCALL3(id,op,a1,a2,a3) \ + XENOMAI_DO_SYSCALL(3,id,op,a1,a2,a3) +#define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4) \ + XENOMAI_DO_SYSCALL(4,id,op,a1,a2,a3,a4) +#define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) \ + XENOMAI_DO_SYSCALL(5,id,op,a1,a2,a3,a4,a5) + +#ifdef XNARCH_ARM_TSC_TYPE +#define XNARCH_HAVE_NONPRIV_TSC 1 +#endif /* XNARCH_ARM_TSC_TYPE */ + +#endif /* __KERNEL__ */ + +#define XENOMAI_SYSARCH_ATOMIC_ADD_RETURN 0 +#define XENOMAI_SYSARCH_ATOMIC_SET_MASK 1 +#define XENOMAI_SYSARCH_ATOMIC_CLEAR_MASK 2 +#define XENOMAI_SYSARCH_XCHG 3 +#define XENOMAI_SYSARCH_TSCINFO 4 + +struct __xn_tscinfo { + int type; /* Must remain first member */ + union { + struct { + volatile unsigned *counter; + unsigned mask; + volatile unsigned long long *tsc; + } fr; + struct { + volatile unsigned *counter; + unsigned mask; + volatile unsigned *last_cnt; + volatile unsigned long long *tsc; + } dec; + } u; +}; +#define __XN_TSC_TYPE_NONE 0 +#define __XN_TSC_TYPE_FREERUNNING 1 +#define __XN_TSC_TYPE_DECREMENTER 2 +#define __XN_TSC_TYPE_FREERUNNING_FAST_WRAP 3 +#define __XN_TSC_TYPE_FREERUNNING_COUNTDOWN 4 + +#ifndef __KERNEL__ +extern struct __xn_tscinfo __xn_tscinfo; + +#ifdef XNARCH_ARM_TSC_TYPE +static inline unsigned long long __xn_rdtsc(void) +{ +#if XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING + volatile unsigned long long *const tscp = __xn_tscinfo.u.fr.tsc; + volatile unsigned *const counterp = __xn_tscinfo.u.fr.counter; + const unsigned mask = __xn_tscinfo.u.fr.mask; + register unsigned long long result; + unsigned counter; + + __asm__ ("ldmia %1, %M0\n": "=r"(result): "r"(tscp), "m"(*tscp)); + __asm__ __volatile__ ("" : /* */ : /* */ : "memory"); + counter = *counterp; + + if ((counter & mask) < ((unsigned) result & mask)) + result += mask + 1ULL; + return (result & ~((unsigned long long) mask)) | (counter & mask); +#elif XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING_COUNTDOWN + volatile unsigned long long *const tscp = __xn_tscinfo.u.fr.tsc; + volatile unsigned *const counterp = __xn_tscinfo.u.fr.counter; + const unsigned mask = __xn_tscinfo.u.fr.mask; + register unsigned long long result; + unsigned counter; + + __asm__ ("ldmia %1, %M0\n": "=r"(result): "r"(tscp), "m"(*tscp)); + __asm__ __volatile__ ("" : /* */ : /* */ : "memory"); + counter = mask - *counterp; + + if ((counter & mask) > ((unsigned) result & mask)) + result += mask + 1ULL; + return (result & ~((unsigned long long) mask)) | (counter & mask); +#elif XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_FREERUNNING_FAST_WRAP + volatile unsigned long long *const tscp = __xn_tscinfo.u.fr.tsc; + volatile unsigned *const counterp = __xn_tscinfo.u.fr.counter; + const unsigned mask = __xn_tscinfo.u.fr.mask; + register unsigned long long after, before; + unsigned counter; + + __asm__ ("ldmia %1, %M0\n": "=r"(after): "r"(tscp), "m"(*tscp)); + do { + before = after; + counter = *counterp; + __asm__ __volatile__ ("" : /* */ : /* */ : "memory"); + __asm__ ("ldmia %1, %M0\n" : "=r"(after): "r"(tscp), "m"(*tscp)); + } while (((unsigned) after) != ((unsigned) before)); + if ((counter & mask) < ((unsigned) before & mask)) + before += mask + 1; + return (before & ~((unsigned long long) mask)) | (counter & mask); + +#elif XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_DECREMENTER + volatile unsigned long long *const tscp = __xn_tscinfo.u.dec.tsc; + volatile unsigned *const counterp = __xn_tscinfo.u.dec.counter; + volatile unsigned *const last_cntp = __xn_tscinfo.u.dec.last_cnt; + const unsigned mask = __xn_tscinfo.u.dec.mask; + register unsigned long long after, before; + unsigned counter, last_cnt; + + __asm__ ("ldmia %1, %M0\n": "=r"(after): "r"(tscp), "m"(*tscp)); + do { + before = after; + counter = *counterp; + last_cnt = *last_cntp; + /* compiler barrier. */ + __asm__ __volatile__ ("" : /* */ : /* */ : "memory"); + __asm__ ("ldmia %1, %M0\n": "=r"(after): "r"(tscp), "m"(*tscp)); + } while (after != before); + + counter &= mask; + last_cnt &= mask; + if (counter > last_cnt) + before += mask + 1ULL; + return (before + last_cnt - counter); + +#endif /* XNARCH_ARM_TSC_TYPE == __XN_TSC_TYPE_DECREMENTER */ +} +#endif /* XNARCH_ARM_TSC_TYPE */ + +#endif /* !__KERNEL__ */ + +#endif /* !_XENO_ASM_ARM_SYSCALL_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/system.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/system.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/system.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/system.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2001,2002,2003,2004 Philippe Gerum . + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_SYSTEM_H +#define _XENO_ASM_ARM_SYSTEM_H + +#ifdef __KERNEL__ + +#include +#include +#include + +#define XNARCH_THREAD_STACKSZ 4096 + +#define xnarch_stack_size(tcb) ((tcb)->stacksize) +#define xnarch_stack_base(tcb) ((tcb)->stackbase) +#define xnarch_stack_end(tcb) ((caddr_t)(tcb)->stackbase - (tcb)->stacksize) +#define xnarch_user_task(tcb) ((tcb)->user_task) +#define xnarch_user_pid(tcb) ((tcb)->user_task->pid) + +struct xnthread; +struct task_struct; + +typedef struct xnarchtcb { /* Per-thread arch-dependent block */ + + /* Kernel mode side */ + +#ifdef CONFIG_XENO_HW_FPU + rthal_fpenv_t fpuenv; + rthal_fpenv_t *fpup; /* Pointer to the FPU backup area */ + struct task_struct *user_fpu_owner; + /* Pointer the the FPU owner in userspace: + - NULL for RT K threads, + - last_task_used_math for Linux US threads (only current or NULL when MP) + - current for RT US threads. + */ + unsigned is_root; +#define xnarch_fpu_ptr(tcb) ((tcb)->fpup) +#else /* !CONFIG_XENO_HW_FPU */ +#define xnarch_fpu_ptr(tcb) NULL +#endif /* CONFIG_XENO_HW_FPU */ + + unsigned stacksize; /* Aligned size of stack (bytes) */ + unsigned long *stackbase; /* Stack space */ + + /* User mode side */ + struct task_struct *user_task; /* Shadowed user-space task */ + struct task_struct *active_task; /* Active user-space task */ + struct mm_struct *mm; + struct mm_struct *active_mm; + struct thread_info ti; /* Holds kernel-based thread info */ + struct thread_info *tip; /* Pointer to the active thread info (ti or user->thread_info). */ +#ifdef XNARCH_HAVE_MAYDAY + struct { + unsigned long pc; + unsigned long r0; + unsigned long r6; +#ifdef CONFIG_XENO_ARM_EABI + unsigned long r7; +#endif + } mayday; +#endif + + /* Init block */ + struct xnthread *self; + int imask; + const char *name; + void (*entry)(void *cookie); + void *cookie; + +} xnarchtcb_t; + +typedef struct xnarch_fltinfo { + + unsigned exception; + struct pt_regs *regs; + +} xnarch_fltinfo_t; + +#define xnarch_fault_trap(fi) ((fi)->exception) +#define xnarch_fault_code(fi) (0) +#define xnarch_fault_pc(fi) ((fi)->regs->ARM_pc - (thumb_mode((fi)->regs) ? 2 : 4)) /* XXX ? */ +#ifndef CONFIG_XENO_HW_FPU +/* It is normal on ARM for user-space support running with a kernel compiled + with FPU support to make FPU faults, even on the context of real-time threads + which do not otherwise use FPU, so we simply ignore these faults. */ +#define xnarch_fault_fpu_p(fi) (0) +#else /* CONFIG_XENO_HW_FPU */ +static inline int xnarch_fault_fpu_p(struct xnarch_fltinfo *fi) +{ + /* This function does the same thing to decode the faulting instruct as + "call_fpe" in arch/arm/entry-armv.S */ + static unsigned copro_to_exc[16] = { + IPIPE_TRAP_UNDEFINSTR, + /* FPE */ + IPIPE_TRAP_FPU, IPIPE_TRAP_FPU, + IPIPE_TRAP_UNDEFINSTR, +#ifdef CONFIG_CRUNCH + IPIPE_TRAP_FPU, IPIPE_TRAP_FPU, IPIPE_TRAP_FPU, +#else /* !CONFIG_CRUNCH */ + IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, +#endif /* !CONFIG_CRUNCH */ + IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, +#ifdef CONFIG_VFP + IPIPE_TRAP_VFP, IPIPE_TRAP_VFP, +#else /* !CONFIG_VFP */ + IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, +#endif /* !CONFIG_VFP */ + IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, + IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, + }; + unsigned instr, exc, cp; + char *pc; + + if (fi->exception == IPIPE_TRAP_FPU) + return 1; + +#ifdef CONFIG_VFP + if (fi->exception == IPIPE_TRAP_VFP) + goto trap_vfp; +#endif + + /* When an FPU fault occurs in user-mode, it will be properly resolved + before __ipipe_dispatch_event is called. */ + if (fi->exception != IPIPE_TRAP_UNDEFINSTR || xnarch_fault_um(fi)) + return 0; + + pc = (char *) xnarch_fault_pc(fi); + if (unlikely(thumb_mode(fi->regs))) { + unsigned short thumbh, thumbl; + + thumbh = *(unsigned short *) pc; + thumbl = *((unsigned short *) pc + 1); + + if ((thumbh & 0x0000f800) < 0x0000e800) + return 0; + instr = (thumbh << 16) | thumbl; + +#ifdef CONFIG_NEON + if ((instr & 0xef000000) == 0xef000000 + || (instr & 0xff100000) == 0xf9000000) + goto trap_vfp; +#endif + } else { + instr = *(unsigned *) pc; + +#ifdef CONFIG_NEON + if ((instr & 0xfe000000) == 0xf2000000 + || (instr & 0xff100000) == 0xf4000000) + goto trap_vfp; +#endif + } + + if ((instr & 0x0c000000) != 0x0c000000) + return 0; + + cp = (instr & 0x00000f00) >> 8; +#ifdef CONFIG_IWMMXT + /* We need something equivalent to _TIF_USING_IWMMXT for Xenomai kernel + threads */ + if (cp <= 1) { + fi->exception = IPIPE_TRAP_FPU; + return 1; + } +#endif + + exc = copro_to_exc[cp]; +#ifdef CONFIG_VFP + if (exc == IPIPE_TRAP_VFP) { + trap_vfp: + /* If an exception is pending, the VFP fault is not really an + "FPU unavailable" fault, so we return undefinstr in that + case, the nucleus will let linux handle the fault. */ + if (rthal_vfp_fmrx(FPEXC) & (FPEXC_EX|FPEXC_DEX) + || rthal_vfp_fmrx(FPSCR) & FPSCR_IXE) + exc = IPIPE_TRAP_UNDEFINSTR; + else + exc = IPIPE_TRAP_VFP; + } +#endif + fi->exception = exc; + return exc != IPIPE_TRAP_UNDEFINSTR; +} +#endif /* CONFIG_XENO_HW_FPU */ +/* The following predicates are only usable over a regular Linux stack + context. */ +#define xnarch_fault_pf_p(fi) ((fi)->exception == IPIPE_TRAP_ACCESS) +#define xnarch_fault_bp_p(fi) ((current->ptrace & PT_PTRACED) && \ + ((fi)->exception == IPIPE_TRAP_BREAK)) + +#define xnarch_fault_notify(fi) (!xnarch_fault_bp_p(fi)) + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void *xnarch_alloc_host_mem (u_long bytes) +{ + if (bytes > 128*1024) + return vmalloc(bytes); + + return kmalloc(bytes,GFP_KERNEL); +} + +static inline void xnarch_free_host_mem (void *chunk, u_long bytes) +{ + if (bytes > 128*1024) + vfree(chunk); + else + kfree(chunk); +} + +static inline void *xnarch_alloc_stack_mem(u_long bytes) +{ + return kmalloc(bytes, GFP_KERNEL); +} + +static inline void xnarch_free_stack_mem(void *chunk, u_long bytes) +{ + kfree(chunk); +} + +#ifdef __cplusplus +} +#endif + +#else /* !__KERNEL__ */ + +#include +#include + +#endif /* __KERNEL__ */ + +#endif /* !_XENO_ASM_ARM_SYSTEM_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/wrappers.h relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/wrappers.h --- orig/linux-2.6.35.9//arch/arm/include/asm/xenomai/wrappers.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/include/asm/xenomai/wrappers.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_ARM_WRAPPERS_H +#define _XENO_ASM_ARM_WRAPPERS_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include +#include +#include /* Read the generic portion. */ + +#define wrap_phys_mem_prot(filp,pfn,size,prot) (prot) + +#define wrap_strncpy_from_user(dstP, srcP, n) __strncpy_from_user(dstP, srcP, n) + +#define rthal_irq_desc_status(irq) (rthal_irq_descp(irq)->status) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +extern spinlock_t irq_controller_lock; + +#define rthal_irq_desc_lock(irq) (&irq_controller_lock) +#define rthal_irq_chip_enable(irq) \ + ({ \ + int __err__ = 0; \ + if (rthal_irq_descp(irq)->chip->unmask == NULL) \ + __err__ = -ENODEV; \ + else \ + rthal_irq_descp(irq)->chip->unmask(irq); \ + __err__; \ + }) +#define rthal_irq_chip_disable(irq) \ + ({ \ + int __err__ = 0; \ + if (rthal_irq_descp(irq)->chip->mask == NULL) \ + __err__ = -ENODEV; \ + else \ + rthal_irq_descp(irq)->chip->mask(irq); \ + __err__; \ + }) +typedef irqreturn_t (*rthal_irq_host_handler_t)(int irq, + void *dev_id, + struct pt_regs *regs); +#define rthal_irq_chip_end(irq) rthal_irq_chip_enable(irq) +#define rthal_mark_irq_disabled(irq) (rthal_irq_descp(irq)->disable_depth = 1) +#define rthal_mark_irq_enabled(irq) (rthal_irq_descp(irq)->disable_depth = 0) + +extern void (*fp_init)(union fp_state *); +#else /* >= 2.6.19 */ +#if !defined(CONFIG_GENERIC_HARDIRQS) \ + || LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#define rthal_irq_chip_enable(irq) ({ rthal_irq_descp(irq)->chip->unmask(irq); 0; }) +#define rthal_irq_chip_disable(irq) ({ rthal_irq_descp(irq)->chip->mask(irq); 0; }) +#endif +#define rthal_irq_desc_lock(irq) (&rthal_irq_descp(irq)->lock) +#define rthal_irq_chip_end(irq) ({ rthal_irq_descp(irq)->ipipe_end(irq, rthal_irq_descp(irq)); 0; }) +typedef irq_handler_t rthal_irq_host_handler_t; +#define rthal_mark_irq_disabled(irq) do { \ + rthal_irq_desc_status(irq) |= IRQ_DISABLED; \ + rthal_irq_descp(irq)->depth = 1; \ + } while(0); +#define rthal_mark_irq_enabled(irq) do { \ + rthal_irq_desc_status(irq) &= ~IRQ_DISABLED; \ + rthal_irq_descp(irq)->depth = 0; \ + } while(0); +static inline void fp_init(union fp_state *state) +{ + /* FIXME: This is insufficient. */ + memset(state, 0, sizeof(*state)); +} + +#endif + +#if IPIPE_MAJOR_NUMBER == 1 && /* There is no version 0. */ \ + (IPIPE_MINOR_NUMBER < 5 || \ + (IPIPE_MINOR_NUMBER == 5 && IPIPE_PATCH_NUMBER < 3)) +#define __ipipe_mach_release_timer() \ + __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy) +#endif /* IPIPE < 1.5-03 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) +#define FPEXC_EN FPEXC_ENABLE +#endif + +#if !defined(__IPIPE_FEATURE_UNMASKED_CONTEXT_SWITCH) && defined(TIF_MMSWITCH_INT) +/* + * Legacy ARM patches might provide unmasked context switch support + * without defining the common config option; force this support in. + */ +#define CONFIG_IPIPE_UNMASKED_CONTEXT_SWITCH 1 +#define CONFIG_XENO_HW_UNLOCKED_SWITCH 1 +#endif + +#endif /* _XENO_ASM_ARM_WRAPPERS_H */ + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//arch/arm/Kconfig relase/linux-2.6.35.9//arch/arm/Kconfig --- orig/linux-2.6.35.9//arch/arm/Kconfig 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/Kconfig 2011-03-15 10:56:25.869702441 +0100 @@ -271,6 +271,8 @@ config ARCH_AT91 bool "Atmel AT91" + select GENERIC_TIME if IPIPE + select GENERIC_CLOCKEVENTS if IPIPE select ARCH_REQUIRE_GPIOLIB select HAVE_CLK help @@ -937,6 +939,13 @@ config ARM_TIMER_SP804 bool +if IPIPE +config IPIPE_ARM_KUSER_TSC + bool + select GENERIC_TIME + default y if ARCH_AT91 || ARM_TIMER_SP804 || ARCH_IXP4XX || ARCH_MXC || ARCH_OMAP || PLAT_PXA || PLAT_S3C24XX || ARCH_SA1100 +endif + source arch/arm/mm/Kconfig config IWMMXT @@ -1192,6 +1201,8 @@ accounting to be spread across the timer interval, preventing a "thundering herd" at every timer tick. +source kernel/ipipe/Kconfig + source kernel/Kconfig.preempt config HZ diff -urN orig/linux-2.6.35.9//arch/arm/kernel/entry-armv.S relase/linux-2.6.35.9//arch/arm/kernel/entry-armv.S --- orig/linux-2.6.35.9//arch/arm/kernel/entry-armv.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/entry-armv.S 2011-03-15 10:56:25.881702441 +0100 @@ -4,6 +4,7 @@ * Copyright (C) 1996,1997,1998 Russell King. * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) * nommu support by Hyok S. Choi (hyok.choi@samsung.com) + * Copyright (C) 2005 Stelian Pop. * * 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 @@ -30,13 +31,18 @@ */ .macro irq_handler get_irqnr_preamble r5, lr -1: get_irqnr_and_base r0, r6, r5, lr +1: get_irqnr_and_base r1, r6, r5, lr + movne r0, r1 movne r1, sp @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ adrne lr, BSYM(1b) +#ifdef CONFIG_IPIPE + bne __ipipe_grab_irq +#else bne asm_do_IRQ +#endif #ifdef CONFIG_SMP /* @@ -45,18 +51,45 @@ * this macro assumes that irqstat (r6) and base (r5) are * preserved from get_irqnr_and_base above */ - test_for_ipi r0, r6, r5, lr + test_for_ipi r1, r6, r5, lr movne r0, sp adrne lr, BSYM(1b) +#ifdef CONFIG_IPIPE + bne __ipipe_grab_ipi +#else bne do_IPI +#endif #ifdef CONFIG_LOCAL_TIMERS - test_for_ltirq r0, r6, r5, lr + test_for_ltirq r1, r6, r5, lr movne r0, sp adrne lr, BSYM(1b) +#ifdef CONFIG_IPIPE + bne __ipipe_grab_localtimer +#else bne do_local_timer #endif #endif +#endif +#ifdef CONFIG_IPIPE +#if !defined(CONFIG_SMP) + ldr r0, =ipipe_percpu_domain + ldr r1, =ipipe_root + ldr r0, [r0] + cmp r0, r1 +#if __GNUC__ >= 4 + ldreq r0, =__ipipe_root_status +#else /* gcc < 4 */ + ldreq r0, =__ipipe_root_status_addr + ldreq r0, [r0] +#endif /* gcc < 4 */ + ldreq r0, [r0] + tsteq r0, #1 +#else /* CONFIG_SMP */ + bl __ipipe_check_root_interruptible + cmp r0, #1 +#endif /* CONFIG_SMP */ +#endif /* CONFIG_IPIPE */ .endm @@ -78,6 +111,21 @@ mov r1, #\reason .endm + .macro fcse_dabt_mva_to_va +#ifdef CONFIG_ARM_FCSE + @ + @ If FCSE is enabled the data abort fault address must be + @ converted from MVA to VA. This must happen before the irqs are + @ enabled if PREEMPT is enabled, as context switches may + @ change the FCSE pid. + @ + mrc p15, 0, r2, c13, c0, 0 + eor r2, r2, r0 + tst r2, #0xfe000000 + moveq r0, r2 +#endif + .endm + __pabt_invalid: inv_entry BAD_PREFETCH b common_invalid @@ -191,6 +239,7 @@ #else bl CPU_DABORT_HANDLER #endif + fcse_dabt_mva_to_va @ @ set desired IRQ state, then call main handler @@ -221,14 +270,25 @@ #endif #ifdef CONFIG_PREEMPT get_thread_info tsk +#ifndef CONFIG_IPIPE ldr r8, [tsk, #TI_PREEMPT] @ get preempt count add r7, r8, #1 @ increment it str r7, [tsk, #TI_PREEMPT] #endif +#endif irq_handler +#ifdef CONFIG_IPIPE + ldrne r4, [sp, #S_PSR] @ irqs are already disabled + bne __ipipe_fast_svc_irq_exit +#endif + #ifdef CONFIG_PREEMPT +#ifndef CONFIG_IPIPE str r8, [tsk, #TI_PREEMPT] @ restore preempt count +#else + ldr r8, [tsk, #TI_PREEMPT] +#endif ldr r0, [tsk, #TI_FLAGS] @ get flags teq r8, #0 @ if preempt count != 0 movne r0, #0 @ force flags to 0 @@ -240,6 +300,9 @@ tst r4, #PSR_I_BIT bleq trace_hardirqs_on #endif +#ifdef CONFIG_IPIPE +__ipipe_fast_svc_irq_exit: +#endif svc_exit r4 @ return from exception UNWIND(.fnend ) ENDPROC(__irq_svc) @@ -249,12 +312,16 @@ #ifdef CONFIG_PREEMPT svc_preempt: mov r8, lr +#ifndef CONFIG_IPIPE 1: bl preempt_schedule_irq @ irq en/disable is done inside +#else /* CONFIG_IPIPE */ +1: bl __ipipe_preempt_schedule_irq @ irq en/disable is done inside +#endif /* CONFIG_IPIPE */ ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED moveq pc, r8 @ go again b 1b -#endif +#endif /* CONFIG_PREEMPT */ .align 5 __und_svc: @@ -267,6 +334,15 @@ svc_entry #endif +#ifdef CONFIG_IPIPE + mov r4, r2 + mov r0, #7 @ r0 = IPIPE_TRAP_UNDEFINSTR + mov r1, sp @ r1 = ®s + bl __ipipe_dispatch_event @ branch to trap handler + cmp r0, #0 + bne 1f + mov r2, r4 +#endif /* CONFIG_IPIPE */ @ @ call emulation code, which returns using r9 if it has emulated @ the instruction, or the more conventional lr if we are to treat @@ -432,6 +508,7 @@ #else bl CPU_DABORT_HANDLER #endif + fcse_dabt_mva_to_va @ @ IRQs on, then call the main handler @@ -450,13 +527,21 @@ get_thread_info tsk #ifdef CONFIG_PREEMPT +#ifndef CONFIG_IPIPE ldr r8, [tsk, #TI_PREEMPT] @ get preempt count add r7, r8, #1 @ increment it str r7, [tsk, #TI_PREEMPT] #endif +#endif irq_handler +#ifdef CONFIG_IPIPE + beq __ipipe_usr_irq_continue + slow_restore_user_regs @ Fast exit path over non-root domains +__ipipe_usr_irq_continue: +#endif #ifdef CONFIG_PREEMPT +#ifndef CONFIG_IPIPE ldr r0, [tsk, #TI_PREEMPT] str r8, [tsk, #TI_PREEMPT] teq r0, r7 @@ -464,6 +549,7 @@ THUMB( movne r0, #0 ) THUMB( strne r0, [r0] ) #endif +#endif mov why, #0 b ret_to_user @@ -476,6 +562,17 @@ __und_usr: usr_entry +#ifdef CONFIG_IPIPE + mov r0, #7 @ r0 = IPIPE_TRAP_UNDEFINSTR + mov r1, sp @ r1 = ®s + mov r4, r2 + mov r5, r3 + bl __ipipe_dispatch_event @ branch to trap handler + cmp r0, #0 + bne ret_from_exception + mov r2, r4 + mov r3, r5 +#endif /* CONFIG_IPIPE */ @ @ fall through to the emulation code, which returns using r9 if @ it has emulated the instruction, or the more conventional lr @@ -711,6 +808,20 @@ ENTRY(ret_from_exception) UNWIND(.fnstart ) UNWIND(.cantunwind ) +#ifdef CONFIG_IPIPE +#if !defined(CONFIG_SMP) + ldr r0, =ipipe_percpu_domain + ldr r1, =ipipe_root + ldr r0, [r0] + cmp r0, r1 +#else /* CONFIG_SMP */ + bl __ipipe_check_root + cmp r0, #1 +#endif /* CONFIG_SMP */ + beq 1f + slow_restore_user_regs @ Fast exit path over non-root domains +1: +#endif /* CONFIG_IPIPE */ get_thread_info tsk mov why, #0 b ret_to_user @@ -748,7 +859,11 @@ add r4, r2, #TI_CPU_SAVE ldr r0, =thread_notify_head mov r1, #THREAD_NOTIFY_SWITCH +#ifndef CONFIG_IPIPE bl atomic_notifier_call_chain +#else /* !CONFIG_IPIPE */ + bl __ipipe_switch_to_notifier_call_chain +#endif /* !CONFIG_IPIPE */ THUMB( mov ip, r4 ) mov r0, r5 ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously @@ -799,6 +914,50 @@ #endif .endm +#ifdef CONFIG_IPIPE +/* + I-pipe tsc area, here we store data shared with user-space for + tsc-emulation. If CONFIG_IPIPE_ARM_KUSER_TSC is enabled + __ipipe_kuser_get_tsc will be overwritten with the real TSC + emulation code. +*/ + .globl __ipipe_tsc_area + .equ __ipipe_tsc_area, CONFIG_VECTORS_BASE + 0x1000 + __ipipe_tsc_area_start - __kuser_helper_end + +#ifdef CONFIG_IPIPE_ARM_KUSER_TSC + .globl __ipipe_tsc_addr + .equ __ipipe_tsc_addr, CONFIG_VECTORS_BASE + 0x1000 + .LCcntr_addr - __kuser_helper_end + + .globl __ipipe_tsc_get + .equ __ipipe_tsc_get, CONFIG_VECTORS_BASE + 0x1000 + __ipipe_kuser_get_tsc - __kuser_helper_end +#endif + + .align 5 + .globl __ipipe_tsc_area_start +__ipipe_tsc_area_start: + .rep 3 + .word 0 + .endr + +#ifdef CONFIG_IPIPE_ARM_KUSER_TSC + .rep 4 + .word 0 + .endr +.LCcntr_addr: + .word 0 + + .align 5 +__ipipe_kuser_get_tsc: + nop + mov r0, #0 + mov r1, #0 + usr_ret lr + .rep 20 + .word 0 + .endr +#endif +#endif + .align 5 .globl __kuser_helper_start __kuser_helper_start: @@ -832,7 +991,7 @@ * * #define __kernel_dmb() \ * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "r0", "lr","cc" ) + * : : : "r0", "lr","cc" ) */ __kuser_memory_barrier: @ 0xffff0fa0 @@ -1000,7 +1159,7 @@ * #define __kernel_get_tls() \ * ({ register unsigned int __val asm("r0"); \ * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \ - * : "=r" (__val) : : "lr","cc" ); \ + * : "=r" (__val) : : "lr","cc" ); \ * __val; }) */ diff -urN orig/linux-2.6.35.9//arch/arm/kernel/entry-common.S relase/linux-2.6.35.9//arch/arm/kernel/entry-common.S --- orig/linux-2.6.35.9//arch/arm/kernel/entry-common.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/entry-common.S 2011-03-15 10:56:25.881702441 +0100 @@ -2,6 +2,7 @@ * linux/arch/arm/kernel/entry-common.S * * Copyright (C) 2000 Russell King + * Copyright (C) 2005 Stelian Pop. * * 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 @@ -34,6 +35,13 @@ arch_ret_to_user r1, lr restore_user_regs fast = 1, offset = S_OFF + +#ifdef CONFIG_IPIPE +__ipipe_fast_exit_syscall: + disable_irq @ disable interrupts + slow_restore_user_regs +#endif /* CONFIG_IPIPE */ + UNWIND(.fnend ) /* @@ -46,12 +54,14 @@ bne work_resched tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME beq no_work_pending + enable_irq_cond mov r0, sp @ 'regs' mov r2, why @ 'syscall' bl do_notify_resume b ret_slow_syscall @ Check work again work_resched: + enable_irq_cond bl schedule /* * "slow" syscall return path. "why" tells us if this was a real syscall. @@ -63,16 +73,14 @@ tst r1, #_TIF_WORK_MASK bne work_pending no_work_pending: - /* perform architecture specific actions before user return */ - arch_ret_to_user r1, lr - - restore_user_regs fast = 0, offset = 0 + slow_restore_user_regs ENDPROC(ret_to_user) /* * This is how we return from a fork. */ ENTRY(ret_from_fork) + enable_irq_cond bl schedule_tail get_thread_info tsk ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing @@ -255,9 +263,13 @@ #endif enable_irq +#ifndef CONFIG_IPIPE get_thread_info tsk adr tbl, sys_call_table @ load syscall table pointer ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing +#else /* CONFIG_IPIPE */ + adr tbl, sys_call_table @ load syscall table pointer +#endif /* CONFIG_IPIPE */ #if defined(CONFIG_OABI_COMPAT) /* @@ -274,6 +286,17 @@ eor scno, scno, #__NR_SYSCALL_BASE @ check OS number #endif +#ifdef CONFIG_IPIPE + mov r1, sp + mov r0, scno + bl __ipipe_syscall_root + cmp r0, #0 + get_thread_info tsk + blt ret_slow_syscall + bgt __ipipe_fast_exit_syscall + ldm sp, { r0 - r3 } + ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing +#endif /* CONFIG_IPIPE */ stmdb sp!, {r4, r5} @ push fifth and sixth args tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? bne __sys_trace @@ -322,6 +345,9 @@ __cr_alignment: .word cr_alignment #endif +#ifdef CONFIG_IPIPE + .word __ipipe_syscall_root +#endif .ltorg /* @@ -477,3 +503,28 @@ #endif + +#ifdef CONFIG_FRAME_POINTER + + .text + .align 0 + .type arm_return_addr %function + .global arm_return_addr + +arm_return_addr: + mov ip, r0 + mov r0, fp +3: + cmp r0, #0 + beq 1f @ frame list hit end, bail + cmp ip, #0 + beq 2f @ reached desired frame + ldr r0, [r0, #-12] @ else continue, get next fp + sub ip, ip, #1 + b 3b +2: + ldr r0, [r0, #-4] @ get target return address +1: + mov pc, lr + +#endif diff -urN orig/linux-2.6.35.9//arch/arm/kernel/entry-header.S relase/linux-2.6.35.9//arch/arm/kernel/entry-header.S --- orig/linux-2.6.35.9//arch/arm/kernel/entry-header.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/entry-header.S 2011-03-15 10:56:25.881702441 +0100 @@ -165,6 +165,12 @@ .endm #endif /* !CONFIG_THUMB2_KERNEL */ + .macro slow_restore_user_regs + /* perform architecture specific actions before user return */ + arch_ret_to_user r1, lr + restore_user_regs fast = 0, offset = 0 + .endm + /* * These are the registers used in the syscall handler, and allow us to * have in theory up to 7 arguments to a function - r0 to r6. diff -urN orig/linux-2.6.35.9//arch/arm/kernel/ipipe.c relase/linux-2.6.35.9//arch/arm/kernel/ipipe.c --- orig/linux-2.6.35.9//arch/arm/kernel/ipipe.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/ipipe.c 2011-03-15 10:56:25.881702441 +0100 @@ -0,0 +1,676 @@ +/* -*- linux-c -*- + * linux/arch/arm/kernel/ipipe.c + * + * Copyright (C) 2002-2005 Philippe Gerum. + * Copyright (C) 2004 Wolfgang Grandegger (Adeos/arm port over 2.4). + * Copyright (C) 2005 Heikki Lindholm (PowerPC 970 fixes). + * Copyright (C) 2005 Stelian Pop. + * Copyright (C) 2006-2008 Gilles Chanteperdrix. + * Copyright (C) 2010 Philippe Gerum (SMP port). + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; 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. + * + * Architecture-dependent I-PIPE support for ARM. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Next tick date (timebase value). */ +DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); +DEFINE_PER_CPU(struct mm_struct *,ipipe_active_mm); +EXPORT_PER_CPU_SYMBOL(ipipe_active_mm); +#ifdef __IPIPE_FEATURE_PIC_MUTE +__ipipe_irqbits_t __ipipe_irqbits; +IPIPE_DEFINE_SPINLOCK(__ipipe_irqbits_lock); +#endif /* __IPIPE_FEATURE_PIC_MUTE */ + +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); + +static void __ipipe_do_IRQ(unsigned irq, void *cookie); + +#ifdef CONFIG_SMP + +struct __ipipe_vnmidata { + void (*fn)(void *); + void *arg; + cpumask_t cpumask; +}; + +static struct __ipipe_vnmislot { + ipipe_spinlock_t lock; + struct __ipipe_vnmidata *data; + ipipe_rwlock_t data_lock; +} __ipipe_vnmi __cacheline_aligned_in_smp = { + .lock = IPIPE_SPIN_LOCK_UNLOCKED, + .data = NULL, + .data_lock = IPIPE_RW_LOCK_UNLOCKED, +}; + +void __ipipe_init_platform(void) +{ + unsigned int virq, _virq; + + for (virq = IPIPE_FIRST_IPI; virq <= IPIPE_LAST_IPI; virq++) { + _virq = ipipe_alloc_virq(); + if (virq != _virq) + panic("I-pipe: cannot reserve virq #%d (got #%d)\n", + virq, _virq); + } + + __ipipe_mach_init_platform(); +} + +void __ipipe_stall_root(void) +{ + unsigned long flags; + + local_irq_save_hw(flags); + set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_stall_root); + +unsigned long __ipipe_test_and_stall_root(void) +{ + unsigned long flags; + int x; + + local_irq_save_hw(flags); + x = test_and_set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); + local_irq_restore_hw(flags); + + return x; +} +EXPORT_SYMBOL(__ipipe_test_and_stall_root); + +unsigned long __ipipe_test_root(void) +{ + unsigned long flags; + int x; + + local_irq_save_hw(flags); + x = test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); + local_irq_restore_hw(flags); + + return x; +} +EXPORT_SYMBOL(__ipipe_test_root); + +void __ipipe_do_vnmi(unsigned int irq, void *cookie) +{ + int cpu = ipipe_processor_id(); + struct __ipipe_vnmidata *data; + + read_lock(&__ipipe_vnmi.data_lock); + + data = __ipipe_vnmi.data; + if (likely(data && cpumask_test_cpu(cpu, &data->cpumask))) { + data->fn(data->arg); + cpu_clear(cpu, data->cpumask); + } + + read_unlock(&__ipipe_vnmi.data_lock); +} + +static inline void +hook_internal_ipi(struct ipipe_domain *ipd, int virq, + void (*handler)(unsigned int irq, void *cookie)) +{ + ipd->irqs[virq].acknowledge = NULL; + ipd->irqs[virq].handler = handler; + ipd->irqs[virq].cookie = NULL; + /* Immediately handle in the current domain but *never* pass */ + ipd->irqs[virq].control = + IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK; +} + +void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd) +{ + hook_internal_ipi(ipd, IPIPE_CRITICAL_IPI, __ipipe_do_critical_sync); + hook_internal_ipi(ipd, IPIPE_SERVICE_VNMI, __ipipe_do_vnmi); +} + +cpumask_t __ipipe_set_irq_affinity(unsigned irq, cpumask_t cpumask) +{ + cpumask_t oldmask; + + if (irq_to_desc(irq)->chip->set_affinity == NULL) + return CPU_MASK_NONE; + + if (cpus_empty(cpumask)) + return CPU_MASK_NONE; /* Return mask value -- no change. */ + + cpus_and(cpumask, cpumask, cpu_online_map); + if (cpus_empty(cpumask)) + return CPU_MASK_NONE; /* Error -- bad mask value or non-routable IRQ. */ + + cpumask_copy(&oldmask, irq_to_desc(irq)->affinity); + irq_to_desc(irq)->chip->set_affinity(irq, &cpumask); + + return oldmask; +} + +void __ipipe_send_vnmi(void (*fn)(void *), cpumask_t cpumask, void *arg) +{ + struct __ipipe_vnmidata data; + unsigned long flags; + int cpu; + + data.fn = fn; + data.arg = arg; + data.cpumask = cpumask; + + while (!spin_trylock_irqsave(&__ipipe_vnmi.lock, flags)) { + if (irqs_disabled_hw()) + __ipipe_do_vnmi(IPIPE_SERVICE_VNMI, NULL); + cpu_relax(); + } + + cpu = ipipe_processor_id(); + cpu_clear(cpu, data.cpumask); + if (cpus_empty(data.cpumask)) { + spin_unlock_irqrestore(&__ipipe_vnmi.lock, flags); + return; + } + + write_lock(&__ipipe_vnmi.data_lock); + __ipipe_vnmi.data = &data; + write_unlock(&__ipipe_vnmi.data_lock); + + __ipipe_send_ipi(IPIPE_SERVICE_VNMI, data.cpumask); + while (!cpus_empty(data.cpumask)) + cpu_relax(); + + write_lock(&__ipipe_vnmi.data_lock); + __ipipe_vnmi.data = NULL; + write_unlock(&__ipipe_vnmi.data_lock); + + spin_unlock_irqrestore(&__ipipe_vnmi.lock, flags); +} +EXPORT_SYMBOL_GPL(__ipipe_send_vnmi); + +static void __ipipe_relay_ext_hrtimer(unsigned int irq, void *cookie) +{ + int cpu = ipipe_processor_id(); + /* + * We are running over the root domain here, so hw IRQs are + * ON. Therefore, we have to use the atomic form of + * __ipipe_schedule_irq_root(). Don't mess with that, or you + * may lose interrupt notifications. + */ + ipipe_schedule_irq_root(__ipipe_mach_ext_hrtimer(cpu)); +} + +#endif /* CONFIG_SMP */ + +/* + * ipipe_trigger_irq() -- Push the interrupt at front of the pipeline + * just like if it has been actually received from a hw source. Also + * works for virtual interrupts. + */ +int ipipe_trigger_irq(unsigned irq) +{ + unsigned long flags; + +#ifdef CONFIG_IPIPE_DEBUG + if (irq >= IPIPE_NR_IRQS) + return -EINVAL; + if (ipipe_virtual_irq_p(irq)) { + if (!test_bit(irq - IPIPE_VIRQ_BASE, + &__ipipe_virtual_irq_map)) + return -EINVAL; + } else if (irq_to_desc(irq) == NULL) + return -EINVAL; +#endif + local_irq_save_hw(flags); + __ipipe_handle_irq(irq, NULL); + local_irq_restore_hw(flags); + + return 1; +} + +int ipipe_get_sysinfo(struct ipipe_sysinfo *info) +{ + info->sys_nr_cpus = num_online_cpus(); + info->sys_cpu_freq = __ipipe_cpu_freq; + info->sys_hrtimer_irq = __ipipe_mach_hrtimer_irq; + info->sys_hrtimer_freq = __ipipe_mach_hrtimer_freq; + info->sys_hrclock_freq = __ipipe_mach_hrclock_freq; + __ipipe_mach_get_tscinfo(&info->arch_tsc); + + return 0; +} + +static void __ipipe_ack_irq(unsigned irq, struct irq_desc *desc) +{ + desc->ipipe_ack(irq, desc); +} + +static void __maybe_unused __ipipe_ack_timerirq(unsigned int irq, struct irq_desc *desc) +{ + desc->ipipe_ack(irq, desc); + __ipipe_mach_acktimer(); + desc->ipipe_end(irq, desc); +} + +void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + unsigned long flags; + irq_to_desc(irq)->status &= ~IRQ_DISABLED; + +#ifdef __IPIPE_FEATURE_PIC_MUTE + spin_lock_irqsave(&__ipipe_irqbits_lock, flags); + if (ipd == &ipipe_root) + __ipipe_irqbits[irq / BITS_PER_LONG] + |= (1 << (irq % BITS_PER_LONG)); + else + __ipipe_irqbits[irq / BITS_PER_LONG] + &= ~(1 << (irq % BITS_PER_LONG)); + spin_unlock_irqrestore(&__ipipe_irqbits_lock, flags); + + __ipipe_mach_enable_irqdesc(ipd, irq); +#else + (void) flags; +#endif /* __IPIPE_FEATURE_PIC_MUTE */ +} +EXPORT_SYMBOL(__ipipe_enable_irqdesc); + +#ifdef __IPIPE_FEATURE_PIC_MUTE +void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + unsigned long flags; + + __ipipe_mach_disable_irqdesc(ipd, irq); + + spin_lock_irqsave(&__ipipe_irqbits_lock, flags); + if (ipd == &ipipe_root || !ipipe_root.irqs[irq].handler) + __ipipe_irqbits[irq / BITS_PER_LONG] + &= ~(1 << (irq % BITS_PER_LONG)); + spin_unlock_irqrestore(&__ipipe_irqbits_lock, flags); + +} +EXPORT_SYMBOL(__ipipe_disable_irqdesc); +EXPORT_SYMBOL(ipipe_mute_pic); +EXPORT_SYMBOL(ipipe_unmute_pic); +#endif /* __IPIPE_FEATURE_PIC_MUTE */ + +/* + * __ipipe_enable_pipeline() -- We are running on the boot CPU, hw + * interrupts are off, and secondary CPUs are still lost in space. + */ +void __ipipe_enable_pipeline(void) +{ + unsigned long flags; + unsigned int irq; + +#ifdef CONFIG_CPU_ARM926T + /* + * We do not want "wfi" to be called in arm926ejs based + * processor, as this causes Linux to disable the I-cache + * when idle. + */ + disable_hlt(); +#endif + flags = ipipe_critical_enter(NULL); + + /* First, virtualize all interrupts from the root domain. */ + + for (irq = 0; irq < NR_IRQS; irq++) + ipipe_virtualize_irq(ipipe_root_domain, + irq, + (ipipe_irq_handler_t)__ipipe_mach_doirq(irq), + NULL, __ipipe_mach_ackirq(irq), + IPIPE_HANDLE_MASK | IPIPE_PASS_MASK); +#ifdef CONFIG_SMP + /* + * If the external hrtimer IRQ is remapped internally to a + * common localtimer IRQ number, we have to relay the virtual + * localtimer interrupt reaching the root stage to the proper + * external IRQ handlers defined by the kernel. + * + * NOTE: we don't make any assumption regarding whether the + * virtual localtimer interrupt should be acked or not, so we + * set the ack handler as the platform-specific + * __ipipe_mach_ackirq() tells us, like for any other + * interrupt. + */ + if (__ipipe_mach_ext_hrtimer(0) != __ipipe_mach_hrtimer_irq) + ipipe_virtualize_irq(ipipe_root_domain, + __ipipe_mach_hrtimer_irq, + __ipipe_relay_ext_hrtimer, + NULL, __ipipe_mach_ackirq(__ipipe_mach_hrtimer_irq), + IPIPE_HANDLE_MASK); +#endif + + ipipe_critical_exit(flags); +} + +#ifdef CONFIG_SMP +asmlinkage int __ipipe_check_root(void) +{ + return ipipe_root_domain_p; +} + +asmlinkage int __ipipe_check_root_interruptible(void) +{ + return __ipipe_root_domain_p && !irqs_disabled(); +} +#endif + +__kprobes int +__ipipe_switch_to_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + ret = atomic_notifier_call_chain(nh, val, v); + __local_irq_restore_nosync(flags); + + return ret; +} + +asmlinkage int __ipipe_syscall_root(unsigned long scno, struct pt_regs *regs) +{ + struct ipipe_percpu_domain_data *p; + unsigned long orig_r7; + int ret = 0; + + WARN_ON_ONCE(irqs_disabled_hw()); + + /* + * We use r7 to pass the syscall number to the other domains. + */ + orig_r7 = regs->ARM_r7; + regs->ARM_r7 = __NR_SYSCALL_BASE + scno; + + /* + * This routine either returns: + * 0 -- if the syscall is to be passed to Linux; + * >0 -- if the syscall should not be passed to Linux, and no + * tail work should be performed; + * <0 -- if the syscall should not be passed to Linux but the + * tail work has to be performed (for handling signals etc). + */ + + if (!__ipipe_syscall_watched_p(current, regs->ARM_r7) || + !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) + goto out; + + ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs); + + local_irq_disable_hw(); + + /* + * This is the end of the syscall path, so we may + * safely assume a valid Linux task stack here. + */ + if (current->ipipe_flags & PF_EVTRET) { + current->ipipe_flags &= ~PF_EVTRET; + __ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs); + } + + if (!__ipipe_root_domain_p) + ret = -1; + else { + p = ipipe_root_cpudom_ptr(); + if (__ipipe_ipending_p(p)) + __ipipe_sync_pipeline(); + } + + local_irq_enable_hw(); +out: + regs->ARM_r7 = orig_r7; + + return -ret; +} + +/* + * __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic + * interrupt protection log is maintained here for each domain. Hw + * interrupts are off on entry. + */ +void __ipipe_handle_irq(int irq, struct pt_regs *regs) +{ + struct ipipe_domain *this_domain, *next_domain; + struct list_head *head, *pos; + struct irq_desc *desc; + int m_ack; + + /* Software-triggered IRQs do not need any ack. */ + m_ack = (regs == NULL); + +#ifdef CONFIG_IPIPE_DEBUG + if (unlikely(irq >= IPIPE_NR_IRQS) || + (!ipipe_virtual_irq_p(irq) && irq_to_desc(irq) == NULL)) { + printk(KERN_ERR "I-pipe: spurious interrupt %d\n", irq); + return; + } +#endif + this_domain = ipipe_current_domain; + if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) + head = &this_domain->p_link; + else { + head = __ipipe_pipeline.next; + next_domain = list_entry(head, struct ipipe_domain, p_link); + if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { + if (!m_ack && next_domain->irqs[irq].acknowledge) { + desc = ipipe_virtual_irq_p(irq) ? NULL : irq_to_desc(irq); + next_domain->irqs[irq].acknowledge(irq, desc); + } + __ipipe_dispatch_wired(next_domain, irq); + return; + } + } + + /* Ack the interrupt. */ + + pos = head; + while (pos != &__ipipe_pipeline) { + next_domain = list_entry(pos, struct ipipe_domain, p_link); + prefetch(next_domain); + /* + * For each domain handling the incoming IRQ, mark it as + * pending in its log. + */ + if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) { + /* + * Domains that handle this IRQ are polled for + * acknowledging it by decreasing priority order. The + * interrupt must be made pending _first_ in the + * domain's status flags before the PIC is unlocked. + */ + __ipipe_set_irq_pending(next_domain, irq); + + if (!m_ack && next_domain->irqs[irq].acknowledge) { + desc = ipipe_virtual_irq_p(irq) ? NULL : irq_to_desc(irq); + next_domain->irqs[irq].acknowledge(irq, desc); + m_ack = 1; + } + } + + /* + * If the domain does not want the IRQ to be passed down the + * interrupt pipe, exit the loop now. + */ + if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control)) + break; + + pos = next_domain->p_link.next; + } + + /* + * If the interrupt preempted the head domain, then do not + * even try to walk the pipeline, unless an interrupt is + * pending for it. + */ + if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) && + !__ipipe_ipending_p(ipipe_head_cpudom_ptr())) + return; + + /* + * Now walk the pipeline, yielding control to the highest + * priority domain that has pending interrupt(s) or + * immediately to the current domain if the interrupt has been + * marked as 'sticky'. This search does not go beyond the + * current domain in the pipeline. + */ + __ipipe_walk_pipeline(head); +} + +void __ipipe_exit_irq(struct pt_regs *regs) +{ + if (user_mode(regs) && + (current->ipipe_flags & PF_EVTRET) != 0) { + /* + * Testing for user_regs() eliminates foreign stack + * contexts, including from careless domains which did + * not set the foreign stack bit (foreign stacks are + * always kernel-based). + */ + current->ipipe_flags &= ~PF_EVTRET; + __ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs); + } +} + +asmlinkage void __ipipe_grab_irq(int irq, struct pt_regs *regs) +{ + int cpu = ipipe_processor_id(); +#ifdef irq_finish + /* AT91 specific workaround */ + irq_finish(irq); +#endif /* irq_finish */ + /* + * Some SMP platforms may remap different per-CPU local timer + * interrupts onto a single (usually virtual) IRQ, so that the + * I-pipe advertises the same local timer IRQ number to the + * client domains, regardless of the CPU. So we first check + * whether we received an external hrtimer IRQ for the current + * CPU, then remap it to its local timer number if so - most + * platforms won't change this value though. + */ + if (likely(__ipipe_mach_ext_hrtimer(cpu) == irq)) { + __ipipe_mach_hrtimer_debug(irq); + irq = __ipipe_mach_localtimer(irq); + /* + * Given our deferred dispatching model for regular IRQs, we + * only record CPU regs for the last timer interrupt, so that + * the timer handler charges CPU times properly. It is assumed + * that other interrupt handlers don't actually care for such + * information. + */ + __raw_get_cpu_var(__ipipe_tick_regs).ARM_cpsr = + (ipipe_root_domain_p + ? regs->ARM_cpsr + : regs->ARM_cpsr | PSR_I_BIT); + __raw_get_cpu_var(__ipipe_tick_regs).ARM_pc = regs->ARM_pc; + } + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + ipipe_trace_begin(regs->ARM_ORIG_r0); +#endif + + __ipipe_handle_irq(irq, regs); + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + ipipe_trace_end(regs->ARM_ORIG_r0); +#endif + __ipipe_exit_irq(regs); +} + +static void __ipipe_do_IRQ(unsigned irq, void *cookie) +{ + asm_do_IRQ(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); +} + +asmlinkage int __ipipe_dispatch_trap(int trap, struct pt_regs *regs) +{ + return ipipe_trap_notify(trap, regs); +} + +#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_IPIPE_DEBUG) + +void printascii(const char *s); + +static IPIPE_DEFINE_SPINLOCK(serial_debug_lock); + +void __ipipe_serial_debug(const char *fmt, ...) +{ + unsigned long flags; + char buf[128]; + va_list ap; + int n; + + va_start(ap, fmt); + n = vsnprintf(buf, sizeof(buf) - 2, fmt, ap); + va_end(ap); + + if (n > 0 && buf[n - 1] == '\n') { + buf[n] = '\r'; + buf[n+1] = '\0'; + } + + spin_lock_irqsave(&serial_debug_lock, flags); + printascii(buf); + spin_unlock_irqrestore(&serial_debug_lock, flags); +} + +#ifndef CONFIG_SERIAL_8250_CONSOLE +EXPORT_SYMBOL_GPL(__ipipe_serial_debug); +#endif + +#endif + +EXPORT_SYMBOL_GPL(show_stack); +EXPORT_SYMBOL_GPL(init_mm); +#ifndef MULTI_CPU +EXPORT_SYMBOL_GPL(cpu_do_switch_mm); +#endif +EXPORT_SYMBOL_GPL(__check_kvm_seq); +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +EXPORT_SYMBOL_GPL(tasklist_lock); +#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */ + +#ifdef CONFIG_SPARSE_IRQ +EXPORT_SYMBOL_GPL(irq_to_desc); +#else +EXPORT_SYMBOL_GPL(irq_desc); +#endif + +#ifdef CONFIG_CPU_HAS_ASID +EXPORT_SYMBOL_GPL(__new_context); +EXPORT_SYMBOL_GPL(cpu_last_asid); +#endif /* CONFIG_CPU_HAS_ASID */ diff -urN orig/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc_asm.S relase/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc_asm.S --- orig/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc_asm.S 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc_asm.S 2011-03-15 10:56:25.881702441 +0100 @@ -0,0 +1,165 @@ +#include +#include +#include + + .macro usr_ret, reg +#ifdef CONFIG_ARM_THUMB + bx \reg +#else + mov pc, \reg +#endif + .endm + + .macro myldrd, rd1, rd2, rtmp, label +#if __LINUX_ARM_ARCH__ < 5 + adr \rtmp, \label + ldm \rtmp, { \rd1, \rd2 } +#else + ldrd \rd1, \label +#endif + .endm + +/* + We use the same mechanism as Linux user helpers to store + variables and functions related to TSC emulation, so that they + can also be used in user-space. + + The function ipipe_tsc_register will copy the proper + implemntation to the vectors page. We repeat the data area so + that the PC relative operations are computed correctly. +*/ + + .align 5 +.LCfr32_last_tsc: + .rep 7 + .word 0 + .endr +.LCfr32_cntr_addr: + .word 0 + + .align 5 + .globl __ipipe_freerunning_32 +__ipipe_freerunning_32: + ldr r0, .LCfr32_cntr_addr +/* User-space entry-point: r0 is the hardware counter virtual address */ + myldrd r2, r3, r1, .LCfr32_last_tsc +#ifndef CONFIG_CPU_ENDIAN_BE8 +/* Little endian */ + ldr r0, [r0] + cmp r2, r0 + adc r1, r3, #0 +#else /* Big endian */ + ldr r1, [r0] + cmp r3, r1 + adc r0, r2, #0 +#endif /* Big endian */ + usr_ret lr + + .align 5 +.LCfrcd32_last_tsc: + .rep 7 + .word 0 + .endr +.LCfrcd32_cntr_addr: + .word 0 + + .align 5 + .globl __ipipe_freerunning_countdown +__ipipe_freerunning_countdown: + ldr r0, .LCfrcd32_cntr_addr +/* User-space entry-point: r0 is the hardware counter virtual address */ + myldrd r2, r3, r1, .LCfrcd32_last_tsc +#ifndef CONFIG_CPU_ENDIAN_BE8 +/* Little endian */ + ldr r0, [r0] + mvn r0, r0 + cmp r2, r0 + adc r1, r3, #0 +#else /* Big endian */ + ldr r1, [r0] + mvn r1, r1 + cmp r3, r1 + adc r0, r2, #0 +#endif /* Big endian */ + usr_ret lr + + .align 5 +.LCfr16_last_tsc: + .rep 7 + .word 0 + .endr +.LCfr16_cntr_addr: + .word 0 + + .align 5 + .globl __ipipe_freerunning_16 +__ipipe_freerunning_16: + ldr r0, .LCfr16_cntr_addr +/* User-space entry-point: r0 is the hardware counter virtual address */ +1: myldrd r2, r3, r1, .LCfr16_last_tsc + ldr ip, [r0] +#ifndef CONFIG_CPU_ENDIAN_BE8 +/* Little endian */ + ldr r1, .LCfr16_last_tsc + cmp r1, r2 + bne 1b + mov r1, r2, lsr #16 + orr r0, ip, r1, lsl #16 + cmp r2, r0 + addhis r0, r0, #0x10000 + adc r1, r3, #0 +#else /* Big endian */ + ldr r1, .LCfr16_last_tsc + 4 + cmp r1, r3 + bne 1b + mov r1, r3, lsr #16 + orr r1, ip, r1, lsl #16 + cmp r3, r0 + addhis r1, r1, #0x10000 + adc r0, r2, #0 +#endif /* Big endian */ + usr_ret lr + + .align 5 +.LCdec16_last_tsc: + .rep 2 + .word 0 + .endr +.LCdec16_last_cnt: + .rep 5 + .word 0 + .endr +.LCdec16_cntr_addr: + .word 0 + + .align 5 + .globl __ipipe_decrementer_16 +__ipipe_decrementer_16: + ldr r0, .LCdec16_cntr_addr +/* User-space entry-point: r0 is the hardware counter virtual address */ +#ifndef CONFIG_CPU_ENDIAN_BE8 +/* Little endian */ +1: ldr r1, .LCdec16_last_tsc + ldr ip, [r0] + ldr r2, .LCdec16_last_cnt + subs ip, r2, ip + addcs ip, ip, #0x10000 + myldrd r2, r3, r3, .LCdec16_last_tsc + cmp r1, r2 + bne 1b + adds r0, ip, r2 + adc r1, r3, #0 +#else /* Big endian */ +/* Little endian */ +1: ldr r1, .LCdec16_last_tsc + 4 + ldr ip, [r0] + ldr r2, .Ldec16_Clast_cnt + subs ip, r2, ip + addcs ip, ip, #0x10000 + myldrd r2, r3, r3, .LCdec16_last_tsc + cmp r1, r3 + bne 1b + adds r1, ip, r3 + adc r0, r2, #0 +#endif /* Big endian */ + usr_ret lr diff -urN orig/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc.c relase/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc.c --- orig/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/ipipe_tsc.c 2011-03-15 10:56:25.881702441 +0100 @@ -0,0 +1,113 @@ +#include +#include +#include +#include + +#include + +#include + +typedef unsigned long long __ipipe_tsc_t(void); + +extern __ipipe_tsc_t __ipipe_freerunning_32, + __ipipe_freerunning_16, + __ipipe_freerunning_countdown, + __ipipe_decrementer_16; +extern unsigned long __ipipe_tsc_addr; + +static struct __ipipe_tscinfo tsc_info; + +static struct clocksource clksrc = { + .name = "ipipe_tsc", + .rating = 0x7fffffff, + .read = (typeof(clksrc.read))__ipipe_tsc_get, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +struct ipipe_tsc_value_t { + unsigned long long last_tsc; + unsigned last_cnt; +}; + +struct ipipe_tsc_value_t *const ipipe_tsc_value = + (struct ipipe_tsc_value_t *)&__ipipe_tsc_area[0]; + +void __ipipe_tsc_register(struct __ipipe_tscinfo *info) +{ + __ipipe_tsc_t *implem; + unsigned long flags; + + switch(info->type) { + case IPIPE_TSC_TYPE_FREERUNNING: + switch(info->u.mask) { + case 0xffff: + implem = &__ipipe_freerunning_16; + break; + case 0xffffffff: + implem = &__ipipe_freerunning_32; + break; + default: + goto unimplemented; + } + break; + + case IPIPE_TSC_TYPE_DECREMENTER: + if (info->u.mask != 0xffff) + goto unimplemented; + implem = &__ipipe_decrementer_16; + break; + + case IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN: + if (info->u.mask != 0xffffffff) + goto unimplemented; + implem = &__ipipe_freerunning_countdown; + break; + + default: + unimplemented: + printk("I-pipel: Unimplemented tsc configuration, " + "type: %d, mask: 0x%08x\n", info->type, info->u.mask); + BUG(); + } + + tsc_info = *info; + __ipipe_tsc_addr = tsc_info.counter_vaddr; + if (tsc_info.type == IPIPE_TSC_TYPE_DECREMENTER) { + tsc_info.u.dec.last_cnt = &ipipe_tsc_value->last_cnt; + tsc_info.u.dec.tsc = &ipipe_tsc_value->last_tsc; + } else + tsc_info.u.fr.tsc = &ipipe_tsc_value->last_tsc; + + local_irq_save_hw(flags); + memcpy(__ipipe_tsc_area + 0x20, implem, 0x60); + flush_icache_range((unsigned long)(__ipipe_tsc_area), + (unsigned long)(__ipipe_tsc_area + 0x80)); + local_irq_restore_hw(flags); + + clksrc.shift = fls(tsc_info.freq) - 1; + clksrc.mult = clocksource_hz2mult(tsc_info.freq, clksrc.shift); + printk(KERN_INFO "I-pipe, %u.%03u MHz clocksource\n", + tsc_info.freq / 1000000, (tsc_info.freq % 1000000) / 1000); + clocksource_register(&clksrc); +} + +void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info) +{ + *info = tsc_info; +} + +void __ipipe_tsc_update(void) +{ + if (tsc_info.type == IPIPE_TSC_TYPE_DECREMENTER) { + unsigned cnt = *(unsigned *)tsc_info.counter_vaddr; + int offset = ipipe_tsc_value->last_cnt - cnt; + if (offset < 0) + offset += 0x10000; + ipipe_tsc_value->last_tsc += offset + 1; + ipipe_tsc_value->last_cnt = cnt - 1; + return; + } + ipipe_tsc_value->last_tsc = __ipipe_tsc_get() - 1; +} +EXPORT_SYMBOL(__ipipe_tsc_get); diff -urN orig/linux-2.6.35.9//arch/arm/kernel/irq.c relase/linux-2.6.35.9//arch/arm/kernel/irq.c --- orig/linux-2.6.35.9//arch/arm/kernel/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/irq.c 2011-03-15 10:56:25.881702441 +0100 @@ -120,8 +120,10 @@ generic_handle_irq(irq); } +#ifndef CONFIG_IPIPE /* AT91 specific workaround */ irq_finish(irq); +#endif /* !CONFIG_IPIPE */ irq_exit(); set_irq_regs(old_regs); diff -urN orig/linux-2.6.35.9//arch/arm/kernel/Makefile relase/linux-2.6.35.9//arch/arm/kernel/Makefile --- orig/linux-2.6.35.9//arch/arm/kernel/Makefile 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/Makefile 2011-03-15 10:56:25.877702441 +0100 @@ -21,7 +21,7 @@ obj-$(CONFIG_OC_ETM) += etm.o obj-$(CONFIG_ISA_DMA_API) += dma.o -obj-$(CONFIG_ARCH_ACORN) += ecard.o +obj-$(CONFIG_ARCH_ACORN) += ecard.o obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o @@ -58,5 +58,7 @@ head-y := head$(MMUEXT).o obj-$(CONFIG_DEBUG_LL) += debug.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_IPIPE) += ipipe.o +obj-$(CONFIG_IPIPE_ARM_KUSER_TSC) += ipipe_tsc.o ipipe_tsc_asm.o extra-y := $(head-y) init_task.o vmlinux.lds diff -urN orig/linux-2.6.35.9//arch/arm/kernel/process.c relase/linux-2.6.35.9//arch/arm/kernel/process.c --- orig/linux-2.6.35.9//arch/arm/kernel/process.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/process.c 2011-03-15 10:56:25.881702441 +0100 @@ -119,6 +119,34 @@ void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; EXPORT_SYMBOL_GPL(arm_pm_restart); +#ifdef CONFIG_IPIPE +static void __ipipe_halt_root(void) +{ + struct ipipe_percpu_domain_data *p; + + /* Emulate idle entry sequence over the root domain. */ + + local_irq_disable_hw(); + + p = ipipe_root_cpudom_ptr(); + + trace_hardirqs_on(); + clear_bit(IPIPE_STALL_FLAG, &p->status); + + if (unlikely(__ipipe_ipending_p(p))) { + __ipipe_sync_pipeline(); + local_irq_enable_hw(); + } else { +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + ipipe_trace_end(0x8000000E); +#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ + local_irq_enable_hw(); + arch_idle(); + } +} +#else /* !CONFIG_IPIPE */ +#define __ipipe_halt_root() arch_idle() +#endif /* !CONFIG_IPIPE */ /* * This is our default idle handler. We need to disable @@ -127,7 +155,7 @@ static void default_idle(void) { if (!need_resched()) - arch_idle(); + __ipipe_halt_root(); local_irq_enable(); } diff -urN orig/linux-2.6.35.9//arch/arm/kernel/ptrace.c relase/linux-2.6.35.9//arch/arm/kernel/ptrace.c --- orig/linux-2.6.35.9//arch/arm/kernel/ptrace.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/ptrace.c 2011-03-15 10:56:25.881702441 +0100 @@ -490,6 +490,10 @@ static int break_trap(struct pt_regs *regs, unsigned int instr) { + + if (ipipe_trap_notify(IPIPE_TRAP_BREAK,regs)) + return 0; + ptrace_break(current, regs); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/kernel/smp.c relase/linux-2.6.35.9//arch/arm/kernel/smp.c --- orig/linux-2.6.35.9//arch/arm/kernel/smp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/smp.c 2011-03-15 10:56:25.881702441 +0100 @@ -50,13 +50,13 @@ * - A collection of single bit ipi messages. */ struct ipi_data { - spinlock_t lock; + ipipe_spinlock_t lock; unsigned long ipi_count; unsigned long bits; }; static DEFINE_PER_CPU(struct ipi_data, ipi_data) = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = IPIPE_SPIN_LOCK_UNLOCKED, }; enum ipi_msg_type { @@ -65,6 +65,25 @@ IPI_CALL_FUNC, IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, + IPI_CPU_DUMP, +#ifdef CONFIG_IPIPE + IPI_IPIPE_CRITICAL, + IPI_IPIPE_0, + IPI_IPIPE_1, + IPI_IPIPE_2, + IPI_IPIPE_3, + IPI_IPIPE_VNMI, +#define IPI_IPIPE_ALL \ + ((1UL << IPI_IPIPE_CRITICAL)| \ + (1UL << IPI_IPIPE_0)| \ + (1UL << IPI_IPIPE_1)| \ + (1UL << IPI_IPIPE_2)| \ + (1UL << IPI_IPIPE_3)| \ + (1UL << IPI_IPIPE_VNMI)) +#define IPI_ROOT_MASK IPI_IPIPE_ALL +#else /* !CONFIG_IPIPE */ +#define IPI_ROOT_MASK 0 +#endif /* !CONFIG_IPIPE */ }; int __cpuinit __cpu_up(unsigned int cpu) @@ -267,7 +286,7 @@ atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); - cpu_switch_mm(mm->pgd, mm); + cpu_switch_mm(mm->pgd, mm, 1); enter_lazy_tlb(mm, current); local_flush_tlb_all(); @@ -344,7 +363,7 @@ unsigned long flags; unsigned int cpu; - local_irq_save(flags); + local_irq_save_hw(flags); for_each_cpu(cpu, mask) { struct ipi_data *ipi = &per_cpu(ipi_data, cpu); @@ -359,7 +378,7 @@ */ smp_cross_call(mask); - local_irq_restore(flags); + local_irq_restore_hw(flags); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -404,6 +423,9 @@ static void ipi_timer(void) { struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); +#ifdef CONFIG_IPIPE + __ipipe_mach_update_tsc(); +#endif irq_enter(); evt->event_handler(evt); irq_exit(); @@ -424,6 +446,72 @@ } #endif +#ifdef CONFIG_IPIPE + +int __ipipe_send_ipi(unsigned ipi, cpumask_t cpumask) +{ + enum ipi_msg_type msg = ipi - IPIPE_FIRST_IPI + IPI_IPIPE_CRITICAL; + send_ipi_message(&cpumask, msg); + return 0; +} + +asmlinkage void __exception __ipipe_grab_ipi(struct pt_regs *regs) /* hw IRQs off */ +{ + unsigned int cpu = ipipe_processor_id(), svc; + struct ipi_data *ipi = &per_cpu(ipi_data, cpu); + unsigned long allmsgs, svcmsgs; + int virq; + + for (;;) { + spin_lock(&ipi->lock); + allmsgs = ipi->bits; + ipi->bits &= ~IPI_IPIPE_ALL; + spin_unlock(&ipi->lock); + + if (allmsgs == 0) + break; + + svcmsgs = allmsgs & IPI_IPIPE_ALL; + while (svcmsgs) { + svc = svcmsgs & -svcmsgs; + svcmsgs &= ~svc; + svc = ffz(~svc); + /* + * Virtual NMIs ignore the root domain's stall + * bit. When caught over high priority + * domains, virtual VMIs are pipelined the + * usual way as normal interrupts. + */ + if (svc == IPI_IPIPE_VNMI && ipipe_root_domain_p) + __ipipe_do_vnmi(IPIPE_SERVICE_VNMI, NULL); + else { + virq = svc - IPI_IPIPE_CRITICAL + IPIPE_FIRST_IPI; + __ipipe_handle_irq(virq, NULL); + } + ipi->ipi_count++; + } + + if (allmsgs & ~IPI_IPIPE_ALL) { + __ipipe_mach_relay_ipi(cpu); + break; + } + } + + __ipipe_exit_irq(regs); +} + +void __ipipe_root_ipi(unsigned int irq, struct pt_regs *regs) +{ + do_IPI(regs); +} + +void __ipipe_root_localtimer(unsigned int irq, struct pt_regs *regs) +{ + do_local_timer(regs); +} + +#endif /* CONFIG_IPIPE */ + #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST static void smp_timer_broadcast(const struct cpumask *mask) { @@ -499,12 +587,12 @@ ipi->ipi_count++; for (;;) { - unsigned long msgs; + unsigned long msgs, flags; - spin_lock(&ipi->lock); - msgs = ipi->bits; - ipi->bits = 0; - spin_unlock(&ipi->lock); + spin_lock_irqsave_cond(&ipi->lock, flags); + msgs = ipi->bits & ~IPI_ROOT_MASK; + ipi->bits &= IPI_ROOT_MASK; + spin_unlock_irqrestore_cond(&ipi->lock, flags); if (!msgs) break; @@ -645,19 +733,21 @@ void flush_tlb_mm(struct mm_struct *mm) { - if (tlb_ops_need_broadcast()) - on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm)); - else + if (tlb_ops_need_broadcast()) { + cpumask_t *mask = mm_cpumask(mm); + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask); + } else local_flush_tlb_mm(mm); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { if (tlb_ops_need_broadcast()) { + cpumask_t *mask = mm_cpumask(vma->vm_mm); struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = uaddr; - on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm)); + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); } else local_flush_tlb_page(vma, uaddr); } @@ -673,14 +763,15 @@ } void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { if (tlb_ops_need_broadcast()) { + cpumask_t *mask = mm_cpumask(vma->vm_mm); struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = start; ta.ta_end = end; - on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm)); + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); } else local_flush_tlb_range(vma, start, end); } diff -urN orig/linux-2.6.35.9//arch/arm/kernel/traps.c relase/linux-2.6.35.9//arch/arm/kernel/traps.c --- orig/linux-2.6.35.9//arch/arm/kernel/traps.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/kernel/traps.c 2011-03-15 10:56:25.881702441 +0100 @@ -748,8 +748,13 @@ unsigned long vectors = CONFIG_VECTORS_BASE; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; +#ifndef CONFIG_IPIPE extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end - __kuser_helper_start; +#else /* !CONFIG_IPIPE */ + extern char __ipipe_tsc_area_start[], __kuser_helper_end[]; + int kuser_sz = __kuser_helper_end - __ipipe_tsc_area_start; +#endif /* !CONFIG_IPIPE */ /* * Copy the vectors, stubs and kuser helpers (in entry-armv.S) @@ -758,7 +763,12 @@ */ memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); +#ifndef CONFIG_IPIPE memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); +#else /* !CONFIG_IPIPE */ + BUG_ON(0x1000 - kuser_sz < 0x200 + __stubs_end - __stubs_start); + memcpy((void *)vectors + 0x1000 - kuser_sz, __ipipe_tsc_area_start, kuser_sz); +#endif /* !CONFIG_IPIPE */ /* * Copy signal return handlers into the vector page, and diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91_ipipe_time.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91_ipipe_time.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91_ipipe_time.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91_ipipe_time.c 2011-03-15 10:56:25.885702441 +0100 @@ -0,0 +1,316 @@ +/* + * linux/arch/arm/mach-at91/at91_ipipe_time.c + * + * Copyright (C) 2007 Gilles Chanteperdrix + * + * Adaptation to AT91SAM926x: + * Copyright (C) 2007 Gregory CLEMENT, Adeneo + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include "clock.h" + +#if defined(CONFIG_ARCH_AT91RM9200) +#define AT91_ID_TC0 AT91RM9200_ID_TC0 +#define AT91_ID_TC1 AT91RM9200_ID_TC1 +#define AT91_ID_TC2 AT91RM9200_ID_TC2 +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) +#define AT91_ID_TC0 AT91SAM9260_ID_TC0 +#define AT91_ID_TC1 AT91SAM9260_ID_TC1 +#define AT91_ID_TC2 AT91SAM9260_ID_TC2 +#elif defined(CONFIG_ARCH_AT91SAM9261) +#define AT91_ID_TC0 AT91SAM9261_ID_TC0 +#define AT91_ID_TC1 AT91SAM9261_ID_TC1 +#define AT91_ID_TC2 AT91SAM9261_ID_TC2 +#elif defined(CONFIG_ARCH_AT91SAM9263) +#define AT91_ID_TC0 AT91SAM9263_ID_TCB +#define AT91_ID_TC1 AT91SAM9263_ID_TCB +#define AT91_ID_TC2 AT91SAM9263_ID_TCB +#elif defined(CONFIG_ARCH_AT91SAM9RL) +#define AT91_ID_TC0 AT91SAM9RL_ID_TC0 +#define AT91_ID_TC1 AT91SAM9RL_ID_TC1 +#define AT91_ID_TC2 AT91SAM9RL_ID_TC2 +#elif defined(CONFIG_ARCH_AT91X40) +#define AT91_ID_TC0 AT91X40_ID_TC0 +#define AT91_ID_TC1 AT91X40_ID_TC1 +#define AT91_ID_TC2 AT91X40_ID_TC2 +#else +#error "AT91 processor unsupported by Adeos" +#endif + +#if (CONFIG_IPIPE_AT91_TC==0) +# define KERNEL_TIMER_IRQ_NUM AT91_ID_TC0 +#elif (CONFIG_IPIPE_AT91_TC==1) +# define KERNEL_TIMER_IRQ_NUM AT91_ID_TC1 +#elif (CONFIG_IPIPE_AT91_TC==2) +# define KERNEL_TIMER_IRQ_NUM AT91_ID_TC2 +#else +#error IPIPE_AT91_TC must be 0, 1 or 2. +#endif + +#define TCNXCNS(timer,v) ((v) << ((timer)<<1)) +#define AT91_TC_REG_MASK (0xffff) + +static unsigned long next_match; + +static unsigned max_delta_ticks, min_delta_ticks; +static struct clock_event_device clkevt; +static int tc_timer_clock; + +static inline unsigned int at91_tc_read(unsigned int reg_offset) +{ + unsigned long addr = + (AT91_VA_BASE_TCB0 + 0x40 * CONFIG_IPIPE_AT91_TC); + + return readl((void __iomem *)(addr + reg_offset)); +} + +static inline void at91_tc_write(unsigned int reg_offset, unsigned long value) +{ + unsigned long addr = + (AT91_VA_BASE_TCB0 + 0x40 * CONFIG_IPIPE_AT91_TC); + + writel(value, (void __iomem *)(addr + reg_offset)); +} + +#define read_CV() at91_tc_read(AT91_TC_CV) +#define read_RC() at91_tc_read(AT91_TC_RC) +#define write_RC(value) at91_tc_write(AT91_TC_RC, value) + +int __ipipe_mach_timerint = KERNEL_TIMER_IRQ_NUM; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen = 0; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); + +unsigned int __ipipe_mach_ticks_per_jiffy = LATCH; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91_timer_interrupt(int irq, void *dev_id) +{ + clkevt.event_handler(&clkevt); + return IRQ_HANDLED; +} + +static struct irqaction at91_timer_irq = { + .name = "at91_tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = &at91_timer_interrupt +}; + +void __ipipe_mach_acktimer(void) +{ + at91_tc_read(AT91_TC_SR); + + if (unlikely(!__ipipe_mach_timerstolen)) { + __ipipe_tsc_update(); + next_match = (next_match + __ipipe_mach_ticks_per_jiffy) + & AT91_TC_REG_MASK; + write_RC(next_match); + } +} + +static void +at91_tc_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) +{ + /* Disable the channel */ + at91_tc_write(AT91_TC_CCR, AT91_TC_CLKDIS); + + /* Disable all interrupts. */ + at91_tc_write(AT91_TC_IDR, ~0ul); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + unsigned long v; + +#ifndef CONFIG_ARCH_AT91SAM9263 + clk_enable(clk_get(NULL, "tc" + __stringify(CONFIG_IPIPE_AT91_TC) "_clk")); +#else /* AT91SAM9263 */ + clk_enable(clk_get(NULL, "tcb_clk")); +#endif /* AT91SAM9263 */ + + /* No Sync. */ + at91_tc_write(AT91_TC_BCR, 0); + + /* program NO signal on XCN */ + v = readl((void __iomem *) (AT91_VA_BASE_TCB0 + AT91_TC_BMR)); + v &= ~TCNXCNS(CONFIG_IPIPE_AT91_TC, 3); + v |= TCNXCNS(CONFIG_IPIPE_AT91_TC, 1); /* AT91_TC_TCNXCNS_NONE */ + writel(v, (void __iomem *) (AT91_VA_BASE_TCB0 + AT91_TC_BMR)); + + /* Use the clock selected by at91_timer_init as input clock. */ + at91_tc_write(AT91_TC_CMR, tc_timer_clock); + + /* Load the TC register C. */ + next_match = __ipipe_mach_ticks_per_jiffy; + write_RC(next_match); + + /* Enable CPCS interrupt. */ + at91_tc_write(AT91_TC_IER, AT91_TC_CPCS); + + /* Enable the channel. */ + at91_tc_write(AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG); + } +} + +/* + * Reprogram the timer + */ +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > max_delta_ticks) + delay = max_delta_ticks; + + if (likely(delay > min_delta_ticks)) { + write_RC((read_CV() + delay) & AT91_TC_REG_MASK); + __ipipe_tsc_update(); + } else + ipipe_trigger_irq(KERNEL_TIMER_IRQ_NUM); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, clkevt.name); +} + +static struct clock_event_device clkevt = { + .name = "at91_tc" __stringify(CONFIG_IPIPE_AT91_TC), + .features = CLOCK_EVT_FEAT_PERIODIC, + .shift = 20, + .rating = 250, + .set_mode = at91_tc_set_mode, +}; + +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .counter_vaddr = (AT91_VA_BASE_TCB0 + + 0x40 * CONFIG_IPIPE_AT91_TC + AT91_TC_CV), + .u = { + { + .counter_paddr = (AT91_BASE_TCB0 + + 0x40 * CONFIG_IPIPE_AT91_TC + + AT91_TC_CV), + .mask = AT91_TC_REG_MASK, + }, + }, +}; + +void __ipipe_mach_release_timer(void) +{ + unsigned long flags; + local_irq_save_hw(flags); + __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return (read_RC() - read_CV()) & AT91_TC_REG_MASK; +} + +void __init at91_timer_init(void) +{ + unsigned char tc_divisors[] = { 2, 8, 32, 128, 0, }; + unsigned master_freq, divisor = 0, divided_freq = 0; + unsigned long long wrap_ns; + + /* Disable (boot loader) timer interrupts. */ +#if defined(CONFIG_ARCH_AT91RM9200) + at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); + (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261) \ + || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9RL) \ + || defined(CONFIG_ARCH_AT91SAM9G20) + at91_sys_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts */ + (void) at91_sys_read(AT91_PIT_PIVR); +#endif /* CONFIG_ARCH_AT91SAM926x */ + + master_freq = clk_get_rate(clk_get(NULL, "mck")); + /* Find the first frequency above 1 MHz */ + for (tc_timer_clock = ARRAY_SIZE(tc_divisors) - 1; + tc_timer_clock >= 0; tc_timer_clock--) { + divisor = tc_divisors[tc_timer_clock]; + divided_freq = (divisor + ? master_freq / divisor : AT91_SLOW_CLOCK); + if (divided_freq > 1000000) + break; + } + + wrap_ns = (unsigned long long) (AT91_TC_REG_MASK + 1) * NSEC_PER_SEC; + do_div(wrap_ns, divided_freq); + + if (divided_freq < 1000000) + printk(KERN_INFO "AT91 I-pipe warning: could not find a" + " frequency greater than 1MHz\n"); + + printk(KERN_INFO "AT91 I-pipe timer: div: %u, freq: %u.%06u MHz, wrap: " + "%u.%06u ms\n", divisor, + divided_freq / 1000000, divided_freq % 1000000, + (unsigned) wrap_ns / 1000000, (unsigned) wrap_ns % 1000000); + + /* Add a 1ms margin. It means that when an interrupt occurs, update_tsc + must be called within 1ms. update_tsc is called by acktimer when no + higher domain handles the timer, and called through set_dec when a + higher domain handles the timer. */ + wrap_ns -= 1000000; + /* Set up the interrupt. */ + setup_irq(KERNEL_TIMER_IRQ_NUM, &at91_timer_irq); + + clkevt.mult = div_sc(divided_freq, NSEC_PER_SEC, clkevt.shift); + clkevt.max_delta_ns = wrap_ns; + clkevt.min_delta_ns = 2000; + clkevt.cpumask = cpumask_of(0); + clockevents_register_device(&clkevt); + + tsc_info.freq = divided_freq; + __ipipe_tsc_register(&tsc_info); + + __ipipe_mach_ticks_per_jiffy = (divided_freq + HZ/2) / HZ; + max_delta_ticks = (wrap_ns * clkevt.mult) >> clkevt.shift; + min_delta_ticks = ((unsigned long long) clkevt.min_delta_ns + * clkevt.mult) >> clkevt.shift; +} + +#ifdef CONFIG_ARCH_AT91RM9200 +struct sys_timer at91rm9200_timer = { +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261) \ + || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9RL) \ + || defined(CONFIG_ARCH_AT91SAM9G20) +struct sys_timer at91sam926x_timer = { +#elif defined(CONFIG_ARCH_AT91X40) +struct sys_timer at91x40_timer = { +#else +#error "Unknown machine" +#endif + .init = at91_timer_init, + .suspend = NULL, + .resume = NULL, +}; diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91rm9200.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91rm9200.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91rm9200.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91rm9200.c 2011-03-15 10:56:25.885702441 +0100 @@ -33,6 +33,13 @@ .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, +#ifdef CONFIG_IPIPE + }, { + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, +#endif /* CONFIG_IPIPE */ }, { .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), @@ -300,6 +307,7 @@ * The default interrupt priority levels (0 = lowest, 7 = highest). */ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { +#ifndef CONFIG_IPIPE 7, /* Advanced Interrupt Controller (FIQ) */ 7, /* System Peripherals */ 1, /* Parallel IO Controller A */ @@ -332,6 +340,42 @@ 0, /* Advanced Interrupt Controller (IRQ4) */ 0, /* Advanced Interrupt Controller (IRQ5) */ 0 /* Advanced Interrupt Controller (IRQ6) */ +#else /* CONFIG_IPIPE */ +/* Give the highest priority to TC, since they are used as timer interrupt by + I-pipe. */ + 7, /* Advanced Interrupt Controller */ + 6, /* System Peripheral */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, /* Parallel IO Controller D */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 0, /* Multimedia Card Interface */ + 3, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface */ + 4, /* Serial Synchronous Controller */ + 4, /* Serial Synchronous Controller */ + 4, /* Serial Synchronous Controller */ + 7, /* Timer Counter 0 */ + 7, /* Timer Counter 1 */ + 7, /* Timer Counter 2 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 2, /* USB Host port */ + 2, /* Ethernet MAC */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0 /* Advanced Interrupt Controller */ +#endif /*CONFIG_IPIPE */ }; void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9260.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9260.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9260.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9260.c 2011-03-15 10:56:25.885702441 +0100 @@ -31,6 +31,13 @@ .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_16K, .type = MT_DEVICE, +#ifdef CONFIG_IPIPE + }, { + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, +#endif /* CONFIG_IPIPE */ } }; @@ -350,6 +357,7 @@ * The default interrupt priority levels (0 = lowest, 7 = highest). */ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { +#ifndef CONFIG_IPIPE 7, /* Advanced Interrupt Controller */ 7, /* System Peripherals */ 1, /* Parallel IO Controller A */ @@ -382,6 +390,42 @@ 0, /* Advanced Interrupt Controller */ 0, /* Advanced Interrupt Controller */ 0, /* Advanced Interrupt Controller */ +#else /* CONFIG_IPIPE */ +/* Give the highest priority to TC, since they are used as timer interrupt by + I-pipe. */ + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 7, /* Timer Counter 0 */ + 7, /* Timer Counter 1 */ + 7, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 6, /* USART 3 */ + 6, /* USART 4 */ + 6, /* USART 5 */ + 7, /* Timer Counter 3 */ + 7, /* Timer Counter 4 */ + 7, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +#endif /*CONFIG_IPIPE */ }; void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9261.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9261.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9261.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9261.c 2011-03-15 10:56:25.885702441 +0100 @@ -31,6 +31,13 @@ .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_16K, .type = MT_DEVICE, +#ifdef CONFIG_IPIPE + }, { + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, +#endif /* CONFIG_IPIPE */ }, }; @@ -306,6 +313,7 @@ * The default interrupt priority levels (0 = lowest, 7 = highest). */ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { +#ifndef CONFIG_IPIPE 7, /* Advanced Interrupt Controller */ 7, /* System Peripherals */ 1, /* Parallel IO Controller A */ @@ -338,6 +346,42 @@ 0, /* Advanced Interrupt Controller */ 0, /* Advanced Interrupt Controller */ 0, /* Advanced Interrupt Controller */ +#else /* CONFIG_IPIPE */ +/* Give the highest priority to TC, since they are used as timer interrupt by + I-pipe. */ + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller 0 */ + 5, /* Serial Synchronous Controller 1 */ + 5, /* Serial Synchronous Controller 2 */ + 7, /* Timer Counter 0 */ + 7, /* Timer Counter 1 */ + 7, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* LCD Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +#endif /*CONFIG_IPIPE */ }; void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9263.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9263.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9263.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9263.c 2011-03-15 10:56:25.885702441 +0100 @@ -30,6 +30,13 @@ .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_16K, .type = MT_DEVICE, +#ifdef CONFIG_IPIPE + }, { + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, +#endif /* CONFIG_IPIPE */ }, { .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE, .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE), @@ -311,6 +318,7 @@ * The default interrupt priority levels (0 = lowest, 7 = highest). */ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { +#ifndef CONFIG_IPIPE 7, /* Advanced Interrupt Controller (FIQ) */ 7, /* System Peripherals */ 1, /* Parallel IO Controller A */ @@ -343,6 +351,42 @@ 2, /* USB Host port */ 0, /* Advanced Interrupt Controller (IRQ0) */ 0, /* Advanced Interrupt Controller (IRQ1) */ +#else /* CONFIG_IPIPE */ +/* Give the highest priority to TC, since they are used as timer interrupt by + I-pipe. */ + 7, /* Advanced Interrupt Controller (FIQ) */ + 6, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C, D and E */ + 0, + 0, + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface 0 */ + 0, /* Multimedia Card Interface 1 */ + 3, /* CAN */ + 0, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 4, /* Serial Synchronous Controller 0 */ + 4, /* Serial Synchronous Controller 1 */ + 5, /* AC97 Controller */ + 7, /* Timer Counter 0, 1 and 2 */ + 0, /* Pulse Width Modulation Controller */ + 2, /* Ethernet */ + 0, + 0, /* 2D Graphic Engine */ + 2, /* USB Device Port */ + 0, /* Image Sensor Interface */ + 2, /* LDC Controller */ + 0, /* DMA Controller */ + 0, + 2, /* USB Host port */ + 0, /* Advanced Interrupt Controller (IRQ0) */ + 0, /* Advanced Interrupt Controller (IRQ1) */ +#endif /*CONFIG_IPIPE */ }; void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9rl.c relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9rl.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/at91sam9rl.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/at91sam9rl.c 2011-03-15 10:56:25.885702441 +0100 @@ -30,6 +30,13 @@ .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_16K, .type = MT_DEVICE, +#ifdef CONFIG_IPIPE + }, { + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, +#endif /* CONFIG_IPIPE */ }, }; @@ -303,6 +310,7 @@ * The default interrupt priority levels (0 = lowest, 7 = highest). */ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { +#ifndef CONFIG_IPIPE 7, /* Advanced Interrupt Controller */ 7, /* System Peripherals */ 1, /* Parallel IO Controller A */ @@ -335,6 +343,42 @@ 0, 0, 0, /* Advanced Interrupt Controller */ +#else /* CONFIG_IPIPE */ +/* Give the highest priority to TC, since they are used as timer interrupt by + I-pipe. */ + 7, /* Advanced Interrupt Controller */ + 6, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 1, /* Parallel IO Controller D */ + 4, /* USART 0 */ + 4, /* USART 1 */ + 4, /* USART 2 */ + 4, /* USART 3 */ + 0, /* Multimedia Card Interface */ + 5, /* Two-Wire Interface 0 */ + 5, /* Two-Wire Interface 1 */ + 4, /* Serial Peripheral Interface */ + 3, /* Serial Synchronous Controller 0 */ + 3, /* Serial Synchronous Controller 1 */ + 7, /* Timer Counter 0 */ + 7, /* Timer Counter 1 */ + 7, /* Timer Counter 2 */ + 0, + 0, /* Touch Screen Controller */ + 0, /* DMA Controller */ + 2, /* USB Device High speed port */ + 2, /* LCD Controller */ + 5, /* AC97 Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ +#endif /*CONFIG_IPIPE */ }; void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS]) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/board-foxg20.c relase/linux-2.6.35.9//arch/arm/mach-at91/board-foxg20.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/board-foxg20.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/board-foxg20.c 2011-03-15 11:04:57.365702441 +0100 @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * Copyright (C) 2010 Lee McLoughlin - lee@lmmrtech.com + * Copyright (C) 2010 Sergio Tanzilli - tanzilli@acmesystems.it + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "sam9_smc.h" +#include "generic.h" + +/* + * The FOX Board G20 hardware comes as the "Netus G20" board with + * just the cpu, ram, dataflash and two header connectors. + * This is plugged into the FOX Board which provides the ethernet, + * usb, rtc, leds, switch, ... + * + * For more info visit: http://www.acmesystems.it/foxg20 + */ + + +static void __init foxg20_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, 0); + + /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART4 on ttyS5. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US4, 5, 0); + + /* USART5 on ttyS6. (Rx & Tx only) */ + at91_register_uart(AT91SAM9260_ID_US5, 6, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); + + /* Set the internal pull-up resistor on DRXD */ + at91_set_A_periph(AT91_PIN_PB14, 1); + +} + +static void __init foxg20_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata foxg20_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata foxg20_udc_data = { + .vbus_pin = AT91_PIN_PC6, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info foxg20_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata foxg20_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + + + + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata foxg20_mmc_data = { + .slot_b = 1, + .wire4 = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led foxg20_leds[] = { + { /* user led, red */ + .name = "user_led", + .gpio = AT91_PIN_PC7, + .active_low = 0, + .default_trigger = "heartbeat", + }, +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button foxg20_buttons[] = { + { + .gpio = AT91_PIN_PC4, + .code = BTN_1, + .desc = "Button 1", + .active_low = 1, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data foxg20_button_data = { + .buttons = foxg20_buttons, + .nbuttons = ARRAY_SIZE(foxg20_buttons), +}; + +static struct platform_device foxg20_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &foxg20_button_data, + } +}; + +static void __init foxg20_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PC4, 1); /* btn1 */ + at91_set_deglitch(AT91_PIN_PC4, 1); + + platform_device_register(&foxg20_button_device); +} +#else +static void __init foxg20_add_device_buttons(void) {} +#endif + + +#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) +static struct w1_gpio_platform_data w1_gpio_pdata = { + /* If you choose to use a pin other than PB16 it needs to be 3.3V */ + .pin = AT91_PIN_PB16, + .is_open_drain = 1, +}; + +static struct platform_device w1_device = { + .name = "w1-gpio", + .id = -1, + .dev.platform_data = &w1_gpio_pdata, +}; + +static void __init at91_add_device_w1(void) +{ + at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); + at91_set_multi_drive(w1_gpio_pdata.pin, 1); + platform_device_register(&w1_device); +} + +#endif + + +static struct i2c_board_info __initdata foxg20_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init foxg20_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&foxg20_usbh_data); + /* USB Device */ + at91_add_device_udc(&foxg20_udc_data); + /* SPI */ + at91_add_device_spi(foxg20_spi_devices, ARRAY_SIZE(foxg20_spi_devices)); + /* Ethernet */ + at91_add_device_eth(&foxg20_macb_data); + /* MMC */ + at91_add_device_mmc(0, &foxg20_mmc_data); + /* I2C */ + at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices)); + /* LEDs */ + at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds)); + /* Push Buttons */ + foxg20_add_device_buttons(); +#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + at91_add_device_w1(); +#endif +} + +MACHINE_START(AT91SAM9G20EK, "Acme Systems srl FOX Board G20") + /* Maintainer: Lee McLoughlin */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = foxg20_map_io, + .init_irq = foxg20_init_irq, + .init_machine = foxg20_board_init, +MACHINE_END + diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/gpio.c relase/linux-2.6.35.9//arch/arm/mach-at91/gpio.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/gpio.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/gpio.c 2011-03-15 10:56:25.885702441 +0100 @@ -19,12 +19,20 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_IPIPE +#include + +#ifdef __IPIPE_FEATURE_PIC_MUTE +DEFINE_PER_CPU(__ipipe_irqbits_t, __ipipe_muted_irqs); +#endif /* __IPIPE_FEATURE_PIC_MUTE */ +#endif /* CONFIG_IPIPE */ #include "generic.h" @@ -33,6 +41,10 @@ struct at91_gpio_chip *next; /* Bank sharing same clock */ struct at91_gpio_bank *bank; /* Bank definition */ void __iomem *regbase; /* Base of register bank */ +#ifdef CONFIG_IPIPE + unsigned *nonroot_gpios; + unsigned nonroot_gpios_storage; +#endif }; #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) @@ -375,6 +387,10 @@ static struct irq_chip gpio_irqchip = { .name = "GPIO", +#ifdef CONFIG_IPIPE + .ack = gpio_irq_mask, + .mask_ack = gpio_irq_mask, +#endif /* CONFIG_IPIPE */ .mask = gpio_irq_mask, .unmask = gpio_irq_unmask, .set_type = gpio_irq_type, @@ -394,6 +410,13 @@ /* temporarily mask (level sensitive) parent IRQ */ desc->chip->ack(irq); +#ifdef CONFIG_IPIPE + if (!(*at91_gpio->nonroot_gpios)) { + local_irq_enable_hw(); + local_irq_disable_hw(); + } +#endif /* CONFIG_IPIPE */ + for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * When there none are pending, we're finished unless we need @@ -420,9 +443,15 @@ * here to be disabled on the GPIO controller. */ gpio_irq_mask(pin); + } else { + ipipe_handle_chained_irq(pin); +#ifdef CONFIG_IPIPE + if (!(*at91_gpio->nonroot_gpios)) { + local_irq_enable_hw(); + local_irq_disable_hw(); + } +#endif /* CONFIG_IPIPE */ } - else - generic_handle_irq(pin); } pin++; gpio++; @@ -433,6 +462,79 @@ /* now it may re-trigger */ } +#if defined(CONFIG_IPIPE) && defined(__IPIPE_FEATURE_PIC_MUTE) +void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + if (desc->chip == &gpio_irqchip) { + struct at91_gpio_chip *chip = &gpio_chip[(irq - PIN_BASE) / 32]; + struct at91_gpio_bank *bank = chip->bank; + + if (ipd != &ipipe_root && ++(*chip->nonroot_gpios) == 1) + __ipipe_irqbits[(bank->id / BITS_PER_LONG)] + &= ~(1 << (bank->id % BITS_PER_LONG)); + } +} + +void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + if (desc->chip == &gpio_irqchip) { + struct at91_gpio_chip *chip = &gpio_chip[(irq - PIN_BASE) / 32]; + struct at91_gpio_bank *bank = chip->bank; + + if (ipd != &ipipe_root && --(*chip->nonroot_gpios) == 0) + __ipipe_irqbits[(bank->id / BITS_PER_LONG)] + |= (1 << (bank->id % BITS_PER_LONG)); + } +} + +void ipipe_mute_pic(void) +{ + struct at91_gpio_chip *prev, *chip = NULL; + unsigned long unmasked, muted; + unsigned i; + + for (i = 0; i < gpio_banks; i++) { + prev = chip; + chip = &gpio_chip[i]; + if (!(*chip->nonroot_gpios)) + continue; + + unmasked = __raw_readl(chip->regbase + PIO_IMR); + muted = unmasked & __ipipe_irqbits[i + 1]; + __raw_get_cpu_var(__ipipe_muted_irqs) + [i + PIN_BASE / 32] = muted; + __raw_writel(muted, chip->regbase + PIO_IDR); + } + + unmasked = at91_sys_read(AT91_AIC_IMR); + muted = unmasked & __ipipe_irqbits[0]; + __raw_get_cpu_var(__ipipe_muted_irqs)[0] = muted; + at91_sys_write(AT91_AIC_IDCR, muted); +} + +void ipipe_unmute_pic(void) +{ + struct at91_gpio_chip *prev, *chip = NULL; + unsigned long muted; + unsigned i; + + at91_sys_write(AT91_AIC_IECR, __raw_get_cpu_var(__ipipe_muted_irqs)[0]); + for (i = 0; i < gpio_banks; i++) { + prev = chip; + chip = &gpio_chip[i]; + if (!(*chip->nonroot_gpios)) + continue; + + muted = __raw_get_cpu_var(__ipipe_muted_irqs) + [i + PIN_BASE / 32]; + __raw_writel(muted, chip->regbase + PIO_IER); + } +} +#endif /* CONFIG_IPIPE && __IPIPE_FEATURE_PIC_MUTE */ + /*--------------------------------------------------------------------------*/ #ifdef CONFIG_DEBUG_FS @@ -631,13 +733,19 @@ at91_gpio->chip.base = PIN_BASE + i * 32; at91_gpio->regbase = at91_gpio->bank->offset + (void __iomem *)AT91_VA_BASE_SYS; - +#ifdef CONFIG_IPIPE + at91_gpio->nonroot_gpios = &at91_gpio->nonroot_gpios_storage; +#endif /* enable PIO controller's clock */ clk_enable(at91_gpio->bank->clock); /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ - if (last && last->bank->id == at91_gpio->bank->id) + if (last && last->bank->id == at91_gpio->bank->id) { last->next = at91_gpio; +#ifdef CONFIG_IPIPE + at91_gpio->nonroot_gpios = last->nonroot_gpios; +#endif + } last = at91_gpio; gpiochip_add(&at91_gpio->chip); diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/hardware.h relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/hardware.h --- orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/hardware.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/hardware.h 2011-03-15 10:56:25.885702441 +0100 @@ -65,6 +65,25 @@ #define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS) #define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91RM9200_BASE_EMAC) +#ifdef CONFIG_IPIPE +#if defined(CONFIG_ARCH_AT91RM9200) +#define AT91_BASE_TCB0 AT91RM9200_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) +#define AT91_BASE_TCB0 AT91SAM9260_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91SAM9261) +#define AT91_BASE_TCB0 AT91SAM9261_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91SAM9263) +#define AT91_BASE_TCB0 AT91SAM9263_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91SAM9RL) +#define AT91_BASE_TCB0 AT91SAM9RL_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91X40) +#define AT91_BASE_TCB0 (AT91_BASE_SYS + AT91_TC) +#else +#error "AT91 processor unsupported by Adeos" +#endif +#define AT91_VA_BASE_TCB0 AT91_IO_P2V(AT91_BASE_TCB0) +#endif + /* Internal SRAM is mapped below the IO devices */ #define AT91_SRAM_MAX SZ_1M #define AT91_VIRT_BASE (AT91_IO_VIRT_BASE - AT91_SRAM_MAX) diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/irqs.h relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/irqs.h --- orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/irqs.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/irqs.h 2011-03-15 10:56:25.885702441 +0100 @@ -45,4 +45,6 @@ /* FIQ is AIC source 0. */ #define FIQ_START AT91_ID_FIQ +#define __IPIPE_FEATURE_PIC_MUTE + #endif diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/timex.h relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/timex.h --- orig/linux-2.6.35.9//arch/arm/mach-at91/include/mach/timex.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/include/mach/timex.h 2011-03-15 10:56:25.885702441 +0100 @@ -87,6 +87,6 @@ #define AT572D940HF_MASTER_CLOCK 80000000 #define CLOCK_TICK_RATE (AT572D940HF_MASTER_CLOCK/16) -#endif +#endif /* arch specific */ #endif diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/irq.c relase/linux-2.6.35.9//arch/arm/mach-at91/irq.c --- orig/linux-2.6.35.9//arch/arm/mach-at91/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/irq.c 2011-03-15 10:56:25.885702441 +0100 @@ -121,6 +121,9 @@ .name = "AIC", .ack = at91_aic_mask_irq, .mask = at91_aic_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = at91_aic_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = at91_aic_unmask_irq, .set_type = at91_aic_set_type, .set_wake = at91_aic_set_wake, diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/Kconfig relase/linux-2.6.35.9//arch/arm/mach-at91/Kconfig --- orig/linux-2.6.35.9//arch/arm/mach-at91/Kconfig 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/Kconfig 2011-03-15 11:01:10.421702442 +0100 @@ -364,6 +364,14 @@ evaluation board. +config MACH_FOXG20 + bool "Acme Systems srl FOX Board G20" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using Acme Systems + FOX Board G20 + + endif # ---------------------------------------------------------- @@ -433,6 +441,19 @@ # ---------------------------------------------------------- +comment "Adeos I-pipe Options" + +config IPIPE_AT91_TC + depends on IPIPE + int "AT91 TC used as time base by Adeos I-pipe" + default 0 + help + When Adeos interrupt pipeline is enabled, TC0 is used by default + as time base, but you can use TC1 or TC2 by setting this variable to 1 + or 2. This should only be needed to avoid conflicts with other drivers. + +# ---------------------------------------------------------- + comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD diff -urN orig/linux-2.6.35.9//arch/arm/mach-at91/Makefile relase/linux-2.6.35.9//arch/arm/mach-at91/Makefile --- orig/linux-2.6.35.9//arch/arm/mach-at91/Makefile 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-at91/Makefile 2011-03-15 11:02:44.401702442 +0100 @@ -65,6 +65,7 @@ obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o +obj-$(CONFIG_MACH_FOXG20) += board-foxg20.o # AT91SAM9G45 board-specific support obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o @@ -89,3 +90,14 @@ ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG endif + +ifeq ($(CONFIG_IPIPE),y) +obj-y := $(filter-out at91rm9200_time.o at91sam926x_time.o at91x40_time.o, $(obj-y)) +obj-$(CONFIG_ARCH_AT91RM9200) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9263) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91X40) += at91_ipipe_time.o +endif diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/core.c relase/linux-2.6.35.9//arch/arm/mach-integrator/core.c --- orig/linux-2.6.35.9//arch/arm/mach-integrator/core.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/core.c 2011-03-15 10:56:25.885702441 +0100 @@ -2,6 +2,7 @@ * linux/arch/arm/mach-integrator/core.c * * Copyright (C) 2000-2003 Deep Blue Solutions Ltd + * Copyright (C) 2005 Stelian Pop. * * 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 diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/entry-macro.S relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/entry-macro.S --- orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/entry-macro.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/entry-macro.S 2011-03-15 10:56:25.885702441 +0100 @@ -29,7 +29,11 @@ teq \irqstat, #0 ldreq \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] moveq \irqnr, #IRQ_CIC_START - +#ifdef CONFIG_IPIPE + tst \irqstat, #0x00000040 @ check IRQ_TIMERINT1 first + movne \irqnr, #6 + bne 1003f +#endif /* CONFIG_IPIPE */ 1001: tst \irqstat, #15 bne 1002f add \irqnr, \irqnr, #4 diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/irqs.h relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/irqs.h --- orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/irqs.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/irqs.h 2011-03-15 10:56:25.885702441 +0100 @@ -79,4 +79,3 @@ #define IRQ_SIC_END 46 #define NR_IRQS 47 - diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/platform.h relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/platform.h --- orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/platform.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/platform.h 2011-03-15 10:56:25.885702441 +0100 @@ -390,7 +390,7 @@ * Timer definitions * * Only use timer 1 & 2 - * (both run at 24MHz and will need the clock divider set to 16). + * (both run at 1MHZ on /CP and at 24MHz on /AP) * * Timer 0 runs at bus frequency */ @@ -399,7 +399,11 @@ #define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100) #define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200) +#ifdef CONFIG_ARCH_INTEGRATOR_CP +#define TICKS_PER_uSEC 1 +#else #define TICKS_PER_uSEC 24 +#endif /* * These are useconds NOT ticks. diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/timex.h relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/timex.h --- orig/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/timex.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/include/mach/timex.h 2011-03-15 10:56:25.889702441 +0100 @@ -21,6 +21,6 @@ */ /* - * ?? + * Timer rate */ -#define CLOCK_TICK_RATE (50000000 / 16) +#define CLOCK_TICK_RATE (1000000) diff -urN orig/linux-2.6.35.9//arch/arm/mach-integrator/integrator_cp.c relase/linux-2.6.35.9//arch/arm/mach-integrator/integrator_cp.c --- orig/linux-2.6.35.9//arch/arm/mach-integrator/integrator_cp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-integrator/integrator_cp.c 2011-03-15 10:56:25.889702441 +0100 @@ -2,6 +2,7 @@ * linux/arch/arm/mach-integrator/integrator_cp.c * * Copyright (C) 2003 Deep Blue Solutions Ltd + * Copyright (C) 2005 Stelian Pop. * * 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 @@ -161,6 +162,9 @@ .name = "CIC", .ack = cic_mask_irq, .mask = cic_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = cic_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = cic_unmask_irq, }; @@ -180,6 +184,9 @@ .name = "PIC", .ack = pic_mask_irq, .mask = pic_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = pic_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = pic_unmask_irq, }; @@ -199,6 +206,9 @@ .name = "SIC", .ack = sic_mask_irq, .mask = sic_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = sic_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = sic_unmask_irq, }; @@ -218,7 +228,7 @@ irq += IRQ_SIC_START; - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); } while (status); } @@ -587,7 +597,7 @@ writel(0, TIMER1_VA_BASE + TIMER_CTRL); writel(0, TIMER2_VA_BASE + TIMER_CTRL); - sp804_clocksource_init(TIMER2_VA_BASE); + sp804_clocksource_init(TIMER2_VA_BASE, INTEGRATOR_TIMER2_BASE); sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-ixp4xx/common.c relase/linux-2.6.35.9//arch/arm/mach-ixp4xx/common.c --- orig/linux-2.6.35.9//arch/arm/mach-ixp4xx/common.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-ixp4xx/common.c 2011-03-15 10:56:25.889702441 +0100 @@ -6,10 +6,10 @@ * Maintainer: Deepak Saxena * * Copyright 2002 (c) Intel Corporation - * Copyright 2003-2004 (c) MontaVista, Software, Inc. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any + * Copyright 2003-2004 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ @@ -44,6 +44,18 @@ static void __init ixp4xx_clockevent_init(void); static struct clock_event_device clockevent_ixp4xx; +#ifdef CONFIG_IPIPE +#include +int __ipipe_mach_timerint = IRQ_IXP4XX_TIMER1; +int __ipipe_mach_timerstolen = 0; +unsigned int __ipipe_mach_ticks_per_jiffy = LATCH; +EXPORT_SYMBOL(__ipipe_mach_timerint); +EXPORT_SYMBOL(__ipipe_mach_timerstolen); +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +#define ONE_SHOT_ENABLE (IXP4XX_OST_ENABLE|IXP4XX_OST_ONE_SHOT) +#endif /* CONFIG_IPIPE */ + /************************************************************************* * IXP4xx chipset I/O mapping *************************************************************************/ @@ -239,7 +251,7 @@ *IXP4XX_ICLR = 0x0; /* Disable all interrupt */ - *IXP4XX_ICMR = 0x0; + *IXP4XX_ICMR = 0x0; if (cpu_is_ixp46x() || cpu_is_ixp43x()) { /* Route upper 32 sources to IRQ instead of FIQ */ @@ -249,7 +261,7 @@ *IXP4XX_ICMR2 = 0x00; } - /* Default to all level triggered */ + /* Default to all level triggered */ for(i = 0; i < NR_IRQS; i++) { set_irq_chip(i, &ixp4xx_irq_chip); set_irq_handler(i, handle_level_irq); @@ -260,7 +272,7 @@ /************************************************************************* * IXP4xx timer tick - * We use OS timer1 on the CPU for the timer tick and the timestamp + * We use OS timer1 on the CPU for the timer tick and the timestamp * counter as a source of real clock ticks to account for missed jiffies. *************************************************************************/ @@ -268,8 +280,12 @@ { struct clock_event_device *evt = dev_id; +#ifndef CONFIG_IPIPE /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; +#else /* CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* CONFIG_IPIPE */ evt->event_handler(evt); @@ -480,6 +496,70 @@ *IXP4XX_OSRT1 = osrt | opts; } +#ifdef CONFIG_IPIPE +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .u = { + { + .counter_paddr = + (IXP4XX_TIMER_BASE_PHYS + IXP4XX_OSTS_OFFSET), + .mask = 0xffffffff, + }, + }, +}; + +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, clockevent_ixp4xx.name); +} + +void __ipipe_mach_acktimer(void) +{ + /* Clear Pending Interrupt by writing '1' to it */ + *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; +} +/* + * Reprogram the timer + * + * The timer is aperiodic (most of the time) when running Xenomai, so + * __ipipe_mach_set_dec is called for each timer tick and programs the + * timer hardware for the next tick. + * + */ +#define MIN_DELAY 333 /* 5 usec with the 66.66 MHz system clock */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > MIN_DELAY) { + *IXP4XX_OSRT1 = delay | ONE_SHOT_ENABLE; + } else { + ipipe_trigger_irq(IRQ_IXP4XX_TIMER1); + } +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +/* + * This returns the number of clock ticks remaining. + */ +unsigned long __ipipe_mach_get_dec(void) +{ + return(*IXP4XX_OST1); /* remaining */ +} +EXPORT_SYMBOL(__ipipe_mach_get_dec); + +void __ipipe_mach_release_timer(void) +{ + unsigned long flags; + + local_irq_save_hw(flags); + ixp4xx_set_mode(clockevent_ixp4xx.mode, &clockevent_ixp4xx); + if (clockevent_ixp4xx.mode == CLOCK_EVT_MODE_ONESHOT) + ixp4xx_set_next_event(LATCH, &clockevent_ixp4xx); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); +#endif /* CONFIG_IPIPE */ + static struct clock_event_device clockevent_ixp4xx = { .name = "ixp4xx timer1", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, @@ -500,4 +580,10 @@ clockevent_ixp4xx.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_ixp4xx); + +#ifdef CONFIG_IPIPE + tsc_info.freq = FREQ; + tsc_info.counter_vaddr = (unsigned long)IXP4XX_OSTS; + __ipipe_tsc_register(&tsc_info); +#endif } diff -urN orig/linux-2.6.35.9//arch/arm/mach-ixp4xx/include/mach/platform.h relase/linux-2.6.35.9//arch/arm/mach-ixp4xx/include/mach/platform.h --- orig/linux-2.6.35.9//arch/arm/mach-ixp4xx/include/mach/platform.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-ixp4xx/include/mach/platform.h 2011-03-15 10:56:25.889702441 +0100 @@ -150,10 +150,14 @@ static inline void gpio_line_config(u8 line, u32 direction) { + unsigned long flags; + + local_irq_save_hw(flags); if (direction == IXP4XX_GPIO_IN) *IXP4XX_GPIO_GPOER |= (1 << line); else *IXP4XX_GPIO_GPOER &= ~(1 << line); + local_irq_restore_hw(flags); } static inline void gpio_line_get(u8 line, int *value) @@ -163,11 +167,14 @@ static inline void gpio_line_set(u8 line, int value) { + unsigned long flags; + + local_irq_save_hw(flags); if (value == IXP4XX_GPIO_HIGH) *IXP4XX_GPIO_GPOUTR |= (1 << line); else if (value == IXP4XX_GPIO_LOW) *IXP4XX_GPIO_GPOUTR &= ~(1 << line); + local_irq_restore_hw(flags); } #endif // __ASSEMBLY__ - diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx1/clock.c relase/linux-2.6.35.9//arch/arm/mach-mx1/clock.c --- orig/linux-2.6.35.9//arch/arm/mach-mx1/clock.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx1/clock.c 2011-03-15 10:56:25.889702441 +0100 @@ -596,7 +596,8 @@ clk_enable(&hclk); clk_enable(&fclk); - mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), TIM1_INT); + mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), + TIM1_BASE_ADDR, TIM1_INT); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx21.c relase/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx21.c --- orig/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx21.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx21.c 2011-03-15 10:56:25.889702441 +0100 @@ -1234,6 +1234,6 @@ #endif mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), - MX21_INT_GPT1); + MX21_GPT1_BASE_ADDR, MX21_INT_GPT1); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx27.c relase/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx27.c --- orig/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx27.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx2/clock_imx27.c 2011-03-15 10:56:25.889702441 +0100 @@ -756,8 +756,7 @@ #endif mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), - MX27_INT_GPT1); + MX27_GPT1_BASE_ADDR, MX27_INT_GPT1); return 0; } - diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx2/devices.c relase/linux-2.6.35.9//arch/arm/mach-mx2/devices.c --- orig/linux-2.6.35.9//arch/arm/mach-mx2/devices.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx2/devices.c 2011-03-15 10:56:25.889702441 +0100 @@ -501,3 +501,13 @@ }; #endif +#ifdef CONFIG_IPIPE +static int post_cpu_init(void) +{ + if (cpu_is_mx27()) + ipipe_mach_allow_hwtimer_uaccess(MX27_AIPI_BASE_ADDR_VIRT, 3); + return 0; +} + +postcore_initcall(post_cpu_init); +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx25/clock.c relase/linux-2.6.35.9//arch/arm/mach-mx25/clock.c --- orig/linux-2.6.35.9//arch/arm/mach-mx25/clock.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx25/clock.c 2011-03-15 10:56:25.889702441 +0100 @@ -242,7 +242,8 @@ /* Clock source for lcdc is upll */ __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7), CRM_BASE + 0x64); - mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); + mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), + MX25_GPT1_BASE_ADDR, 54); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx25/devices.c relase/linux-2.6.35.9//arch/arm/mach-mx25/devices.c --- orig/linux-2.6.35.9//arch/arm/mach-mx25/devices.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx25/devices.c 2011-03-15 10:56:25.889702441 +0100 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -515,3 +516,15 @@ .num_resources = ARRAY_SIZE(mxc_wdt_resources), .resource = mxc_wdt_resources, }; + +#ifdef CONFIG_IPIPE +static int post_cpu_init(void) +{ + if (cpu_is_mx25()) + ipipe_mach_allow_hwtimer_uaccess(MX25_AIPS1_BASE_ADDR_VIRT, + MX25_AIPS2_BASE_ADDR_VIRT); + return 0; +} + +postcore_initcall(post_cpu_init); +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx31.c relase/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx31.c --- orig/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx31.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx31.c 2011-03-15 10:56:25.889702441 +0100 @@ -623,8 +623,7 @@ } mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), - MX31_INT_GPT); + MX31_GPT1_BASE_ADDR, MX31_INT_GPT); return 0; } - diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx35.c relase/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx35.c --- orig/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx35.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx3/clock-imx35.c 2011-03-15 10:56:25.893702441 +0100 @@ -502,9 +502,8 @@ __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); __raw_writel(0, CCM_BASE + CCM_CGR3); - mxc_timer_init(&gpt_clk, - MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); + mxc_timer_init(&gpt_clk, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), + MX35_GPT1_BASE_ADDR, MX35_INT_GPT); return 0; } - diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx3/devices.c relase/linux-2.6.35.9//arch/arm/mach-mx3/devices.c --- orig/linux-2.6.35.9//arch/arm/mach-mx3/devices.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx3/devices.c 2011-03-15 10:56:25.893702441 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -658,3 +659,15 @@ } subsys_initcall(mx3_devices_init); + +#ifdef CONFIG_IPIPE +static int post_cpu_init(void) +{ + if (cpu_is_mx31()) + ipipe_mach_allow_hwtimer_uaccess(AIPS1_BASE_ADDR_VIRT, + AIPS2_BASE_ADDR_VIRT); + return 0; +} + +postcore_initcall(post_cpu_init); +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31_3ds.c relase/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31_3ds.c --- orig/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31_3ds.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31_3ds.c 2011-03-15 10:56:25.893702441 +0100 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -263,7 +264,7 @@ for (; int_valid != 0; int_valid >>= 1, expio_irq++) { if ((int_valid & 1) == 0) continue; - generic_handle_irq(expio_irq); + ipipe_handle_chained_irq(expio_irq); } } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31ads.c relase/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31ads.c --- orig/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31ads.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx3/mach-mx31ads.c 2011-03-15 10:56:25.893702441 +0100 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -134,7 +135,7 @@ if ((int_valid & 1) == 0) continue; - generic_handle_irq(expio_irq); + ipipe_handle_chained_irq(expio_irq); } } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mx5/clock-mx51.c relase/linux-2.6.35.9//arch/arm/mach-mx5/clock-mx51.c --- orig/linux-2.6.35.9//arch/arm/mach-mx5/clock-mx51.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mx5/clock-mx51.c 2011-03-15 10:56:25.893702441 +0100 @@ -866,6 +866,6 @@ /* System timer */ mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), - MX51_MXC_INT_GPT); + MX51_GPT1_BASE_ADDR, MX51_MXC_INT_GPT); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-mxc91231/clock.c relase/linux-2.6.35.9//arch/arm/mach-mxc91231/clock.c --- orig/linux-2.6.35.9//arch/arm/mach-mxc91231/clock.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-mxc91231/clock.c 2011-03-15 10:56:25.893702441 +0100 @@ -634,7 +634,8 @@ clkdev_add_table(lookups, ARRAY_SIZE(lookups)); gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR); - mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT); + mxc_timer_init(&gpt_clk, gpt_base, + MXC91231_GPT1_BASE_ADDR, MXC91231_INT_GPT); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-omap2/irq.c relase/linux-2.6.35.9//arch/arm/mach-omap2/irq.c --- orig/linux-2.6.35.9//arch/arm/mach-omap2/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-omap2/irq.c 2011-03-15 10:56:25.893702441 +0100 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -32,9 +33,16 @@ #define INTC_MIR_CLEAR0 0x0088 #define INTC_MIR_SET0 0x008c #define INTC_PENDING_IRQ0 0x0098 +#define INTC_PRIO 0x0100 /* Number of IRQ state bits in each MIR register */ #define IRQ_BITS_PER_REG 32 +#if !defined(MULTI_OMAP1) && !defined(MULTI_OMAP2) +#define inline_single inline +#else +#define inline_single +#endif + /* * OMAP2 has a number of different interrupt controllers, each interrupt * controller is identified as its own "bank". Register definitions are @@ -66,12 +74,12 @@ /* INTC bank register get/set */ -static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) +static inline_single void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) { __raw_writel(val, bank->base_reg + reg); } -static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) +static inline_single u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) { return __raw_readl(bank->base_reg + reg); } @@ -83,7 +91,7 @@ * an interrupt handler does not get posted before we unmask. Warn about * the interrupt handlers that need to flush posted writes. */ -static int omap_check_spurious(unsigned int irq) +static inline_single int omap_check_spurious(unsigned int irq) { u32 sir, spurious; @@ -101,12 +109,13 @@ } /* XXX: FIQ and additional INTC support (only MPU at the moment) */ -static void omap_ack_irq(unsigned int irq) +static inline_single void omap_ack_irq(unsigned int irq) { intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL); + dsb(); } -static void omap_mask_irq(unsigned int irq) +static inline_single void omap_mask_irq(unsigned int irq) { int offset = irq & (~(IRQ_BITS_PER_REG - 1)); @@ -148,6 +157,7 @@ .name = "INTC", .ack = omap_mask_ack_irq, .mask = omap_mask_irq, + .mask_ack = omap_mask_ack_irq, .unmask = omap_unmask_irq, }; @@ -167,8 +177,15 @@ while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1)) /* Wait for reset to complete */; +#ifndef CONFIG_IPIPE /* Enable autoidle */ intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG); + intc_bank_write_reg(0x2, bank, INTC_IDLE); +#else /* CONFIG_IPIPE */ + /* Disable autoidle */ + intc_bank_write_reg(0, bank, INTC_SYSCONFIG); + intc_bank_write_reg(0x1, bank, INTC_IDLE); +#endif /* CONFIG_IPIPE */ } int omap_irq_pending(void) @@ -227,6 +244,65 @@ } } +#if defined(CONFIG_IPIPE) && defined(__IPIPE_FEATURE_PIC_MUTE) +DECLARE_PER_CPU(__ipipe_irqbits_t, __ipipe_muted_irqs); + +void omap_mute_pic(void) +{ + struct omap_irq_bank *bank = &irq_banks[0]; + unsigned muted; + int i; + + if (cpu_is_omap34xx()) { + intc_bank_write_reg(0x1, bank, INTC_THRESHOLD); + intc_bank_write_reg(0x1, bank, INTC_CONTROL); + return; + } + + for (i = 0; i < INTCPS_NR_MIR_REGS; i++) { + muted = __ipipe_irqbits[i]; + if (muted) + muted &= ~intc_bank_read_reg(bank, + INTC_MIR0 + 0x20 * i); + __raw_get_cpu_var(__ipipe_muted_irqs)[i] = muted; + if (muted) + intc_bank_write_reg(muted, bank, + INTC_MIR_SET0 + 0x20 * i); + } + intc_bank_write_reg(0x1, bank, INTC_CONTROL); +} + +void omap_unmute_pic(void) +{ + struct omap_irq_bank *bank = &irq_banks[0]; + unsigned muted; + int i; + + if (cpu_is_omap34xx()) { + intc_bank_write_reg(0xff, bank, INTC_THRESHOLD); + return; + } + + for (i = 0; i < INTCPS_NR_MIR_REGS; i++) { + muted = __raw_get_cpu_var(__ipipe_muted_irqs)[i]; + if (muted) + intc_bank_write_reg(muted, bank, + INTC_MIR_CLEAR0 + 0x20 * i); + } +} + +void omap_set_irq_prio(int irq, int hi) +{ + if (cpu_is_omap34xx()) { + struct omap_irq_bank *bank = &irq_banks[0]; + + if (irq >= INTCPS_NR_MIR_REGS * 32) + return; + intc_bank_write_reg(hi ? 0 : 0xfc, bank, INTC_PRIO + 4 * irq); + } +} +#endif /* __IPIPE_FEATURE_PIC_MUTE */ + #ifdef CONFIG_ARCH_OMAP3 void omap_intc_save_context(void) { diff -urN orig/linux-2.6.35.9//arch/arm/mach-omap2/timer-gp.c relase/linux-2.6.35.9//arch/arm/mach-omap2/timer-gp.c --- orig/linux-2.6.35.9//arch/arm/mach-omap2/timer-gp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-omap2/timer-gp.c 2011-03-15 10:56:25.897702441 +0100 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -48,13 +49,31 @@ static u8 __initdata gptimer_id = 1; static u8 __initdata inited; struct omap_dm_timer *gptimer_wakeup; +#ifndef CONFIG_OMAP_32K_TIMER +static struct omap_dm_timer *gpt_clocksource; +#endif /* !CONFIG_OMAP_32K_TIMER */ + +#ifdef CONFIG_IPIPE +int __ipipe_mach_timerint; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); +unsigned int __ipipe_mach_ticks_per_jiffy; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +#endif /* CONFIG_IPIPE */ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) { - struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id; struct clock_event_device *evt = &clockevent_gpt; +#ifndef CONFIG_IPIPE + struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id; omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW); +#else /* CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* CONFIG_IPIPE */ evt->event_handler(evt); return IRQ_HANDLED; @@ -124,6 +143,22 @@ return 0; } +#ifdef CONFIG_IPIPE +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .u = { + { + .mask = 0xffffffff, + }, + }, +}; + +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, clockevent_gpt.name); +} +#endif /* CONFIG_IPIPE */ + static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; @@ -131,7 +166,7 @@ inited = 1; - gptimer = omap_dm_timer_request_specific(gptimer_id); + gptimer = omap_dm_timer_request_specific_nonposted(gptimer_id); BUG_ON(gptimer == NULL); gptimer_wakeup = gptimer; @@ -153,6 +188,12 @@ gptimer_id, tick_rate); omap2_gp_timer_irq.dev_id = (void *)gptimer; + +#ifdef CONFIG_IPIPE + __ipipe_mach_timerint = omap_dm_timer_get_irq(gptimer); + __ipipe_mach_ticks_per_jiffy = (tick_rate + HZ / 2) / HZ; +#endif /* CONFIG_IPIPE */ + setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); @@ -163,7 +204,6 @@ clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ - clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); } @@ -171,10 +211,10 @@ /* Clocksource code */ #ifdef CONFIG_OMAP_32K_TIMER -/* +/* * When 32k-timer is enabled, don't use GPTimer for clocksource * instead, just leave default clocksource which uses the 32k - * sync counter. See clocksource setup in see plat-omap/common.c. + * sync counter. See clocksource setup in see plat-omap/common.c. */ static inline void __init omap2_gp_clocksource_init(void) {} @@ -182,7 +222,6 @@ /* * clocksource */ -static struct omap_dm_timer *gpt_clocksource; static cycle_t clocksource_read_cycles(struct clocksource *cs) { return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource); @@ -207,7 +246,11 @@ static char err2[] __initdata = KERN_ERR "%s: can't register clocksource!\n"; +#ifdef CONFIG_IPIPE + gpt = omap_dm_timer_request_specific(3); +#else gpt = omap_dm_timer_request(); +#endif if (!gpt) printk(err1, clocksource_gpt.name); gpt_clocksource = gpt; @@ -218,8 +261,18 @@ omap_dm_timer_set_load_start(gpt, 1, 0); +#ifdef CONFIG_IPIPE + tsc_info.freq = tick_rate; + tsc_info.counter_vaddr = + omap_dm_timer_get_virt_counter_addr(gpt_clocksource); + tsc_info.u.counter_paddr = + omap_dm_timer_get_phys_counter_addr(gpt_clocksource); + __ipipe_tsc_register(&tsc_info); +#endif + clocksource_gpt.mult = clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); + if (clocksource_register(&clocksource_gpt)) printk(err2, clocksource_gpt.name); } @@ -233,6 +286,9 @@ #endif omap_dm_timer_init(); +#ifdef CONFIG_IPIPE + omap2_gp_clockevent_set_gptimer(2); +#endif omap2_gp_clockevent_init(); omap2_gp_clocksource_init(); } @@ -240,3 +296,38 @@ struct sys_timer omap_timer = { .init = omap2_gp_timer_init, }; + +#ifdef CONFIG_IPIPE +void __ipipe_mach_acktimer(void) +{ + omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); + omap_dm_timer_read_status(gptimer); +} + +/* + * Reprogram the timer + */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > 3) + omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - delay); + else + ipipe_trigger_irq(__ipipe_mach_timerint); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + struct clock_event_device *ckdev = &clockevent_gpt; + ckdev->set_mode(ckdev->mode, ckdev); + if (ckdev->mode == CLOCK_EVT_MODE_ONESHOT) + ckdev->set_next_event(__ipipe_mach_ticks_per_jiffy, ckdev); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return 0xffffffff - omap_dm_timer_read_counter(gptimer); +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/irq.c relase/linux-2.6.35.9//arch/arm/mach-pxa/irq.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/irq.c 2011-03-15 10:56:25.897702441 +0100 @@ -51,6 +51,9 @@ .name = "SC", .ack = pxa_mask_irq, .mask = pxa_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = pxa_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = pxa_unmask_irq, }; diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-idp.c relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-idp.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-idp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-idp.c 2011-03-15 10:56:25.897702441 +0100 @@ -13,6 +13,7 @@ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-lubbock.c relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-lubbock.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-lubbock.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-lubbock.c 2011-03-15 10:56:25.897702441 +0100 @@ -12,6 +12,7 @@ */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-mainstone.c relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-mainstone.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/leds-mainstone.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/leds-mainstone.c 2011-03-15 10:56:25.897702441 +0100 @@ -11,6 +11,7 @@ */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/lpd270.c relase/linux-2.6.35.9//arch/arm/mach-pxa/lpd270.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/lpd270.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/lpd270.c 2011-03-15 10:56:25.897702441 +0100 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -128,7 +129,7 @@ desc->chip->ack(irq); /* clear useless edge notification */ if (likely(pending)) { irq = LPD270_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled; diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/lubbock.c relase/linux-2.6.35.9//arch/arm/mach-pxa/lubbock.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/lubbock.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/lubbock.c 2011-03-15 10:56:25.897702441 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -149,7 +150,7 @@ desc->chip->ack(irq); /* clear our parent irq */ if (likely(pending)) { irq = LUBBOCK_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); } pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/mainstone.c relase/linux-2.6.35.9//arch/arm/mach-pxa/mainstone.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/mainstone.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/mainstone.c 2011-03-15 10:56:25.897702441 +0100 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -150,7 +151,7 @@ desc->chip->ack(irq); /* clear useless edge notification */ if (likely(pending)) { irq = MAINSTONE_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); } pending = MST_INTSETCLR & mainstone_irq_enabled; } while (pending); diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/pcm990-baseboard.c relase/linux-2.6.35.9//arch/arm/mach-pxa/pcm990-baseboard.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/pcm990-baseboard.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/pcm990-baseboard.c 2011-03-15 10:56:25.897702441 +0100 @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -268,7 +269,7 @@ desc->chip->ack(irq); /* clear our parent IRQ */ if (likely(pending)) { irq = PCM027_IRQ(0) + __ffs(pending); - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); } pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled; } while (pending); diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/time.c relase/linux-2.6.35.9//arch/arm/mach-pxa/time.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/time.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/time.c 2011-03-15 10:56:25.897702441 +0100 @@ -24,6 +24,28 @@ #include #include +#ifdef CONFIG_IPIPE +int __ipipe_mach_timerint = IRQ_OST0; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen = 0; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); + +unsigned int __ipipe_mach_ticks_per_jiffy = LATCH; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .counter_vaddr = io_p2v(0x40A00010UL), + .u = { + { + .counter_paddr = 0x40A00010UL, + .mask = 0xffffffff, + }, + }, +}; +#endif /* CONFIG_IPIPE */ + /* * This is PXA's sched_clock implementation. This has a resolution * of at least 308 ns and a maximum value of 208 days. @@ -66,8 +88,12 @@ struct clock_event_device *c = dev_id; /* Disarm the compare/match, signal the event. */ +#ifndef CONFIG_IPIPE OIER &= ~OIER_E0; OSSR = OSSR_M0; +#else /* CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* CONFIG_IPIPE */ c->event_handler(c); return IRQ_HANDLED; @@ -78,8 +104,8 @@ { unsigned long next, oscr; - OIER |= OIER_E0; next = OSCR + delta; + OIER |= OIER_E0; OSMR0 = next; oscr = OSCR; @@ -117,6 +143,46 @@ .set_mode = pxa_osmr0_set_mode, }; +#ifdef CONFIG_IPIPE +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, ckevt_pxa_osmr0.name); +} + +void __ipipe_mach_acktimer(void) +{ + OSSR = OSSR_M0; /* Clear match on timer 0 */ + OIER &= ~OIER_E0; +} + +/* + * Reprogram the timer + */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > MIN_OSCR_DELTA) { + OSMR0 = delay + OSCR; + OIER |= OIER_E0; + } else + ipipe_trigger_irq(IRQ_OST0); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + pxa_osmr0_set_mode(ckevt_pxa_osmr0.mode, &ckevt_pxa_osmr0); + if (ckevt_pxa_osmr0.mode == CLOCK_EVT_MODE_ONESHOT) + pxa_osmr0_set_next_event(LATCH, &ckevt_pxa_osmr0); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return OSMR0 - OSCR; +} +#endif /* CONFIG_IPIPE */ + static cycle_t pxa_read_oscr(struct clocksource *cs) { return OSCR; @@ -160,6 +226,11 @@ setup_irq(IRQ_OST0, &pxa_ost0_irq); +#ifdef CONFIG_IPIPE + tsc_info.freq = clock_tick_rate; + __ipipe_tsc_register(&tsc_info); +#endif /* CONFIG_IPIPE */ + clocksource_register(&cksrc_pxa_oscr0); clockevents_register_device(&ckevt_pxa_osmr0); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-pxa/viper.c relase/linux-2.6.35.9//arch/arm/mach-pxa/viper.c --- orig/linux-2.6.35.9//arch/arm/mach-pxa/viper.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-pxa/viper.c 2011-03-15 10:56:25.901702441 +0100 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -287,7 +288,7 @@ if (likely(pending)) { irq = viper_bit_to_irq(__ffs(pending)); - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); } pending = viper_irq_pending(); } while (pending); diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/core.c relase/linux-2.6.35.9//arch/arm/mach-realview/core.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/core.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/core.c 2011-03-15 10:56:25.901702441 +0100 @@ -634,6 +634,7 @@ void __iomem *timer1_va_base; void __iomem *timer2_va_base; void __iomem *timer3_va_base; +void __iomem *timer3_pa_base; /* * Set up the clock source and clock events devices @@ -642,14 +643,14 @@ { u32 val; - /* - * set clock frequency: + /* + * set clock frequency: * REALVIEW_REFCLK is 32KHz * REALVIEW_TIMCLK is 1MHz */ val = readl(__io_address(REALVIEW_SCTL_BASE)); writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) | - (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | + (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) | (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val, __io_address(REALVIEW_SCTL_BASE)); @@ -662,7 +663,7 @@ writel(0, timer2_va_base + TIMER_CTRL); writel(0, timer3_va_base + TIMER_CTRL); - sp804_clocksource_init(timer3_va_base); + sp804_clocksource_init(timer3_va_base, timer3_pa_base); sp804_clockevents_init(timer0_va_base, timer_irq); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/core.h relase/linux-2.6.35.9//arch/arm/mach-realview/core.h --- orig/linux-2.6.35.9//arch/arm/mach-realview/core.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/core.h 2011-03-15 10:56:25.901702441 +0100 @@ -58,6 +58,7 @@ extern void __iomem *timer1_va_base; extern void __iomem *timer2_va_base; extern void __iomem *timer3_va_base; +extern void __iomem *timer3_pa_base; extern void realview_leds_event(led_event_t ledevt); extern void realview_timer_init(unsigned int timer_irq); diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/realview_eb.c relase/linux-2.6.35.9//arch/arm/mach-realview/realview_eb.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/realview_eb.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/realview_eb.c 2011-03-15 10:56:25.901702441 +0100 @@ -395,6 +395,7 @@ timer1_va_base = __io_address(REALVIEW_EB_TIMER0_1_BASE) + 0x20; timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20; + timer3_pa_base = REALVIEW_EB_TIMER2_3_BASE + 0x20; if (core_tile_eb11mp() || core_tile_a9mp()) { #ifdef CONFIG_LOCAL_TIMERS diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pb1176.c relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pb1176.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pb1176.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pb1176.c 2011-03-15 10:56:25.901702441 +0100 @@ -295,6 +295,7 @@ timer1_va_base = __io_address(REALVIEW_PB1176_TIMER0_1_BASE) + 0x20; timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20; + timer3_pa_base = REALVIEW_PB1176_TIMER2_3_BASE + 0x20; realview_timer_init(IRQ_DC1176_TIMER0); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pb11mp.c relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pb11mp.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pb11mp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pb11mp.c 2011-03-15 10:56:25.901702441 +0100 @@ -318,6 +318,7 @@ timer1_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE) + 0x20; timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; + timer3_pa_base = REALVIEW_PB11MP_TIMER2_3_BASE + 0x20; #ifdef CONFIG_LOCAL_TIMERS twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE); diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pba8.c relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pba8.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pba8.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pba8.c 2011-03-15 10:56:25.901702441 +0100 @@ -277,6 +277,7 @@ timer1_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE) + 0x20; timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20; + timer3_pa_base = REALVIEW_PBA8_TIMER2_3_BASE + 0x20; realview_timer_init(IRQ_PBA8_TIMER0_1); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pbx.c relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pbx.c --- orig/linux-2.6.35.9//arch/arm/mach-realview/realview_pbx.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-realview/realview_pbx.c 2011-03-15 10:56:25.901702441 +0100 @@ -324,6 +324,7 @@ timer1_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE) + 0x20; timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; + timer3_pa_base = REALVIEW_PBX_TIMER2_3_BASE + 0x20; #ifdef CONFIG_LOCAL_TIMERS if (core_tile_pbx11mp() || core_tile_pbxa9mp()) diff -urN orig/linux-2.6.35.9//arch/arm/mach-s3c2410/include/mach/irqs.h relase/linux-2.6.35.9//arch/arm/mach-s3c2410/include/mach/irqs.h --- orig/linux-2.6.35.9//arch/arm/mach-s3c2410/include/mach/irqs.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-s3c2410/include/mach/irqs.h 2011-03-15 10:56:25.901702441 +0100 @@ -3,6 +3,8 @@ * Copyright (c) 2003-2005 Simtec Electronics * Ben Dooks * + * Copyright (C) 2006, 2007 Sebastian Smolorz , emlix GmbH + * * 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. diff -urN orig/linux-2.6.35.9//arch/arm/mach-s3c2440/irq.c relase/linux-2.6.35.9//arch/arm/mach-s3c2440/irq.c --- orig/linux-2.6.35.9//arch/arm/mach-s3c2440/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-s3c2440/irq.c 2011-03-15 10:56:25.901702441 +0100 @@ -3,6 +3,8 @@ * Copyright (c) 2003-2004 Simtec Electronics * Ben Dooks * + * Copyright (C) 2006, 2007 Sebastian Smolorz , emlix GmbH + * * 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 @@ -25,6 +27,7 @@ #include #include #include +#include #include #include @@ -57,10 +60,10 @@ if (subsrc != 0) { if (subsrc & 1) { - generic_handle_irq(IRQ_S3C2440_WDT); + ipipe_handle_chained_irq(IRQ_S3C2440_WDT); } if (subsrc & 2) { - generic_handle_irq(IRQ_S3C2440_AC97); + ipipe_handle_chained_irq(IRQ_S3C2440_AC97); } } } diff -urN orig/linux-2.6.35.9//arch/arm/mach-s3c2440/s3c244x-irq.c relase/linux-2.6.35.9//arch/arm/mach-s3c2440/s3c244x-irq.c --- orig/linux-2.6.35.9//arch/arm/mach-s3c2440/s3c244x-irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-s3c2440/s3c244x-irq.c 2011-03-15 10:56:25.901702441 +0100 @@ -3,6 +3,8 @@ * Copyright (c) 2003-2004 Simtec Electronics * Ben Dooks * + * Copyright (C) 2007 Sebastian Smolorz , emlix GmbH + * * 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 @@ -25,6 +27,7 @@ #include #include #include +#include #include #include @@ -57,10 +60,10 @@ if (subsrc != 0) { if (subsrc & 1) { - generic_handle_irq(IRQ_S3C2440_CAM_C); + ipipe_handle_chained_irq(IRQ_S3C2440_CAM_C); } if (subsrc & 2) { - generic_handle_irq(IRQ_S3C2440_CAM_P); + ipipe_handle_chained_irq(IRQ_S3C2440_CAM_P); } } } @@ -89,6 +92,9 @@ .mask = s3c_irq_cam_mask, .unmask = s3c_irq_cam_unmask, .ack = s3c_irq_cam_ack, +#ifdef CONFIG_IPIPE + .mask_ack = s3c_irq_cam_ack, +#endif /* CONFIG_IPIPE */ }; static int s3c244x_irq_add(struct sys_device *sysdev) diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/gpio.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/gpio.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/gpio.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/gpio.c 2011-03-15 10:56:25.901702441 +0100 @@ -32,9 +32,9 @@ { unsigned long flags; - local_irq_save(flags); + local_irq_save_hw(flags); GPDR &= ~GPIO_GPIO(offset); - local_irq_restore(flags); + local_irq_restore_hw(flags); return 0; } @@ -42,10 +42,10 @@ { unsigned long flags; - local_irq_save(flags); + local_irq_save_hw(flags); sa1100_gpio_set(chip, offset, value); GPDR |= GPIO_GPIO(offset); - local_irq_restore(flags); + local_irq_restore_hw(flags); return 0; } diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/irq.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/irq.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/irq.c 2011-03-15 10:56:25.901702441 +0100 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -125,7 +126,7 @@ mask >>= 11; do { if (mask & 1) - generic_handle_irq(irq); + ipipe_handle_chained_irq(irq); mask >>= 1; irq++; } while (mask); @@ -217,6 +218,9 @@ .name = "SC", .ack = sa1100_mask_irq, .mask = sa1100_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = sa1100_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = sa1100_unmask_irq, .set_wake = sa1100_set_wake, }; diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-assabet.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-assabet.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-assabet.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-assabet.c 2011-03-15 10:56:25.901702441 +0100 @@ -10,6 +10,7 @@ * - Red - on if system is not idle */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-badge4.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-badge4.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-badge4.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-badge4.c 2011-03-15 10:56:25.905702441 +0100 @@ -11,6 +11,7 @@ */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-cerf.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-cerf.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-cerf.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-cerf.c 2011-03-15 10:56:25.905702441 +0100 @@ -4,6 +4,7 @@ * Author: ??? */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-hackkit.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-hackkit.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-hackkit.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-hackkit.c 2011-03-15 10:56:25.905702441 +0100 @@ -10,6 +10,7 @@ * as cpu led, the green one is used as timer led. */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-lart.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-lart.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-lart.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-lart.c 2011-03-15 10:56:25.905702441 +0100 @@ -10,6 +10,7 @@ * pace of the LED. */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-simpad.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-simpad.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/leds-simpad.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/leds-simpad.c 2011-03-15 10:56:25.905702441 +0100 @@ -4,6 +4,7 @@ * Author: Juergen Messerer */ #include +#include #include #include diff -urN orig/linux-2.6.35.9//arch/arm/mach-sa1100/time.c relase/linux-2.6.35.9//arch/arm/mach-sa1100/time.c --- orig/linux-2.6.35.9//arch/arm/mach-sa1100/time.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-sa1100/time.c 2011-03-15 10:56:25.905702441 +0100 @@ -14,19 +14,47 @@ #include #include #include +#include #include #include #define MIN_OSCR_DELTA 2 +#ifdef CONFIG_IPIPE +int __ipipe_mach_timerint = IRQ_OST0; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen = 0; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); + +unsigned int __ipipe_mach_ticks_per_jiffy = LATCH; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .freq = CLOCK_TICK_RATE, + .counter_vaddr = io_p2v(0x90000010UL), + .u = { + { + .counter_paddr = 0x90000010UL, + .mask = 0xffffffff, + }, + }, +}; +#endif /* CONFIG_IPIPE */ + static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) { struct clock_event_device *c = dev_id; /* Disarm the compare/match, signal the event. */ +#ifndef CONFIG_IPIPE OIER &= ~OIER_E0; OSSR = OSSR_M0; +#else /* CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* CONFIG_IPIPE */ c->event_handler(c); return IRQ_HANDLED; @@ -71,7 +99,14 @@ .set_mode = sa1100_osmr0_set_mode, }; -static cycle_t sa1100_read_oscr(struct clocksource *s) +#ifdef CONFIG_IPIPE +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, ckevt_sa1100_osmr0.name); +} +#endif /* CONFIG_IPIPE */ + +static cycle_t sa1100_read_oscr(struct clocksource *cs) { return OSCR; } @@ -110,6 +145,10 @@ setup_irq(IRQ_OST0, &sa1100_timer_irq); +#ifdef CONFIG_IPIPE + __ipipe_tsc_register(&tsc_info); +#endif /* CONFIG_IPIPE */ + clocksource_register(&cksrc_sa1100_oscr); clockevents_register_device(&ckevt_sa1100_osmr0); } @@ -150,3 +189,38 @@ .suspend = sa1100_timer_suspend, .resume = sa1100_timer_resume, }; + +#ifdef CONFIG_IPIPE +void __ipipe_mach_acktimer(void) +{ + OSSR = OSSR_M0; /* Clear match on timer 0 */ + OIER &= ~OIER_E0; +} + +/* + * Reprogram the timer + */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > MIN_OSCR_DELTA) { + OSMR0 = delay + OSCR; + OIER |= OIER_E0; + } else + ipipe_trigger_irq(IRQ_OST0); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + sa1100_osmr0_set_mode(ckevt_sa1100_osmr0.mode, &ckevt_sa1100_osmr0); + if (ckevt_sa1100_osmr0.mode == CLOCK_EVT_MODE_ONESHOT) + sa1100_osmr0_set_next_event(LATCH, &ckevt_sa1100_osmr0); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return OSMR0 - OSCR; +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mach-versatile/core.c relase/linux-2.6.35.9//arch/arm/mach-versatile/core.c --- orig/linux-2.6.35.9//arch/arm/mach-versatile/core.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-versatile/core.c 2011-03-15 10:56:25.905702441 +0100 @@ -869,14 +869,14 @@ { u32 val; - /* - * set clock frequency: + /* + * set clock frequency: * VERSATILE_REFCLK is 32KHz * VERSATILE_TIMCLK is 1MHz */ val = readl(__io_address(VERSATILE_SCTL_BASE)); writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, __io_address(VERSATILE_SCTL_BASE)); @@ -889,11 +889,10 @@ writel(0, TIMER2_VA_BASE + TIMER_CTRL); writel(0, TIMER3_VA_BASE + TIMER_CTRL); - sp804_clocksource_init(TIMER3_VA_BASE); + sp804_clocksource_init(TIMER3_VA_BASE, VERSATILE_TIMER2_3_BASE + 0x20); sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1); } struct sys_timer versatile_timer = { .init = versatile_timer_init, }; - diff -urN orig/linux-2.6.35.9//arch/arm/mach-vexpress/ct-ca9x4.c relase/linux-2.6.35.9//arch/arm/mach-vexpress/ct-ca9x4.c --- orig/linux-2.6.35.9//arch/arm/mach-vexpress/ct-ca9x4.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-vexpress/ct-ca9x4.c 2011-03-15 10:56:25.905702441 +0100 @@ -71,7 +71,7 @@ writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); - sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1)); + sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), CT_CA9X4_TIMER1); sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0); } diff -urN orig/linux-2.6.35.9//arch/arm/mach-vexpress/v2m.c relase/linux-2.6.35.9//arch/arm/mach-vexpress/v2m.c --- orig/linux-2.6.35.9//arch/arm/mach-vexpress/v2m.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mach-vexpress/v2m.c 2011-03-15 10:56:25.905702441 +0100 @@ -53,7 +53,7 @@ writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); - sp804_clocksource_init(MMIO_P2V(V2M_TIMER1)); + sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), V2M_TIMER1); sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); } diff -urN orig/linux-2.6.35.9//arch/arm/Makefile relase/linux-2.6.35.9//arch/arm/Makefile --- orig/linux-2.6.35.9//arch/arm/Makefile 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/Makefile 2011-03-15 10:56:26.077702442 +0100 @@ -292,3 +292,5 @@ echo ' (distribution) /sbin/$(INSTALLKERNEL) or' echo ' install to $$(INSTALL_PATH) and run lilo' endef + +drivers-$(CONFIG_XENOMAI) += arch/arm/xenomai/ diff -urN orig/linux-2.6.35.9//arch/arm/mm/alignment.c relase/linux-2.6.35.9//arch/arm/mm/alignment.c --- orig/linux-2.6.35.9//arch/arm/mm/alignment.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/alignment.c 2011-03-15 10:56:25.905702441 +0100 @@ -727,6 +727,9 @@ int isize = 4; int thumb2_32b = 0; + if (ipipe_trap_notify(IPIPE_TRAP_ALIGNMENT,regs)) + return 0; + instrptr = instruction_pointer(regs); fs = get_fs(); diff -urN orig/linux-2.6.35.9//arch/arm/mm/context.c relase/linux-2.6.35.9//arch/arm/mm/context.c --- orig/linux-2.6.35.9//arch/arm/mm/context.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/context.c 2011-03-15 10:56:25.905702441 +0100 @@ -16,12 +16,47 @@ #include #include -static DEFINE_SPINLOCK(cpu_asid_lock); +static IPIPE_DEFINE_SPINLOCK(cpu_asid_lock); unsigned int cpu_last_asid = ASID_FIRST_VERSION; #ifdef CONFIG_SMP DEFINE_PER_CPU(struct mm_struct *, current_mm); #endif +#if defined(CONFIG_IPIPE) && defined(CONFIG_SMP) +/* + * We shall be able to serve interrupts while attempting to grab the + * ASID lock on entry to __new_context(). This is a prerequisite for + * broadcasting VNMIs to other CPUs later on, to have them reset their + * current ASID, without risking deadlocks. I.e. each CPU shall be + * able to reset the current ASID upon a remote request, while trying + * to get a new ASID. + */ +#define asid_lock(flags) \ + do { \ + WARN_ON_ONCE(irqs_disabled_hw()); \ + while (!spin_trylock_irqsave(&cpu_asid_lock, (flags))) \ + cpu_relax(); \ + } while (0) \ + +#define asid_unlock(flags) \ + spin_unlock_irqrestore(&cpu_asid_lock, flags) + +#define asid_broadcast_reset() \ + __ipipe_send_vnmi(reset_context, cpu_online_map, NULL); + +#else /* !(CONFIG_IPIPE && CONFIG_SMP) */ + +#define asid_lock(flags) \ + spin_lock_irqsave_cond(&cpu_asid_lock, flags) + +#define asid_unlock(flags) \ + spin_unlock_irqrestore_cond(&cpu_asid_lock, flags) + +#define asid_broadcast_reset() \ + smp_call_function(reset_context, NULL, 1); + +#endif /* !(CONFIG_IPIPE && CONFIG_SMP) */ + /* * We fork()ed a process, and we need a new context for the child * to run in. We reserve version 0 for initial tasks so we will @@ -72,7 +107,7 @@ /* * Set the mm_cpumask(mm) bit for the current CPU. */ - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + cpumask_set_cpu(ipipe_processor_id(), mm_cpumask(mm)); } /* @@ -82,7 +117,7 @@ static void reset_context(void *info) { unsigned int asid; - unsigned int cpu = smp_processor_id(); + unsigned int cpu = ipipe_processor_id(); struct mm_struct *mm = per_cpu(current_mm, cpu); /* @@ -108,24 +143,26 @@ static inline void set_mm_context(struct mm_struct *mm, unsigned int asid) { mm->context.id = asid; - cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id())); + cpumask_copy(mm_cpumask(mm), cpumask_of(ipipe_processor_id())); } #endif void __new_context(struct mm_struct *mm) { + int cpu = ipipe_processor_id(); + unsigned long flags; unsigned int asid; - spin_lock(&cpu_asid_lock); + asid_lock(flags); #ifdef CONFIG_SMP /* * Check the ASID again, in case the change was broadcast from * another CPU before we acquired the lock. */ if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) { - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); - spin_unlock(&cpu_asid_lock); + cpumask_set_cpu(cpu, mm_cpumask(mm)); + asid_unlock(flags); return; } #endif @@ -143,15 +180,15 @@ * to start a new version and flush the TLB. */ if (unlikely((asid & ~ASID_MASK) == 0)) { - asid = cpu_last_asid + smp_processor_id() + 1; + asid = cpu_last_asid + cpu + 1; flush_context(); #ifdef CONFIG_SMP smp_wmb(); - smp_call_function(reset_context, NULL, 1); + asid_broadcast_reset(); #endif cpu_last_asid += NR_CPUS; } set_mm_context(mm, asid); - spin_unlock(&cpu_asid_lock); + asid_unlock(flags); } diff -urN orig/linux-2.6.35.9//arch/arm/mm/copypage-v4mc.c relase/linux-2.6.35.9//arch/arm/mm/copypage-v4mc.c --- orig/linux-2.6.35.9//arch/arm/mm/copypage-v4mc.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/copypage-v4mc.c 2011-03-15 10:56:25.909702441 +0100 @@ -44,7 +44,7 @@ * instruction. If your processor does not supply this, you have to write your * own copy_user_highpage that does the right thing. */ -static void __naked +static void notrace __naked mc_copy_user_page(void *from, void *to) { asm volatile( diff -urN orig/linux-2.6.35.9//arch/arm/mm/copypage-xscale.c relase/linux-2.6.35.9//arch/arm/mm/copypage-xscale.c --- orig/linux-2.6.35.9//arch/arm/mm/copypage-xscale.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/copypage-xscale.c 2011-03-15 10:56:25.909702441 +0100 @@ -42,7 +42,7 @@ * Dcache aliasing issue. The writes will be forwarded to the write buffer, * and merged as appropriate. */ -static void __naked +static void notrace __naked mc_copy_user_page(void *from, void *to) { /* diff -urN orig/linux-2.6.35.9//arch/arm/mm/fault-armv.c relase/linux-2.6.35.9//arch/arm/mm/fault-armv.c --- orig/linux-2.6.35.9//arch/arm/mm/fault-armv.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/fault-armv.c 2011-03-15 10:56:25.909702441 +0100 @@ -28,6 +28,30 @@ static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +static void fcse_set_pte_shared(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep) +{ + pte_t entry; + + if (!(vma->vm_flags & VM_MAYSHARE) || address >= TASK_SIZE) + return; + + entry = *ptep; + if ((pte_val(entry) + & (L_PTE_PRESENT | PTE_CACHEABLE | L_PTE_WRITE | L_PTE_DIRTY | L_PTE_SHARED)) + == (L_PTE_PRESENT | PTE_CACHEABLE | L_PTE_WRITE | L_PTE_DIRTY)) { + pte_val(entry) |= L_PTE_SHARED; + /* Bypass set_pte_at here, we are not changing + hardware bits, flush is not needed */ + ++vma->vm_mm->context.fcse.shared_dirty_pages; + *ptep = entry; + } +} +#else /* !CONFIG_ARM_FCSE_BEST_EFFORT */ +#define fcse_set_pte_shared(vma, addr, ptep) do { } while (0) +#endif /* !CONFIG_ARM_FCSE_BEST_EFFORT */ + /* * We take the easy way out of this problem - we make the * PTE uncacheable. However, we leave the write buffer on. @@ -65,6 +89,31 @@ return ret; } +#ifndef CONFIG_ARM_FCSE_GUARANTEED +#if USE_SPLIT_PTLOCKS +/* + * If we are using split PTE locks, then we need to take the page + * lock here. Otherwise we are using shared mm->page_table_lock + * which is already locked, thus cannot take it. + */ +static inline void do_pte_lock(spinlock_t *ptl) +{ + /* + * Use nested version here to indicate that we are already + * holding one similar spinlock. + */ + spin_lock_nested(ptl, SINGLE_DEPTH_NESTING); +} + +static inline void do_pte_unlock(spinlock_t *ptl) +{ + spin_unlock(ptl); +} +#else /* !USE_SPLIT_PTLOCKS */ +static inline void do_pte_lock(spinlock_t *ptl) {} +static inline void do_pte_unlock(spinlock_t *ptl) {} +#endif /* USE_SPLIT_PTLOCKS */ + static int adjust_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { @@ -89,20 +138,22 @@ */ ptl = pte_lockptr(vma->vm_mm, pmd); pte = pte_offset_map_nested(pmd, address); - spin_lock(ptl); + do_pte_lock(ptl); ret = do_adjust_pte(vma, address, pfn, pte); - spin_unlock(ptl); + do_pte_unlock(ptl); pte_unmap_nested(pte); return ret; } +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ static void make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, unsigned long pfn) { +#ifndef CONFIG_ARM_FCSE_GUARANTEED struct mm_struct *mm = vma->vm_mm; struct vm_area_struct *mpnt; struct prio_tree_iter iter; @@ -134,6 +185,14 @@ flush_dcache_mmap_unlock(mapping); if (aliases) do_adjust_pte(vma, addr, pfn, ptep); + else { + fcse_set_pte_shared(vma, addr, ptep); + flush_cache_page(vma, addr, pfn); + } +#else /* CONFIG_ARM_FCSE_GUARANTEED */ + if (vma->vm_flags & VM_MAYSHARE) + do_adjust_pte(vma, addr, pfn, ptep); +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ } /* diff -urN orig/linux-2.6.35.9//arch/arm/mm/fault.c relase/linux-2.6.35.9//arch/arm/mm/fault.c --- orig/linux-2.6.35.9//arch/arm/mm/fault.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/fault.c 2011-03-15 10:56:25.909702441 +0100 @@ -74,6 +74,10 @@ if (!mm) mm = &init_mm; +#ifdef CONFIG_ARM_FCSE + printk(KERN_ALERT "fcse pid: %ld, 0x%08lx\n", + mm->context.fcse.pid >> FCSE_PID_SHIFT, mm->context.fcse.pid); +#endif /* CONFIG_ARM_FCSE */ printk(KERN_ALERT "pgd = %p\n", mm->pgd); pgd = pgd_offset(mm, addr); printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); @@ -162,11 +166,21 @@ if (user_debug & UDBG_SEGV) { printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", tsk->comm, sig, addr, fsr); +#ifdef CONFIG_ARM_FCSE_DYNPID + /* Disable preemption to avoid page tables changing under our + feet */ + preempt_disable(); +#endif /* CONFIG_ARM_FCSE_DYNPID */ show_pte(tsk->mm, addr); +#ifdef CONFIG_ARM_FCSE_DYNPID + preempt_enable(); +#endif /* CONFIG_ARM_FCSE_DYNPID */ show_regs(regs); } #endif + fcse_notify_segv(tsk->mm, addr, regs); + tsk->thread.address = addr; tsk->thread.error_code = fsr; tsk->thread.trap_no = 14; @@ -267,6 +281,9 @@ if (notify_page_fault(regs, fsr)) return 0; + if (ipipe_trap_notify(IPIPE_TRAP_ACCESS,regs)) + return 0; + tsk = current; mm = tsk->mm; @@ -393,6 +410,9 @@ if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); + if (ipipe_trap_notify(IPIPE_TRAP_ACCESS,regs)) + return 0; + if (user_mode(regs)) goto bad_area; @@ -439,6 +459,10 @@ static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + + if (ipipe_trap_notify(IPIPE_TRAP_SECTION,regs)) + return 0; + do_bad_area(addr, fsr, regs); return 0; } @@ -449,6 +473,9 @@ static int do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + if (ipipe_trap_notify(IPIPE_TRAP_DABT,regs)) + return 0; + return 1; } @@ -529,6 +556,9 @@ if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) return; + if (ipipe_trap_notify(IPIPE_TRAP_UNKNOWN,regs)) + return; + printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); @@ -594,3 +624,42 @@ arm_notify_die("", regs, &info, ifsr, 0); } +#ifdef CONFIG_IPIPE +extern spinlock_t pgd_lock; +extern struct page *pgd_list; + +static void vmalloc_sync_one(pgd_t *pgd, unsigned long addr) +{ + unsigned int index = pgd_index(addr); + pgd_t *pgd_k; + pmd_t *pmd, *pmd_k; + + pgd += index; + pgd_k = init_mm.pgd + index; + + if (!pgd_present(*pgd)) + set_pgd(pgd, *pgd_k); + + pmd_k = pmd_offset(pgd_k, addr); + pmd = pmd_offset(pgd, addr); + + copy_pmd(pmd, pmd_k); +} + +void __ipipe_pin_range_globally(unsigned long start, unsigned long end) +{ + unsigned long next, addr = start; + + do { + unsigned long flags; + struct page *page; + + next = pgd_addr_end(addr, end); + spin_lock_irqsave(&pgd_lock, flags); + for (page = pgd_list; page; page = (struct page *)page->index) + vmalloc_sync_one(page_address(page), addr); + spin_unlock_irqrestore(&pgd_lock, flags); + + } while (addr = next, addr != end); +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/mm/fcse.c relase/linux-2.6.35.9//arch/arm/mm/fcse.c --- orig/linux-2.6.35.9//arch/arm/mm/fcse.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/fcse.c 2011-03-15 10:56:25.909702441 +0100 @@ -0,0 +1,466 @@ +/* + * arch/arm/kernel/fcse.c + * + * Helper functions for using the ARM Fast Context Switch Extension with + * processors supporting it. + * + * Copyright (C) 2008 Richard Cochran + * Copyright (C) 2009-2011 Gilles Chanteperdrix + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define NR_PIDS (TASK_SIZE / FCSE_PID_TASK_SIZE) +#define PIDS_LONGS ((NR_PIDS + BITS_PER_LONG - 1) / BITS_PER_LONG) + +static IPIPE_DEFINE_SPINLOCK(fcse_lock); +static unsigned long fcse_pids_bits[PIDS_LONGS]; +unsigned long fcse_pids_cache_dirty[PIDS_LONGS]; +EXPORT_SYMBOL(fcse_pids_cache_dirty); + +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +static unsigned random_pid; +struct fcse_user fcse_pids_user[NR_PIDS]; +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ + +static inline void fcse_pid_reference_inner(unsigned pid) +{ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + if (++fcse_pids_user[pid].count == 1) +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ + __set_bit(pid, fcse_pids_bits); +} + +static inline void fcse_pid_dereference(struct mm_struct *mm) +{ + unsigned fcse_pid = mm->context.fcse.pid >> FCSE_PID_SHIFT; + +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + if (--fcse_pids_user[fcse_pid].count == 0) + __clear_bit(fcse_pid, fcse_pids_bits); + + /* + * The following means we suppose that by the time this + * function is called, this mm is out of cache: + * - when the caller is destroy_context, exit_mmap is called + * by mmput before, which flushes the cache; + * - when the caller is fcse_relocate_mm_to_pid from + * fcse_switch_mm_inner, we only relocate when the mm is out + * of cache; + * - when the caller is fcse_relocate_mm_to_pid from + * fcse_relocate_mm_to_null_pid, we flush the cache in this + * function. + */ + if (fcse_pids_user[fcse_pid].mm == mm) { + fcse_pids_user[fcse_pid].mm = NULL; + __clear_bit(fcse_pid, fcse_pids_cache_dirty); + } +#else /* CONFIG_ARM_FCSE_BEST_EFFORT */ + __clear_bit(fcse_pid, fcse_pids_bits); + __clear_bit(fcse_pid, fcse_pids_cache_dirty); +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ +} + +static inline unsigned find_free_pid(unsigned long bits[]) +{ + unsigned fcse_pid; + + fcse_pid = find_next_zero_bit(bits, NR_PIDS, 1); + if (fcse_pid == NR_PIDS) + /* Allocate zero pid last, since zero pid is also used by + processes with address space larger than 32MB in + best-effort mode. */ + if (!test_bit(0, bits)) + fcse_pid = 0; + + return fcse_pid; +} + +void fcse_pid_free(struct mm_struct *mm) +{ + unsigned long flags; + + spin_lock_irqsave(&fcse_lock, flags); + fcse_pid_dereference(mm); + spin_unlock_irqrestore(&fcse_lock, flags); +} + +int fcse_pid_alloc(struct mm_struct *mm) +{ + unsigned long flags; + unsigned fcse_pid; + + spin_lock_irqsave(&fcse_lock, flags); + fcse_pid = find_free_pid(fcse_pids_bits); + if (fcse_pid == NR_PIDS) { + /* Allocate zero pid last, since zero pid is also used by + processes with address space larger than 32MB in + best-effort mode. */ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + if(++random_pid == NR_PIDS) + random_pid = 0; + fcse_pid = random_pid; +#else /* CONFIG_ARM_FCSE_GUARANTEED */ + spin_unlock_irqrestore(&fcse_lock, flags); +#ifdef CONFIG_ARM_FCSE_MESSAGES + printk(KERN_WARNING "FCSE: %s[%d] would exceed the %lu processes limit.\n", + current->comm, current->pid, NR_PIDS); +#endif /* CONFIG_ARM_FCSE_MESSAGES */ + return -EAGAIN; +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ + } + fcse_pid_reference_inner(fcse_pid); + spin_unlock_irqrestore(&fcse_lock, flags); + + return fcse_pid; +} + +static inline void fcse_clear_dirty_all(void) +{ + switch(ARRAY_SIZE(fcse_pids_cache_dirty)) { + case 4: + fcse_pids_cache_dirty[3] = 0UL; + case 3: + fcse_pids_cache_dirty[2] = 0UL; + case 2: + fcse_pids_cache_dirty[1] = 0UL; + case 1: + fcse_pids_cache_dirty[0] = 0UL; + } +} + +unsigned fcse_flush_all_start(void) +{ + if (!cache_is_vivt()) + return 0; + +#ifndef CONFIG_ARM_FCSE_PREEMPT_FLUSH + preempt_disable(); +#endif /* CONFIG_ARM_FCSE_PREEMPT_FLUSH */ + +#if defined(CONFIG_IPIPE) + clear_ti_thread_flag(current_thread_info(), TIF_SWITCHED); +#elif defined(CONFIG_ARM_FCSE_PREEMPT_FLUSH) + return nr_context_switches(); +#endif /* CONFIG_ARM_FCSE_PREEMPT_FLUSH */ + + return 0; +} + +noinline void +fcse_flush_all_done(unsigned seq, unsigned dirty) +{ + unsigned long flags; + + if (!cache_is_vivt()) + return; + + spin_lock_irqsave(&fcse_lock, flags); +#if defined(CONFIG_IPIPE) + if (!test_ti_thread_flag(current_thread_info(), TIF_SWITCHED)) +#elif defined(CONFIG_ARM_FCSE_PREEMPT_FLUSH) + if (seq == nr_context_switches()) +#endif /* CONFIG_ARM_FCSE_PREEMPT_FLUSH */ + fcse_clear_dirty_all(); + + if (dirty && current->mm != &init_mm && current->mm) { + unsigned fcse_pid = + current->mm->context.fcse.pid >> FCSE_PID_SHIFT; + __set_bit(fcse_pid, fcse_pids_cache_dirty); + } + spin_unlock_irqrestore(&fcse_lock, flags); +#ifndef CONFIG_ARM_FCSE_PREEMPT_FLUSH + preempt_enable(); +#endif /* CONFIG_ARM_FCSE_PREEMPT_FLUSH */ +} + +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +/* Called with preemption disabled, mm->mmap_sem being held for writing. */ +static noinline int fcse_relocate_mm_to_pid(struct mm_struct *mm, int fcse_pid) +{ + const unsigned len = pgd_index(FCSE_TASK_SIZE) * sizeof(pgd_t); + unsigned long flags; + pgd_t *from, *to; + + spin_lock_irqsave(&fcse_lock, flags); +#if defined(CONFIG_ARM_FCSE_DYNPID) + /* pid == -1 means find a free pid. */ + if (fcse_pid == -1) { + fcse_pid = find_free_pid(fcse_pids_bits); + if (fcse_pid == NR_PIDS) { + fcse_pid = find_free_pid(fcse_pids_cache_dirty); + if (unlikely(fcse_pid == NR_PIDS)) { + spin_unlock_irqrestore(&fcse_lock, flags); + return -ENOENT; + } + } + } +#endif /* CONFIG_ARM_FCSE_DYNPID */ + fcse_pid_dereference(mm); + fcse_pid_reference_inner(fcse_pid); + fcse_pids_user[fcse_pid].mm = mm; + __set_bit(fcse_pid, fcse_pids_cache_dirty); + spin_unlock_irqrestore(&fcse_lock, flags); + + from = pgd_offset(mm, 0); + mm->context.fcse.pid = fcse_pid << FCSE_PID_SHIFT; + to = pgd_offset(mm, 0); + + memcpy(to, from, len); + memset(from, '\0', len); + barrier(); + clean_dcache_area(from, len); + clean_dcache_area(to, len); + + return fcse_pid; +} + +int fcse_switch_mm_inner(struct mm_struct *prev, struct mm_struct *next) +{ + unsigned fcse_pid = next->context.fcse.pid >> FCSE_PID_SHIFT; + unsigned flush_needed, reused_pid = 0; + unsigned long flags; + + if (unlikely(next == &init_mm)) { + spin_lock_irqsave(&fcse_lock, flags); + goto is_flush_needed; + } + +#ifdef CONFIG_ARM_FCSE_DYNPID + /* + * If the next mm's pid is currently in use, and not by that + * mm, try and find a new, free, pid. + */ + if (unlikely(fcse_pids_user[fcse_pid].mm != next) + && test_bit(fcse_pid, fcse_pids_cache_dirty) + && fcse_pids_user[fcse_pid].mm + && !rwsem_is_locked(&next->mmap_sem) + && !next->context.fcse.large + && !next->core_state) { + int new_fcse_pid = fcse_relocate_mm_to_pid(next, -1); + if (new_fcse_pid >= 0) + fcse_pid = new_fcse_pid; + } +#endif /* CONFIG_ARM_FCSE_DYNPID */ + + spin_lock_irqsave(&fcse_lock, flags); + if (fcse_pids_user[fcse_pid].mm != next) { + if (fcse_pids_user[fcse_pid].mm) + reused_pid = test_bit(fcse_pid, fcse_pids_cache_dirty); + fcse_pids_user[fcse_pid].mm = next; + } + + is_flush_needed: + flush_needed = reused_pid + || next->context.fcse.high_pages + || !prev + || prev->context.fcse.shared_dirty_pages + || prev->context.fcse.high_pages; + + fcse_pid_set(fcse_pid << FCSE_PID_SHIFT); + if (flush_needed) + fcse_clear_dirty_all(); + if (next != &init_mm) + __set_bit(fcse_pid, fcse_pids_cache_dirty); + spin_unlock_irqrestore(&fcse_lock, flags); + + return flush_needed; +} +EXPORT_SYMBOL_GPL(fcse_switch_mm_inner); + +void fcse_pid_reference(unsigned fcse_pid) +{ + unsigned long flags; + + spin_lock_irqsave(&fcse_lock, flags); + fcse_pid_reference_inner(fcse_pid); + spin_unlock_irqrestore(&fcse_lock, flags); +} + +/* Called with mm->mmap_sem write-locked. */ +static noinline void fcse_relocate_mm_to_null_pid(struct mm_struct *mm) +{ + if (!cache_is_vivt()) + return; + + preempt_disable(); + while (fcse_mm_in_cache(mm)) { + unsigned seq; + + preempt_enable(); + + seq = fcse_flush_all_start(); + flush_cache_all(); + + preempt_disable(); + fcse_flush_all_done(seq, 0); + } + + fcse_relocate_mm_to_pid(mm, 0); + barrier(); + flush_tlb_mm(mm); + fcse_pid_set(0); + + preempt_enable(); +} +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ + +unsigned long +fcse_check_mmap_inner(struct mm_struct *mm, unsigned long start_addr, + unsigned long addr, unsigned long len, unsigned long fl) +{ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + unsigned long stack_reserved = + current->signal->rlim[RLIMIT_STACK].rlim_cur; + unsigned long stack_base = PAGE_ALIGN(mm->start_stack) - stack_reserved; + + /* We enfore the RLIMIT_STACK stack size, and here, the return + address would fall in that reserved stack area */ + if ((unsigned long)(addr + len - stack_base) < stack_reserved) { + /* Restart to try and find a hole, once. */ + if (start_addr != TASK_UNMAPPED_BASE && !(fl & MAP_FIXED) + && !mm->context.fcse.large) + return TASK_UNMAPPED_BASE; + + /* Forcibly restart from above the stack */ + if (!(fl & MAP_FIXED)) + return PAGE_ALIGN(mm->start_stack); + + /* If MAP_FIXED is set, we encroach upon the reserved + stack area. No choice. */ + } + + /* Address above 32MB */ + if (addr + len > FCSE_TASK_SIZE && !mm->context.fcse.high_pages) { + /* Restart to try and find a hole, once. */ + if (start_addr != TASK_UNMAPPED_BASE && !(fl & MAP_FIXED)) + return TASK_UNMAPPED_BASE; + + if (!mm->context.fcse.large) { + /* Ok, the process is going to be larger than 32MB */ +#ifdef CONFIG_ARM_FCSE_MSSAGES + printk(KERN_INFO "FCSE: process %u(%s) VM exceeds 32MB.\n", + current->pid, current->comm); +#endif /* CONFIG_ARM_FCSE_MESSAGES */ + mm->context.fcse.large = 1; + } + if (mm->context.fcse.pid) + fcse_relocate_mm_to_null_pid(mm); + } + + return addr; + +#else /* CONFIG_ARM_FCSE_GUARANTEED */ + /* Address above 32MB */ + /* Restart to try and find a hole, once. */ + if (start_addr != TASK_UNMAPPED_BASE && !(fl & MAP_FIXED)) + return TASK_UNMAPPED_BASE; + + /* Fail, no 32MB processes in guaranteed mode. */ +#ifdef CONFIG_ARM_FCSE_MESSAGES + printk(KERN_WARNING "FCSE: process %u(%s) VM would exceed the 32MB limit.\n", + current->pid, current->comm); +#endif /* CONFIG_ARM_FCSE_MESSAGES */ + return -ENOMEM; +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ +} + +#ifdef CONFIG_ARM_FCSE_MESSAGES +#define addr_in_vma(vma, addr) \ + ({ \ + struct vm_area_struct *_vma = (vma); \ + ((unsigned long)((addr) - _vma->vm_start) \ + < (unsigned long)((_vma->vm_end - _vma->vm_start))); \ + }) + +#ifdef CONFIG_DEBUG_USER +static noinline void +dump_vmas(struct mm_struct *mm, unsigned long addr, struct pt_regs *regs) +{ + struct vm_area_struct *vma; + char path[128]; + int locked = 0; + + printk("mappings:\n"); + if (!in_atomic()) + locked = down_read_trylock(&mm->mmap_sem); + for(vma = mm->mmap; vma; vma = vma->vm_next) { + struct file *file = vma->vm_file; + int flags = vma->vm_flags; + const char *name; + + printk("0x%08lx-0x%08lx %c%c%c%c 0x%08llx ", + vma->vm_start, + vma->vm_end, + flags & VM_READ ? 'r' : '-', + flags & VM_WRITE ? 'w' : '-', + flags & VM_EXEC ? 'x' : '-', + flags & VM_MAYSHARE ? 's' : 'p', + ((loff_t)vma->vm_pgoff) << PAGE_SHIFT); + + if (file) + name = d_path(&file->f_path, path, sizeof(path)); + else if ((name = arch_vma_name(vma))) + ; + else if (!vma->vm_mm) + name = "[vdso]"; + else if (vma->vm_start <= mm->start_brk + && vma->vm_end >= mm->brk) + name = "[heap]"; + else if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) + name = "[stack]"; + else + name = ""; + printk("%s", name); + if (addr_in_vma(vma, regs->ARM_pc)) + printk(" <- PC"); + if (addr_in_vma(vma, regs->ARM_sp)) + printk(" <- SP"); + if (addr_in_vma(vma, addr)) + printk("%s fault", + (addr_in_vma(vma, regs->ARM_pc) + || addr_in_vma(vma, regs->ARM_sp) + ? "," : " <-")); + printk("\n"); + } + if (locked) + up_read(&mm->mmap_sem); +} +#endif /* CONFIG_DEBUG_USER */ + +void fcse_notify_segv(struct mm_struct *mm, + unsigned long addr, struct pt_regs *regs) +{ + int locked = 0; + +#if defined(CONFIG_DEBUG_USER) + if (user_debug & UDBG_SEGV) + dump_vmas(mm, addr, regs); +#endif /* CONFIG_DEBUG_USER */ + + if (!in_atomic()) + locked = down_read_trylock(&mm->mmap_sem); + if (find_vma(mm, addr) == find_vma(mm, regs->ARM_sp)) + printk(KERN_INFO "FCSE: process %u(%s) probably overflowed stack at 0x%08lx.\n", + current->pid, current->comm, regs->ARM_pc); + if (locked) + up_read(&mm->mmap_sem); +} +#endif /* CONFIG_ARM_FCSE_MESSAGES */ diff -urN orig/linux-2.6.35.9//arch/arm/mm/flush.c relase/linux-2.6.35.9//arch/arm/mm/flush.c --- orig/linux-2.6.35.9//arch/arm/mm/flush.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/flush.c 2011-03-15 10:56:25.909702441 +0100 @@ -105,7 +105,7 @@ unsigned long uaddr, void *kaddr, unsigned long len) { if (cache_is_vivt()) { - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + if (fcse_mm_in_cache(vma->vm_mm)) { unsigned long addr = (unsigned long)kaddr; __cpuc_coherent_kern_range(addr, addr + len); } @@ -144,6 +144,7 @@ #ifdef CONFIG_SMP preempt_disable(); #endif + fcse_flush_cache_user_range(vma, uaddr, uaddr + len); memcpy(dst, src, len); flush_ptrace_access(vma, page, uaddr, dst, len); #ifdef CONFIG_SMP diff -urN orig/linux-2.6.35.9//arch/arm/mm/ioremap.c relase/linux-2.6.35.9//arch/arm/mm/ioremap.c --- orig/linux-2.6.35.9//arch/arm/mm/ioremap.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/ioremap.c 2011-03-15 10:56:25.909702441 +0100 @@ -302,6 +302,7 @@ } flush_cache_vmap(addr, addr + size); + __ipipe_pin_range_globally(addr, addr + size); return (void __iomem *) (offset + addr); } diff -urN orig/linux-2.6.35.9//arch/arm/mm/Kconfig relase/linux-2.6.35.9//arch/arm/mm/Kconfig --- orig/linux-2.6.35.9//arch/arm/mm/Kconfig 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/Kconfig 2011-03-15 10:56:25.905702441 +0100 @@ -837,3 +837,85 @@ help This option allows the use of custom mandatory barriers included via the mach/barriers.h file. + +config ARM_FCSE + bool "Fast Context Switch Extension (EXPERIMENTAL)" + depends on EXPERIMENTAL && !SMP && (CPU_32v4 || CPU_32v4T || CPU_32v5) + help + The Fast Context Switch Extension (FCSE for short) is an extension of + some ARM processors which allows to switch contexts between processes + without flushing cache and saves a few tens of microseconds in the + worst case. + + Enabling this option makes linux use the FCSE. + + We propose two modes: + - the guaranteed mode: we guarantee that there will never be any cache + flush when switching context, but this means that there can not be + more than 95 running processes in the system, each with a virtual + memory space smaller than 32MB, and that the shared memory + mappings do not use cache; + - the best effort mode: we allow some cache flushes to happen from + time to time, but do not limit the number of processes or the + virtual memory space available for each process, and the shared + memory mappings use cache. + +if ARM_FCSE + +choice + prompt "FCSE mode" + default ARM_FCSE_BEST_EFFORT + help + This option allow setting which FCSE mode will be used. + +config ARM_FCSE_GUARANTEED + bool "guaranteed" + help + Select guaranteed mode. + +config ARM_FCSE_BEST_EFFORT + bool "best effort" + help + Select best-effort mode. + +endchoice + +config ARM_FCSE_DYNPID + bool "Dynamic FCSE pid allocation" + depends on ARM_FCSE_BEST_EFFORT && !IPIPE + help + When this option is enabled, the kernel may decide to change the FCSE + pid of a process when switching context. This helps reducing the + number of cache flushes, but adds some overhead to the context + switches. + +config ARM_FCSE_PREEMPT_FLUSH + bool "Preemptible cache flushes" + default ARM_FCSE_GUARANTEED + help + When FCSE is enabled, some cache flushes happen with preemption + disabled by default, this allows avoiding more cache + flushes, but increases the latency. This option allows making + them preemptible. It probably only make sense in guaranteed mode. + +config ARM_FCSE_MESSAGES + bool "help messages" + default ARM_FCSE_BEST_EFFORT + help + When FCSE is enabled in best-effort mode, due to the VM space + reduction, a too large stack size limit may result in processes + exceeding the 32MB limit too easily. A too small stack size may result + in stack overflows. Enabling this option will print messages in these + situations to assist you in tuning the stack size limit. + + In guaranteed mode, this option will cause message to be printed if + one of the hard limits (95 proceses, 32 MB VM space) is exceeded. + +config ARM_FCSE_DEBUG + bool "FCSE debug" + select ARM_FCSE_MESSAGES + help + This option enables some internal debug checks. It has a high + overhead, and is only useful for debugging the FCSE code. + +endif diff -urN orig/linux-2.6.35.9//arch/arm/mm/Makefile relase/linux-2.6.35.9//arch/arm/mm/Makefile --- orig/linux-2.6.35.9//arch/arm/mm/Makefile 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/Makefile 2011-03-15 10:56:25.905702441 +0100 @@ -100,3 +100,4 @@ obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o +obj-$(CONFIG_ARM_FCSE) += fcse.o diff -urN orig/linux-2.6.35.9//arch/arm/mm/mmap.c relase/linux-2.6.35.9//arch/arm/mm/mmap.c --- orig/linux-2.6.35.9//arch/arm/mm/mmap.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/mmap.c 2011-03-15 10:56:25.909702441 +0100 @@ -29,7 +29,8 @@ { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - unsigned long start_addr; + unsigned long start_addr = addr; + #ifdef CONFIG_CPU_V6 unsigned int cache_type; int do_align = 0, aliasing = 0; @@ -50,6 +51,9 @@ #define aliasing 0 #endif +#ifdef CONFIG_ARM_FCSE + start_addr = addr; +#endif /* CONFIG_ARM_FCSE */ /* * We enforce the MAP_FIXED case. */ @@ -57,7 +61,7 @@ if (aliasing && flags & MAP_SHARED && (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) return -EINVAL; - return addr; + goto found_addr; } if (len > TASK_SIZE) @@ -72,13 +76,13 @@ vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && (!vma || addr + len <= vma->vm_start)) - return addr; + goto found_addr; } if (len > mm->cached_hole_size) { - start_addr = addr = mm->free_area_cache; + start_addr = addr = mm->free_area_cache; } else { - start_addr = addr = TASK_UNMAPPED_BASE; - mm->cached_hole_size = 0; + start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; } full_search: @@ -106,14 +110,31 @@ * Remember the place where we stopped the search: */ mm->free_area_cache = addr + len; - return addr; + goto found_addr; } if (addr + mm->cached_hole_size < vma->vm_start) - mm->cached_hole_size = vma->vm_start - addr; + mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; if (do_align) addr = COLOUR_ALIGN(addr, pgoff); } + + found_addr: +#ifdef CONFIG_ARM_FCSE + { + unsigned long new_addr = fcse_check_mmap_addr(mm, start_addr, + addr, len, flags); + if (new_addr != addr) { + addr = new_addr; + if (!(addr & ~PAGE_MASK)) { + start_addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; + goto full_search; + } + } + } +#endif /* CONFIG_ARM_FCSE */ + return addr; } diff -urN orig/linux-2.6.35.9//arch/arm/mm/pgd.c relase/linux-2.6.35.9//arch/arm/mm/pgd.c --- orig/linux-2.6.35.9//arch/arm/mm/pgd.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/pgd.c 2011-03-15 10:56:25.909702441 +0100 @@ -19,6 +19,41 @@ #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) +#ifdef CONFIG_IPIPE +/* Copied from arch/i386/mm/pgdtable.c, maintains the list of pgds for the + implementation of ipipe_pin_range_globally in arch/arm/mm/fault.c. */ +DEFINE_SPINLOCK(pgd_lock); +struct page *pgd_list; + +#define pgd_list_lock(flags) spin_lock_irqsave(&pgd_lock, flags) +#define pgd_list_unlock(flags) spin_unlock_irqrestore(&pgd_lock, flags) + +static inline void pgd_list_add(pgd_t *pgd) +{ + struct page *page = virt_to_page(pgd); + page->index = (unsigned long)pgd_list; + if (pgd_list) + set_page_private(pgd_list, (unsigned long)&page->index); + pgd_list = page; + set_page_private(page, (unsigned long)&pgd_list); +} + +static inline void pgd_list_del(pgd_t *pgd) +{ + struct page *next, **pprev, *page = virt_to_page(pgd); + next = (struct page *)page->index; + pprev = (struct page **)page_private(page); + *pprev = next; + if (next) + set_page_private(next, (unsigned long)pprev); +} +#else /* !CONFIG_IPIPE */ +#define pgd_list_lock(flags) ((void) (flags)) +#define pgd_list_unlock(flags) ((void) (flags)) +#define pgd_list_add(pgd) do { } while (0) +#define pgd_list_del(pgd) do { } while (0) +#endif /* !CONFIG_IPIPE */ + /* * need to get a 16k page for level 1 */ @@ -27,6 +62,7 @@ pgd_t *new_pgd, *init_pgd; pmd_t *new_pmd, *init_pmd; pte_t *new_pte, *init_pte; + unsigned long flags; new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); if (!new_pgd) @@ -38,12 +74,20 @@ * Copy over the kernel and IO PGD entries */ init_pgd = pgd_offset_k(0); + pgd_list_lock(flags); memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + pgd_list_add(new_pgd); + pgd_list_unlock(flags); clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); if (!vectors_high()) { +#ifdef CONFIG_ARM_FCSE + /* FCSE does not work without high vectors. */ + BUG(); +#endif /* CONFIG_ARM_FCSE */ + /* * On ARM, first page must always be allocated since it * contains the machine vectors. @@ -75,6 +119,7 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) { + unsigned long flags; pmd_t *pmd; pgtable_t pte; @@ -82,7 +127,7 @@ return; /* pgd is always present and good */ - pmd = pmd_off(pgd, 0); + pmd = pmd_off(pgd + pgd_index(fcse_va_to_mva(mm, 0)), 0); if (pmd_none(*pmd)) goto free; if (pmd_bad(*pmd)) { @@ -96,5 +141,8 @@ pte_free(mm, pte); pmd_free(mm, pmd); free: + pgd_list_lock(flags); + pgd_list_del(pgd); + pgd_list_unlock(flags); free_pages((unsigned long) pgd, 2); } diff -urN orig/linux-2.6.35.9//arch/arm/mm/proc-arm920.S relase/linux-2.6.35.9//arch/arm/mm/proc-arm920.S --- orig/linux-2.6.35.9//arch/arm/mm/proc-arm920.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/proc-arm920.S 2011-03-15 10:56:25.909702441 +0100 @@ -346,6 +346,11 @@ ENTRY(cpu_arm920_switch_mm) #ifdef CONFIG_MMU mov ip, #0 +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + cmp r2, #0 + beq 3f +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ +#ifndef CONFIG_ARM_FCSE_GUARANTEED #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @@ -363,6 +368,10 @@ #endif mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache mcr p15, 0, ip, c7, c10, 4 @ drain WB +#endif /* !CONFIG_ARM_FCSE_GUARANTEED */ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +3: +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs #endif diff -urN orig/linux-2.6.35.9//arch/arm/mm/proc-arm926.S relase/linux-2.6.35.9//arch/arm/mm/proc-arm926.S --- orig/linux-2.6.35.9//arch/arm/mm/proc-arm926.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/proc-arm926.S 2011-03-15 10:56:25.909702441 +0100 @@ -362,6 +362,11 @@ ENTRY(cpu_arm926_switch_mm) #ifdef CONFIG_MMU mov ip, #0 +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + cmp r2, #0 + beq 2f +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ +#ifndef CONFIG_ARM_FCSE_GUARANTEED #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @@ -371,6 +376,10 @@ #endif mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache mcr p15, 0, ip, c7, c10, 4 @ drain WB +#endif /* !CONFIG_ARM_FCSE_GUARANTEED */ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +2: +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs #endif diff -urN orig/linux-2.6.35.9//arch/arm/mm/proc-feroceon.S relase/linux-2.6.35.9//arch/arm/mm/proc-feroceon.S --- orig/linux-2.6.35.9//arch/arm/mm/proc-feroceon.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/proc-feroceon.S 2011-03-15 10:56:25.909702441 +0100 @@ -460,6 +460,12 @@ .align 5 ENTRY(cpu_feroceon_switch_mm) #ifdef CONFIG_MMU +#ifndef CONFIG_ARM_FCSE_GUARANTEED +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + cmp r2, #0 + mov r2, lr + beq 2f +#else /* !CONFIG_ARM_FCSE */ /* * Note: we wish to call __flush_whole_cache but we need to preserve * lr to do so. The only way without touching main memory is to @@ -467,12 +473,19 @@ * compensate locally for the skipped ops if it is not set. */ mov r2, lr @ abuse r2 to preserve lr +#endif /* !CONFIG_ARM_FCSE */ bl __flush_whole_cache @ if r2 contains the VM_EXEC bit then the next 2 ops are done already tst r2, #VM_EXEC mcreq p15, 0, ip, c7, c5, 0 @ invalidate I cache mcreq p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_ARM_FCSE +2: +#endif +#else /* CONFIG_ARM_FCSE_GUARANTEED */ + mov r2, lr +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs mov pc, r2 diff -urN orig/linux-2.6.35.9//arch/arm/mm/proc-xscale.S relase/linux-2.6.35.9//arch/arm/mm/proc-xscale.S --- orig/linux-2.6.35.9//arch/arm/mm/proc-xscale.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/mm/proc-xscale.S 2011-03-15 10:56:25.913702441 +0100 @@ -453,9 +453,18 @@ */ .align 5 ENTRY(cpu_xscale_switch_mm) +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT + cmp r2, #0 + beq 2f +#endif /* CONFIG_ARM_FCSE_BEST_EFFORT */ +#ifndef CONFIG_ARM_FCSE_GUARANTEED clean_d_cache r1, r2 mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer +#endif /* CONFIG_ARM_FCSE_GUARANTEED */ +#ifdef CONFIG_ARM_FCSE_BEST_EFFORT +2: +#endif /* !CONFIG_ARM_FCSE_GUARANTEED */ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs cpwait_ret lr, ip diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/cpu.c relase/linux-2.6.35.9//arch/arm/plat-mxc/cpu.c --- orig/linux-2.6.35.9//arch/arm/plat-mxc/cpu.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/cpu.c 2011-03-15 10:56:25.913702441 +0100 @@ -1,5 +1,6 @@ - #include +#include +#include unsigned int __mxc_cpu_type; EXPORT_SYMBOL(__mxc_cpu_type); @@ -9,3 +10,35 @@ __mxc_cpu_type = type; } +#ifdef CONFIG_IPIPE +void ipipe_mach_allow_hwtimer_uaccess(unsigned long aips1, unsigned long aips2) +{ + volatile unsigned long aips_reg; + + if (!cpu_is_mx27()) { + /* + * S/W workaround: Clear the off platform peripheral modules + * Supervisor Protect bit for SDMA to access them. + */ + __raw_writel(0x0, aips1 + 0x40); + __raw_writel(0x0, aips1 + 0x44); + __raw_writel(0x0, aips1 + 0x48); + __raw_writel(0x0, aips1 + 0x4C); + aips_reg = __raw_readl(aips1 + 0x50); + aips_reg &= 0x00FFFFFF; + __raw_writel(aips_reg, aips1 + 0x50); + + __raw_writel(0x0, aips2 + 0x40); + __raw_writel(0x0, aips2 + 0x44); + __raw_writel(0x0, aips2 + 0x48); + __raw_writel(0x0, aips2 + 0x4C); + aips_reg = __raw_readl(aips2 + 0x50); + aips_reg &= 0x00FFFFFF; + __raw_writel(aips_reg, aips2 + 0x50); + } else { + aips_reg = __raw_readl(aips1 + 8); + aips_reg &= ~(1 << aips2); + __raw_writel(aips_reg, aips1 + 8); + } +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/gpio.c relase/linux-2.6.35.9//arch/arm/plat-mxc/gpio.c --- orig/linux-2.6.35.9//arch/arm/plat-mxc/gpio.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/gpio.c 2011-03-15 10:56:25.913702441 +0100 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -86,6 +87,7 @@ { u32 gpio = irq_to_gpio(irq); struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + unsigned long flags; u32 bit, val; int edge; void __iomem *reg = port->base; @@ -119,11 +121,13 @@ return -EINVAL; } + spin_lock_irqsave(&port->lock, flags); reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; val = __raw_readl(reg) & ~(0x3 << (bit << 1)); __raw_writel(val | (edge << (bit << 1)), reg); _clear_gpio_irqstatus(port, gpio & 0x1f); + spin_unlock_irqrestore(&port->lock, flags); return 0; } @@ -161,10 +165,17 @@ while (irq_stat != 0) { int irqoffset = fls(irq_stat) - 1; +#ifdef CONFIG_IPIPE + if (!port->nonroot_gpios) { + local_irq_enable_hw(); + local_irq_disable_hw(); + } +#endif /* CONFIG_IPIPE */ + if (port->both_edges & (1 << irqoffset)) mxc_flip_edge(port, irqoffset); - generic_handle_irq(gpio_irq_no_base + irqoffset); + ipipe_handle_chained_irq(gpio_irq_no_base + irqoffset); irq_stat &= ~(1 << irqoffset); } @@ -311,3 +322,42 @@ return 0; } + +#if defined(CONFIG_IPIPE) && defined(__IPIPE_FEATURE_PIC_MUTE) +extern void tzic_set_irq_prio(int irq, int hi); + +void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + if (desc->chip == &gpio_irq_chip) { + /* It is a gpio. */ + u32 gpio = irq_to_gpio(irq); + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + + if (ipd != &ipipe_root && ++port->nonroot_gpios == 1) { + __ipipe_irqbits[(port->irq / 32)] + &= ~(1 << (port->irq % 32)); + tzic_set_irq_prio(port->irq, 1); + } + } else + tzic_set_irq_prio(irq, ipd != &ipipe_root); +} + +void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + if (desc->chip == &gpio_irq_chip) { + /* It is a gpio. */ + u32 gpio = irq_to_gpio(irq); + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + + if (ipd != &ipipe_root && --port->nonroot_gpios == 0) { + tzic_set_irq_prio(port->irq, 0); + __ipipe_irqbits[(port->irq / 32)] + |= (1 << (port->irq % 32)); + } + } else if (ipd != &ipipe_root) + tzic_set_irq_prio(irq, 0); +} +#endif /* CONFIG_IPIPE && __IPIPE_FEATURE_PIC_MUTE */ diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/common.h relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/common.h --- orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/common.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/common.h 2011-03-15 10:56:25.913702441 +0100 @@ -32,7 +32,7 @@ extern void mx35_init_irq(void); extern void mx51_init_irq(void); extern void mxc91231_init_irq(void); -extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); +extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, unsigned long, int); extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx25_clocks_init(void); @@ -50,4 +50,8 @@ extern void mxc91231_arch_reset(int, const char *); extern void mxc91231_prepare_idle(void); +#ifdef CONFIG_IPIPE +void ipipe_mach_allow_hwtimer_uaccess(unsigned long aips1, unsigned long aips2); +#endif + #endif diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/gpio.h relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/gpio.h --- orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/gpio.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/gpio.h 2011-03-15 10:56:25.913702441 +0100 @@ -37,7 +37,10 @@ int virtual_irq_start; struct gpio_chip chip; u32 both_edges; - spinlock_t lock; + ipipe_spinlock_t lock; +#ifdef CONFIG_IPIPE + unsigned nonroot_gpios; +#endif /* CONFIG_IPIPE */ }; int mxc_gpio_init(struct mxc_gpio_port*, int); diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/irqs.h relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/irqs.h --- orig/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/irqs.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/include/mach/irqs.h 2011-03-15 10:56:25.913702441 +0100 @@ -69,4 +69,8 @@ /* switch betwean IRQ and FIQ */ extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type); +#ifdef CONFIG_MXC_TZIC +#define __IPIPE_FEATURE_PIC_MUTE +#endif /* CONFIG_MXC_TZIC */ + #endif /* __ASM_ARCH_MXC_IRQS_H__ */ diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/irq.c relase/linux-2.6.35.9//arch/arm/plat-mxc/irq.c --- orig/linux-2.6.35.9//arch/arm/plat-mxc/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/irq.c 2011-03-15 10:56:25.913702441 +0100 @@ -105,6 +105,9 @@ static struct irq_chip mxc_avic_chip = { .ack = mxc_mask_irq, .mask = mxc_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = mxc_mask_irq, +#endif .unmask = mxc_unmask_irq, }; @@ -152,4 +155,3 @@ printk(KERN_INFO "MXC IRQ initialized\n"); } - diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/time.c relase/linux-2.6.35.9//arch/arm/plat-mxc/time.c --- orig/linux-2.6.35.9//arch/arm/plat-mxc/time.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/time.c 2011-03-15 10:56:25.913702441 +0100 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,19 @@ #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) #define timer_is_v2() (!timer_is_v1()) +#ifdef CONFIG_IPIPE +int __ipipe_mach_timerint; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen = 0; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); + +unsigned int __ipipe_mach_ticks_per_jiffy = LATCH; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +static unsigned mxc_min_delay; +#endif /* CONFIG_IPIPE */ + static struct clock_event_device clockevent_mxc; static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; @@ -249,7 +263,11 @@ else tstat = __raw_readl(timer_base + MX1_2_TSTAT); +#ifndef CONFIG_IPIPE gpt_irq_acknowledge(); +#else /* !CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* !CONFIG_IPIPE */ evt->event_handler(evt); @@ -292,7 +310,68 @@ return 0; } -void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +#ifdef CONFIG_IPIPE +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .u = { + { + .mask = 0xffffffff, + }, + }, +}; + +int __ipipe_check_tickdev(const char *devname) +{ + return !strcmp(devname, clockevent_mxc.name); +} + +void __ipipe_mach_acktimer(void) +{ + gpt_irq_acknowledge(); +} +/* + * Reprogram the timer + */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > mxc_min_delay) { + unsigned long tcmp; + + if (!timer_is_v2()) { + tcmp = __raw_readl(timer_base + MX1_2_TCN) + delay; + __raw_writel(tcmp, timer_base + MX1_2_TCMP); + } else { + tcmp = __raw_readl(timer_base + V2_TCN) + delay; + __raw_writel(tcmp, timer_base + V2_TCMP); + } + } else + ipipe_trigger_irq(__ipipe_mach_timerint); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + mxc_set_mode(clockevent_mxc.mode, &clockevent_mxc); + if (clockevent_mxc.mode == CLOCK_EVT_MODE_ONESHOT) + clockevent_mxc.set_next_event(LATCH, &clockevent_mxc); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + if (!timer_is_v2()) + return __raw_readl(timer_base + MX1_2_TCMP) + - __raw_readl(timer_base + MX1_2_TCN); + else + return __raw_readl(timer_base + V2_TCMP) + - __raw_readl(timer_base + V2_TCN); +} +#endif /* CONFIG_IPIPE */ + +void __init +mxc_timer_init(struct clk *timer_clk, + void __iomem *base, unsigned long phys, int irq) { uint32_t tctl_val; @@ -320,4 +399,20 @@ /* Make irqs happen */ setup_irq(irq, &mxc_timer_irq); + +#ifdef CONFIG_IPIPE + __ipipe_mach_timerint = irq; + __ipipe_mach_ticks_per_jiffy = (clk_get_rate(timer_clk) + HZ/2) / HZ; + tsc_info.freq = clk_get_rate(timer_clk); + mxc_min_delay = ((__ipipe_cpu_freq + 500000) / 1000000) ?: 1; + + if (timer_is_v1()) { + tsc_info.u.counter_paddr = phys + MX1_2_TCN; + tsc_info.counter_vaddr =(unsigned long)(phys + MX1_2_TCN); + } else { + tsc_info.u.counter_paddr = phys + V2_TCN; + tsc_info.counter_vaddr = (unsigned long)(timer_base + V2_TCN); + } + __ipipe_tsc_register(&tsc_info); +#endif /* CONFIG_IPIPE */ } diff -urN orig/linux-2.6.35.9//arch/arm/plat-mxc/tzic.c relase/linux-2.6.35.9//arch/arm/plat-mxc/tzic.c --- orig/linux-2.6.35.9//arch/arm/plat-mxc/tzic.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-mxc/tzic.c 2011-03-15 10:56:25.913702441 +0100 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -108,9 +109,33 @@ .name = "MXC_TZIC", .ack = tzic_mask_irq, .mask = tzic_mask_irq, +#ifdef CONFIG_IPIPE + .mask_ack = tzic_mask_irq, +#endif /* CONFIG_IPIPE */ .unmask = tzic_unmask_irq, .set_wake = tzic_set_wake_irq, }; +#if defined(CONFIG_IPIPE) && defined(__IPIPE_FEATURE_PIC_MUTE) +DEFINE_PER_CPU(__ipipe_irqbits_t, __ipipe_muted_irqs); + +void tzic_set_irq_prio(unsigned irq, unsigned hi) +{ + if (irq >= MXC_INTERNAL_IRQS) + return; + + __raw_writeb(hi ? 0 : 0x80, tzic_base + TZIC_PRIORITY0 + irq); +} + +void ipipe_mute_pic(void) +{ + __raw_writel(0x10, tzic_base + TZIC_PRIOMASK); +} + +void ipipe_unmute_pic(void) +{ + __raw_writel(0xf0, tzic_base + TZIC_PRIOMASK); +} +#endif /* CONFIG_IPIPE && __IPIPE_FEATURE_PIC_MUTE */ /* * This function initializes the TZIC hardware and disables all the @@ -128,8 +153,13 @@ i = __raw_readl(tzic_base + TZIC_INTCNTL); __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL); +#ifndef CONFIG_IPIPE __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK); __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL); +#else + __raw_writel(0xf0, tzic_base + TZIC_PRIOMASK); + __raw_writel(0, tzic_base + TZIC_SYNCCTRL); +#endif for (i = 0; i < 4; i++) __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); diff -urN orig/linux-2.6.35.9//arch/arm/plat-omap/dmtimer.c relase/linux-2.6.35.9//arch/arm/plat-omap/dmtimer.c --- orig/linux-2.6.35.9//arch/arm/plat-omap/dmtimer.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-omap/dmtimer.c 2011-03-15 10:56:25.913702441 +0100 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -328,7 +329,7 @@ } } -static void omap_dm_timer_reset(struct omap_dm_timer *timer) +static void omap_dm_timer_reset(struct omap_dm_timer *timer, int posted) { u32 l; @@ -339,8 +340,13 @@ omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); +#if !defined(CONFIG_IPIPE) l |= 0x02 << 3; /* Set to smart-idle mode */ - l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ + l |= 0x2 << 8; /* Set clock activity to perserve f-clock on + * idle */ +#else /* IPIPE */ + l = (0x3 << 8) | (l & (1 << 5)) | (0x1 << 3) | (l & (1 << 2)); +#endif /* IPIPE */ /* * Enable wake-up on OMAP2 CPUs. @@ -351,14 +357,14 @@ /* Match hardware reset default of posted mode */ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, - OMAP_TIMER_CTRL_POSTED); - timer->posted = 1; + posted ? OMAP_TIMER_CTRL_POSTED : 0); + timer->posted = posted; } -static void omap_dm_timer_prepare(struct omap_dm_timer *timer) +static void omap_dm_timer_prepare(struct omap_dm_timer *timer, int posted) { omap_dm_timer_enable(timer); - omap_dm_timer_reset(timer); + omap_dm_timer_reset(timer, posted); } struct omap_dm_timer *omap_dm_timer_request(void) @@ -379,13 +385,14 @@ spin_unlock_irqrestore(&dm_timer_lock, flags); if (timer != NULL) - omap_dm_timer_prepare(timer); + omap_dm_timer_prepare(timer, 1); return timer; } EXPORT_SYMBOL_GPL(omap_dm_timer_request); -struct omap_dm_timer *omap_dm_timer_request_specific(int id) +static struct omap_dm_timer * +omap_dm_timer_request_specific_inner(int id, int posted) { struct omap_dm_timer *timer; unsigned long flags; @@ -403,16 +410,26 @@ timer->reserved = 1; spin_unlock_irqrestore(&dm_timer_lock, flags); - omap_dm_timer_prepare(timer); + omap_dm_timer_prepare(timer, posted); return timer; } +struct omap_dm_timer *omap_dm_timer_request_specific(int id) +{ + return omap_dm_timer_request_specific_inner(id, 1); +} EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific); +struct omap_dm_timer *omap_dm_timer_request_specific_nonposted(int id) +{ + return omap_dm_timer_request_specific_inner(id, 0); +} +EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific_nonposted); + void omap_dm_timer_free(struct omap_dm_timer *timer) { omap_dm_timer_enable(timer); - omap_dm_timer_reset(timer); + omap_dm_timer_reset(timer, 1); omap_dm_timer_disable(timer); WARN_ON(!timer->reserved); @@ -458,6 +475,18 @@ } EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq); +#ifdef CONFIG_IPIPE +unsigned long omap_dm_timer_get_phys_counter_addr(struct omap_dm_timer *timer) +{ + return timer->phys_base + (OMAP_TIMER_COUNTER_REG & 0xff); +} + +unsigned long omap_dm_timer_get_virt_counter_addr(struct omap_dm_timer *timer) +{ + return (unsigned long)timer->io_base + (OMAP_TIMER_COUNTER_REG & 0xff); +} +#endif /* CONFIG_IPIPE */ + #if defined(CONFIG_ARCH_OMAP1) /** diff -urN orig/linux-2.6.35.9//arch/arm/plat-omap/gpio.c relase/linux-2.6.35.9//arch/arm/plat-omap/gpio.c --- orig/linux-2.6.35.9//arch/arm/plat-omap/gpio.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-omap/gpio.c 2011-03-15 10:56:25.913702441 +0100 @@ -20,7 +20,9 @@ #include #include #include +#include /* For irq_desc */ #include +#include #include #include @@ -200,11 +202,14 @@ #endif u32 level_mask; u32 toggle_mask; - spinlock_t lock; + ipipe_spinlock_t lock; struct gpio_chip chip; struct clk *dbck; u32 mod_usage; u32 dbck_enable_mask; +#ifdef CONFIG_IPIPE + unsigned nonroot_gpios; +#endif }; #define METHOD_MPUIO 0 @@ -214,6 +219,12 @@ #define METHOD_GPIO_24XX 5 #define METHOD_GPIO_44XX 6 +#if !defined(MULTI_OMAP1) && !defined(MULTI_OMAP2) +#define inline_single inline +#else +#define inline_single +#endif + #ifdef CONFIG_ARCH_OMAP16XX static struct gpio_bank gpio_bank_1610[5] = { { OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE, @@ -339,6 +350,12 @@ static struct gpio_bank *gpio_bank; static int gpio_bank_count; +#ifdef CONFIG_IPIPE +#ifdef __IPIPE_FEATURE_PIC_MUTE +DEFINE_PER_CPU(__ipipe_irqbits_t, __ipipe_muted_irqs); +#endif /* __IPIPE_FEATURE_PIC_MUTE */ +#endif /* CONFIG_IPIPE */ + static inline struct gpio_bank *get_gpio_bank(int gpio) { if (cpu_is_omap15xx()) { @@ -397,7 +414,7 @@ return -1; } -static int check_gpio(int gpio) +static inline_single int check_gpio(int gpio) { if (unlikely(gpio_valid(gpio) < 0)) { printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); @@ -760,7 +777,7 @@ * This only applies to chips that can't do both rising and falling edge * detection at once. For all other chips, this function is a noop. */ -static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +static inline_single void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) { void __iomem *reg = bank->base; u32 l = 0; @@ -793,7 +810,7 @@ } #endif -static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) +static inline_single int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { void __iomem *reg = bank->base; u32 l = 0; @@ -916,7 +933,7 @@ return retval; } -static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) +static inline_single void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) { void __iomem *reg = bank->base; @@ -977,7 +994,7 @@ _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); } -static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) +static inline_single u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; int inv = 0; @@ -1036,7 +1053,7 @@ return l; } -static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) +static inline_single void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) { void __iomem *reg = bank->base; u32 l; @@ -1320,6 +1337,13 @@ u32 isr_saved, level_mask = 0; u32 enabled; +#ifdef CONFIG_IPIPE + if (!bank->nonroot_gpios) { + local_irq_enable_hw(); + local_irq_disable_hw(); + } +#endif /* CONFIG_IPIPE */ + enabled = _get_gpio_irqbank_mask(bank); isr_saved = isr = __raw_readl(isr_reg) & enabled; @@ -1356,6 +1380,13 @@ if (!(isr & 1)) continue; +#ifdef CONFIG_IPIPE + if (!bank->nonroot_gpios) { + local_irq_enable_hw(); + local_irq_disable_hw(); + } +#endif /* CONFIG_IPIPE */ + #ifdef CONFIG_ARCH_OMAP1 /* * Some chips can't respond to both rising and falling @@ -1367,8 +1398,7 @@ if (bank->toggle_mask & (1 << gpio_index)) _toggle_gpio_edge_triggering(bank, gpio_index); #endif - - generic_handle_irq(gpio_irq); + ipipe_handle_chained_irq(gpio_irq); } } /* if bank has any level sensitive GPIO pin interrupt @@ -1405,6 +1435,16 @@ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); } +static void gpio_mask_ack_irq(unsigned int irq) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank = get_irq_chip_data(irq); + + _set_gpio_irqenable(bank, gpio, 0); + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); + _clear_gpio_irqstatus(bank, gpio); +} + static void gpio_unmask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; @@ -1431,6 +1471,7 @@ .shutdown = gpio_irq_shutdown, .ack = gpio_ack_irq, .mask = gpio_mask_irq, + .mask_ack = gpio_mask_ack_irq, .unmask = gpio_unmask_irq, .set_type = gpio_irq_type, .set_wake = gpio_wake_enable, @@ -1935,6 +1976,11 @@ set_irq_chained_handler(bank->irq, gpio_irq_handler); set_irq_data(bank->irq, bank); +#ifdef CONFIG_IPIPE + __ipipe_irqbits[1 << (bank->irq / 32)] + |= (1 << (bank->irq % 32)); +#endif + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { sprintf(clk_name, "gpio%d_dbck", i + 1); bank->dbck = clk_get(NULL, clk_name); @@ -1959,6 +2005,92 @@ return 0; } +#if defined(CONFIG_IPIPE) && defined(__IPIPE_FEATURE_PIC_MUTE) +extern void omap_set_irq_prio(int irq, int hi); +extern void omap_mute_pic(void); +extern void omap_unmute_pic(void); + +void __ipipe_mach_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + if (desc->chip == &gpio_irq_chip +#ifdef CONFIG_ARCH_OMAP1 + || desc->chip == &mpuio_irq_chip +#endif + ) { + /* It is a gpio. */ + struct gpio_bank *bank = get_irq_chip_data(irq); + + if (ipd != &ipipe_root && ++bank->nonroot_gpios == 1) { + __ipipe_irqbits[(bank->irq / 32)] + &= ~(1 << (bank->irq % 32)); + omap_set_irq_prio(bank->irq, 1); + } + } else + omap_set_irq_prio(irq, ipd != &ipipe_root); +} + +void __ipipe_mach_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + if (desc->chip == &gpio_irq_chip +#ifdef CONFIG_ARCH_OMAP1 + || desc->chip == &mpuio_irq_chip +#endif + ) { + /* It is a gpio. */ + struct gpio_bank *bank = get_irq_chip_data(irq); + + if (ipd != &ipipe_root && --bank->nonroot_gpios == 0) { + omap_set_irq_prio(bank->irq, 0); + __ipipe_irqbits[(bank->irq / 32)] + |= (1 << (bank->irq % 32)); + } + } else if (ipd != &ipipe_root) + omap_set_irq_prio(irq, 0); +} + +void ipipe_mute_pic(void) +{ + unsigned muted; + unsigned i; + + omap_mute_pic(); + + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + if (!bank->nonroot_gpios) + continue; + + muted = __ipipe_irqbits[IH_GPIO_BASE / 32 + i]; + if (muted) + muted &= _get_gpio_irqbank_mask(bank); + __raw_get_cpu_var(__ipipe_muted_irqs)[IH_GPIO_BASE / 32 + i] = muted; + if (muted) + _enable_gpio_irqbank(bank, muted, 0); + } +} + +void ipipe_unmute_pic(void) +{ + unsigned muted; + unsigned i; + + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + if (!bank->nonroot_gpios) + continue; + + muted = __raw_get_cpu_var(__ipipe_muted_irqs)[IH_GPIO_BASE / 32 + i]; + if (muted) + _enable_gpio_irqbank(bank, muted, 1); + } + + omap_unmute_pic(); +} +#endif /* CONFIG_IPIPE && __IPIPE_FEATURE_PIC_MUTE */ + #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) { diff -urN orig/linux-2.6.35.9//arch/arm/plat-omap/include/plat/dmtimer.h relase/linux-2.6.35.9//arch/arm/plat-omap/include/plat/dmtimer.h --- orig/linux-2.6.35.9//arch/arm/plat-omap/include/plat/dmtimer.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-omap/include/plat/dmtimer.h 2011-03-15 10:56:25.917702441 +0100 @@ -56,6 +56,11 @@ void omap_dm_timer_disable(struct omap_dm_timer *timer); int omap_dm_timer_get_irq(struct omap_dm_timer *timer); +#ifdef CONFIG_IPIPE +struct omap_dm_timer *omap_dm_timer_request_specific_nonposted(int timer_id); +unsigned long omap_dm_timer_get_phys_counter_addr(struct omap_dm_timer *timer); +unsigned long omap_dm_timer_get_virt_counter_addr(struct omap_dm_timer *timer); +#endif /* CONFIG_IPIPE */ u32 omap_dm_timer_modify_idlect_mask(u32 inputmask); struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer); diff -urN orig/linux-2.6.35.9//arch/arm/plat-omap/include/plat/irqs.h relase/linux-2.6.35.9//arch/arm/plat-omap/include/plat/irqs.h --- orig/linux-2.6.35.9//arch/arm/plat-omap/include/plat/irqs.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-omap/include/plat/irqs.h 2011-03-15 10:56:25.917702441 +0100 @@ -416,6 +416,8 @@ #define INTCPS_NR_MIR_REGS 3 #define INTCPS_NR_IRQS 96 +#define __IPIPE_FEATURE_PIC_MUTE + #ifndef __ASSEMBLY__ extern void omap_init_irq(void); extern int omap_irq_pending(void); diff -urN orig/linux-2.6.35.9//arch/arm/plat-omap/Kconfig relase/linux-2.6.35.9//arch/arm/plat-omap/Kconfig --- orig/linux-2.6.35.9//arch/arm/plat-omap/Kconfig 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-omap/Kconfig 2011-03-15 10:56:25.913702441 +0100 @@ -129,6 +129,7 @@ timer provides more intra-tick resolution than the 32KHz timer, but consumes more power. +if !IPIPE config OMAP_32K_TIMER bool "Use 32KHz timer" depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS @@ -138,6 +139,7 @@ support for no tick during idle. The 32KHz timer provides less intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is currently only available for OMAP16XX, 24XX, 34XX and OMAP4. +endif endchoice diff -urN orig/linux-2.6.35.9//arch/arm/plat-pxa/gpio.c relase/linux-2.6.35.9//arch/arm/plat-pxa/gpio.c --- orig/linux-2.6.35.9//arch/arm/plat-pxa/gpio.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-pxa/gpio.c 2011-03-15 10:56:25.917702441 +0100 @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -39,7 +40,7 @@ #endif }; -static DEFINE_SPINLOCK(gpio_lock); +static IPIPE_DEFINE_SPINLOCK(gpio_lock); static struct pxa_gpio_chip *pxa_gpio_chips; #define for_each_gpio_chip(i, c) \ @@ -220,7 +221,7 @@ while (n < BITS_PER_LONG) { loop = 1; - generic_handle_irq(gpio_to_irq(gpio_base + n)); + ipipe_handle_chained_irq(gpio_to_irq(gpio_base + n)); n = find_next_bit(&gedr, BITS_PER_LONG, n + 1); } } diff -urN orig/linux-2.6.35.9//arch/arm/plat-s3c24xx/irq.c relase/linux-2.6.35.9//arch/arm/plat-s3c24xx/irq.c --- orig/linux-2.6.35.9//arch/arm/plat-s3c24xx/irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-s3c24xx/irq.c 2011-03-15 10:56:25.917702441 +0100 @@ -3,6 +3,8 @@ * Copyright (c) 2003-2004 Simtec Electronics * Ben Dooks * + * Copyright (C) 2006, 2007 Sebastian Smolorz , emlix GmbH + * * 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 @@ -23,6 +25,7 @@ #include #include #include +#include #include #include @@ -87,6 +90,9 @@ .name = "s3c-level", .ack = s3c_irq_maskack, .mask = s3c_irq_mask, +#ifdef CONFIG_IPIPE + .mask_ack = s3c_irq_maskack, +#endif /* CONFIG_IPIPE */ .unmask = s3c_irq_unmask, .set_wake = s3c_irq_wake }; @@ -283,6 +289,9 @@ .mask = s3c_irq_uart0_mask, .unmask = s3c_irq_uart0_unmask, .ack = s3c_irq_uart0_ack, +#ifdef CONFIG_IPIPE + .mask_ack = s3c_irq_uart0_ack, +#endif /* CONFIG_IPIPE */ }; /* UART1 */ @@ -310,6 +319,9 @@ .mask = s3c_irq_uart1_mask, .unmask = s3c_irq_uart1_unmask, .ack = s3c_irq_uart1_ack, +#ifdef CONFIG_IPIPE + .mask_ack = s3c_irq_uart1_ack, +#endif /* CONFIG_IPIPE */ }; /* UART2 */ @@ -337,6 +349,9 @@ .mask = s3c_irq_uart2_mask, .unmask = s3c_irq_uart2_unmask, .ack = s3c_irq_uart2_ack, +#ifdef CONFIG_IPIPE + .mask_ack = s3c_irq_uart2_ack, +#endif /* CONFIG_IPIPE */ }; /* ADC and Touchscreen */ @@ -385,10 +400,10 @@ if (subsrc != 0) { if (subsrc & 1) { - generic_handle_irq(IRQ_TC); + ipipe_handle_chained_irq(IRQ_TC); } if (subsrc & 2) { - generic_handle_irq(IRQ_ADC); + ipipe_handle_chained_irq(IRQ_ADC); } } } @@ -413,13 +428,13 @@ if (subsrc != 0) { if (subsrc & 1) - generic_handle_irq(start); + ipipe_handle_chained_irq(start); if (subsrc & 2) - generic_handle_irq(start+1); + ipipe_handle_chained_irq(start+1); if (subsrc & 4) - generic_handle_irq(start+2); + ipipe_handle_chained_irq(start+2); } } @@ -466,7 +481,7 @@ eintpnd &= ~(1< * + * Copyright (C) 2006, 2007 Sebastian Smolorz , emlix GmbH + * * 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 @@ -27,6 +29,7 @@ #include #include #include +#include #include #include @@ -42,7 +45,6 @@ #include #include -static unsigned long timer_startval; static unsigned long timer_usec_ticks; #ifndef TICK_MAX @@ -61,6 +63,35 @@ * Original patch by Dimitry Andric, updated by Ben Dooks */ +static unsigned long last_free_running_tcnt = 0; +static unsigned long free_running_tcon = 0; +static unsigned long timer_lxlost = 0; + +#ifdef CONFIG_IPIPE +unsigned int __ipipe_mach_ticks_per_jiffy; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +int __ipipe_mach_timerint = IRQ_TIMER4; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +static unsigned long timer_ackval = 1UL << (IRQ_TIMER4 - IRQ_EINT0); + +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_DECREMENTER, + .counter_vaddr = (unsigned long)S3C2410_TCNTO(3), + .u = { + { + .counter_paddr = 0x51000038UL, + .mask = 0xffff, + }, + }, +}; + +static IPIPE_DEFINE_SPINLOCK(timer_lock); + +int __ipipe_mach_timerstolen = 0; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); +#endif /* CONFIG_IPIPE */ /* timer_mask_usec_ticks * @@ -91,40 +122,45 @@ return res >> TIMER_USEC_SHIFT; } -/*** - * Returns microsecond since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - * IRQs are disabled before entering here from do_gettimeofday() - */ - -static unsigned long s3c2410_gettimeoffset (void) +static inline unsigned long timer_freerunning_getvalue(void) { - unsigned long tdone; - unsigned long tval; + return __raw_readl(S3C2410_TCNTO(3)); +} - /* work out how many ticks have gone since last timer interrupt */ +static inline unsigned long timer_freerunning_getticksoffset(unsigned long tval) +{ + long tdone; - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; + tdone = last_free_running_tcnt - tval; + if (tdone < 0) + tdone += 0x10000; - /* check to see if there is an interrupt pending */ + return tdone; +} - if (s3c24xx_ostimer_pending()) { - /* re-read the timer, and try and fix up for the missed - * interrupt. Note, the interrupt may go off before the - * timer has re-loaded from wrapping. - */ +static inline unsigned long getticksoffset(void) +{ + return timer_freerunning_getticksoffset(timer_freerunning_getvalue()); +} - tval = __raw_readl(S3C2410_TCNTO(4)); - tdone = timer_startval - tval; +#ifdef CONFIG_IPIPE +static inline unsigned long getticksoffset_tscupdate(void) +{ + unsigned long tval; + unsigned long ticks; - if (tval != 0) - tdone += timer_startval; + tval = timer_freerunning_getvalue(); + ticks = timer_freerunning_getticksoffset(tval); + last_free_running_tcnt = tval; + __ipipe_tsc_update(); + return ticks; } - - return timer_ticks_to_usec(tdone); +#else +static unsigned long s3c2410_gettimeoffset (void) +{ + return timer_ticks_to_usec(timer_lxlost + getticksoffset()); } - +#endif /* CONFIG_IPIPE */ /* * IRQ handler for the timer @@ -132,6 +168,16 @@ static irqreturn_t s3c2410_timer_interrupt(int irq, void *dev_id) { +#ifdef CONFIG_IPIPE + timer_lxlost = 0; + + if (!__ipipe_mach_timerstolen) { + spin_lock(&timer_lock); + getticksoffset_tscupdate(); + spin_unlock(&timer_lock); + } +#endif /* CONFIG_IPIPE */ + timer_tick(); return IRQ_HANDLED; } @@ -153,10 +199,10 @@ static struct clk *timerclk; /* - * Set up timer interrupt, and return the current time in seconds. + * Set up timer interrupt. * - * Currently we only use timer4, as it is the only timer which has no - * other function that can be exploited externally + * Currently we use timer4 as event timer and timer3 as tick counter which + * permanently counts ticks without interrupt generation. */ static void s3c2410_timer_setup (void) { @@ -164,6 +210,7 @@ unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; + unsigned long intmask; tcnt = TICK_MAX; /* default value for tcnt */ @@ -175,8 +222,8 @@ tcnt = 12000000 / HZ; tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; - tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; + tcfg1 &= ~(S3C2410_TCFG1_MUX4_MASK | S3C2410_TCFG1_MUX3_MASK); + tcfg1 |= (S3C2410_TCFG1_MUX4_TCLK1 | S3C2410_TCFG1_MUX3_TCLK1); __raw_writel(tcfg1, S3C2410_TCFG1); } else { unsigned long pclk; @@ -210,6 +257,12 @@ tcfg0 = __raw_readl(S3C2410_TCFG0); tcfg1 = __raw_readl(S3C2410_TCFG1); +#ifdef CONFIG_IPIPE + __ipipe_mach_ticks_per_jiffy = tcnt; + tsc_info.freq = tcnt * HZ; + __ipipe_tsc_register(&tsc_info); +#endif /* CONFIG_IPIPE */ + /* timers reload after counting zero, so reduce the count by 1 */ tcnt--; @@ -226,23 +279,37 @@ __raw_writel(tcfg1, S3C2410_TCFG1); __raw_writel(tcfg0, S3C2410_TCFG0); - timer_startval = tcnt; - __raw_writel(tcnt, S3C2410_TCNTB(4)); - - /* ensure timer is stopped... */ + /* ensure timers are stopped... */ + tcon &= ~(0x3f<<17); + __raw_writel(tcon, S3C2410_TCON); - tcon &= ~(7<<20); - tcon |= S3C2410_TCON_T4RELOAD; - tcon |= S3C2410_TCON_T4MANUALUPD; + /* Mask timer3 interrupt. */ + intmask = __raw_readl(S3C2410_INTMSK); + intmask |= 1UL << (IRQ_TIMER3 - IRQ_EINT0); + __raw_writel(intmask, S3C2410_INTMSK); - __raw_writel(tcon, S3C2410_TCON); + /* Set timer values */ __raw_writel(tcnt, S3C2410_TCNTB(4)); __raw_writel(tcnt, S3C2410_TCMPB(4)); + __raw_writel(0xffff, S3C2410_TCNTB(3)); + __raw_writel(0xffff, S3C2410_TCMPB(3)); + + /* Set base tcon value for later programming of timer 4 by Xenomai. */ + free_running_tcon = tcon | S3C2410_TCON_T3RELOAD | S3C2410_TCON_T3START; + + /* Set auto reloads for both timers. */ + tcon |= S3C2410_TCON_T3RELOAD | S3C2410_TCON_T4RELOAD; + + /* Manual update */ + __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD + | S3C2410_TCON_T4MANUALUPD, S3C2410_TCON); - /* start the timer running */ - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; + tcon |= S3C2410_TCON_T3START | S3C2410_TCON_T4START; + /* Start timers.*/ __raw_writel(tcon, S3C2410_TCON); + + /* Save start value of timer 3 as begining of first period. */ + last_free_running_tcnt = 0xffff; } static void __init s3c2410_timer_resources(void) @@ -280,6 +347,49 @@ struct sys_timer s3c24xx_timer = { .init = s3c2410_timer_init, +#ifndef CONFIG_IPIPE .offset = s3c2410_gettimeoffset, +#endif .resume = s3c2410_timer_setup }; + +#ifdef CONFIG_IPIPE +void __ipipe_mach_acktimer(void) +{ + __raw_writel(timer_ackval, S3C2410_SRCPND); + __raw_writel(timer_ackval, S3C2410_INTPND); +} + +static inline void set_dec(unsigned long reload) +{ + __raw_writel(reload, S3C2410_TCNTB(4)); + /* Manual update */ + __raw_writel(free_running_tcon | S3C2410_TCON_T4MANUALUPD, S3C2410_TCON); + /* Start timer */ + __raw_writel(free_running_tcon | S3C2410_TCON_T4START, S3C2410_TCON); +} + +void __ipipe_mach_set_dec(unsigned long reload) +{ + unsigned long flags; + + spin_lock_irqsave(&timer_lock, flags); + timer_lxlost += getticksoffset_tscupdate(); + set_dec(reload); + spin_unlock_irqrestore(&timer_lock, flags); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + free_running_tcon |= S3C2410_TCON_T4RELOAD; + __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy - 1); + free_running_tcon &= ~S3C2410_TCON_T4RELOAD; +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return __raw_readl(S3C2410_TCNTO(4)); +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/plat-versatile/include/plat/timer-sp.h relase/linux-2.6.35.9//arch/arm/plat-versatile/include/plat/timer-sp.h --- orig/linux-2.6.35.9//arch/arm/plat-versatile/include/plat/timer-sp.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-versatile/include/plat/timer-sp.h 2011-03-15 10:56:25.917702441 +0100 @@ -1,2 +1,2 @@ -void sp804_clocksource_init(void __iomem *); +void sp804_clocksource_init(void __iomem *, unsigned long); void sp804_clockevents_init(void __iomem *, unsigned int); diff -urN orig/linux-2.6.35.9//arch/arm/plat-versatile/timer-sp.c relase/linux-2.6.35.9//arch/arm/plat-versatile/timer-sp.c --- orig/linux-2.6.35.9//arch/arm/plat-versatile/timer-sp.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/plat-versatile/timer-sp.c 2011-03-15 10:56:25.917702441 +0100 @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -36,6 +38,26 @@ static void __iomem *clksrc_base; +#ifdef CONFIG_IPIPE +int __ipipe_mach_timerint; +EXPORT_SYMBOL(__ipipe_mach_timerint); + +int __ipipe_mach_timerstolen; +EXPORT_SYMBOL(__ipipe_mach_timerstolen); + +unsigned int __ipipe_mach_ticks_per_jiffy; +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING_COUNTDOWN, + .u = { + { + .mask = 0xffffffff, + }, + }, +}; +#endif /* CONFIG_IPIPE */ + static cycle_t sp804_read(struct clocksource *cs) { return ~readl(clksrc_base + TIMER_VALUE); @@ -50,7 +72,7 @@ .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -void __init sp804_clocksource_init(void __iomem *base) +void __init sp804_clocksource_init(void __iomem *base, unsigned long phys) { struct clocksource *cs = &clocksource_sp804; @@ -63,6 +85,13 @@ writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, clksrc_base + TIMER_CTRL); +#ifdef CONFIG_IPIPE + tsc_info.freq = TIMER_FREQ_KHZ * 1000; + tsc_info.counter_vaddr = (unsigned long)base + TIMER_VALUE; + tsc_info.u.counter_paddr = phys + TIMER_VALUE; + __ipipe_tsc_register(&tsc_info); +#endif + cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift); clocksource_register(cs); } @@ -77,8 +106,12 @@ { struct clock_event_device *evt = dev_id; +#ifndef CONFIG_IPIPE /* clear the interrupt */ writel(1, clkevt_base + TIMER_INTCLR); +#else /* CONFIG_IPIPE */ + __ipipe_tsc_update(); +#endif /* CONFIG_IPIPE */ evt->event_handler(evt); @@ -151,6 +184,51 @@ evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); evt->min_delta_ns = clockevent_delta2ns(0xf, evt); +#ifdef CONFIG_IPIPE + __ipipe_mach_timerint = timer_irq; + __ipipe_mach_ticks_per_jiffy = (TIMER_FREQ_KHZ * 1000 + HZ / 2) / HZ; +#endif /* CONFIG_IPIPE */ + setup_irq(timer_irq, &sp804_timer_irq); clockevents_register_device(evt); } + +#ifdef CONFIG_IPIPE +int __ipipe_check_tickdev(const char *devname) +{ + /* Keep compatibility with old patches */ + return !strcmp(devname, "TIMER1"); +} + +void __ipipe_mach_acktimer(void) +{ + writel(1, clkevt_base + TIMER_INTCLR); +} + +/* + * Reprogram the timer + */ + +void __ipipe_mach_set_dec(unsigned long delay) +{ + if (delay > 0xf) + sp804_set_next_event(delay, NULL); + else + ipipe_trigger_irq(__ipipe_mach_timerint); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); + +void __ipipe_mach_release_timer(void) +{ + struct clock_event_device *ckdev = &sp804_clockevent; + ckdev->set_mode(ckdev->mode, ckdev); + if (ckdev->mode == CLOCK_EVT_MODE_ONESHOT) + ckdev->set_next_event(__ipipe_mach_ticks_per_jiffy, ckdev); +} +EXPORT_SYMBOL(__ipipe_mach_release_timer); + +unsigned long __ipipe_mach_get_dec(void) +{ + return ~readl(clkevt_base + TIMER_VALUE); +} +#endif /* CONFIG_IPIPE */ diff -urN orig/linux-2.6.35.9//arch/arm/vfp/entry.S relase/linux-2.6.35.9//arch/arm/vfp/entry.S --- orig/linux-2.6.35.9//arch/arm/vfp/entry.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/vfp/entry.S 2011-03-15 10:56:25.917702441 +0100 @@ -25,7 +25,6 @@ add r11, r4, #1 @ increment it str r11, [r10, #TI_PREEMPT] #endif - enable_irq ldr r4, .LCvfp ldr r11, [r10, #TI_CPU] @ CPU number add r10, r10, #TI_VFPSTATE @ r10 = workspace @@ -33,6 +32,7 @@ ENDPROC(do_vfp) ENTRY(vfp_null_entry) + enable_irq #ifdef CONFIG_PREEMPT get_thread_info r10 ldr r4, [r10, #TI_PREEMPT] @ get preempt count @@ -51,6 +51,7 @@ __INIT ENTRY(vfp_testing_entry) + enable_irq #ifdef CONFIG_PREEMPT get_thread_info r10 ldr r4, [r10, #TI_PREEMPT] @ get preempt count diff -urN orig/linux-2.6.35.9//arch/arm/vfp/vfphw.S relase/linux-2.6.35.9//arch/arm/vfp/vfphw.S --- orig/linux-2.6.35.9//arch/arm/vfp/vfphw.S 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/vfp/vfphw.S 2011-03-15 10:56:25.917702441 +0100 @@ -19,7 +19,7 @@ #include "../kernel/entry-header.S" .macro DBGSTR, str -#ifdef DEBUG +#if defined(DEBUG) && !defined(CONFIG_IPIPE) stmfd sp!, {r0-r3, ip, lr} add r0, pc, #4 bl printk @@ -31,7 +31,7 @@ .endm .macro DBGSTR1, str, arg -#ifdef DEBUG +#if defined(DEBUG) && !defined(CONFIG_IPIPE) stmfd sp!, {r0-r3, ip, lr} mov r1, \arg add r0, pc, #4 @@ -44,7 +44,7 @@ .endm .macro DBGSTR3, str, arg1, arg2, arg3 -#ifdef DEBUG +#if defined(DEBUG) && !defined(CONFIG_IPIPE) stmfd sp!, {r0-r3, ip, lr} mov r3, \arg3 mov r2, \arg2 @@ -87,6 +87,14 @@ @ still there. In this case, we do @ not want to drop a pending exception. + enable_irq +#ifdef CONFIG_IPIPE + disable_irq +#ifdef CONFIG_SMP + mrc p15, 0, r11, c0, c0, 5 @ reload current CPU number +#endif + ldr r4, [r3, r11, lsl #2] @ reload last_VFP_context pointer +#endif VFPFMXR FPEXC, r5 @ enable VFP, disable any pending @ exceptions, so we can get at the @ rest of it @@ -139,6 +147,7 @@ @ out before setting an FPEXC that @ stops us reading stuff VFPFMXR FPEXC, r1 @ restore FPEXC last + enable_irq_cond sub r2, r2, #4 str r2, [sp, #S_PC] @ retry the instruction #ifdef CONFIG_PREEMPT @@ -164,6 +173,7 @@ @ Fall into hand on to next handler - appropriate coproc instr @ not recognised by VFP + enable_irq_cond DBGSTR "not VFP" #ifdef CONFIG_PREEMPT get_thread_info r10 diff -urN orig/linux-2.6.35.9//arch/arm/vfp/vfpmodule.c relase/linux-2.6.35.9//arch/arm/vfp/vfpmodule.c --- orig/linux-2.6.35.9//arch/arm/vfp/vfpmodule.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/vfp/vfpmodule.c 2011-03-15 10:56:25.917702441 +0100 @@ -44,6 +44,7 @@ static void vfp_thread_flush(struct thread_info *thread) { union vfp_state *vfp = &thread->vfpstate; + unsigned long flags; unsigned int cpu; memset(vfp, 0, sizeof(union vfp_state)); @@ -56,22 +57,23 @@ * that the modification of last_VFP_context[] and hardware disable * are done for the same CPU and without preemption. */ - cpu = get_cpu(); + cpu = ipipe_get_cpu(flags); if (last_VFP_context[cpu] == vfp) last_VFP_context[cpu] = NULL; fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); - put_cpu(); + ipipe_put_cpu(flags); } static void vfp_thread_exit(struct thread_info *thread) { /* release case: Per-thread VFP cleanup. */ union vfp_state *vfp = &thread->vfpstate; - unsigned int cpu = get_cpu(); + unsigned long flags; + unsigned int cpu = ipipe_get_cpu(flags); if (last_VFP_context[cpu] == vfp) last_VFP_context[cpu] = NULL; - put_cpu(); + ipipe_put_cpu(flags); } /* @@ -100,12 +102,16 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { struct thread_info *thread = v; + unsigned long flags; + unsigned int cpu; if (likely(cmd == THREAD_NOTIFY_SWITCH)) { - u32 fpexc = fmrx(FPEXC); + u32 fpexc; + local_irq_save_hw_cond(flags); + fpexc = fmrx(FPEXC); #ifdef CONFIG_SMP - unsigned int cpu = thread->cpu; + cpu = thread->cpu; /* * On SMP, if VFP is enabled, save the old state in @@ -123,6 +129,8 @@ */ if (thread->vfpstate.hard.cpu != cpu) last_VFP_context[cpu] = NULL; +#else + (void)cpu; #endif /* @@ -130,6 +138,7 @@ * old state. */ fmxr(FPEXC, fpexc & ~FPEXC_EN); + local_irq_restore_hw_cond(flags); return NOTIFY_DONE; } @@ -266,7 +275,7 @@ */ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) { - u32 fpscr, orig_fpscr, fpsid, exceptions; + u32 fpscr, orig_fpscr, fpsid, exceptions, next_trigger = 0; pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); @@ -296,6 +305,7 @@ /* * Synchronous exception, emulate the trigger instruction */ + local_irq_enable_hw_cond(); goto emulate; } @@ -308,7 +318,18 @@ trigger = fmrx(FPINST); regs->ARM_pc -= 4; #endif - } else if (!(fpexc & FPEXC_DEX)) { + if (fpexc & FPEXC_FP2V) { + /* + * The barrier() here prevents fpinst2 being read + * before the condition above. + */ + barrier(); + next_trigger = fmrx(FPINST2); + } + } + local_irq_enable_hw_cond(); + + if (!(fpexc & (FPEXC_EX | FPEXC_DEX))) { /* * Illegal combination of bits. It can be caused by an * unallocated VFP instruction but with FPSCR.IXE set and not @@ -348,18 +369,14 @@ if (fpexc ^ (FPEXC_EX | FPEXC_FP2V)) goto exit; - /* - * The barrier() here prevents fpinst2 being read - * before the condition above. - */ - barrier(); - trigger = fmrx(FPINST2); + trigger = next_trigger; emulate: exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); if (exceptions) vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); exit: + local_irq_enable_hw_cond(); preempt_enable(); } diff -urN orig/linux-2.6.35.9//arch/arm/xenomai/hal.c relase/linux-2.6.35.9//arch/arm/xenomai/hal.c --- orig/linux-2.6.35.9//arch/arm/xenomai/hal.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/xenomai/hal.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,485 @@ +/** + * @ingroup hal + * @file + * + * Adeos-based Real-Time Abstraction Layer for ARM. + * + * ARM port + * Copyright (C) 2005 Stelian Pop + * + * Xenomai 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, Inc., 675 Mass Ave, + * Cambridge MA 02139, USA; either version 2 of the License, or (at + * your option) any later version. + * + * Xenomai 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. + */ + +/** + * @addtogroup hal + * + * ARM-specific HAL services. + * + *@{*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PROC_FS +#include +#endif /* CONFIG_PROC_FS */ +#include + +rthal_u32frac_t rthal_tsc_to_timer; +EXPORT_SYMBOL(rthal_tsc_to_timer); + +#define RTHAL_CALIBRATE_LOOPS 10 + +static struct { + unsigned long flags; + int count; +} rthal_linux_irq[IPIPE_NR_XIRQS]; + +enum rthal_ktimer_mode rthal_ktimer_saved_mode; + +#define RTHAL_SET_ONESHOT_XENOMAI 1 +#define RTHAL_SET_ONESHOT_LINUX 2 +#define RTHAL_SET_PERIODIC 3 + +static inline void steal_timer(int stolen) +{ + /* + * Some platform-specific I-pipe bits may want to know whether + * non-vanilla kernel code is currently fiddling with the + * timer chip; setting this flag on tells them so. + */ + __ipipe_mach_timerstolen = stolen; +} + +static inline void force_oneshot_hw_mode(void) +{ + /* + * Program next tick ahead at a sensible date. We expect + * __ipipe_mach_set_dec() to switch off any auto-reload mode + * if that makes sense for the hardware. + */ + __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy); +} + +static inline void restore_normal_hw_mode(void) +{ + steal_timer(0); + /* + * Ask the I-pipe to reset the normal timer operating mode at + * hardware level, which should match the current logical mode + * for the active clockevent. + */ + __ipipe_mach_release_timer(); +} + +unsigned long rthal_timer_calibrate(void) +{ + unsigned long long start, end, sum = 0, sum_sq = 0; + volatile unsigned const_delay = 0xffffffff; + unsigned int delay = const_delay, diff; + unsigned long result, flags, tsc_lat; + int i, j; + + flags = rthal_critical_enter(NULL); + + /* + * Hw interrupts off, other CPUs quiesced, no migration + * possible. We can now fiddle with the timer chip (per-cpu + * local or global, rthal_timer_program_shot() will handle + * this transparently via the I-pipe). + */ + steal_timer(1); + force_oneshot_hw_mode(); + + rthal_read_tsc(start); + barrier(); + rthal_read_tsc(end); + tsc_lat = end - start; + barrier(); + + for (i = 0; i < RTHAL_CALIBRATE_LOOPS; i++) { + flush_cache_all(); + for (j = 0; j < RTHAL_CALIBRATE_LOOPS; j++) { + rthal_read_tsc(start); + barrier(); + rthal_timer_program_shot( + rthal_nodiv_imuldiv_ceil(delay, rthal_tsc_to_timer)); + barrier(); + rthal_read_tsc(end); + diff = end - start - tsc_lat; + sum += diff; + sum_sq += diff * diff; + } + } + + restore_normal_hw_mode(); + + rthal_critical_exit(flags); + + /* Use average + standard deviation as timer programming latency. */ + do_div(sum, RTHAL_CALIBRATE_LOOPS * RTHAL_CALIBRATE_LOOPS); + do_div(sum_sq, RTHAL_CALIBRATE_LOOPS * RTHAL_CALIBRATE_LOOPS); + result = sum + int_sqrt(sum_sq - sum * sum) + 1; + + return result; +} + +#ifdef CONFIG_SMP +static void rthal_critical_sync(void) +{ + switch (rthal_sync_op) { + case RTHAL_SET_ONESHOT_XENOMAI: + force_oneshot_hw_mode(); + steal_timer(1); + break; + + case RTHAL_SET_ONESHOT_LINUX: + force_oneshot_hw_mode(); + steal_timer(0); + /* We need to keep the timing cycle alive for the kernel. */ + rthal_trigger_irq(RTHAL_TIMER_IRQ); + break; + + case RTHAL_SET_PERIODIC: + restore_normal_hw_mode(); + break; + } +} +#else /* CONFIG_SMP */ +#define rthal_critical_sync NULL +#endif /* !CONFIG_SMP */ + +static void rthal_timer_set_oneshot(int rt_mode) +{ + unsigned long flags; + + flags = rthal_critical_enter(rthal_critical_sync); + if (rt_mode) { + rthal_sync_op = RTHAL_SET_ONESHOT_XENOMAI; + force_oneshot_hw_mode(); + steal_timer(1); + } else { + rthal_sync_op = RTHAL_SET_ONESHOT_LINUX; + force_oneshot_hw_mode(); + steal_timer(0); + /* We need to keep the timing cycle alive for the kernel. */ + rthal_trigger_irq(RTHAL_TIMER_IRQ); + } + rthal_critical_exit(flags); +} + +static void rthal_timer_set_periodic(void) +{ + unsigned long flags; + + flags = rthal_critical_enter(rthal_critical_sync); + rthal_sync_op = RTHAL_SET_PERIODIC; + restore_normal_hw_mode(); + rthal_critical_exit(flags); +} + +static int cpu_timers_requested; + +#ifdef CONFIG_GENERIC_CLOCKEVENTS + +int rthal_timer_request( + void (*tick_handler)(void), + void (*mode_emul)(enum clock_event_mode mode, + struct clock_event_device *cdev), + int (*tick_emul)(unsigned long delay, + struct clock_event_device *cdev), + int cpu) +{ + unsigned long dummy, *tmfreq = &dummy; + int tickval, ret; + + if (rthal_timerfreq_arg == 0) + tmfreq = &rthal_tunables.timer_freq; + + ret = ipipe_request_tickdev(RTHAL_TIMER_DEVICE, mode_emul, tick_emul, cpu, + tmfreq); + switch (ret) { + case CLOCK_EVT_MODE_PERIODIC: + /* oneshot tick emulation callback won't be used, ask + * the caller to start an internal timer for emulating + * a periodic tick. */ + tickval = 1000000000UL / HZ; + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* oneshot tick emulation */ + tickval = 1; + break; + + case CLOCK_EVT_MODE_UNUSED: + /* we don't need to emulate the tick at all. */ + tickval = 0; + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + return -ENODEV; + + default: + return ret; + } + + rthal_ktimer_saved_mode = ret; + + /* + * The rest of the initialization should only be performed + * once by a single CPU. + */ + if (cpu_timers_requested++ > 0) + goto out; + + ret = rthal_irq_request(RTHAL_TIMER_IRQ, + (rthal_irq_handler_t)tick_handler, + NULL, NULL); + if (ret) + return ret; + + rthal_timer_set_oneshot(1); +out: + return tickval; +} + +void rthal_timer_release(int cpu) +{ + ipipe_release_tickdev(cpu); + + if (--cpu_timers_requested > 0) + return; + + rthal_irq_release(RTHAL_TIMER_IRQ); + + if (rthal_ktimer_saved_mode == KTIMER_MODE_PERIODIC) + rthal_timer_set_periodic(); + else if (rthal_ktimer_saved_mode == KTIMER_MODE_ONESHOT) + rthal_timer_set_oneshot(0); +} + +void rthal_timer_notify_switch(enum clock_event_mode mode, + struct clock_event_device *cdev) +{ + if (rthal_processor_id() > 0) + /* + * We assume all CPUs switch the same way, so we only + * track mode switches from the boot CPU. + */ + return; + + rthal_ktimer_saved_mode = mode; +} +EXPORT_SYMBOL(rthal_timer_notify_switch); + +#else /* !CONFIG_GENERIC_CLOCKEVENTS */ + +int rthal_timer_request(void (*handler)(void), int cpu) +{ + int ret; + + /* + * The rest of the initialization should only be performed + * once by a single CPU. + */ + if (cpu_timers_requested++ > 0) + return 0; + + rthal_ktimer_saved_mode = KTIMER_MODE_PERIODIC; + + if (rthal_timerfreq_arg == 0) + rthal_tunables.timer_freq = rthal_cpufreq_arg; + + ret = rthal_irq_request(RTHAL_TIMER_IRQ, + (rthal_irq_handler_t) handler, + NULL, NULL); + if (ret) + return ret; + + rthal_timer_set_oneshot(1); + + return 0; +} + +void rthal_timer_release(int cpu) +{ + if (--cpu_timers_requested > 0) + return; + + rthal_irq_release(RTHAL_TIMER_IRQ); + rthal_timer_set_periodic(); +} + +#endif /* !CONFIG_GENERIC_CLOCKEVENTS */ + +int rthal_irq_host_request(unsigned irq, + rthal_irq_host_handler_t handler, + char *name, void *dev_id) +{ + unsigned long flags; + + if (irq >= IPIPE_NR_XIRQS || + handler == NULL || + rthal_irq_descp(irq) == NULL) + return -EINVAL; + + rthal_irqdesc_lock(irq, flags); + + if (rthal_linux_irq[irq].count++ == 0 && rthal_irq_descp(irq)->action) { + rthal_linux_irq[irq].flags = rthal_irq_descp(irq)->action->flags; + rthal_irq_descp(irq)->action->flags |= IRQF_SHARED; + } + + rthal_irqdesc_unlock(irq, flags); + + return request_irq(irq, handler, IRQF_SHARED, name, dev_id); +} + +int rthal_irq_host_release(unsigned irq, void *dev_id) +{ + unsigned long flags; + + if (irq >= IPIPE_NR_XIRQS || + rthal_linux_irq[irq].count == 0 || + rthal_irq_descp(irq) == NULL) + return -EINVAL; + + free_irq(irq, dev_id); + + rthal_irqdesc_lock(irq, flags); + + if (--rthal_linux_irq[irq].count == 0 && rthal_irq_descp(irq)->action) + rthal_irq_descp(irq)->action->flags = rthal_linux_irq[irq].flags; + + rthal_irqdesc_unlock(irq, flags); + + return 0; +} + +int rthal_irq_enable(unsigned int irq) +{ + if (irq >= IPIPE_NR_XIRQS || rthal_irq_descp(irq) == NULL) + return -EINVAL; + + /* + * We don't care of disable nesting level: real-time IRQ + * channels are not meant to be shared with the regular + * kernel. + */ + rthal_mark_irq_enabled(irq); + + return rthal_irq_chip_enable(irq); +} + +int rthal_irq_disable(unsigned int irq) +{ + if (irq >= IPIPE_NR_XIRQS || rthal_irq_descp(irq) == NULL) + return -EINVAL; + + rthal_mark_irq_disabled(irq); + + return rthal_irq_chip_disable(irq); +} + +int rthal_irq_end(unsigned int irq) +{ + if (irq >= IPIPE_NR_XIRQS || rthal_irq_descp(irq) == NULL) + return -EINVAL; + + return rthal_irq_chip_end(irq); +} + +void __rthal_arm_fault_range(struct vm_area_struct *vma) +{ + unsigned long addr; + for (addr = vma->vm_start; addr != vma->vm_end; addr += PAGE_SIZE) + handle_mm_fault(vma->vm_mm, vma, addr, 1); +} + +static inline int do_exception_event(unsigned event, unsigned domid, void *data) +{ + if (domid == RTHAL_DOMAIN_ID) { + rthal_realtime_faults[rthal_processor_id()][event]++; + + if (rthal_trap_handler != NULL && + rthal_trap_handler(event, domid, data) != 0) + return RTHAL_EVENT_STOP; + } + + return RTHAL_EVENT_PROPAGATE; +} + +RTHAL_DECLARE_EVENT(exception_event); + +static inline void do_rthal_domain_entry(void) +{ + unsigned trapnr; + + /* Trap all faults. */ + for (trapnr = 0; trapnr < RTHAL_NR_FAULTS; trapnr++) + rthal_catch_exception(trapnr, &exception_event); + + printk(KERN_INFO "Xenomai: hal/arm started.\n"); +} + +RTHAL_DECLARE_DOMAIN(rthal_domain_entry); + +int rthal_arch_init(void) +{ + if (rthal_cpufreq_arg == 0) + rthal_cpufreq_arg = rthal_get_cpufreq(); + + if (rthal_timerfreq_arg == 0) + rthal_timerfreq_arg = rthal_get_timerfreq(); + + if (rthal_clockfreq_arg == 0) + rthal_clockfreq_arg = rthal_get_clockfreq(); + + xnarch_init_u32frac(&rthal_tsc_to_timer, + rthal_timerfreq_arg, rthal_clockfreq_arg); + + return 0; +} + +void rthal_arch_cleanup(void) +{ + /* Nothing to cleanup so far. */ + printk(KERN_INFO "Xenomai: hal/arm stopped.\n"); +} + +/*@}*/ + +EXPORT_SYMBOL(rthal_arch_init); +EXPORT_SYMBOL(rthal_arch_cleanup); +EXPORT_SYMBOL(rthal_thread_switch); +EXPORT_SYMBOL(rthal_thread_trampoline); +EXPORT_SYMBOL(__rthal_arm_fault_range); +#if defined(CONFIG_VFP) && defined(CONFIG_XENO_HW_FPU) +EXPORT_SYMBOL(last_VFP_context); +EXPORT_SYMBOL(rthal_vfp_save); +EXPORT_SYMBOL(rthal_vfp_load); +#endif /* CONFIG_VFP && CONFIG_XENO_HW_FPU */ diff -urN orig/linux-2.6.35.9//arch/arm/xenomai/Kconfig relase/linux-2.6.35.9//arch/arm/xenomai/Kconfig --- orig/linux-2.6.35.9//arch/arm/xenomai/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/xenomai/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,54 @@ +config XENO_GENERIC_STACKPOOL + bool + default y + +config XENO_FASTSYNCH_DEP + bool + default y if (CPU_32v3 || CPU_32v4T || CPU_32v5) && !SMP || CPU_32v6 || CPU_32v7 + +config XENO_FASTSYNCH + bool + default y if XENO_FASTSYNCH_DEP + +source "kernel/xenomai/nucleus/Kconfig" + +menu "Machine" + +depends on XENO_OPT_NUCLEUS + +config IPIPE_WANT_PREEMPTIBLE_SWITCH + bool + default y if (XENO_HW_UNLOCKED_SWITCH || SMP) + default n if !XENO_HW_UNLOCKED_SWITCH && !SMP + +config XENO_HW_FPU + bool "Enable FPU support" + default y + help + The FPU executes instructions from the processor's normal + instruction stream. It can handle the types of high-precision + floating-point processing operations commonly found in + scientific, engineering, and business applications. + If your target system has no FPU, say NO here; otherwise, + enabling FPU support when the hardware is available may + greatly improve performance. + +config XENO_HW_UNLOCKED_SWITCH + bool "Enable unlocked context switch" + default y + help + The nucleus may allow non-atomic execution of the + machine-dependent context switching code, so that other CPUs + and/or local interrupts may execute concurrently. + + This option reduces interrupt latency when costly cache and + TLB flushes are required to switch context, and may improve + concurrency on some SMP/multi-core systems as well. + + You definitely want to enable that option on embedded ARM + platforms. + +endmenu + +source "kernel/xenomai/skins/Kconfig" +source "drivers/xenomai/Kconfig" diff -urN orig/linux-2.6.35.9//arch/arm/xenomai/Makefile relase/linux-2.6.35.9//arch/arm/xenomai/Makefile --- orig/linux-2.6.35.9//arch/arm/xenomai/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/xenomai/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,6 @@ +obj-$(CONFIG_XENOMAI) += xeno_hal.o + +xeno_hal-y := hal.o switch.o + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + diff -urN orig/linux-2.6.35.9//arch/arm/xenomai/switch.S relase/linux-2.6.35.9//arch/arm/xenomai/switch.S --- orig/linux-2.6.35.9//arch/arm/xenomai/switch.S 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//arch/arm/xenomai/switch.S 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2005 Stelian Pop. + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; 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 +#include +#include +#include +#ifdef CONFIG_VFP +#include +#endif + +/* + * Switch context routine. + * + * Registers according to the ARM procedure call standard: + * Reg Description + * r0-r3 argument/scratch registers + * r4-r9 variable register + * r10=sl stack limit/variable register + * r11=fp frame pointer/variable register + * r12=ip intra-procedure-call scratch register + * r13=sp stack pointer (auto preserved) + * r14=lr link register + * r15=pc program counter (auto preserved) + * + * rthal_thread_switch(struct thread_info *out, struct thread_info *in) + */ + + .text + +#ifdef CONFIG_VFP +/* Copied from vfp_save_state in arch/arm/vfp/vfphw.S + * r0 = pointer to union vfp_state, r1 = fpexc + */ +ENTRY(rthal_vfp_save) + VFPFSTMIA r0, r2 @ save the working registers + VFPFMRX r2, FPSCR @ current status + tst r1, #FPEXC_EX @ is there additional state to save? + beq 1f + VFPFMRX r3, FPINST @ FPINST (only if FPEXC.EX is set) + tst r1, #FPEXC_FP2V @ is there an FPINST2 to read? + beq 1f + VFPFMRX r12, FPINST2 @ FPINST2 if needed (and present) +1: + stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2 + mov pc, lr + +/* Copied from no_old_VFP_process in arch/arm/vfp/vfphw.S + * r0 = pointer to union vfp_state + */ +ENTRY(rthal_vfp_load) + VFPFLDMIA r0, r2 @ reload the working registers while + @ FPEXC is in a safe state + ldmia r0, {r1, r2, r3, r12} @ load FPEXC, FPSCR, FPINST, FPINST2 + tst r1, #FPEXC_EX @ is there additional state to restore? + beq 1f + VFPFMXR FPINST, r3 @ restore FPINST (only if FPEXC.EX is set) + tst r1, #FPEXC_FP2V @ is there an FPINST2 to write? + beq 1f + VFPFMXR FPINST2, r12 @ FPINST2 if needed (and present) +1: + VFPFMXR FPSCR, r2 @ restore status + mov pc, lr +#endif + +/* + * Copied from __switch_to, arch/arm/kernel/entry-armv.S. + * Right now it is identical, but who knows what the + * future reserves us... + * + * XXX: All the following config options are NOT tested: + * CONFIG_CPU_MPCORE + * CONFIG_CPU_XSCALE + * CONFIG_IWMMXT + * CONFIG_HAS_TLS_REG + * CONFIG_VFP + * + * Calling args: + * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info + */ +ENTRY(rthal_thread_switch) + add ip, r1, #TI_CPU_SAVE + ldr r3, [r2, #TI_TP_VALUE] + stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack +#ifdef CONFIG_MMU + ldr r6, [r2, #TI_CPU_DOMAIN] +#endif +#if __LINUX_ARM_ARCH__ >= 6 +#ifdef CONFIG_CPU_MPCORE + clrex +#else + strex r5, r4, [ip] @ Clear exclusive monitor +#endif +#endif +#if 0 +#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) + mra r4, r5, acc0 + stmia ip, {r4, r5} +#endif +#endif +#if defined(CONFIG_HAS_TLS_REG) + mcr p15, 0, r3, c13, c0, 3 @ set TLS register +#elif !defined(CONFIG_TLS_REG_EMUL) + mov r4, #0xffff0fff + str r3, [r4, #-15] @ TLS val at 0xffff0ff0 +#endif +#ifdef CONFIG_MMU + mcr p15, 0, r6, c3, c0, 0 @ Set domain register +#endif +#ifdef CONFIG_VFP + @ Always disable VFP so we can lazily save/restore the old + @ state. This occurs in the context of the previous thread. + VFPFMRX r4, FPEXC +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + bic r4, r4, #FPEXC_ENABLE +#else + bic r4, r4, #FPEXC_EN +#endif + VFPFMXR FPEXC, r4 +#endif +#if 0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) && defined(CONFIG_IWMMXT) + bl iwmmxt_task_switch +#endif +#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) + add r4, r2, #40 @ cpu_context_save->extra + ldmib r4, {r4, r5} + mar acc0, r4, r5 +#endif +#endif + add r4, r2, #TI_CPU_SAVE +#if 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) && defined(CONFIG_IWMMXT) + mov r5, r0 + mov r0, r2 + bl iwmmxt_task_switch + mov r0, r5 +#endif +#endif + ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously + +/* + * r4 = xnarch_thread_trampoline + * r5 = xnarchtcb_t * + */ +ENTRY(rthal_thread_trampoline) + mov r0, r5 + mov pc, r4 + +// vim: ts=4 et sw=4 sts=4 diff -urN orig/linux-2.6.35.9//.config relase/linux-2.6.35.9//.config --- orig/linux-2.6.35.9//.config 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//.config 2011-03-15 11:08:25.157702442 +0100 @@ -0,0 +1,3153 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.35.9 +# Tue Mar 15 11:08:25 2011 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_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_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +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_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set + +# +# Real-time sub-system +# +CONFIG_XENOMAI=y +CONFIG_XENO_GENERIC_STACKPOOL=y +CONFIG_XENO_FASTSYNCH_DEP=y +CONFIG_XENO_FASTSYNCH=y +CONFIG_XENO_OPT_NUCLEUS=y +CONFIG_XENO_OPT_PERVASIVE=y +CONFIG_XENO_OPT_PRIOCPL=y +CONFIG_XENO_OPT_PIPELINE_HEAD=y +# CONFIG_XENO_OPT_SCHED_CLASSES is not set +CONFIG_XENO_OPT_PIPE=y +CONFIG_XENO_OPT_PIPE_NRDEV=32 +CONFIG_XENO_OPT_REGISTRY_NRSLOTS=512 +CONFIG_XENO_OPT_SYS_HEAPSZ=256 +CONFIG_XENO_OPT_SYS_STACKPOOLSZ=128 +CONFIG_XENO_OPT_SEM_HEAPSZ=12 +CONFIG_XENO_OPT_GLOBAL_SEM_HEAPSZ=12 +CONFIG_XENO_OPT_STATS=y +# CONFIG_XENO_OPT_DEBUG is not set +# CONFIG_XENO_OPT_SHIRQ is not set + +# +# Timing +# +# CONFIG_XENO_OPT_TIMING_PERIODIC is not set +CONFIG_XENO_OPT_TIMING_VIRTICK=1000 +CONFIG_XENO_OPT_TIMING_SCHEDLAT=0 + +# +# Scalability +# +# CONFIG_XENO_OPT_SCALABLE_SCHED is not set +CONFIG_XENO_OPT_TIMER_LIST=y +# CONFIG_XENO_OPT_TIMER_HEAP is not set +# CONFIG_XENO_OPT_TIMER_WHEEL is not set + +# +# Machine +# +CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH=y +CONFIG_XENO_HW_FPU=y +CONFIG_XENO_HW_UNLOCKED_SWITCH=y + +# +# Interfaces +# +CONFIG_XENO_SKIN_NATIVE=y +CONFIG_XENO_OPT_NATIVE_PERIOD=0 +CONFIG_XENO_OPT_NATIVE_PIPE=y +CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ=1024 +CONFIG_XENO_OPT_NATIVE_SEM=y +CONFIG_XENO_OPT_NATIVE_EVENT=y +CONFIG_XENO_OPT_NATIVE_MUTEX=y +CONFIG_XENO_OPT_NATIVE_COND=y +CONFIG_XENO_OPT_NATIVE_QUEUE=y +CONFIG_XENO_OPT_NATIVE_BUFFER=y +CONFIG_XENO_OPT_NATIVE_HEAP=y +CONFIG_XENO_OPT_NATIVE_ALARM=y +CONFIG_XENO_OPT_NATIVE_MPS=y +# CONFIG_XENO_OPT_NATIVE_INTR is not set +CONFIG_XENO_SKIN_POSIX=y +CONFIG_XENO_OPT_POSIX_PERIOD=0 +# CONFIG_XENO_OPT_POSIX_SHM is not set +# CONFIG_XENO_OPT_POSIX_INTR is not set +# CONFIG_XENO_OPT_POSIX_SELECT is not set +# CONFIG_XENO_OPT_DEBUG_POSIX is not set +# CONFIG_XENO_SKIN_PSOS is not set +# CONFIG_XENO_SKIN_UITRON is not set +# CONFIG_XENO_SKIN_VRTX is not set +# CONFIG_XENO_SKIN_VXWORKS is not set +# CONFIG_XENO_SKIN_RTAI is not set +# CONFIG_XENO_OPT_NOWARN_DEPRECATED is not set +CONFIG_XENO_SKIN_RTDM=y +CONFIG_XENO_OPT_RTDM_PERIOD=0 +CONFIG_XENO_OPT_RTDM_FILDES=128 +# CONFIG_XENO_OPT_RTDM_SELECT is not set + +# +# Drivers +# + +# +# Serial drivers +# +# CONFIG_XENO_DRIVERS_16550A is not set + +# +# Testing drivers +# +# CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES is not set +CONFIG_XENO_DRIVERS_TIMERBENCH=y +# CONFIG_XENO_DRIVERS_KLATENCY is not set +# CONFIG_XENO_DRIVERS_IRQBENCH is not set +CONFIG_XENO_DRIVERS_SWITCHTEST=y +# CONFIG_XENO_DRIVERS_SIGTEST is not set +# CONFIG_XENO_DRIVERS_RTDMTEST is not set + +# +# CAN drivers +# +# CONFIG_XENO_DRIVERS_CAN is not set + +# +# ANALOGY drivers +# +# CONFIG_XENO_DRIVERS_ANALOGY is not set + +# +# Real-time IPC drivers +# +# CONFIG_XENO_DRIVERS_RTIPC is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# 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_VEXPRESS is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X 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_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +CONFIG_HAVE_AT91_USART3=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_HAVE_AT91_USART5=y + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +CONFIG_ARCH_AT91SAM9G20=y +# CONFIG_ARCH_AT91SAM9G45 is not set +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT572D940HF is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9G20 Board Type +# +# CONFIG_MACH_AT91SAM9G20EK is not set +# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set +# CONFIG_MACH_CPU9G20 is not set +# CONFIG_MACH_PORTUXG20 is not set +# CONFIG_MACH_STAMP9G20 is not set +CONFIG_MACH_FOXG20=y + +# +# Adeos I-pipe Options +# +CONFIG_IPIPE_AT91_TC=0 + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_AT91_TIMER_HZ=100 +# CONFIG_AT91_EARLY_DBGU is not set +CONFIG_AT91_EARLY_USART0=y +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set +CONFIG_IPIPE_ARM_KUSER_TSC=y + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=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_ARM_L1_CACHE_SHIFT=5 +# CONFIG_ARM_FCSE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_IPIPE=y +CONFIG_IPIPE_DOMAINS=4 +CONFIG_IPIPE_DELAYED_ATOMICSW=y +# CONFIG_IPIPE_UNMASKED_CONTEXT_SWITCH is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rw rootwait init=/sbin/init" +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_NVS=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_APM_EMULATION=m +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_PHONET=m +CONFIG_IEEE802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +# CONFIG_MKISS is not set +# CONFIG_6PACK is not set +# CONFIG_BPQETHER is not set +# CONFIG_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_BAYCOM_PAR is not set +# CONFIG_BAYCOM_EPP is not set +# CONFIG_YAM is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_DEV is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +# CONFIG_BT_L2CAP_EXT_FEATURES is not set +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +# CONFIG_BT_ATH3K is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_1284 is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_BLK_DEV=y +# CONFIG_PARIDE 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_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_OSD 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=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +CONFIG_ATMEL_TCLIB=y +# CONFIG_ICS932S401 is not set +CONFIG_ATMEL_SSC=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +CONFIG_SENSORS_TSL2550=m +CONFIG_DS1682=m +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +CONFIG_IWMC3200TOP=m +# CONFIG_IWMC3200TOP_DEBUG is not set +# CONFIG_IWMC3200TOP_DEBUGFS is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m +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=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FC_TGT_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_ATA is not set +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_SRP_TGT_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +# CONFIG_SATA_AHCI_PLATFORM is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_SATA_MV=m + +# +# PATA SFF controllers with BMDMA +# + +# +# PIO-only SFF controllers +# +CONFIG_PATA_AT91=m +CONFIG_PATA_PLATFORM=m + +# +# Generic fallback / legacy drivers +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_AT76C50X_USB=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8187=m +CONFIG_MAC80211_HWSIM=m +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH9K_HTC is not set +CONFIG_AR9170_USB=m +CONFIG_B43=m +# CONFIG_B43_SDIO is not set +CONFIG_B43_PIO=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_IWM=m +# CONFIG_IWM_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_MESH is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_SPI=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT30XX=y +# CONFIG_RT2800USB_RT35XX is not set +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL12XX is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO 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=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=m +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_CDC_PHONET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set +CONFIG_IEEE802154_DRIVERS=m +# CONFIG_IEEE802154_FAKEHARD is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +CONFIG_PHONE=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_APMPOWER=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADP5588=m +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_QT2160 is not set +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_TCA6416 is not set +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_LM8323=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +# CONFIG_JOYSTICK_IFORCE_USB is not set +# CONFIG_JOYSTICK_IFORCE_232 is not set +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +# CONFIG_JOYSTICK_XPAD_FF is not set +# CONFIG_JOYSTICK_XPAD_LEDS is not set +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879=m +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC5UH=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_W90X900=m +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_SI is not set +# CONFIG_IPMI_WATCHDOG is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_NVRAM=m +CONFIG_R3964=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB 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_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +CONFIG_SPI_BITBANG=m +# CONFIG_SPI_BUTTERFLY is not set +CONFIG_SPI_GPIO=m +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_TLE62X0=m + +# +# PPS support +# +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_W1=y +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=y + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=y +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_APM_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91SAM9X_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TC35892 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB8500_CORE is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_IR_CORE=m +CONFIG_VIDEO_IR=m +CONFIG_RC_MAP=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +# CONFIG_IR_IMON is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_AU0828=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +# CONFIG_SOC_CAMERA_MT9T112 is not set +CONFIG_SOC_CAMERA_MT9V022=m +# CONFIG_SOC_CAMERA_RJ54N1 is not set +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_OV772X=m +# CONFIG_SOC_CAMERA_OV9640 is not set +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +# CONFIG_USB_GSPCA_BENQ is not set +CONFIG_USB_GSPCA_CONEX=m +# CONFIG_USB_GSPCA_CPIA1 is not set +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +# CONFIG_USB_GSPCA_OV534_9 is not set +CONFIG_USB_GSPCA_PAC207=m +# CONFIG_USB_GSPCA_PAC7302 is not set +CONFIG_USB_GSPCA_PAC7311=m +# CONFIG_USB_GSPCA_SN9C2028 is not set +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_STK014=m +# CONFIG_USB_GSPCA_STV0680 is not set +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +# CONFIG_VIDEO_TLG2300 is not set +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_DSBR=m +# CONFIG_RADIO_SI470X is not set +CONFIG_USB_MR800=m +CONFIG_RADIO_TEA5764=m +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_FRIIO=m +# CONFIG_DVB_USB_EC168 is not set +# CONFIG_DVB_USB_AZ6027 is not set +CONFIG_SMS_SIANO_MDTV=m + +# +# Siano module components +# +CONFIG_SMS_USB_DRV=m +CONFIG_SMS_SDIO_DRV=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_STB6100=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=m +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +CONFIG_LCD_LMS283GF05=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +CONFIG_LCD_PLATFORM=m +# CONFIG_LCD_S6E63M0 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP8860 is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_MPU401_UART=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_ARM=y + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_AC97C is not set +CONFIG_SND_SPI=y +CONFIG_SND_AT73C213=m +CONFIG_SND_AT73C213_TARGET_BITRATE=48000 +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +CONFIG_SND_USB_CAIAQ=m +# CONFIG_SND_USB_CAIAQ_INPUT is not set +CONFIG_SND_SOC=m +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_ATMEL_SOC_SSC=m +CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_WM_HUBS=m +CONFIG_SND_SOC_AD1836=m +CONFIG_SND_SOC_AD193X=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_ADS117X=m +CONFIG_SND_SOC_AK4104=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK4671=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_DA7210=m +CONFIG_SND_SOC_L3=m +CONFIG_SND_SOC_PCM3008=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320DAC33=m +CONFIG_SND_SOC_UDA134X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8727=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8940=m +CONFIG_SND_SOC_WM8955=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8961=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8988=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SOC_WM8993=m +CONFIG_SND_SOC_WM9081=m +CONFIG_SND_SOC_MAX9877=m +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_WM2000=m +CONFIG_SND_SOC_WM9090=m +CONFIG_SOUND_PRIME=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +# CONFIG_HID_CANDO is not set +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_PRODIKEYS is not set +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +# CONFIG_DRAGONRISE_FF is not set +# CONFIG_HID_EGALAX is not set +CONFIG_HID_EZKEY=m +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MICROSOFT=m +# CONFIG_HID_MOSART is not set +CONFIG_HID_MONTEREY=m +CONFIG_HID_NTRIG=m +# CONFIG_HID_ORTEK is not set +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_ROCCAT_KONE is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +# CONFIG_HID_STANTUM is not set +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=m +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_WACOM=m +# CONFIG_HID_WACOM_POWER_SUPPLY is not set +CONFIG_HID_ZEROPLUS=m +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=m +# CONFIG_USB_ULPI is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_AT91=y +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_DAC124S085=m +CONFIG_LEDS_BD2802=m +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_DEBUG=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 +# CONFIG_DMADEVICES is not set +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_STAGING 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_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +# CONFIG_GFS2_FS_LOCKING_DLM is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_NILFS2_FS=m +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=m +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m + +# +# Caches +# +CONFIG_FSCACHE=m +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_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_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTRS is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_EXOFS_FS=m +# CONFIG_EXOFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_FSCACHE is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +# CONFIG_AFS_FSCACHE 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=y +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_IPIPE_DEBUG is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_PCOMP=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MANAGER_TESTS=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=m +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -urN orig/linux-2.6.35.9//.config.old relase/linux-2.6.35.9//.config.old --- orig/linux-2.6.35.9//.config.old 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//.config.old 2011-03-15 11:06:13.629702442 +0100 @@ -0,0 +1,3029 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.35.4 +# Tue Sep 21 10:13:28 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_ARCH_USES_GETTIMEOFFSET=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_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_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +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_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# 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_VEXPRESS is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X 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_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +CONFIG_HAVE_AT91_USART3=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_HAVE_AT91_USART5=y + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +CONFIG_ARCH_AT91SAM9G20=y +# CONFIG_ARCH_AT91SAM9G45 is not set +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT572D940HF is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9G20 Board Type +# +# CONFIG_MACH_AT91SAM9G20EK is not set +# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set +# CONFIG_MACH_CPU9G20 is not set +# CONFIG_MACH_PORTUXG20 is not set +# CONFIG_MACH_STAMP9G20 is not set +CONFIG_MACH_FOXG20=y + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_AT91_TIMER_HZ=100 +# CONFIG_AT91_EARLY_DBGU is not set +CONFIG_AT91_EARLY_USART0=y +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=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_ARM_L1_CACHE_SHIFT=5 + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rw rootwait init=/sbin/init" +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_NVS=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_APM_EMULATION=m +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_PHONET=m +CONFIG_IEEE802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +# CONFIG_MKISS is not set +# CONFIG_6PACK is not set +# CONFIG_BPQETHER is not set +# CONFIG_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_BAYCOM_PAR is not set +# CONFIG_BAYCOM_EPP is not set +# CONFIG_YAM is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_DEV is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +# CONFIG_BT_L2CAP_EXT_FEATURES is not set +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +# CONFIG_BT_ATH3K is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_1284 is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_BLK_DEV=y +# CONFIG_PARIDE 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_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_OSD 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=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +# CONFIG_ICS932S401 is not set +CONFIG_ATMEL_SSC=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +CONFIG_SENSORS_TSL2550=m +CONFIG_DS1682=m +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +CONFIG_IWMC3200TOP=m +# CONFIG_IWMC3200TOP_DEBUG is not set +# CONFIG_IWMC3200TOP_DEBUGFS is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m +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=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FC_TGT_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_ATA is not set +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_SRP_TGT_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +# CONFIG_SATA_AHCI_PLATFORM is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_SATA_MV=m + +# +# PATA SFF controllers with BMDMA +# + +# +# PIO-only SFF controllers +# +CONFIG_PATA_AT91=m +CONFIG_PATA_PLATFORM=m + +# +# Generic fallback / legacy drivers +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_AT76C50X_USB=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8187=m +CONFIG_MAC80211_HWSIM=m +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH9K_HTC is not set +CONFIG_AR9170_USB=m +CONFIG_B43=m +# CONFIG_B43_SDIO is not set +CONFIG_B43_PIO=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_IWM=m +# CONFIG_IWM_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_SPI=m +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_MESH is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_SPI=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT30XX=y +# CONFIG_RT2800USB_RT35XX is not set +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL12XX is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO 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=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=m +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_CDC_PHONET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set +CONFIG_IEEE802154_DRIVERS=m +# CONFIG_IEEE802154_FAKEHARD is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +CONFIG_PHONE=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_APMPOWER=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADP5588=m +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_QT2160 is not set +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_TCA6416 is not set +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_LM8323=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +# CONFIG_JOYSTICK_IFORCE_USB is not set +# CONFIG_JOYSTICK_IFORCE_232 is not set +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +# CONFIG_JOYSTICK_XPAD_FF is not set +# CONFIG_JOYSTICK_XPAD_LEDS is not set +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879=m +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC5UH=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_W90X900=m +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_SI is not set +# CONFIG_IPMI_WATCHDOG is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_NVRAM=m +CONFIG_R3964=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB 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_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +CONFIG_SPI_BITBANG=m +# CONFIG_SPI_BUTTERFLY is not set +CONFIG_SPI_GPIO=m +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_TLE62X0=m + +# +# PPS support +# +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_W1=y +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=y + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=y +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_APM_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91SAM9X_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TC35892 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB8500_CORE is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_IR_CORE=m +CONFIG_VIDEO_IR=m +CONFIG_RC_MAP=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +# CONFIG_IR_IMON is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_AU0828=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +# CONFIG_SOC_CAMERA_MT9T112 is not set +CONFIG_SOC_CAMERA_MT9V022=m +# CONFIG_SOC_CAMERA_RJ54N1 is not set +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_OV772X=m +# CONFIG_SOC_CAMERA_OV9640 is not set +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +# CONFIG_USB_GSPCA_BENQ is not set +CONFIG_USB_GSPCA_CONEX=m +# CONFIG_USB_GSPCA_CPIA1 is not set +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +# CONFIG_USB_GSPCA_OV534_9 is not set +CONFIG_USB_GSPCA_PAC207=m +# CONFIG_USB_GSPCA_PAC7302 is not set +CONFIG_USB_GSPCA_PAC7311=m +# CONFIG_USB_GSPCA_SN9C2028 is not set +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_STK014=m +# CONFIG_USB_GSPCA_STV0680 is not set +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +# CONFIG_VIDEO_TLG2300 is not set +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_DSBR=m +# CONFIG_RADIO_SI470X is not set +CONFIG_USB_MR800=m +CONFIG_RADIO_TEA5764=m +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_FRIIO=m +# CONFIG_DVB_USB_EC168 is not set +# CONFIG_DVB_USB_AZ6027 is not set +CONFIG_SMS_SIANO_MDTV=m + +# +# Siano module components +# +CONFIG_SMS_USB_DRV=m +CONFIG_SMS_SDIO_DRV=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_STB6100=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=m +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +CONFIG_LCD_LMS283GF05=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +CONFIG_LCD_PLATFORM=m +# CONFIG_LCD_S6E63M0 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP8860 is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_MPU401_UART=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_ARM=y + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_AC97C is not set +CONFIG_SND_SPI=y +CONFIG_SND_AT73C213=m +CONFIG_SND_AT73C213_TARGET_BITRATE=48000 +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +CONFIG_SND_USB_CAIAQ=m +# CONFIG_SND_USB_CAIAQ_INPUT is not set +CONFIG_SND_SOC=m +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_ATMEL_SOC_SSC=m +CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_WM_HUBS=m +CONFIG_SND_SOC_AD1836=m +CONFIG_SND_SOC_AD193X=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_ADS117X=m +CONFIG_SND_SOC_AK4104=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK4671=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_DA7210=m +CONFIG_SND_SOC_L3=m +CONFIG_SND_SOC_PCM3008=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320DAC33=m +CONFIG_SND_SOC_UDA134X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8727=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8940=m +CONFIG_SND_SOC_WM8955=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8961=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8988=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SOC_WM8993=m +CONFIG_SND_SOC_WM9081=m +CONFIG_SND_SOC_MAX9877=m +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_WM2000=m +CONFIG_SND_SOC_WM9090=m +CONFIG_SOUND_PRIME=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +# CONFIG_HID_CANDO is not set +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_PRODIKEYS is not set +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +# CONFIG_DRAGONRISE_FF is not set +# CONFIG_HID_EGALAX is not set +CONFIG_HID_EZKEY=m +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MICROSOFT=m +# CONFIG_HID_MOSART is not set +CONFIG_HID_MONTEREY=m +CONFIG_HID_NTRIG=m +# CONFIG_HID_ORTEK is not set +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_ROCCAT_KONE is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +# CONFIG_HID_STANTUM is not set +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=m +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_WACOM=m +# CONFIG_HID_WACOM_POWER_SUPPLY is not set +CONFIG_HID_ZEROPLUS=m +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=m +# CONFIG_USB_ULPI is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_AT91=y +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_DAC124S085=m +CONFIG_LEDS_BD2802=m +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_DEBUG=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 +# CONFIG_DMADEVICES is not set +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_STAGING 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_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +# CONFIG_GFS2_FS_LOCKING_DLM is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_NILFS2_FS=m +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=m +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m + +# +# Caches +# +CONFIG_FSCACHE=m +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_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_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTRS is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_EXOFS_FS=m +# CONFIG_EXOFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_FSCACHE is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +# CONFIG_AFS_FSCACHE 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=y +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_PCOMP=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MANAGER_TESTS=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=m +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff -urN orig/linux-2.6.35.9//drivers/Makefile relase/linux-2.6.35.9//drivers/Makefile --- orig/linux-2.6.35.9//drivers/Makefile 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/Makefile 2011-03-15 10:56:26.081702442 +0100 @@ -113,3 +113,5 @@ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ obj-y += ieee802154/ + +obj-$(CONFIG_XENOMAI) += xenomai/ diff -urN orig/linux-2.6.35.9//drivers/mfd/twl4030-irq.c relase/linux-2.6.35.9//drivers/mfd/twl4030-irq.c --- orig/linux-2.6.35.9//drivers/mfd/twl4030-irq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/mfd/twl4030-irq.c 2011-03-15 10:56:25.917702441 +0100 @@ -334,7 +334,11 @@ note_interrupt(module_irq, d, IRQ_NONE); else +#ifndef CONFIG_IPIPE d->handle_irq(module_irq, d); +#else + d->ipipe_ack(module_irq, d); +#endif } } local_irq_enable(); diff -urN orig/linux-2.6.35.9//drivers/misc/Kconfig relase/linux-2.6.35.9//drivers/misc/Kconfig --- orig/linux-2.6.35.9//drivers/misc/Kconfig 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/misc/Kconfig 2011-03-15 10:56:25.921702441 +0100 @@ -72,7 +72,7 @@ config ATMEL_TCB_CLKSRC bool "TC Block Clocksource" - depends on ATMEL_TCLIB && GENERIC_TIME + depends on ATMEL_TCLIB && GENERIC_TIME && !IPIPE default y help Select this to get a high precision clocksource based on a diff -urN orig/linux-2.6.35.9//drivers/pci/htirq.c relase/linux-2.6.35.9//drivers/pci/htirq.c --- orig/linux-2.6.35.9//drivers/pci/htirq.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/pci/htirq.c 2011-03-15 10:56:25.921702441 +0100 @@ -20,7 +20,7 @@ * With multiple simultaneous hypertransport irq devices it might pay * to make this more fine grained. But start with simple, stupid, and correct. */ -static DEFINE_SPINLOCK(ht_irq_lock); +static IPIPE_DEFINE_SPINLOCK(ht_irq_lock); struct ht_irq_cfg { struct pci_dev *dev; diff -urN orig/linux-2.6.35.9//drivers/serial/8250.c relase/linux-2.6.35.9//drivers/serial/8250.c --- orig/linux-2.6.35.9//drivers/serial/8250.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/serial/8250.c 2011-03-15 10:56:25.921702441 +0100 @@ -3051,6 +3051,53 @@ return 0; } +#if defined(CONFIG_IPIPE_DEBUG) && defined(CONFIG_SERIAL_8250_CONSOLE) + +#include + +void __weak __ipipe_serial_debug(const char *fmt, ...) +{ + struct uart_8250_port *up = &serial8250_ports[0]; + unsigned int ier, count; + unsigned long flags; + char buf[128]; + va_list ap; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + count = strlen(buf); + + touch_nmi_watchdog(); + + local_irq_save_hw(flags); + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(up, UART_IER); + + if (up->capabilities & UART_CAP_UUE) + serial_out(up, UART_IER, UART_IER_UUE); + else + serial_out(up, UART_IER, 0); + + uart_console_write(&up->port, buf, count, serial8250_console_putchar); + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(up, BOTH_EMPTY); + serial_out(up, UART_IER, ier); + + local_irq_restore_hw(flags); +} + +EXPORT_SYMBOL(__ipipe_serial_debug); + +#endif + static struct platform_driver serial8250_isa_driver = { .probe = serial8250_probe, .remove = __devexit_p(serial8250_remove), diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/buffer.c relase/linux-2.6.35.9//drivers/xenomai/analogy/buffer.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/buffer.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/buffer.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1067 @@ +/** + * @file + * Analogy for Linux, buffer related features + * + * @note Copyright (C) 1997-2000 David A. Schleef + * @note Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* --- Initialization functions (init, alloc, free) --- */ + +/* The buffer charactistic is very close to the Comedi one: it is + allocated with vmalloc() and all physical addresses of the pages which + compose the virtual buffer are hold in a table */ + +void a4l_free_buffer(a4l_buf_t * buf_desc) +{ + if (buf_desc->pg_list != NULL) { + rtdm_free(buf_desc->pg_list); + buf_desc->pg_list = NULL; + } + + if (buf_desc->buf != NULL) { + char *vaddr, *vabase = buf_desc->buf; + for (vaddr = vabase; vaddr < vabase + buf_desc->size; + vaddr += PAGE_SIZE) + ClearPageReserved(vmalloc_to_page(vaddr)); + vfree(buf_desc->buf); + buf_desc->buf = NULL; + } +} + +int a4l_alloc_buffer(a4l_buf_t *buf_desc, int buf_size) +{ + int ret = 0; + char *vaddr, *vabase; + + buf_desc->size = buf_size; + buf_desc->size = PAGE_ALIGN(buf_desc->size); + + buf_desc->buf = vmalloc(buf_desc->size); + if (buf_desc->buf == NULL) { + ret = -ENOMEM; + goto out_virt_contig_alloc; + } + + vabase = buf_desc->buf; + + for (vaddr = vabase; vaddr < vabase + buf_desc->size; + vaddr += PAGE_SIZE) + SetPageReserved(vmalloc_to_page(vaddr)); + + buf_desc->pg_list = rtdm_malloc(((buf_desc->size) >> PAGE_SHIFT) * + sizeof(unsigned long)); + if (buf_desc->pg_list == NULL) { + ret = -ENOMEM; + goto out_virt_contig_alloc; + } + + for (vaddr = vabase; vaddr < vabase + buf_desc->size; + vaddr += PAGE_SIZE) + buf_desc->pg_list[(vaddr - vabase) >> PAGE_SHIFT] = + (unsigned long) page_to_phys(vmalloc_to_page(vaddr)); + +out_virt_contig_alloc: + if (ret != 0) + a4l_free_buffer(buf_desc); + + return ret; +} + +static void a4l_reinit_buffer(a4l_buf_t *buf_desc) +{ + /* No command to process yet */ + buf_desc->cur_cmd = NULL; + + /* No more (or not yet) linked with a subdevice */ + buf_desc->subd = NULL; + + /* Initializes counts and flags */ + buf_desc->end_count = 0; + buf_desc->prd_count = 0; + buf_desc->cns_count = 0; + buf_desc->tmp_count = 0; + buf_desc->mng_count = 0; + + /* Flush pending events */ + buf_desc->flags = 0; + a4l_flush_sync(&buf_desc->sync); +} + +void a4l_init_buffer(a4l_buf_t *buf_desc) +{ + memset(buf_desc, 0, sizeof(a4l_buf_t)); + a4l_init_sync(&buf_desc->sync); + a4l_reinit_buffer(buf_desc); +} + +void a4l_cleanup_buffer(a4l_buf_t *buf_desc) +{ + a4l_cleanup_sync(&buf_desc->sync); +} + +int a4l_setup_buffer(a4l_cxt_t *cxt, a4l_cmd_t *cmd) +{ + a4l_buf_t *buf_desc = cxt->buffer; + int i; + + /* Retrieve the related subdevice */ + buf_desc->subd = a4l_get_subd(cxt->dev, cmd->idx_subd); + if (buf_desc->subd == NULL) { + __a4l_err("a4l_setup_buffer: subdevice index " + "out of range (%d)\n", cmd->idx_subd); + return -EINVAL; + } + + if (test_and_set_bit(A4L_SUBD_BUSY_NR, &buf_desc->subd->status)) { + __a4l_err("a4l_setup_buffer: subdevice %d already busy\n", + cmd->idx_subd); + return -EBUSY; + } + + /* Checks if the transfer system has to work in bulk mode */ + if (cmd->flags & A4L_CMD_BULK) + set_bit(A4L_BUF_BULK_NR, &buf_desc->flags); + + /* Sets the working command */ + buf_desc->cur_cmd = cmd; + + /* Link the subdevice with the context's buffer */ + buf_desc->subd->buf = buf_desc; + + /* Computes the count to reach, if need be */ + if (cmd->stop_src == TRIG_COUNT) { + for (i = 0; i < cmd->nb_chan; i++) { + a4l_chan_t *chft; + chft = a4l_get_chfeat(buf_desc->subd, + CR_CHAN(cmd->chan_descs[i])); + buf_desc->end_count += chft->nb_bits / 8; + } + buf_desc->end_count *= cmd->stop_arg; + } + + __a4l_dbg(1, core_dbg, + "a4l_setup_buffer: end_count=%lu\n", buf_desc->end_count); + + return 0; +} + +int a4l_cancel_buffer(a4l_cxt_t *cxt) +{ + a4l_buf_t *buf_desc = cxt->buffer; + a4l_subd_t *subd = buf_desc->subd; + + int err = 0; + + if (!subd || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return 0; + + /* If a "cancel" function is registered, call it + (Note: this function is called before having checked + if a command is under progress; we consider that + the "cancel" function can be used as as to (re)initialize + some component) */ + if (subd->cancel != NULL && (err = subd->cancel(subd)) < 0) { + __a4l_err("a4l_cancel: cancel handler failed (err=%d)\n", err); + } + + if (buf_desc->cur_cmd != NULL) { + a4l_free_cmddesc(buf_desc->cur_cmd); + rtdm_free(buf_desc->cur_cmd); + buf_desc->cur_cmd = NULL; + } + + a4l_reinit_buffer(buf_desc); + + clear_bit(A4L_SUBD_BUSY_NR, &subd->status); + subd->buf = NULL; + + return err; +} + +/* --- Munge related function --- */ + +int a4l_get_chan(a4l_subd_t *subd) +{ + int i, j, tmp_count, tmp_size = 0; + a4l_cmd_t *cmd; + + cmd = a4l_get_cmd(subd); + if (!cmd) + return -EINVAL; + + /* There is no need to check the channel idx, + it has already been controlled in command_test */ + + /* We assume channels can have different sizes; + so, we have to compute the global size of the channels + in this command... */ + for (i = 0; i < cmd->nb_chan; i++) { + j = (subd->chan_desc->mode != A4L_CHAN_GLOBAL_CHANDESC) ? + CR_CHAN(cmd->chan_descs[i]) : 0; + tmp_size += subd->chan_desc->chans[j].nb_bits; + } + + /* Translation bits -> bytes */ + tmp_size /= 8; + + tmp_count = subd->buf->mng_count % tmp_size; + + /* Translation bytes -> bits */ + tmp_count *= 8; + + /* ...and find the channel the last munged sample + was related with */ + for (i = 0; tmp_count > 0 && i < cmd->nb_chan; i++) { + j = (subd->chan_desc->mode != A4L_CHAN_GLOBAL_CHANDESC) ? + CR_CHAN(cmd->chan_descs[i]) : 0; + tmp_count -= subd->chan_desc->chans[j].nb_bits; + } + + if (tmp_count == 0) + return i; + else + return -EINVAL; +} + +/* --- Transfer / copy functions --- */ + +/* The following functions are explained in the Doxygen section + "Buffer management services" in driver_facilities.c */ + +int a4l_buf_prepare_absput(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_input(subd)) + return -EINVAL; + + return __pre_abs_put(buf, count); +} + + +int a4l_buf_commit_absput(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_input(subd)) + return -EINVAL; + + return __abs_put(buf, count); +} + +int a4l_buf_prepare_put(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_input(subd)) + return -EINVAL; + + return __pre_put(buf, count); +} + +int a4l_buf_commit_put(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_input(subd)) + return -EINVAL; + + return __put(buf, count); +} + +int a4l_buf_put(a4l_subd_t *subd, void *bufdata, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + int err; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_input(subd)) + return -EINVAL; + + if (__count_to_put(buf) < count) + return -EAGAIN; + + err = __produce(NULL, buf, bufdata, count); + if (err < 0) + return err; + + err = __put(buf, count); + + return err; +} + +int a4l_buf_prepare_absget(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_output(subd)) + return -EINVAL; + + return __pre_abs_get(buf, count); +} + +int a4l_buf_commit_absget(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_output(subd)) + return -EINVAL; + + return __abs_get(buf, count); +} + +int a4l_buf_prepare_get(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_output(subd)) + return -EINVAL; + + return __pre_get(buf, count); +} + +int a4l_buf_commit_get(a4l_subd_t *subd, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + + /* Basic checkings */ + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_output(subd)) + return -EINVAL; + + return __get(buf, count); +} + +int a4l_buf_get(a4l_subd_t *subd, void *bufdata, unsigned long count) +{ + a4l_buf_t *buf = subd->buf; + int err; + + /* Basic checkings */ + + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (!a4l_subd_is_output(subd)) + return -EINVAL; + + if (__count_to_get(buf) < count) + return -EAGAIN; + + /* Update the counter */ + err = __consume(NULL, buf, bufdata, count); + if (err < 0) + return err; + + /* Perform the transfer */ + err = __get(buf, count); + + return err; +} + +int a4l_buf_evt(a4l_subd_t *subd, unsigned long evts) +{ + a4l_buf_t *buf = subd->buf; + int tmp; + + /* Warning: here, there may be a condition race : the cancel + function is called by the user side and a4l_buf_evt and all + the a4l_buf_... functions are called by the kernel + side. Nonetheless, the driver should be in charge of such + race conditions, not the framework */ + + /* Basic checking */ + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + /* Even if it is a little more complex, + atomic operations are used so as + to prevent any kind of corner case */ + while ((tmp = ffs(evts) - 1) != -1) { + set_bit(tmp, &buf->flags); + clear_bit(tmp, &evts); + } + + /* Notify the user-space side */ + a4l_signal_sync(&buf->sync); + + return 0; +} + +unsigned long a4l_buf_count(a4l_subd_t *subd) +{ + a4l_buf_t *buf = subd->buf; + unsigned long ret = 0; + + /* Basic checking */ + if (!buf || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) + return -ENOENT; + + if (a4l_subd_is_input(subd)) + ret = __count_to_put(buf); + else if (a4l_subd_is_output(subd)) + ret = __count_to_get(buf); + + return ret; +} + +/* --- Mmap functions --- */ + +void a4l_map(struct vm_area_struct *area) +{ + unsigned long *status = (unsigned long *)area->vm_private_data; + set_bit(A4L_BUF_MAP_NR, status); +} + +void a4l_unmap(struct vm_area_struct *area) +{ + unsigned long *status = (unsigned long *)area->vm_private_data; + clear_bit(A4L_BUF_MAP_NR, status); +} + +static struct vm_operations_struct a4l_vm_ops = { + .open = a4l_map, + .close = a4l_unmap, +}; + +int a4l_ioctl_mmap(a4l_cxt_t *cxt, void *arg) +{ + a4l_mmap_t map_cfg; + a4l_dev_t *dev; + a4l_buf_t *buf; + int ret; + + /* The mmap operation cannot be performed in a + real-time context */ + if (rtdm_in_rt_context()) { + return -ENOSYS; + } + + dev = a4l_get_dev(cxt); + buf = cxt->buffer; + + /* Basic checkings */ + + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_mmap: cannot mmap on " + "an unattached device\n"); + return -EINVAL; + } + + if (test_bit(A4L_BUF_MAP_NR, &buf->flags)) { + __a4l_err("a4l_ioctl_mmap: buffer already mapped\n"); + return -EBUSY; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &map_cfg, arg, sizeof(a4l_mmap_t)) != 0) + return -EFAULT; + + /* Check the size to be mapped */ + if ((map_cfg.size & ~(PAGE_MASK)) != 0 || map_cfg.size > buf->size) + return -EFAULT; + + /* All the magic is here */ + ret = rtdm_mmap_to_user(cxt->user_info, + buf->buf, + map_cfg.size, + PROT_READ | PROT_WRITE, + &map_cfg.ptr, &a4l_vm_ops, &buf->flags); + + if (ret < 0) { + __a4l_err("a4l_ioctl_mmap: internal error, " + "rtdm_mmap_to_user failed (err=%d)\n", ret); + return ret; + } + + return rtdm_safe_copy_to_user(cxt->user_info, + arg, &map_cfg, sizeof(a4l_mmap_t)); +} + +/* --- IOCTL / FOPS functions --- */ + +int a4l_ioctl_cancel(a4l_cxt_t * cxt, void *arg) +{ + unsigned int idx_subd = (unsigned long)arg; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_subd_t *subd; + + /* Basically check the device */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_cancel: operation not supported on " + "an unattached device\n"); + return -EINVAL; + } + + if (cxt->buffer->subd == NULL) { + __a4l_err("a4l_ioctl_cancel: " + "no acquisition to cancel on this context\n"); + return -EINVAL; + } + + if (idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_ioctl_cancel: bad subdevice index\n"); + return -EINVAL; + } + + subd = dev->transfer.subds[idx_subd]; + + if (subd != cxt->buffer->subd) { + __a4l_err("a4l_ioctl_cancel: " + "current context works on another subdevice " + "(%d!=%d)\n", cxt->buffer->subd->idx, subd->idx); + return -EINVAL; + } + + return a4l_cancel_buffer(cxt); +} + +/* The ioctl BUFCFG is only useful for changing the size of the + asynchronous buffer. + (BUFCFG = free of the current buffer + allocation of a new one) */ + +int a4l_ioctl_bufcfg(a4l_cxt_t * cxt, void *arg) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + a4l_bufcfg_t buf_cfg; + + /* As Linux API is used to allocate a virtual buffer, + the calling process must not be in primary mode */ + if (rtdm_in_rt_context()) { + return -ENOSYS; + } + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_bufcfg: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &buf_cfg, + arg, sizeof(a4l_bufcfg_t)) != 0) + return -EFAULT; + + if (buf_cfg.buf_size > A4L_BUF_MAXSIZE) { + __a4l_err("a4l_ioctl_bufcfg: buffer size too big (<=16MB)\n"); + return -EINVAL; + } + + if (buf_cfg.idx_subd == A4L_BUF_DEFMAGIC) { + cxt->dev->transfer.default_bufsize = buf_cfg.buf_size; + return 0; + } + + if (subd && test_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + __a4l_err("a4l_ioctl_bufcfg: acquisition in progress\n"); + return -EBUSY; + } + + if (test_bit(A4L_BUF_MAP, &buf->flags)) { + __a4l_err("a4l_ioctl_bufcfg: please unmap before " + "configuring buffer\n"); + return -EPERM; + } + + /* Free the buffer... */ + a4l_free_buffer(buf); + + /* ...to reallocate it */ + return a4l_alloc_buffer(buf, buf_cfg.buf_size); +} + +/* The BUFINFO ioctl provides two basic roles: + - tell the user app the size of the asynchronous buffer + - display the read/write counters (how many bytes to read/write) */ + +int a4l_ioctl_bufinfo(a4l_cxt_t * cxt, void *arg) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + a4l_bufinfo_t info; + + unsigned long tmp_cnt; + int ret; + + if (!rtdm_in_rt_context() && rtdm_rt_capable(cxt->user_info)) + return -ENOSYS; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_bufinfo: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &info, arg, sizeof(a4l_bufinfo_t)) != 0) + return -EFAULT; + + + /* If a transfer is not occuring, simply return buffer + informations, otherwise make the transfer progress */ + if (!subd || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + info.rw_count = 0; + goto a4l_ioctl_bufinfo_out; + } + + ret = __handle_event(buf); + + if (a4l_subd_is_input(subd)) { + + /* Updates consume count if rw_count is not null */ + if (info.rw_count != 0) + buf->cns_count += info.rw_count; + + /* Retrieves the data amount to read */ + tmp_cnt = info.rw_count = __count_to_get(buf); + + __a4l_dbg(1, core_dbg, + "a4l_ioctl_bufinfo: count to read=%lu\n", tmp_cnt); + + if ((ret < 0 && ret != -ENOENT) || + (ret == -ENOENT && tmp_cnt == 0)) { + a4l_cancel_buffer(cxt); + return ret; + } + } else if (a4l_subd_is_output(subd)) { + + if (ret < 0) { + a4l_cancel_buffer(cxt); + if (info.rw_count != 0) + return ret; + } + + /* If rw_count is not null, + there is something to write / munge */ + if (info.rw_count != 0 && info.rw_count <= __count_to_put(buf)) { + + /* Updates the production pointer */ + buf->prd_count += info.rw_count; + + /* Sets the munge count */ + tmp_cnt = info.rw_count; + } else + tmp_cnt = 0; + + /* Retrieves the data amount which is writable */ + info.rw_count = __count_to_put(buf); + + __a4l_dbg(1, core_dbg, + "a4l_ioctl_bufinfo: count to write=%lu\n", + info.rw_count); + + } else { + __a4l_err("a4l_ioctl_bufinfo: inappropriate subdevice\n"); + return -EINVAL; + } + + /* Performs the munge if need be */ + if (subd->munge != NULL) { + + /* Call the munge callback */ + __munge(subd, subd->munge, buf, tmp_cnt); + + /* Updates munge count */ + buf->mng_count += tmp_cnt; + } + +a4l_ioctl_bufinfo_out: + + /* Sets the buffer size */ + info.buf_size = buf->size; + + /* Sends the structure back to user space */ + if (rtdm_safe_copy_to_user(cxt->user_info, + arg, &info, sizeof(a4l_bufinfo_t)) != 0) + return -EFAULT; + + return 0; +} + +/* The function a4l_read_buffer can be considered as the kernel entry + point of the RTDM syscall read. This syscall is supposed to be used + only during asynchronous acquisitions */ +ssize_t a4l_read_buffer(a4l_cxt_t * cxt, void *bufdata, size_t nbytes) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + ssize_t count = 0; + + /* Basic checkings */ + + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_read: unattached device\n"); + return -EINVAL; + } + + if (!subd || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + __a4l_err("a4l_read: idle subdevice on this context\n"); + return -ENOENT; + } + + if (!a4l_subd_is_input(subd)) { + __a4l_err("a4l_read: current context " + "does not work with an input subdevice\n"); + return -EINVAL; + } + + while (count < nbytes) { + + /* Check the events */ + int ret = __handle_event(buf); + + /* Compute the data amount to copy */ + unsigned long tmp_cnt = __count_to_get(buf); + + /* Check tmp_cnt count is not higher than + the global count to read */ + if (tmp_cnt > nbytes - count) + tmp_cnt = nbytes - count; + + /* We check whether there is an error */ + if (ret < 0 && ret != -ENOENT) { + a4l_cancel_buffer(cxt); + count = ret; + goto out_a4l_read; + } + + /* We check whether the acquisition is over */ + if (ret == -ENOENT && tmp_cnt == 0) { + a4l_cancel_buffer(cxt); + count = 0; + goto out_a4l_read; + } + + if (tmp_cnt > 0) { + + /* Performs the munge if need be */ + if (subd->munge != NULL) { + __munge(subd, subd->munge, buf, tmp_cnt); + + /* Updates munge count */ + buf->mng_count += tmp_cnt; + } + + /* Performs the copy */ + ret = __consume(cxt, buf, bufdata + count, tmp_cnt); + + if (ret < 0) { + count = ret; + goto out_a4l_read; + } + + /* Updates consume count */ + buf->cns_count += tmp_cnt; + + /* Updates the return value */ + count += tmp_cnt; + + /* If the driver does not work in bulk mode, + we must leave this function */ + if (!test_bit(A4L_BUF_BULK, &buf->flags)) + goto out_a4l_read; + } + /* If the acquisition is not over, we must not + leave the function without having read a least byte */ + else { + ret = a4l_wait_sync(&(buf->sync), rtdm_in_rt_context()); + if (ret < 0) { + if (ret == -ERESTARTSYS) + ret = -EINTR; + count = ret; + goto out_a4l_read; + } + } + } + +out_a4l_read: + + return count; +} + +/* The function a4l_write_buffer can be considered as the kernel entry + point of the RTDM syscall write. This syscall is supposed to be + used only during asynchronous acquisitions */ +ssize_t a4l_write_buffer(a4l_cxt_t *cxt, const void *bufdata, size_t nbytes) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + ssize_t count = 0; + + /* Basic checkings */ + + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_write: unattached device\n"); + return -EINVAL; + } + + if (!subd || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + __a4l_err("a4l_write: idle subdevice on this context\n"); + return -ENOENT; + } + + if (!a4l_subd_is_output(subd)) { + __a4l_err("a4l_write: current context " + "does not work with an output subdevice\n"); + return -EINVAL; + } + + while (count < nbytes) { + + /* Check the events */ + int ret = __handle_event(buf); + + /* Compute the data amount to copy */ + unsigned long tmp_cnt = __count_to_put(buf); + + /* Check tmp_cnt count is not higher than + the global count to write */ + if (tmp_cnt > nbytes - count) + tmp_cnt = nbytes - count; + + if (ret < 0) { + a4l_cancel_buffer(cxt); + count = (ret == -ENOENT) ? -EINVAL : ret; + goto out_a4l_write; + } + + if (tmp_cnt > 0) { + + /* Performs the copy */ + ret = __produce(cxt, + buf, (void *)bufdata + count, tmp_cnt); + if (ret < 0) { + count = ret; + goto out_a4l_write; + } + + /* Performs the munge if need be */ + if (subd->munge != NULL) { + __munge(subd, subd->munge, buf, tmp_cnt); + + /* Updates munge count */ + buf->mng_count += tmp_cnt; + } + + /* Updates produce count */ + buf->prd_count += tmp_cnt; + + /* Updates the return value */ + count += tmp_cnt; + + /* If the driver does not work in bulk mode, + we must leave this function */ + if (!test_bit(A4L_BUF_BULK, &buf->flags)) + goto out_a4l_write; + } else { + /* The buffer is full, we have to wait for a slot to free */ + ret = a4l_wait_sync(&(buf->sync), rtdm_in_rt_context()); + if (ret < 0) { + if (ret == -ERESTARTSYS) + ret = -EINTR; + count = ret; + goto out_a4l_write; + } + } + } + +out_a4l_write: + + return count; +} + +int a4l_select(a4l_cxt_t *cxt, + rtdm_selector_t *selector, + enum rtdm_selecttype type, unsigned fd_index) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + + /* Basic checkings */ + + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_select: unattached device\n"); + return -EINVAL; + } + + if (!subd || !test_bit(A4L_SUBD_BUSY, &subd->status)) { + __a4l_err("a4l_select: idle subdevice on this context\n"); + return -ENOENT; + } + + /* Check the RTDM select type + (RTDM_SELECTTYPE_EXCEPT is not supported) */ + + if(type != RTDM_SELECTTYPE_READ && + type != RTDM_SELECTTYPE_WRITE) { + __a4l_err("a4l_select: wrong select argument\n"); + return -EINVAL; + } + + if (type == RTDM_SELECTTYPE_READ && !a4l_subd_is_input(subd)) { + __a4l_err("a4l_select: current context " + "does not work with an input subdevice\n"); + return -EINVAL; + } + + if (type == RTDM_SELECTTYPE_WRITE && !a4l_subd_is_output(subd)) { + __a4l_err("a4l_select: current context " + "does not work with an input subdevice\n"); + return -EINVAL; + } + + /* Performs a bind on the Analogy synchronization element */ + return a4l_select_sync(&(buf->sync), selector, type, fd_index); +} + +int a4l_ioctl_poll(a4l_cxt_t * cxt, void *arg) +{ + int ret = 0; + unsigned long tmp_cnt = 0; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_buf_t *buf = cxt->buffer; + a4l_subd_t *subd = buf->subd; + a4l_poll_t poll; + + if (!rtdm_in_rt_context() && rtdm_rt_capable(cxt->user_info)) + return -ENOSYS; + + /* Basic checking */ + + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_poll: unattached device\n"); + return -EINVAL; + } + + if (!subd || !test_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + __a4l_err("a4l_poll: idle subdevice on this context\n"); + return -ENOENT; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &poll, arg, sizeof(a4l_poll_t)) != 0) + return -EFAULT; + + /* Checks the buffer events */ + a4l_flush_sync(&buf->sync); + ret = __handle_event(buf); + + /* Retrieves the data amount to compute + according to the subdevice type */ + if (a4l_subd_is_input(subd)) { + + tmp_cnt = __count_to_get(buf); + + /* Check if some error occured */ + if (ret < 0 && ret != -ENOENT) { + a4l_cancel_buffer(cxt); + return ret; + } + + /* Check whether the acquisition is over */ + if (ret == -ENOENT && tmp_cnt == 0) { + a4l_cancel_buffer(cxt); + return 0; + } + } else { + + /* If some error was detected, cancel the transfer */ + if (ret < 0) { + a4l_cancel_buffer(cxt); + return ret; + } + + tmp_cnt = __count_to_put(buf); + } + + if (poll.arg == A4L_NONBLOCK || tmp_cnt != 0) + goto out_poll; + + if (poll.arg == A4L_INFINITE) + ret = a4l_wait_sync(&(buf->sync), rtdm_in_rt_context()); + else { + unsigned long long ns = ((unsigned long long)poll.arg) * + ((unsigned long long)NSEC_PER_MSEC); + ret = a4l_timedwait_sync(&(buf->sync), + rtdm_in_rt_context(), ns); + } + + if (ret == 0) { + /* Retrieves the count once more */ + if (a4l_subd_is_input(dev->transfer.subds[poll.idx_subd])) + tmp_cnt = __count_to_get(buf); + else + tmp_cnt = __count_to_put(buf); + } + +out_poll: + + poll.arg = tmp_cnt; + + ret = rtdm_safe_copy_to_user(cxt->user_info, + arg, &poll, sizeof(a4l_poll_t)); + + return ret; +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/command.c relase/linux-2.6.35.9//drivers/xenomai/analogy/command.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/command.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/command.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,379 @@ +/** + * @file + * Analogy for Linux, command related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include +#include + +#include +#include + +/* --- Command descriptor management functions --- */ + +int a4l_fill_cmddesc(a4l_cxt_t * cxt, a4l_cmd_t * desc, void *arg) +{ + int ret = 0; + unsigned int *tmpchans = NULL; + + ret = rtdm_safe_copy_from_user(cxt->user_info, + desc, arg, sizeof(a4l_cmd_t)); + if (ret != 0) + goto out_cmddesc; + + if (desc->nb_chan == 0) { + ret = -EINVAL; + goto out_cmddesc; + } + + tmpchans = rtdm_malloc(desc->nb_chan * sizeof(unsigned int)); + if (tmpchans == NULL) { + ret = -ENOMEM; + goto out_cmddesc; + } + + ret = rtdm_safe_copy_from_user(cxt->user_info, + tmpchans, + desc->chan_descs, + desc->nb_chan * sizeof(unsigned long)); + if (ret != 0) + goto out_cmddesc; + + desc->chan_descs = tmpchans; + + __a4l_dbg(1, core_dbg, "a4l_fill_cmddesc: desc dump\n"); + __a4l_dbg(1, core_dbg, "\t->idx_subd=%u\n", desc->idx_subd); + __a4l_dbg(1, core_dbg, "\t->flags=%lu\n", desc->flags); + __a4l_dbg(1, core_dbg, "\t->nb_chan=%u\n", desc->nb_chan); + __a4l_dbg(1, core_dbg, "\t->chan_descs=0x%x\n", *desc->chan_descs); + __a4l_dbg(1, core_dbg, "\t->data_len=%u\n", desc->data_len); + __a4l_dbg(1, core_dbg, "\t->pdata=0x%p\n", desc->data); + + out_cmddesc: + + if (ret != 0) { + if (tmpchans != NULL) + rtdm_free(tmpchans); + desc->chan_descs = NULL; + } + + return ret; +} + +void a4l_free_cmddesc(a4l_cmd_t * desc) +{ + if (desc->chan_descs != NULL) + rtdm_free(desc->chan_descs); +} + +int a4l_check_cmddesc(a4l_cxt_t * cxt, a4l_cmd_t * desc) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_subd_t *subd; + + if (desc->idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_check_cmddesc: " + "subdevice index out of range (idx=%u)\n", + desc->idx_subd); + return -EINVAL; + } + + subd = dev->transfer.subds[desc->idx_subd]; + + if ((subd->flags & A4L_SUBD_TYPES) == A4L_SUBD_UNUSED) { + __a4l_err("a4l_check_cmddesc: " + "subdevice type incoherent\n"); + return -EIO; + } + + if (!(subd->flags & A4L_SUBD_CMD)) { + __a4l_err("a4l_check_cmddesc: operation not supported, " + "synchronous only subdevice\n"); + return -EIO; + } + + if (test_bit(A4L_SUBD_BUSY, &subd->status)) { + __a4l_err("a4l_check_cmddesc: subdevice busy\n"); + return -EBUSY; + } + + return a4l_check_chanlist(dev->transfer.subds[desc->idx_subd], + desc->nb_chan, desc->chan_descs); +} + +/* --- Command checking functions --- */ + +int a4l_check_generic_cmdcnt(a4l_cmd_t * desc) +{ + unsigned int tmp1, tmp2; + + /* Makes sure trigger sources are trivially valid */ + tmp1 = + desc->start_src & ~(TRIG_NOW | TRIG_INT | TRIG_EXT | TRIG_FOLLOW); + tmp2 = desc->start_src & (TRIG_NOW | TRIG_INT | TRIG_EXT | TRIG_FOLLOW); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: start_src, weird trigger\n"); + return -EINVAL; + } + + tmp1 = desc->scan_begin_src & ~(TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW); + tmp2 = desc->scan_begin_src & (TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: scan_begin_src, , weird trigger\n"); + return -EINVAL; + } + + tmp1 = desc->convert_src & ~(TRIG_TIMER | TRIG_EXT | TRIG_NOW); + tmp2 = desc->convert_src & (TRIG_TIMER | TRIG_EXT | TRIG_NOW); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: convert_src, weird trigger\n"); + return -EINVAL; + } + + tmp1 = desc->scan_end_src & ~(TRIG_COUNT); + if (tmp1 != 0) { + __a4l_err("a4l_check_cmddesc: scan_end_src, weird trigger\n"); + return -EINVAL; + } + + tmp1 = desc->stop_src & ~(TRIG_COUNT | TRIG_NONE); + tmp2 = desc->stop_src & (TRIG_COUNT | TRIG_NONE); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: stop_src, weird trigger\n"); + return -EINVAL; + } + + /* Makes sure trigger sources are unique */ + if (desc->start_src != TRIG_NOW && + desc->start_src != TRIG_INT && + desc->start_src != TRIG_EXT && desc->start_src != TRIG_FOLLOW) { + __a4l_err("a4l_check_cmddesc: start_src, " + "only one trigger should be set\n"); + return -EINVAL; + } + + if (desc->scan_begin_src != TRIG_TIMER && + desc->scan_begin_src != TRIG_EXT && + desc->scan_begin_src != TRIG_FOLLOW) { + __a4l_err("a4l_check_cmddesc: scan_begin_src, " + "only one trigger should be set\n"); + return -EINVAL; + } + + if (desc->convert_src != TRIG_TIMER && + desc->convert_src != TRIG_EXT && desc->convert_src != TRIG_NOW) { + __a4l_err("a4l_check_cmddesc: convert_src, " + "only one trigger should be set\n"); + return -EINVAL; + } + + if (desc->stop_src != TRIG_COUNT && desc->stop_src != TRIG_NONE) { + __a4l_err("a4l_check_cmddesc: stop_src, " + "only one trigger should be set\n"); + return -EINVAL; + } + + /* Makes sure arguments are trivially compatible */ + tmp1 = desc->start_src & (TRIG_NOW | TRIG_FOLLOW | TRIG_INT); + tmp2 = desc->start_arg; + if (tmp1 != 0 && tmp2 != 0) { + __a4l_err("a4l_check_cmddesc: no start_arg expected\n"); + return -EINVAL; + } + + tmp1 = desc->scan_begin_src & TRIG_FOLLOW; + tmp2 = desc->scan_begin_arg; + if (tmp1 != 0 && tmp2 != 0) { + __a4l_err("a4l_check_cmddesc: no scan_begin_arg expected\n"); + return -EINVAL; + } + + tmp1 = desc->convert_src & TRIG_NOW; + tmp2 = desc->convert_arg; + if (tmp1 != 0 && tmp2 != 0) { + __a4l_err("a4l_check_cmddesc: no convert_arg expected\n"); + return -EINVAL; + } + + tmp1 = desc->stop_src & TRIG_NONE; + tmp2 = desc->stop_arg; + if (tmp1 != 0 && tmp2 != 0) { + __a4l_err("a4l_check_cmddesc: no stop_arg expected\n"); + return -EINVAL; + } + + return 0; +} + +int a4l_check_specific_cmdcnt(a4l_cxt_t * cxt, a4l_cmd_t * desc) +{ + unsigned int tmp1, tmp2; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_cmd_t *cmd_mask = dev->transfer.subds[desc->idx_subd]->cmd_mask; + + if (cmd_mask == NULL) + return 0; + + if (cmd_mask->start_src != 0) { + tmp1 = desc->start_src & ~(cmd_mask->start_src); + tmp2 = desc->start_src & (cmd_mask->start_src); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: start_src, " + "trigger unsupported\n"); + return -EINVAL; + } + } + + if (cmd_mask->scan_begin_src != 0) { + tmp1 = desc->scan_begin_src & ~(cmd_mask->scan_begin_src); + tmp2 = desc->scan_begin_src & (cmd_mask->scan_begin_src); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: scan_begin_src, " + "trigger unsupported\n"); + return -EINVAL; + } + } + + if (cmd_mask->convert_src != 0) { + tmp1 = desc->convert_src & ~(cmd_mask->convert_src); + tmp2 = desc->convert_src & (cmd_mask->convert_src); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: convert_src, " + "trigger unsupported\n"); + return -EINVAL; + } + } + + if (cmd_mask->scan_end_src != 0) { + tmp1 = desc->scan_end_src & ~(cmd_mask->scan_end_src); + if (tmp1 != 0) { + __a4l_err("a4l_check_cmddesc: scan_end_src, " + "trigger unsupported\n"); + return -EINVAL; + } + } + + if (cmd_mask->stop_src != 0) { + tmp1 = desc->stop_src & ~(cmd_mask->stop_src); + tmp2 = desc->stop_src & (cmd_mask->stop_src); + if (tmp1 != 0 || tmp2 == 0) { + __a4l_err("a4l_check_cmddesc: stop_src, " + "trigger unsupported\n"); + return -EINVAL; + } + } + + return 0; +} + +/* --- IOCTL / FOPS function --- */ + +int a4l_ioctl_cmd(a4l_cxt_t * cxt, void *arg) +{ + int ret = 0, simul_flag = 0; + a4l_cmd_t *cmd_desc = NULL; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_subd_t *subd; + + /* The command launching cannot be done in real-time because + of some possible buffer allocations in the drivers */ + if (rtdm_in_rt_context()) + return -ENOSYS; + + /* Basically check the device */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_cmd: cannot command " + "an unattached device\n"); + return -EINVAL; + } + + /* Allocates the command */ + cmd_desc = (a4l_cmd_t *) rtdm_malloc(sizeof(a4l_cmd_t)); + if (cmd_desc == NULL) + return -ENOMEM; + memset(cmd_desc, 0, sizeof(a4l_cmd_t)); + + /* Gets the command */ + ret = a4l_fill_cmddesc(cxt, cmd_desc, arg); + if (ret != 0) + goto out_ioctl_cmd; + + /* Checks the command */ + ret = a4l_check_cmddesc(cxt, cmd_desc); + if (ret != 0) + goto out_ioctl_cmd; + + ret = a4l_check_generic_cmdcnt(cmd_desc); + if (ret != 0) + goto out_ioctl_cmd; + + ret = a4l_check_specific_cmdcnt(cxt, cmd_desc); + if (ret != 0) + goto out_ioctl_cmd; + + __a4l_dbg(1, core_dbg, + "a4l_ioctl_cmd: 1st cmd checks passed\n"); + + subd = dev->transfer.subds[cmd_desc->idx_subd]; + + /* Tests the command with the cmdtest function */ + if (subd->do_cmdtest != NULL) + ret = subd->do_cmdtest(subd, cmd_desc); + if (ret != 0) { + __a4l_err("a4l_ioctl_cmd: driver's cmd_test failed\n"); + goto out_ioctl_cmd; + } + + __a4l_dbg(1, core_dbg, + "a4l_ioctl_cmd: driver's cmd checks passed\n"); + + if (cmd_desc->flags & A4L_CMD_SIMUL) { + simul_flag = 1; + goto out_ioctl_cmd; + } + + /* Gets the transfer system ready */ + ret = a4l_setup_buffer(cxt, cmd_desc); + if (ret < 0) + goto out_ioctl_cmd; + + /* Eventually launches the command */ + ret = subd->do_cmd(subd, cmd_desc); + + if (ret != 0) { + a4l_cancel_buffer(cxt); + goto out_ioctl_cmd; + } + +out_ioctl_cmd: + if (ret != 0 || simul_flag == 1) { + a4l_free_cmddesc(cmd_desc); + rtdm_free(cmd_desc); + } + + return ret; +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/device.c relase/linux-2.6.35.9//drivers/xenomai/analogy/device.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/device.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/device.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,483 @@ +/** + * @file + * Analogy for Linux, device related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include + +#include +#include + +#include "proc.h" + +static a4l_dev_t a4l_devs[A4L_NB_DEVICES]; + +/* --- Device tab management functions --- */ + +void a4l_init_devs(void) +{ + int i; + memset(a4l_devs, 0, A4L_NB_DEVICES * sizeof(a4l_dev_t)); + for (i = 0; i < A4L_NB_DEVICES; i++) { + a4l_lock_init(&a4l_devs[i].lock); + a4l_devs[i].transfer.irq_desc.irq = A4L_IRQ_UNUSED; + } +} + +int a4l_check_cleanup_devs(void) +{ + int i, ret = 0; + + for (i = 0; i < A4L_NB_DEVICES && ret == 0; i++) + if (test_bit(A4L_DEV_ATTACHED_NR, &a4l_devs[i].flags)) + ret = -EBUSY; + + return ret; +} + +void a4l_set_dev(a4l_cxt_t *cxt) +{ + /* Retrieve the minor index */ + const int minor = a4l_get_minor(cxt); + /* Fill the dev fields accordingly */ + cxt->dev = &(a4l_devs[minor]); +} + +/* --- Device tab proc section --- */ + +#ifdef CONFIG_PROC_FS + +int a4l_rdproc_devs(char *page, + char **start, off_t off, int count, int *eof, void *data) +{ + int i, len = 0; + char *p = page; + + p += sprintf(p, "-- Analogy devices --\n\n"); + p += sprintf(p, "| idx | status | driver\n"); + + for (i = 0; i < A4L_NB_DEVICES; i++) { + char *status, *name; + + /* Gets the device's state */ + if (a4l_devs[i].flags == 0) { + status = "Unused"; + name = "No driver"; + } else if (test_bit(A4L_DEV_ATTACHED_NR, &a4l_devs[i].flags)) { + status = "Linked"; + name = a4l_devs[i].driver->board_name; + } else { + status = "Broken"; + name = "Unknown"; + } + + p += sprintf(p, "| %02d | %s | %s\n", i, status, name); + } + + /* Handle any proc-file reading way */ + len = p - page - off; + /* If the requested size is greater than we provide, + the read operation is over */ + if (len <= off + count) + *eof = 1; + /* In case the read operation is performed in many steps, + the start pointer must be redefined */ + *start = page + off; + /* If the requested size is lower than we provide, + the read operation will be done in more than one step */ + if (len > count) + len = count; + /* In case the offset is not correct (too high) */ + if (len < 0) + len = 0; + + return len; +} + +int a4l_proc_attach(a4l_cxt_t * cxt) +{ + int ret = 0; + a4l_dev_t *dev = a4l_get_dev(cxt); + struct proc_dir_entry *entry; + char *entry_name, *p; + + /* Allocate the buffer for the file name */ + entry_name = rtdm_malloc(A4L_NAMELEN + 4); + if ((p = entry_name) == NULL) { + __a4l_err("a4l_proc_attach: failed to allocate buffer\n"); + return -ENOMEM; + } + + /* Create the proc file name */ + p += sprintf(p, "%02d-", a4l_get_minor(cxt)); + strncpy(p, dev->driver->board_name, A4L_NAMELEN); + + /* Create the proc entry */ + entry = create_proc_entry(entry_name, 0444, a4l_proc_root); + if (entry == NULL) { + __a4l_err("a4l_proc_attach: " + "failed to create /proc/analogy/%s\n", + entry_name); + ret = -ENOMEM; + goto out_setup_proc_transfer; + } + + entry->nlink = 1; + entry->data = &dev->transfer; + entry->write_proc = NULL; + entry->read_proc = a4l_rdproc_transfer; + wrap_proc_dir_entry_owner(entry); + + out_setup_proc_transfer: + /* Free the file name buffer */ + rtdm_free(entry_name); + + return ret; +} + +void a4l_proc_detach(a4l_cxt_t * cxt) +{ + char *entry_name, *p; + a4l_dev_t *dev = a4l_get_dev(cxt); + + /* Allocate the buffer for the file name */ + entry_name = rtdm_malloc(A4L_NAMELEN + 4); + if ((p = entry_name) == NULL) { + __a4l_err("a4l_proc_detach: " + "failed to allocate filename buffer\n"); + return; + } + + /* Build the name */ + p += sprintf(p, "%02d-", a4l_get_minor(cxt)); + strncpy(p, dev->driver->board_name, A4L_NAMELEN); + + /* Remove the proc file */ + remove_proc_entry(entry_name, a4l_proc_root); + + /* Free the temporary buffer */ + rtdm_free(entry_name); +} + +#else /* !CONFIG_PROC_FS */ + +int a4l_proc_attach(a4l_cxt_t * cxt) +{ + return 0; +} + +void a4l_proc_detach(a4l_cxt_t * cxt) +{ +} + +#endif /* CONFIG_PROC_FS */ + +/* --- Attach / detach section --- */ + +int a4l_fill_lnkdesc(a4l_cxt_t * cxt, + a4l_lnkdesc_t * link_arg, void *arg) +{ + int ret; + char *tmpname = NULL; + void *tmpopts = NULL; + + ret = rtdm_safe_copy_from_user(cxt->user_info, + link_arg, arg, sizeof(a4l_lnkdesc_t)); + if (ret != 0) { + __a4l_err("a4l_fill_lnkdesc: " + "call1(copy_from_user) failed\n"); + goto out_get_lnkdesc; + } + + if (link_arg->bname_size != 0 && link_arg->bname != NULL) { + tmpname = rtdm_malloc(link_arg->bname_size + 1); + if (tmpname == NULL) { + __a4l_err("a4l_fill_lnkdesc: " + "call1(alloc) failed\n"); + ret = -ENOMEM; + goto out_get_lnkdesc; + } + tmpname[link_arg->bname_size] = 0; + + ret = rtdm_safe_copy_from_user(cxt->user_info, + tmpname, + link_arg->bname, + link_arg->bname_size); + if (ret != 0) { + __a4l_err("a4l_fill_lnkdesc: " + "call2(copy_from_user) failed\n"); + goto out_get_lnkdesc; + } + } else { + __a4l_err("a4l_fill_lnkdesc: board name missing\n"); + ret = -EINVAL; + goto out_get_lnkdesc; + } + + if (link_arg->opts_size != 0 && link_arg->opts != NULL) { + tmpopts = rtdm_malloc(link_arg->opts_size); + + if (tmpopts == NULL) { + __a4l_err("a4l_fill_lnkdesc: " + "call2(alloc) failed\n"); + ret = -ENOMEM; + goto out_get_lnkdesc; + } + + ret = rtdm_safe_copy_from_user(cxt->user_info, + tmpopts, + link_arg->opts, + link_arg->opts_size); + if (ret != 0) { + __a4l_err("a4l_fill_lnkdesc: " + "call3(copy_from_user) failed\n"); + goto out_get_lnkdesc; + } + } + + link_arg->bname = tmpname; + link_arg->opts = tmpopts; + + out_get_lnkdesc: + + if (tmpname == NULL) { + link_arg->bname = NULL; + link_arg->bname_size = 0; + } + + if (tmpopts == NULL) { + link_arg->opts = NULL; + link_arg->opts_size = 0; + } + + return ret; +} + +void a4l_free_lnkdesc(a4l_cxt_t * cxt, a4l_lnkdesc_t * link_arg) +{ + if (link_arg->bname != NULL) + rtdm_free(link_arg->bname); + + if (link_arg->opts != NULL) + rtdm_free(link_arg->opts); +} + +int a4l_assign_driver(a4l_cxt_t * cxt, + a4l_drv_t * drv, a4l_lnkdesc_t * link_arg) +{ + int ret = 0; + a4l_dev_t *dev = a4l_get_dev(cxt); + + dev->driver = drv; + + if (drv->privdata_size == 0) + __a4l_dbg(1, core_dbg, + "a4l_assign_driver: warning! " + "the field priv will not be usable\n"); + else { + + INIT_LIST_HEAD(&dev->subdvsq); + + dev->priv = rtdm_malloc(drv->privdata_size); + if (dev->priv == NULL && drv->privdata_size != 0) { + __a4l_err("a4l_assign_driver: " + "call(alloc) failed\n"); + ret = -ENOMEM; + goto out_assign_driver; + } + + /* Initialize the private data even if it not our role + (the driver should do it), that may prevent hard to + find bugs */ + memset(dev->priv, 0, drv->privdata_size); + } + + if ((ret = drv->attach(dev, link_arg)) != 0) + __a4l_err("a4l_assign_driver: " + "call(drv->attach) failed (ret=%d)\n", + ret); + +out_assign_driver: + + /* Increments module's count */ + if (ret == 0 && (!try_module_get(drv->owner))) { + __a4l_err("a4l_assign_driver: " + "driver's owner field wrongly set\n"); + ret = -ENODEV; + } + + if (ret != 0 && dev->priv != NULL) { + rtdm_free(dev->priv); + dev->driver = NULL; + } + + return ret; +} + +int a4l_release_driver(a4l_cxt_t * cxt) +{ + int ret = 0; + a4l_dev_t *dev = a4l_get_dev(cxt); + + if ((ret = dev->driver->detach(dev)) != 0) + goto out_release_driver; + + /* Decrease module's count + so as to allow module unloading */ + module_put(dev->driver->owner); + + /* In case, the driver developer did not free the subdevices */ + while (&dev->subdvsq != dev->subdvsq.next) { + struct list_head *this = dev->subdvsq.next; + a4l_subd_t *tmp = list_entry(this, a4l_subd_t, list); + + list_del(this); + rtdm_free(tmp); + } + + /* Free the private field */ + rtdm_free(dev->priv); + dev->driver = NULL; + +out_release_driver: + return ret; +} + +int a4l_device_attach(a4l_cxt_t * cxt, void *arg) +{ + int ret = 0; + a4l_lnkdesc_t link_arg; + a4l_drv_t *drv = NULL; + + if ((ret = a4l_fill_lnkdesc(cxt, &link_arg, arg)) != 0) + goto out_attach; + + if ((ret = a4l_lct_drv(link_arg.bname, &drv)) != 0) { + __a4l_err("a4l_device_attach: " + "cannot find board name %s\n", link_arg.bname); + goto out_attach; + } + + if ((ret = a4l_assign_driver(cxt, drv, &link_arg)) != 0) + goto out_attach; + + out_attach: + a4l_free_lnkdesc(cxt, &link_arg); + return ret; +} + +int a4l_device_detach(a4l_cxt_t * cxt) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + + if (dev->driver == NULL) { + __a4l_err("a4l_device_detach: " + "incoherent state, driver not reachable\n"); + return -ENXIO; + } + + return a4l_release_driver(cxt); +} + +/* --- IOCTL / FOPS functions --- */ + +int a4l_ioctl_devcfg(a4l_cxt_t * cxt, void *arg) +{ + int ret = 0; + + if (rtdm_in_rt_context()) + return -ENOSYS; + + if (arg == NULL) { + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &(a4l_get_dev(cxt)->flags))) { + __a4l_err("a4l_ioctl_devcfg: " + "free device, no driver to detach\n"); + return -EINVAL; + } + /* Pre-cleanup of the transfer structure, we ensure + that nothing is busy */ + if ((ret = a4l_precleanup_transfer(cxt)) != 0) + return ret; + /* Remove the related proc file */ + a4l_proc_detach(cxt); + /* Free the transfer structure and its related data */ + if ((ret = a4l_cleanup_transfer(cxt)) != 0) + return ret; + /* Free the device and the driver from each other */ + if ((ret = a4l_device_detach(cxt)) == 0) + clear_bit(A4L_DEV_ATTACHED_NR, + &(a4l_get_dev(cxt)->flags)); + } else { + /* Basic checking */ + if (test_bit + (A4L_DEV_ATTACHED_NR, &(a4l_get_dev(cxt)->flags))) { + __a4l_err("a4l_ioctl_devcfg: " + "linked device, cannot attach more driver\n"); + return -EINVAL; + } + /* Pre-initialization of the transfer structure */ + a4l_presetup_transfer(cxt); + /* Link the device with the driver */ + if ((ret = a4l_device_attach(cxt, arg)) != 0) + return ret; + /* Create the transfer structure and + the related proc file */ + if ((ret = a4l_setup_transfer(cxt)) != 0 || + (ret = a4l_proc_attach(cxt)) != 0) + a4l_device_detach(cxt); + else + set_bit(A4L_DEV_ATTACHED_NR, + &(a4l_get_dev(cxt)->flags)); + } + + return ret; +} + +int a4l_ioctl_devinfo(a4l_cxt_t * cxt, void *arg) +{ + a4l_dvinfo_t info; + a4l_dev_t *dev = a4l_get_dev(cxt); + + memset(&info, 0, sizeof(a4l_dvinfo_t)); + + if (test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + int len = (strlen(dev->driver->board_name) > A4L_NAMELEN) ? + A4L_NAMELEN : strlen(dev->driver->board_name); + + memcpy(info.board_name, dev->driver->board_name, len); + info.nb_subd = dev->transfer.nb_subd; + /* TODO: for API compatibility issue, find the first + read subdevice and write subdevice */ + } + + if (rtdm_safe_copy_to_user(cxt->user_info, + arg, &info, sizeof(a4l_dvinfo_t)) != 0) + return -EFAULT; + + return 0; +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/driver.c relase/linux-2.6.35.9//drivers/xenomai/analogy/driver.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/driver.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/driver.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,130 @@ +/** + * @file + * Analogy for Linux, driver related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include + +#include +#include +#include + +#include "proc.h" + +static LIST_HEAD(a4l_drvs); + +/* --- Driver list management functions --- */ + +int a4l_lct_drv(char *pin, a4l_drv_t ** pio) +{ + struct list_head *this; + int ret = -EINVAL; + + __a4l_dbg(1, core_dbg, "a4l_lct_drv: name=%s\n", pin); + + /* Goes through the linked list so as to find + a driver instance with the same name */ + list_for_each(this, &a4l_drvs) { + a4l_drv_t *drv = list_entry(this, a4l_drv_t, list); + + if (strcmp(drv->board_name, pin) == 0) { + /* The argument pio can be NULL + if there is no need to retrieve the pointer */ + if (pio != NULL) + *pio = drv; + ret = 0; + break; + } + } + + return ret; +} + +int a4l_register_drv(a4l_drv_t * drv) +{ + __a4l_dbg(1, core_dbg, "a4l_add_drv: name=%s\n", drv->board_name); + + if (a4l_lct_drv(drv->board_name, NULL) != 0) { + list_add(&drv->list, &a4l_drvs); + return 0; + } else + return -EINVAL; +} + +int a4l_unregister_drv(a4l_drv_t * drv) +{ + __a4l_dbg(1, core_dbg, "a4l_rm_drv: name=%s\n", drv->board_name); + + if (a4l_lct_drv(drv->board_name, NULL) == 0) { + /* Here, we consider the argument is pointing + to a real driver struct (not a blank structure + with only the name field properly set */ + list_del(&drv->list); + return 0; + } else + return -EINVAL; +} + +#ifdef CONFIG_PROC_FS + +/* --- Driver list proc section --- */ + +int a4l_rdproc_drvs(char *page, + char **start, off_t off, int count, int *eof, void *data) +{ + int i = 0, len = 0; + char *p = page; + struct list_head *this; + + p += sprintf(p, "-- Analogy drivers --\n\n"); + p += sprintf(p, "| idx | driver name\n"); + + list_for_each(this, &a4l_drvs) { + a4l_drv_t *drv = list_entry(this, a4l_drv_t, list); + + p += sprintf(p, "| %02d | %s\n", i++, drv->board_name); + } + + /* Handles any proc-file reading way */ + len = p - page - off; + /* If the requested size is greater than we provide, + the read operation is over */ + if (len <= off + count) + *eof = 1; + /* In case the read operation is performed in many steps, + the start pointer must be redefined */ + *start = page + off; + /* If the requested size is lower than we provide, + the read operation will be done in more than one step */ + if (len > count) + len = count; + /* In case the offset is not correct (too high) */ + if (len < 0) + len = 0; + + return len; +} + +#endif /* CONFIG_PROC_FS */ + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/driver_facilities.c relase/linux-2.6.35.9//drivers/xenomai/analogy/driver_facilities.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/driver_facilities.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/driver_facilities.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,668 @@ +/** + * @file + * Analogy for Linux, driver facilities + * + * @note Copyright (C) 1997-2000 David A. Schleef + * @note Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/*! + * @defgroup Analogy4Linux Analogy API. + * + * This is the API interface of Analogy (kernel layer and user + * layer) + * + */ + +/*! + * @ingroup Analogy4Linux + * @defgroup driverfacilities Driver API. + * + * This is the API interface of Analogy provided to device drivers. + * + */ + +#include +#include + +#include +#include +#include + +/* --- Driver section --- */ + +/*! + * @ingroup driverfacilities + * @defgroup driver Driver management services + * + * Analogy driver registration / unregistration + * + * In a common Linux char driver, the developer has to register a fops + * structure filled with callbacks for read / write / mmap / ioctl + * operations. + * + * Analogy drivers do not have to implement read / write / mmap / + * ioctl functions, these procedures are implemented in the Analogy + * generic layer. Then, the transfers between user-space and + * kernel-space are already managed. Analogy drivers work with commands + * and instructions which are some kind of more dedicated read / write + * operations. And, instead of registering a fops structure, a Analogy + * driver must register some a4l_driver structure. + * + * @{ + */ + +/** + * @brief Register an Analogy driver + * + * After initialising a driver structure, the driver must be made + * available so as to be attached. + * + * @param[in] drv Driver descriptor structure + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_register_drv(a4l_drv_t * drv); +EXPORT_SYMBOL_GPL(a4l_register_drv); + +/** + * @brief Unregister an Analogy driver + * + * This function removes the driver descriptor from the Analogy driver + * list. The driver cannot be attached anymore. + * + * @param[in] drv Driver descriptor structure + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_unregister_drv(a4l_drv_t * drv); +EXPORT_SYMBOL_GPL(a4l_unregister_drv); + +/** @} */ + +/* --- Subdevice section --- */ + +/*! + * @ingroup driverfacilities + * @defgroup subdevice Subdevice management services + * + * Subdevice declaration in a driver + * + * The subdevice structure is the most complex one in the Analogy + * driver layer. It contains some description fields to fill and some + * callbacks to declare. + * + * The description fields are: + * - flags: to define the subdevice type and its capabilities; + * - chan_desc: to describe the channels which compose the subdevice; + * - rng_desc: to declare the usable ranges; + * + * The functions callbakcs are: + * - do_cmd() and do_cmdtest(): to performe asynchronous acquisitions + * thanks to commands; + * - cancel(): to abort a working asynchronous acquisition; + * - munge(): to apply modifications on the data freshly acquired + * during an asynchronous transfer. Warning: using this feature with + * can significantly reduce the performances (if the munge operation + * is complex, it will trigger high CPU charge and if the + * acquisition device is DMA capable, many cache-misses and + * cache-replaces will occur (the benefits of the DMA controller + * will vanish); + * - trigger(): optionnaly to launch an asynchronous acquisition; + * - insn_read(), insn_write(), insn_bits(), insn_config(): to perform + * synchronous acquisition operations. + * + * Once the subdevice is filled, it must be inserted into the driver + * structure thanks to a4l_add_subd(). + * + * @{ + */ + +EXPORT_SYMBOL_GPL(range_bipolar10); +EXPORT_SYMBOL_GPL(range_bipolar5); +EXPORT_SYMBOL_GPL(range_unipolar10); +EXPORT_SYMBOL_GPL(range_unipolar5); +EXPORT_SYMBOL_GPL(range_unknown); +EXPORT_SYMBOL_GPL(range_fake); + +/** + * @brief Allocate a subdevice descriptor + * + * This is a helper function so as to get a suitable subdevice + * descriptor + * + * @param[in] sizeof_priv Size of the subdevice's private data + * @param[in] setup Setup function to be called after the allocation + * + * @return the index with which the subdevice has been registered, in + * case of error a negative error code is returned. + * + */ +a4l_subd_t * a4l_alloc_subd(int sizeof_priv, + void (*setup)(a4l_subd_t *)); +EXPORT_SYMBOL_GPL(a4l_alloc_subd); + +/** + * @brief Add a subdevice to the driver descriptor + * + * Once the driver descriptor structure is initialized, the function + * a4l_add_subd() must be used so to add some subdevices to the + * driver. + * + * @param[in] dev Device descriptor structure + * @param[in] subd Subdevice descriptor structure + * + * @return the index with which the subdevice has been registered, in + * case of error a negative error code is returned. + * + */ +int a4l_add_subd(a4l_dev_t *dev, a4l_subd_t *subd); +EXPORT_SYMBOL_GPL(a4l_add_subd); + +/** + * @brief Get a pointer to the subdevice descriptor referenced by its + * registration index + * + * This function is scarcely useful as all the drivers callbacks get + * the related subdevice descriptor as first argument. + * This function is not optimized, it goes through a linked list to + * get the proper pointer. So it must not be used in real-time context + * but at initialization / cleanup time (attach / detach). + * + * @param[in] dev Device descriptor structure + * @param[in] idx Subdevice index + * + * @return 0 on success, otherwise negative error code. + * + */ +a4l_subd_t *a4l_get_subd(a4l_dev_t *dev, int idx); +EXPORT_SYMBOL_GPL(a4l_get_subd); + +/** @} */ + +/* --- Buffer section --- */ + +/*! + * @ingroup driverfacilities + * @defgroup analogy_buffer Buffer management services + * + * Buffer management services + * + * The buffer is the key component of the Analogy infrastructure. It + * manages transfers between the user-space and the Analogy drivers + * thanks to generic functions which are described hereafter. Thanks + * to the buffer subsystem, the driver developer does not have to care + * about the way the user program retrieves or sends data. + * + * To write a classical char driver, the developer has to fill a fops + * structure so as to provide transfer operations to the user program + * (read, write, ioctl and mmap if need be). + * + * The Analogy infrastructure manages the whole interface with the + * userspace; the common read, write, mmap, etc. callbacks are generic + * Analogy functions. These functions manage (and perform, if need be) + * tranfers between the user-space and an asynchronous buffer thanks + * to lockless mechanisms. + * + * Consequently, the developer has to use the proper buffer functions + * in order to write / read acquired data into / from the asynchronous + * buffer. + * + * Here are listed the functions: + * - a4l_buf_prepare_(abs)put() and a4l_buf_commit_(abs)put() + * - a4l_buf_prepare_(abs)get() and a4l_buf_commit_(abs)get() + * - a4l_buf_put() + * - a4l_buf_get() + * - a4l_buf_evt(). + * + * The functions count might seem high; however, the developer needs a + * few of them to write a driver. Having so many functions enables to + * manage any transfer cases: + * - If some DMA controller is available, there is no need to make the + * driver copy the acquired data into the asynchronous buffer, the + * DMA controller must directly trigger DMA shots into / from the + * buffer. In that case, a function a4l_buf_prepare_*() must be used + * so as to set up the DMA transfer and a function + * a4l_buf_commit_*() has to be called to complete the transfer(). + * - For DMA controllers which need to work with global counter (the + * transfered data count since the beginning of the acquisition), + * the functions a4l_buf_*_abs_*() have been made available. + * - If no DMA controller is available, the driver has to perform the + * copy between the hardware component and the asynchronous + * buffer. In such cases, the functions a4l_buf_get() and + * a4l_buf_put() are useful. + * + * @{ + */ + +/** + * @brief Update the absolute count of data sent from the device to + * the buffer since the start of the acquisition and after the next + * DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(absg)et() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, some + * pointers still have to be updated so as to monitor the tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count to be transferred during the next + * DMA shot plus the data count which have been copied since the start + * of the acquisition + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_prepare_absput(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_prepare_absput); + +/** + * @brief Set the absolute count of data which was sent from the + * device to the buffer since the start of the acquisition and until + * the last DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count transferred to the buffer during + * the last DMA shot plus the data count which have been sent / + * retrieved since the beginning of the acquisition + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_commit_absput(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_commit_absput); + +/** + * @brief Set the count of data which is to be sent to the buffer at + * the next DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count to be transferred + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_prepare_put(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_prepare_put); + +/** + * @brief Set the count of data sent to the buffer during the last + * completed DMA shots + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The amount of data transferred + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_commit_put(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_commit_put); + +/** + * @brief Copy some data from the device driver to the buffer + * + * The function a4l_buf_put() must copy data coming from some + * acquisition device to the Analogy buffer. This ring-buffer is an + * intermediate area between the device driver and the user-space + * program, which is supposed to recover the acquired data. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] bufdata The data buffer to copy into the Analogy buffer + * @param[in] count The amount of data to copy + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_put(a4l_subd_t *subd, void *bufdata, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_put); + +/** + * @brief Update the absolute count of data sent from the buffer to + * the device since the start of the acquisition and after the next + * DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(absg)et() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count to be transferred during the next + * DMA shot plus the data count which have been copied since the start + * of the acquisition + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_prepare_absget(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_prepare_absget); + +/** + * @brief Set the absolute count of data which was sent from the + * buffer to the device since the start of the acquisition and until + * the last DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count transferred to the device during + * the last DMA shot plus the data count which have been sent since + * the beginning of the acquisition + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_commit_absget(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_commit_absget); + +/** + * @brief Set the count of data which is to be sent from the buffer to + * the device at the next DMA shot + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The data count to be transferred + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_prepare_get(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_prepare_get); + +/** + * @brief Set the count of data sent from the buffer to the device + * during the last completed DMA shots + * + * The functions a4l_buf_prepare_(abs)put(), + * a4l_buf_commit_(abs)put(), a4l_buf_prepare_(abs)get() and + * a4l_buf_commit_(abs)get() have been made available for DMA + * transfers. In such situations, no data copy is needed between the + * Analogy buffer and the device as some DMA controller is in charge + * of performing data shots from / to the Analogy buffer. However, + * some pointers still have to be updated so as to monitor the + * tranfers. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] count The amount of data transferred + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_commit_get(a4l_subd_t *subd, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_commit_get); + +/** + * @brief Copy some data from the buffer to the device driver + * + * The function a4l_buf_get() must copy data coming from the Analogy + * buffer to some acquisition device. This ring-buffer is an + * intermediate area between the device driver and the user-space + * program, which is supposed to provide the data to send to the + * device. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] bufdata The data buffer to copy into the Analogy buffer + * @param[in] count The amount of data to copy + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_get(a4l_subd_t *subd, void *bufdata, unsigned long count); +EXPORT_SYMBOL_GPL(a4l_buf_get); + +/** + * @brief Signal some event(s) to a user-space program involved in + * some read / write operation + * + * The function a4l_buf_evt() is useful in many cases: + * - To wake-up a process waiting for some data to read. + * - To wake-up a process waiting for some data to write. + * - To notify the user-process an error has occured during the + * acquistion. + * + * @param[in] subd Subdevice descriptor structure + * @param[in] evts Some specific event to notify: + * - A4L_BUF_ERROR to indicate some error has occured during the + * transfer + * - A4L_BUF_EOA to indicate the acquisition is complete (this + * event is automatically set, it should not be used). + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_buf_evt(a4l_subd_t *subd, unsigned long evts); +EXPORT_SYMBOL_GPL(a4l_buf_evt); + +/** + * @brief Get the data amount available in the Analogy buffer + * + * @param[in] subd Subdevice descriptor structure + * + * @return the amount of data available in the Analogy buffer. + * + */ +unsigned long a4l_buf_count(a4l_subd_t *subd); +EXPORT_SYMBOL_GPL(a4l_buf_count); + +#ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */ + +/** + * @brief Get the current Analogy command descriptor + * + * @param[in] subd Subdevice descriptor structure + * + * @return the command descriptor. + * + */ +a4l_cmd_t *a4l_get_cmd(a4l_subd_t * subd); + +#endif /* DOXYGEN_CPP */ + +/** + * @brief Get the channel index according to its type + * + * @param[in] subd Subdevice descriptor structure + * + * @return the channel index. + * + */ +int a4l_get_chan(a4l_subd_t *subd); +EXPORT_SYMBOL_GPL(a4l_get_chan); + +/** @} */ + +/* --- IRQ handling section --- */ + +/*! + * @ingroup driverfacilities + * @defgroup analogy_interrupt Interrupt management services + * @{ + */ + +/** + * @brief Get the interrupt number in use for a specific device + * + * @param[in] dev Device descriptor structure + * + * @return the line number used or A4L_IRQ_UNUSED if no interrupt + * is registered. + * + */ +unsigned int a4l_get_irq(a4l_dev_t * dev); +EXPORT_SYMBOL_GPL(a4l_get_irq); + +/** + * @brief Register an interrupt handler for a specific device + * + * @param[in] dev Device descriptor structure + * @param[in] irq Line number of the addressed IRQ + * @param[in] handler Interrupt handler + * @param[in] flags Registration flags: + * - A4L_IRQ_SHARED: enable IRQ-sharing with other drivers + * (Warning: real-time drivers and non-real-time drivers cannot + * share an interrupt line). + * - A4L_IRQ_EDGE: mark IRQ as edge-triggered (Warning: this flag + * is meaningless in RTDM-less context). + * - A4L_IRQ_DISABLED: keep IRQ disabled when calling the action + * handler (Warning: this flag is ignored in RTDM-enabled + * configuration). + * @param[in] cookie Pointer to be passed to the interrupt handler on + * invocation + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_request_irq(a4l_dev_t * dev, + unsigned int irq, + a4l_irq_hdlr_t handler, + unsigned long flags, void *cookie); +EXPORT_SYMBOL_GPL(a4l_request_irq); + +/** + * @brief Release an interrupt handler for a specific device + * + * @param[in] dev Device descriptor structure + * @param[in] irq Line number of the addressed IRQ + * + * @return 0 on success, otherwise negative error code. + * + */ +int a4l_free_irq(a4l_dev_t * dev, unsigned int irq); +EXPORT_SYMBOL_GPL(a4l_free_irq); + +/** @} */ + +/* --- Misc section --- */ + +/*! + * @ingroup driverfacilities + * @defgroup misc Misc services + * @{ + */ + +#ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */ + +/** + * @brief Intialise and start an Analogy task + * + * This function belongs to a minimal set of task management services + * (with a4l_task_destroy() and a4l_task_sleep()). Such features + * are not critical for Analogy driver development. + * + * @param[in,out] task Task handle + * @param[in] name Optional task name + * @param[in] proc Procedure to be executed by the task + * @param[in] arg Custom argument passed to @c proc() on entry + * @param[in] priority Priority of the task + * + * @return 0 on success, otherwise negative error code + * + */ +int a4l_task_init(a4l_task_t * task, + const char *name, + a4l_task_proc_t proc, void *arg, int priority); + +/** + * @brief Destroy an Analogy task + * + * This function belongs to a minimal set of task management services + * (with a4l_task_init() and a4l_task_sleep()). Such features + * are not critical for Analogy driver development. + * + * @param[in,out] task Task handle + * + */ +void a4l_task_destroy(a4l_task_t * task); + +/** + * @brief Make the current Analogy task passively wait a defined delay + * + * This function belongs to a minimal set of task management services + * (with a4l_task_init() and a4l_task_destroy()). Such features + * are not critical for Analogy driver development. + * + * @param[in] nsdelay Amount of time expressed in nanoseconds during + * which the Analogy task must be sleeping. + * + * @return 0 on success, otherwise negative error code + * + */ +int a4l_task_sleep(unsigned long long nsdelay); + +#endif /* DOXYGEN_CPP */ + +/** + * @brief Get the absolute time in nanoseconds + * + * @return the absolute time expressed in nanoseconds + * + */ +unsigned long long a4l_get_time(void); +EXPORT_SYMBOL_GPL(a4l_get_time); + +/** @} */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/instruction.c relase/linux-2.6.35.9//drivers/xenomai/analogy/instruction.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/instruction.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/instruction.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,428 @@ +/** + * @file + * Analogy for Linux, instruction related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int a4l_do_insn_gettime(a4l_kinsn_t * dsc) +{ + nanosecs_abs_t ns; + uint32_t ns2; + + unsigned int *data = (unsigned int *)dsc->data; + + /* Basic checkings */ + if (dsc->data_size != 2 * sizeof(unsigned int)) { + __a4l_err("a4l_do_insn_gettime: data size should be 2\n"); + return -EINVAL; + } + + /* Get a timestamp */ + ns = a4l_get_time(); + + /* Perform the conversion */ + ns2 = do_div(ns, 1000000000); + data[0] = (unsigned int) ns; + data[1] = (unsigned int) ns2 / 1000; + + return 0; +} + +int a4l_do_insn_wait(a4l_kinsn_t * dsc) +{ + unsigned int us; + unsigned int *data = (unsigned int *)dsc->data; + + /* Basic checkings */ + if (dsc->data_size != sizeof(unsigned int)) { + __a4l_err("a4l_do_insn_wait: data size should be 1\n"); + return -EINVAL; + } + + if (data[0] > A4L_INSN_WAIT_MAX) { + __a4l_err("a4l_do_insn_wait: wait duration is out of range\n"); + return -EINVAL; + } + + /* As we use (a4l_)udelay, we have to convert the delay into + microseconds */ + us = data[0] / 1000; + + /* At least, the delay is rounded up to 1 microsecond */ + if (us == 0) + us = 1; + + /* Performs the busy waiting */ + a4l_udelay(us); + + return 0; +} + +int a4l_do_insn_trig(a4l_cxt_t * cxt, a4l_kinsn_t * dsc) +{ + a4l_subd_t *subd; + a4l_dev_t *dev = a4l_get_dev(cxt); + unsigned int trignum; + unsigned int *data = (unsigned int*)dsc->data; + + /* Basic checkings */ + if (dsc->data_size > 1) { + __a4l_err("a4l_do_insn_trig: data size should not be > 1\n"); + return -EINVAL; + } + + trignum = (dsc->data_size == sizeof(unsigned int)) ? data[0] : 0; + + if (dsc->idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_do_insn_trig: " + "subdevice index is out of range\n"); + return -EINVAL; + } + + subd = dev->transfer.subds[dsc->idx_subd]; + + /* Checks that the concerned subdevice is trigger-compliant */ + if ((subd->flags & A4L_SUBD_CMD) == 0 || subd->trigger == NULL) { + __a4l_err("a4l_do_insn_trig: subdevice does not support " + "triggering or asynchronous acquisition\n"); + return -EINVAL; + } + + /* Performs the trigger */ + return subd->trigger(subd, trignum); +} + +int a4l_fill_insndsc(a4l_cxt_t * cxt, a4l_kinsn_t * dsc, void *arg) +{ + int ret = 0; + void *tmp_data = NULL; + + ret = rtdm_safe_copy_from_user(cxt->user_info, + dsc, arg, sizeof(a4l_insn_t)); + if (ret != 0) + goto out_insndsc; + + if (dsc->data_size != 0 && dsc->data == NULL) { + __a4l_err("a4l_fill_insndsc: no data pointer specified\n"); + ret = -EINVAL; + goto out_insndsc; + } + + if (dsc->data_size != 0 && dsc->data != NULL) { + tmp_data = rtdm_malloc(dsc->data_size); + if (tmp_data == NULL) { + ret = -ENOMEM; + goto out_insndsc; + } + + if ((dsc->type & A4L_INSN_MASK_WRITE) != 0) { + ret = rtdm_safe_copy_from_user(cxt->user_info, + tmp_data, dsc->data, + dsc->data_size); + if (ret < 0) + goto out_insndsc; + } + } + + dsc->__udata = dsc->data; + dsc->data = tmp_data; + +out_insndsc: + + if (ret != 0 && tmp_data != NULL) + rtdm_free(tmp_data); + + return ret; +} + +int a4l_free_insndsc(a4l_cxt_t * cxt, a4l_kinsn_t * dsc) +{ + int ret = 0; + + if ((dsc->type & A4L_INSN_MASK_READ) != 0) + ret = rtdm_safe_copy_to_user(cxt->user_info, + dsc->__udata, + dsc->data, dsc->data_size); + + if (dsc->data != NULL) + rtdm_free(dsc->data); + + return ret; +} + +int a4l_do_special_insn(a4l_cxt_t * cxt, a4l_kinsn_t * dsc) +{ + int ret = 0; + + switch (dsc->type) { + case A4L_INSN_GTOD: + ret = a4l_do_insn_gettime(dsc); + break; + case A4L_INSN_WAIT: + ret = a4l_do_insn_wait(dsc); + break; + case A4L_INSN_INTTRIG: + ret = a4l_do_insn_trig(cxt, dsc); + break; + default: + __a4l_err("a4l_do_special_insn: " + "incoherent instruction code\n"); + return -EINVAL; + } + + if (ret < 0) + __a4l_err("a4l_do_special_insn: " + "execution of the instruction failed (err=%d)\n", + ret); + + return ret; +} + +int a4l_do_insn(a4l_cxt_t * cxt, a4l_kinsn_t * dsc) +{ + int ret; + a4l_subd_t *subd; + a4l_dev_t *dev = a4l_get_dev(cxt); + int (*hdlr) (a4l_subd_t *, a4l_kinsn_t *) = NULL; + + /* Checks the subdevice index */ + if (dsc->idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_do_insn: " + "subdevice index out of range (idx=%d)\n", + dsc->idx_subd); + return -EINVAL; + } + + /* Recovers pointers on the proper subdevice */ + subd = dev->transfer.subds[dsc->idx_subd]; + + /* Checks the subdevice's characteristics */ + if ((subd->flags & A4L_SUBD_TYPES) == A4L_SUBD_UNUSED) { + __a4l_err("a4l_do_insn: wrong subdevice selected\n"); + return -EINVAL; + } + + /* Checks the channel descriptor */ + ret = a4l_check_chanlist(dev->transfer.subds[dsc->idx_subd], + 1, &dsc->chan_desc); + if (ret < 0) + return ret; + + /* Choose the proper handler, we can check the pointer because + the subdevice was memset to 0 at allocation time */ + switch (dsc->type) { + case A4L_INSN_READ: + hdlr = subd->insn_read; + break; + case A4L_INSN_WRITE: + hdlr = subd->insn_write; + break; + case A4L_INSN_BITS: + hdlr = subd->insn_bits; + break; + case A4L_INSN_CONFIG: + hdlr = subd->insn_config; + break; + default: + ret = -EINVAL; + } + + /* We check the instruction type */ + if (ret < 0) + return ret; + + /* We check whether a handler is available */ + if (hdlr == NULL) + return -ENOSYS; + + /* Prevents the subdevice from being used during + the following operations */ + if (test_and_set_bit(A4L_SUBD_BUSY_NR, &subd->status)) { + ret = -EBUSY; + goto out_do_insn; + } + + /* Let's the driver-specific code perform the instruction */ + ret = hdlr(subd, dsc); + + if (ret < 0) + __a4l_err("a4l_do_insn: " + "execution of the instruction failed (err=%d)\n", + ret); + +out_do_insn: + + /* Releases the subdevice from its reserved state */ + clear_bit(A4L_SUBD_BUSY_NR, &subd->status); + + return ret; +} + +int a4l_ioctl_insn(a4l_cxt_t * cxt, void *arg) +{ + int ret = 0; + a4l_kinsn_t insn; + a4l_dev_t *dev = a4l_get_dev(cxt); + + if (!rtdm_in_rt_context() && rtdm_rt_capable(cxt->user_info)) + return -ENOSYS; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_insn: unattached device\n"); + return -EINVAL; + } + + /* Recovers the instruction descriptor */ + ret = a4l_fill_insndsc(cxt, &insn, arg); + if (ret != 0) + goto err_ioctl_insn; + + /* Performs the instruction */ + if ((insn.type & A4L_INSN_MASK_SPECIAL) != 0) + ret = a4l_do_special_insn(cxt, &insn); + else + ret = a4l_do_insn(cxt, &insn); + + if (ret < 0) + goto err_ioctl_insn; + + /* Frees the used memory and sends back some + data, if need be */ + ret = a4l_free_insndsc(cxt, &insn); + + return ret; + +err_ioctl_insn: + a4l_free_insndsc(cxt, &insn); + return ret; +} + +int a4l_fill_ilstdsc(a4l_cxt_t * cxt, a4l_kilst_t * dsc, void *arg) +{ + int i, ret = 0; + + dsc->insns = NULL; + + /* Recovers the structure from user space */ + ret = rtdm_safe_copy_from_user(cxt->user_info, + dsc, arg, sizeof(a4l_insnlst_t)); + if (ret < 0) + return ret; + + /* Some basic checking */ + if (dsc->count == 0) { + __a4l_err("a4l_fill_ilstdsc: instruction list's count is 0\n"); + return -EINVAL; + } + + /* Keeps the user pointer in an opaque field */ + dsc->__uinsns = (a4l_insn_t *)dsc->insns; + + dsc->insns = rtdm_malloc(dsc->count * sizeof(a4l_kinsn_t)); + if (dsc->insns == NULL) + return -ENOMEM; + + /* Recovers the instructions, one by one. This part is not + optimized */ + for (i = 0; i < dsc->count && ret == 0; i++) + ret = a4l_fill_insndsc(cxt, + &(dsc->insns[i]), + &(dsc->__uinsns[i])); + + /* In case of error, frees the allocated memory */ + if (ret < 0 && dsc->insns != NULL) + rtdm_free(dsc->insns); + + return ret; +} + +int a4l_free_ilstdsc(a4l_cxt_t * cxt, a4l_kilst_t * dsc) +{ + int i, ret = 0; + + if (dsc->insns != NULL) { + + for (i = 0; i < dsc->count && ret == 0; i++) + ret = a4l_free_insndsc(cxt, &(dsc->insns[i])); + + while (i < dsc->count) { + a4l_free_insndsc(cxt, &(dsc->insns[i])); + i++; + } + + rtdm_free(dsc->insns); + } + + return ret; +} + +/* This function is not optimized in terms of memory footprint and + CPU charge; however, the whole analogy instruction system was not + designed for performance issues */ +int a4l_ioctl_insnlist(a4l_cxt_t * cxt, void *arg) +{ + int i, ret = 0; + a4l_kilst_t ilst; + a4l_dev_t *dev = a4l_get_dev(cxt); + + if (!rtdm_in_rt_context() && rtdm_rt_capable(cxt->user_info)) + return -ENOSYS; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_insnlist: unattached device\n"); + return -EINVAL; + } + + if ((ret = a4l_fill_ilstdsc(cxt, &ilst, arg)) < 0) + return ret; + + /* Performs the instructions */ + for (i = 0; i < ilst.count && ret == 0; i++) { + if ((ilst.insns[i].type & A4L_INSN_MASK_SPECIAL) != 0) + ret = a4l_do_special_insn(cxt, &ilst.insns[i]); + else + ret = a4l_do_insn(cxt, &ilst.insns[i]); + } + + if (ret < 0) + goto err_ioctl_ilst; + + return a4l_free_ilstdsc(cxt, &ilst); + +err_ioctl_ilst: + a4l_free_ilstdsc(cxt, &ilst); + return ret; +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.c relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,332 @@ +/** + * @file + * Analogy subdevice driver for 8255 chip + * @note Copyright (C) 1999 David A. Schleef + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include "8255.h" + +#define CALLBACK_ARG (((subd_8255_t *)subd->priv)->cb_arg) +#define CALLBACK_FUNC (((subd_8255_t *)subd->priv)->cb_func) + +/* Channels descriptor */ +static a4l_chdesc_t chandesc_8255 = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 24, + .chans = { + {A4L_CHAN_AREF_GROUND, sizeof(sampl_t)}, + }, +}; + +/* Command options mask */ +static a4l_cmd_t cmd_mask_8255 = { + .idx_subd = 0, + .start_src = TRIG_NOW, + .scan_begin_src = TRIG_EXT, + .convert_src = TRIG_FOLLOW, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_NONE, +}; + +void subdev_8255_interrupt(a4l_subd_t *subd) +{ + sampl_t d; + + /* Retrieve the sample... */ + d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG); + d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8); + + /* ...and send it */ + a4l_buf_put(subd, &d, sizeof(sampl_t)); + + a4l_buf_evt(subd, 0); +} +EXPORT_SYMBOL_GPL(subdev_8255_interrupt); + +static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) +{ + unsigned long iobase = arg; + + if (dir) { + outb(data, iobase + port); + return 0; + } else { + return inb(iobase + port); + } +} + +static void do_config(a4l_subd_t *subd) +{ + int config; + subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv; + + config = CR_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(subd_8255->io_bits & 0x0000ff)) + config |= CR_A_IO; + if (!(subd_8255->io_bits & 0x00ff00)) + config |= CR_B_IO; + if (!(subd_8255->io_bits & 0x0f0000)) + config |= CR_C_LO_IO; + if (!(subd_8255->io_bits & 0xf00000)) + config |= CR_C_HI_IO; + CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); +} + +int subd_8255_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + /* FIXME */ + return 0; +} + +int subd_8255_cmdtest(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + return -EINVAL; + } + if (cmd->scan_begin_arg != 0) { + cmd->scan_begin_arg = 0; + return -EINVAL; + } + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + return -EINVAL; + } + if (cmd->scan_end_arg != 1) { + cmd->scan_end_arg = 1; + return -EINVAL; + } + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + return -EINVAL; + } + + return 0; +} + +int subd_8255_cancel(a4l_subd_t *subd) +{ + /* FIXME */ + return 0; +} + +int subd_8255_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv; + uint32_t *data = (uint32_t *)insn->data; + + if (data[0]) { + + subd_8255->status &= ~data[0]; + subd_8255->status |= (data[0] & data[1]); + + if (data[0] & 0xff) + CALLBACK_FUNC(1, _8255_DATA, + subd_8255->status & 0xff, CALLBACK_ARG); + if (data[0] & 0xff00) + CALLBACK_FUNC(1, _8255_DATA + 1, + (subd_8255->status >> 8) & 0xff, + CALLBACK_ARG); + if (data[0] & 0xff0000) + CALLBACK_FUNC(1, _8255_DATA + 2, + (subd_8255->status >> 16) & 0xff, + CALLBACK_ARG); + } + + data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG); + data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8); + data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16); + + return 0; +} + +int subd_8255_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + unsigned int mask; + unsigned int bits; + subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv; + unsigned int *data = (unsigned int *)insn->data; + + mask = 1 << CR_CHAN(insn->chan_desc); + + if (mask & 0x0000ff) { + bits = 0x0000ff; + } else if (mask & 0x00ff00) { + bits = 0x00ff00; + } else if (mask & 0x0f0000) { + bits = 0x0f0000; + } else { + bits = 0xf00000; + } + + switch (data[0]) { + case A4L_INSN_CONFIG_DIO_INPUT: + subd_8255->io_bits &= ~bits; + break; + case A4L_INSN_CONFIG_DIO_OUTPUT: + subd_8255->io_bits |= bits; + break; + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = (subd_8255->io_bits & bits) ? + A4L_OUTPUT : A4L_INPUT; + return 0; + break; + default: + return -EINVAL; + } + + do_config(subd); + + return 0; +} + +void subdev_8255_init(a4l_subd_t *subd) +{ + subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv; + /* Initializes the subdevice structure */ + memset(&subd, 0, sizeof(a4l_subd_t)); + + /* Subdevice filling part */ + + subd->flags = A4L_SUBD_DIO; + subd->flags |= A4L_SUBD_CMD; + subd->chan_desc = &chandesc_8255; + subd->insn_bits = subd_8255_insn_bits; + subd->insn_config = subd_8255_insn_config; + + if(subd_8255->have_irq) { + subd->cmd_mask = &cmd_mask_8255; + subd->do_cmdtest = subd_8255_cmdtest; + subd->do_cmd = subd_8255_cmd; + subd->cancel = subd_8255_cancel; + } + + /* 8255 setting part */ + + if(CALLBACK_FUNC == NULL) + CALLBACK_FUNC = subdev_8255_cb; + + do_config(subd); +} +EXPORT_SYMBOL_GPL(subdev_8255_init); + +/* + + Start of the 8255 standalone device + +*/ + +static int dev_8255_attach(a4l_dev_t *dev, a4l_lnkdesc_t *arg) +{ + unsigned long *addrs; + int i, err = 0; + + if(arg->opts == NULL || arg->opts_size == 0) { + a4l_err(dev, + "dev_8255_attach: unable to detect any 8255 chip, " + "chips addresses must be passed as attach arguments\n"); + return -EINVAL; + } + + addrs = (unsigned long*) arg->opts; + + for(i = 0; i < (arg->opts_size / sizeof(unsigned long)); i++) { + a4l_subd_t * subd; + subd_8255_t *subd_8255; + + subd = a4l_alloc_subd(sizeof(subd_8255_t), NULL); + if(subd == NULL) { + a4l_err(dev, + "dev_8255_attach: " + "unable to allocate subdevice\n"); + /* There is no need to free previously + allocated structure(s), the analogy layer will + do it for us */ + err = -ENOMEM; + goto out_attach; + } + + memset(&subd, 0, sizeof(a4l_subd_t)); + memset(subd->priv, 0, sizeof(subd_8255_t)); + + subd_8255 = (subd_8255_t *)subd->priv; + + if(request_region(addrs[i], _8255_SIZE, "Analogy 8255") == 0) { + subd->flags = A4L_SUBD_UNUSED; + a4l_warn(dev, + "dev_8255_attach: " + "I/O port conflict at 0x%lx\n", addrs[i]); + } + else { + subd_8255->cb_arg = addrs[i]; + subdev_8255_init(subd); + } + + err = a4l_add_subd(dev, subd); + if(err < 0) { + a4l_err(dev, + "dev_8255_attach: " + "a4l_add_subd() failed (err=%d)\n", err); + goto out_attach; + } + } + +out_attach: + return err; +} + +static int dev_8255_detach(a4l_dev_t *dev) +{ + a4l_subd_t *subd; + int i = 0; + + while((subd = a4l_get_subd(dev, i++)) != NULL) { + subd_8255_t *subd_8255 = (subd_8255_t *) subd->priv; + if(subd_8255 != NULL && subd_8255->cb_arg != 0) + release_region(subd_8255->cb_arg, _8255_SIZE); + } + + return 0; +} + +static a4l_drv_t drv_8255 = { + .owner = THIS_MODULE, + .board_name = "analogy_8255", + .attach = dev_8255_attach, + .detach = dev_8255_detach, + .privdata_size = 0, +}; + +static int __init drv_8255_init(void) +{ + return a4l_register_drv(&drv_8255); +} + +static void __exit drv_8255_cleanup(void) +{ + a4l_unregister_drv(&drv_8255); +} +MODULE_DESCRIPTION("Analogy driver for 8255 chip"); +MODULE_LICENSE("GPL"); + +module_init(drv_8255_init); +module_exit(drv_8255_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.h relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/8255.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,62 @@ +/** + * @file + * Hardware driver for 8255 chip + * @note Copyright (C) 1999 David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef __ANALOGY_8255_H__ +#define __ANALOGY_8255_H__ + +#include + +typedef int (*a4l_8255_cb_t)(int, int, int, unsigned long); + +typedef struct subd_8255_struct { + unsigned long cb_arg; + a4l_8255_cb_t cb_func; + unsigned int status; + int have_irq; + int io_bits; +} subd_8255_t; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_8255) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_8255_MODULE)) + +#define _8255_SIZE 4 + +#define _8255_DATA 0 +#define _8255_CR 3 + +#define CR_C_LO_IO 0x01 +#define CR_B_IO 0x02 +#define CR_B_MODE 0x04 +#define CR_C_HI_IO 0x08 +#define CR_A_IO 0x10 +#define CR_A_MODE(a) ((a)<<5) +#define CR_CW 0x80 + +void subdev_8255_init(a4l_subd_t *subd); +void subdev_8255_interrupt(a4l_subd_t *subd); + +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_8255 */ + +#define subdev_8255_init(x) do { } while(0) +#define subdev_8255_interrupt(x) do { } while(0) + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_8255 */ + +#endif /* !__ANALOGY_8255_H__ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/Kconfig relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,10 @@ + +config XENO_DRIVERS_ANALOGY_8255 + depends on XENO_DRIVERS_ANALOGY + tristate "8255 driver" + default n + +config XENO_DRIVERS_ANALOGY_PARPORT + depends on XENO_DRIVERS_ANALOGY && X86 + tristate "Standard parallel port driver" + default n diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/Makefile relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,40 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_8255) += analogy_8255.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_PARPORT) += analogy_parport.o + +analogy_8255-y := 8255.o + +analogy_parport-y := parport.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_8255) += analogy_8255.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_PARPORT) += analogy_parport.o + +analogy_8255-objs := 8255.o + +analogy_parport-objs := parport.o + +export-objs := $(analogy_8255-objs) $(analogy_parport-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +analogy_8255.o: $(analogy_8255-objs) + $(LD) -r -o $@ $(analogy_8255-objs) + +analogy_parport.o: $(analogy_parport-objs) + $(LD) -r -o $@ $(analogy_parport-objs) +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/parport.c relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/parport.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/intel/parport.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/intel/parport.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,458 @@ +/** + * @file + * Analogy driver for standard parallel port + * @note Copyright (C) 1998,2001 David A. Schleef + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + A cheap and easy way to get a few more digital I/O lines. Steal + additional parallel ports from old computers or your neighbors' + computers. + + Attach options list: + 0: I/O port base for the parallel port. + 1: IRQ + + Parallel Port Lines: + + pin subdev chan aka + --- ------ ---- --- + 1 2 0 strobe + 2 0 0 data 0 + 3 0 1 data 1 + 4 0 2 data 2 + 5 0 3 data 3 + 6 0 4 data 4 + 7 0 5 data 5 + 8 0 6 data 6 + 9 0 7 data 7 + 10 1 3 acknowledge + 11 1 4 busy + 12 1 2 output + 13 1 1 printer selected + 14 2 1 auto LF + 15 1 0 error + 16 2 2 init + 17 2 3 select printer + 18-25 ground + + Notes: + + Subdevices 0 is digital I/O, subdevice 1 is digital input, and + subdevice 2 is digital output. Unlike other Analogy devices, + subdevice 0 defaults to output. + + Pins 13 and 14 are inverted once by Analogy and once by the + hardware, thus cancelling the effect. + + Pin 1 is a strobe, thus acts like one. There's no way in software + to change this, at least on a standard parallel port. + + Subdevice 3 pretends to be a digital input subdevice, but it always + returns 0 when read. However, if you run a command with + scan_begin_src=TRIG_EXT, it uses pin 10 as a external triggering + pin, which can be used to wake up tasks. + + see http://www.beyondlogic.org/ for information. + or http://www.linux-magazin.de/ausgabe/1999/10/IO/io.html +*/ + +#include +#include +#include + +#define PARPORT_SIZE 3 + +#define PARPORT_A 0 +#define PARPORT_B 1 +#define PARPORT_C 2 + +#define DEFAULT_ADDRESS 0x378 +#define DEFAULT_IRQ 7 + +typedef struct parport_subd_priv { + unsigned long io_bits; +} parport_spriv_t; + +typedef struct parport_priv { + unsigned long io_base; + unsigned int a_data; + unsigned int c_data; + int enable_irq; +} parport_priv_t; + +#define devpriv ((parport_priv_t *)(dev->priv)) + +static int parport_insn_a(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + if (data[0]) { + devpriv->a_data &= ~data[0]; + devpriv->a_data |= (data[0] & data[1]); + + outb(devpriv->a_data, devpriv->io_base + PARPORT_A); + } + + data[1] = inb(devpriv->io_base + PARPORT_A); + + return 0; +} + +static int parport_insn_config_a(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + parport_spriv_t *spriv = (parport_spriv_t *)subd->priv; + unsigned int *data = (unsigned int *)insn->data; + + /* No need to check the channel descriptor; the input / output + setting is global for all channels */ + + switch (data[0]) { + + case A4L_INSN_CONFIG_DIO_OUTPUT: + spriv->io_bits = 0xff; + devpriv->c_data &= ~(1 << 5); + break; + + case A4L_INSN_CONFIG_DIO_INPUT: + spriv->io_bits = 0; + devpriv->c_data |= (1 << 5); + break; + + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = (spriv->io_bits == 0xff) ? + A4L_OUTPUT: A4L_INPUT; + break; + + default: + return -EINVAL; + } + + outb(devpriv->c_data, devpriv->io_base + PARPORT_C); + + return 0; +} + +static int parport_insn_b(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + if (data[0]) { + /* should writes be ignored? */ + } + + data[1] = (inb(devpriv->io_base + PARPORT_B) >> 3); + + return 0; +} + +static int parport_insn_c(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + data[0] &= 0x0f; + if (data[0]) { + devpriv->c_data &= ~data[0]; + devpriv->c_data |= (data[0] & data[1]); + + outb(devpriv->c_data, devpriv->io_base + PARPORT_C); + } + + data[1] = devpriv->c_data & 0xf; + + return 2; +} + +static int parport_intr_insn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + uint8_t *data = (uint8_t *)insn->data; + + if (insn->data_size < sizeof(uint8_t)) + return -EINVAL; + + data[1] = 0; + return 0; +} + +static a4l_cmd_t parport_intr_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_NOW, + .scan_begin_src = TRIG_EXT, + .convert_src = TRIG_FOLLOW, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_NONE, +}; + +static int parport_intr_cmdtest(a4l_subd_t *subd, a4l_cmd_t * cmd) +{ + + if (cmd->start_arg != 0) { + return -EINVAL; + } + if (cmd->scan_begin_arg != 0) { + return -EINVAL; + } + if (cmd->convert_arg != 0) { + return -EINVAL; + } + if (cmd->scan_end_arg != 1) { + return -EINVAL; + } + if (cmd->stop_arg != 0) { + return -EINVAL; + } + + return 0; +} + +static int parport_intr_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_dev_t *dev = subd->dev; + + devpriv->c_data |= 0x10; + outb(devpriv->c_data, devpriv->io_base + PARPORT_C); + + devpriv->enable_irq = 1; + + return 0; +} + +static int parport_intr_cancel(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + + a4l_info(dev, "parport_intr_cancel: cancel in progress\n"); + + devpriv->c_data &= ~0x10; + outb(devpriv->c_data, devpriv->io_base + PARPORT_C); + + devpriv->enable_irq = 0; + + return 0; +} + +static int parport_interrupt(unsigned int irq, void *d) +{ + a4l_dev_t *dev = d; + a4l_subd_t *subd = a4l_get_subd(dev, 3); + + if (!devpriv->enable_irq) { + a4l_err(dev, "parport_interrupt: bogus irq, ignored\n"); + return IRQ_NONE; + } + + a4l_buf_put(subd, 0, sizeof(unsigned int)); + a4l_buf_evt(subd, 0); + + return 0; +} + + +/* --- Channels descriptor --- */ + +static a4l_chdesc_t parport_chan_desc_a = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 8, + .chans = { + {A4L_CHAN_AREF_GROUND, 1}, + }, +}; + +static a4l_chdesc_t parport_chan_desc_b = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 5, + .chans = { + {A4L_CHAN_AREF_GROUND, 1}, + }, +}; + +static a4l_chdesc_t parport_chan_desc_c = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 4, + .chans = { + {A4L_CHAN_AREF_GROUND, 1}, + }, +}; + +static a4l_chdesc_t parport_chan_desc_intr = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 1, + .chans = { + {A4L_CHAN_AREF_GROUND, 1}, + }, +}; + +/* --- Subdevice initialization functions --- */ + +static void setup_subd_a(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_DIO; + subd->chan_desc = &parport_chan_desc_a; + subd->rng_desc = &range_digital; + subd->insn_bits = parport_insn_a; + subd->insn_config = parport_insn_config_a; +} + +static void setup_subd_b(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_DI; + subd->chan_desc = &parport_chan_desc_b; + subd->rng_desc = &range_digital; + subd->insn_bits = parport_insn_b; +} + +static void setup_subd_c(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_DO; + subd->chan_desc = &parport_chan_desc_c; + subd->rng_desc = &range_digital; + subd->insn_bits = parport_insn_c; +} + +static void setup_subd_intr(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_DI; + subd->chan_desc = &parport_chan_desc_intr; + subd->rng_desc = &range_digital; + subd->insn_bits = parport_intr_insn; + subd->cmd_mask = &parport_intr_cmd_mask; + subd->do_cmdtest = parport_intr_cmdtest; + subd->do_cmd = parport_intr_cmd; + subd->cancel = parport_intr_cancel; +} + +static void (*setup_subds[3])(a4l_subd_t *) = { + setup_subd_a, + setup_subd_b, + setup_subd_c +}; + +static int dev_parport_attach(a4l_dev_t *dev, a4l_lnkdesc_t *arg) +{ + int i, err = 0, irq = A4L_IRQ_UNUSED; + unsigned long io_base; + + if(arg->opts == NULL || arg->opts_size < sizeof(unsigned long)) { + + a4l_warn(dev, + "dev_parport_attach: no attach options specified, " + "taking default options (addr=0x%x, irq=%d)\n", + DEFAULT_ADDRESS, DEFAULT_IRQ); + + io_base = DEFAULT_ADDRESS; + irq = DEFAULT_IRQ; + } else { + + io_base = ((unsigned long *)arg->opts)[0]; + + if (arg->opts_size >= 2 * sizeof(unsigned long)) + irq = (int) ((unsigned long *)arg->opts)[1]; + } + + if (!request_region(io_base, PARPORT_SIZE, "analogy_parport")) { + a4l_err(dev, "dev_parport_attach: I/O port conflict"); + return -EIO; + } + + a4l_info(dev, "dev_parport_attach: address = 0x%lx\n", io_base); + + for (i = 0; i < 3; i++) { + + a4l_subd_t *subd = a4l_alloc_subd(sizeof(parport_spriv_t), + setup_subds[i]); + if (subd == NULL) + return -ENOMEM; + + err = a4l_add_subd(dev, subd); + if (err != i) + return err; + } + + if (irq != A4L_IRQ_UNUSED) { + + a4l_subd_t *subd; + + a4l_info(dev, "dev_parport_attach: irq = %d\n", irq); + + err = a4l_request_irq(dev, irq, parport_interrupt, 0, dev); + if (err < 0) { + a4l_err(dev, "dev_parport_attach: irq not available\n"); + return err; + } + + subd = a4l_alloc_subd(0, setup_subd_intr); + if (subd == NULL) + return -ENOMEM; + + err = a4l_add_subd(dev, subd); + if (err < 0) + return err; + } + + devpriv->io_base = io_base; + + devpriv->a_data = 0; + outb(devpriv->a_data, devpriv->io_base + PARPORT_A); + + devpriv->c_data = 0; + outb(devpriv->c_data, devpriv->io_base + PARPORT_C); + + return 0; +} + +static int dev_parport_detach(a4l_dev_t *dev) +{ + int err = 0; + + if (devpriv->io_base != 0) + release_region(devpriv->io_base, PARPORT_SIZE); + + if (a4l_get_irq(dev) != A4L_IRQ_UNUSED) { + a4l_free_irq(dev, a4l_get_irq(dev)); + } + + + return err; +} + +static a4l_drv_t drv_parport = { + .owner = THIS_MODULE, + .board_name = "analogy_parport", + .attach = dev_parport_attach, + .detach = dev_parport_detach, + .privdata_size = sizeof(parport_priv_t), +}; + +static int __init drv_parport_init(void) +{ + return a4l_register_drv(&drv_parport); +} + +static void __exit drv_parport_cleanup(void) +{ + a4l_unregister_drv(&drv_parport); +} + +MODULE_DESCRIPTION("Analogy driver for standard parallel port"); +MODULE_LICENSE("GPL"); + +module_init(drv_parport_init); +module_exit(drv_parport_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/Kconfig relase/linux-2.6.35.9//drivers/xenomai/analogy/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/analogy/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,49 @@ +menu "ANALOGY drivers" + +config XENO_DRIVERS_ANALOGY + depends on XENO_SKIN_RTDM + tristate "ANALOGY interface" + help + + ANALOGY is a framework aimed at supporting data acquisition + devices. + +config XENO_DRIVERS_ANALOGY_DEBUG + depends on XENO_DRIVERS_ANALOGY + bool "Analogy debug trace" + default y + help + + Enable debugging traces in Analogy so as to monitor Analogy's + core and drivers behaviours. + +config XENO_DRIVERS_ANALOGY_DEBUG_LEVEL + depends on XENO_DRIVERS_ANALOGY_DEBUG + int "Analogy core debug level threshold" + default 0 + help + + Define the level above which the debugging traces will not be + displayed. + + WARNING: this threshold is only applied on the Analogy + core. That will not affect the driver. + +config XENO_DRIVERS_ANALOGY_DRIVER_DEBUG_LEVEL + depends on XENO_DRIVERS_ANALOGY_DEBUG + int "Analogy driver debug level threshold" + default 0 + help + + Define the level above which the debugging traces will not be + displayed. + + WARNING: this threshold is only applied on the Analogy + driver. That will not affect the core. + +source drivers/xenomai/analogy/testing/Kconfig +source drivers/xenomai/analogy/intel/Kconfig +source drivers/xenomai/analogy/national_instruments/Kconfig +source drivers/xenomai/analogy/sensoray/Kconfig + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/Makefile relase/linux-2.6.35.9//drivers/xenomai/analogy/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/analogy/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,61 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/analogy + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY) += xeno_analogy.o testing/ intel/ national_instruments/ sensoray/ + +xeno_analogy-y := \ + buffer.o \ + command.o \ + device.o \ + driver.o \ + driver_facilities.o \ + instruction.o \ + os_facilities.o \ + subdevice.o \ + transfer.o + +xeno_analogy-$(CONFIG_XENO_OPT_PERVASIVE) += rtdm_interface.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY_FAKE) += testing +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY_LOOP) += testing +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY_8255) += intel +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) += national_instruments +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY_S526) += sensoray + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY) += xeno_analogy.o + +opt_objs-y := +opt_objs-$(CONFIG_XENO_OPT_PERVASIVE) += rtdm_interface.o + +xeno_analogy-objs := \ + buffer.o \ + command.o \ + device.o \ + driver.o \ + driver_facilities.o \ + instruction.o \ + os_facilities.o \ + subdevice.o \ + transfer.o + +xeno_analogy-objs += $(opt_objs-y) + +export-objs := $(xeno_analogy-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat -I. + +include $(TOPDIR)/Rules.make + +xeno_analogy.o: $(xeno_analogy-objs) + $(LD) -r -o $@ $(xeno_analogy-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Kconfig relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,24 @@ + +config XENO_DRIVERS_ANALOGY_NI_MITE + depends on XENO_DRIVERS_ANALOGY && PCI + tristate "NI MITE driver" + default n + +config XENO_DRIVERS_ANALOGY_NI_TIO + depends on XENO_DRIVERS_ANALOGY + tristate "NI TIO driver" + default n + +config XENO_DRIVERS_ANALOGY_NI_MIO + depends on XENO_DRIVERS_ANALOGY && XENO_DRIVERS_ANALOGY_NI_TIO && PCI + tristate "NI MIO driver" + default n + +config XENO_DRIVERS_ANALOGY_NI_PCIMIO + depends on XENO_DRIVERS_ANALOGY && PCI + select XENO_DRIVERS_ANALOGY_NI_MITE + select XENO_DRIVERS_ANALOGY_NI_TIO + select XENO_DRIVERS_ANALOGY_NI_MIO + select XENO_DRIVERS_ANALOGY_8255 + tristate "NI PCIMIO driver" + default n diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Makefile relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,54 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) += analogy_ni_mite.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_TIO) += analogy_ni_tio.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_MIO) += analogy_ni_mio.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_PCIMIO) += analogy_ni_pcimio.o + +analogy_ni_mite-y := mite.o +analogy_ni_tio-y := tio_common.o +analogy_ni_mio-y := mio_common.o +analogy_ni_pcimio-y := pcimio.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) += analogy_ni_mite.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_TIO) += analogy_ni_tio.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_MIO) += analogy_ni_mio.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_NI_PCIMIO) += analogy_ni_pcimio.o + +analogy_ni_mite-objs := mite.o +analogy_ni_tio-objs := tio_common.o +analogy_ni_mio-objs := mio_common.o +analogy_ni_pcimio-objs := pcimio.o + +export-objs := $(analogy_ni_mite-objs) \ + $(analogy_ni_tio-objs) \ + $(analogy_ni_mio-objs) \ + $(analogy_ni_pcimio-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +analogy_ni_mite.o: $(analogy_ni_mite-objs) + $(LD) -r -o $@ $(analogy_ni_mite-objs) + +analogy_ni_tio.o: $(analogy_ni_tio-objs) + $(LD) -r -o $@ $(analogy_ni_tio-objs) + +analogy_ni_mio.o: $(analogy_ni_mio-objs) + $(LD) -r -o $@ $(analogy_ni_mio-objs) + +analogy_ni_pcimio.o: $(analogy_ni_pcimio-objs) + $(LD) -r -o $@ $(analogy_ni_pcimio-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mio_common.c relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mio_common.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mio_common.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mio_common.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,5523 @@ +/** + * @file + * Hardware driver for DAQ-STC based boards + * + * Copyright (C) 1997-2001 David A. Schleef + * Copyright (C) 2002-2006 Frank Mori Hess + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Description: DAQ-STC systems + * + * References: + * 340747b.pdf AT-MIO E series Register-Level Programmer Manual + * 341079b.pdf PCI E Series Register-Level Programmer Manual + * 340934b.pdf DAQ-STC reference manual + * 322080b.pdf 6711/6713/6715 User Manual + * 320945c.pdf PCI E Series User Manual + * 322138a.pdf PCI-6052E and DAQPad-6052E User Manual + * 320517c.pdf AT E Series User manual (obsolete) + * 320517f.pdf AT E Series User manual + * 320906c.pdf Maximum signal ratings + * 321066a.pdf About 16x + * 321791a.pdf Discontinuation of at-mio-16e-10 rev. c + * 321808a.pdf About at-mio-16e-10 rev P + * 321837a.pdf Discontinuation of at-mio-16de-10 rev d + * 321838a.pdf About at-mio-16de-10 rev N + * + * ISSUES: + * - The interrupt routine needs to be cleaned up + * - S-Series PCI-6143 support has been added but is not fully tested + * as yet. Terry Barnaby, BEAM Ltd. + * + */ + +#include "../intel/8255.h" +#include "mite.h" +#include "ni_stc.h" +#include "ni_mio.h" + +#define NI_TIMEOUT 1000 + +/* Note: this table must match the ai_gain_* definitions */ +static const short ni_gainlkup[][16] = { + /* ai_gain_16 */ + {0, 1, 2, 3, 4, 5, 6, 7, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, + 0x106, 0x107}, + /* ai_gain_8 */ + {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107}, + /* ai_gain_14 */ + {1, 2, 3, 4, 5, 6, 7, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, + 0x107}, + /* ai_gain_4 */ + {0, 1, 4, 7}, + /* ai_gain_611x */ + {0x00a, 0x00b, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006}, + /* ai_gain_622x */ + {0, 1, 4, 5}, + /* ai_gain_628x */ + {1, 2, 3, 4, 5, 6, 7}, + /* ai_gain_6143 */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; + +a4l_rngtab_t rng_ni_E_ai = {16, { + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-2.5, 2.5), + RANGE_V(-1, 1), + RANGE_V(-0.5, 0.5), + RANGE_V(-0.25, 0.25), + RANGE_V(-0.1, 0.1), + RANGE_V(-0.05, 0.05), + RANGE_V(0, 20), + RANGE_V(0, 10), + RANGE_V(0, 5), + RANGE_V(0, 2), + RANGE_V(0, 1), + RANGE_V(0, 0.5), + RANGE_V(0, 0.2), + RANGE_V(0, 0.1), +}}; +a4l_rngdesc_t range_ni_E_ai = + RNG_GLOBAL(rng_ni_E_ai); + +a4l_rngtab_t rng_ni_E_ai_limited = {8, { + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-1, 1), + RANGE_V(-0.1, 0.1), + RANGE_V(0, 10), + RANGE_V(0, 5), + RANGE_V(0, 1), + RANGE_V(0, 0.1), +}}; +a4l_rngdesc_t range_ni_E_ai_limited = + RNG_GLOBAL(rng_ni_E_ai_limited); + +a4l_rngtab_t rng_ni_E_ai_limited14 = {14, { + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-2, 2), + RANGE_V(-1, 1), + RANGE_V(-0.5, 0.5), + RANGE_V(-0.2, 0.2), + RANGE_V(-0.1, 0.1), + RANGE_V(0, 10), + RANGE_V(0, 5), + RANGE_V(0, 2), + RANGE_V(0, 1), + RANGE_V(0, 0.5), + RANGE_V(0, 0.2), + RANGE_V(0, 0.1), +}}; +a4l_rngdesc_t range_ni_E_ai_limited14 = + RNG_GLOBAL(rng_ni_E_ai_limited14); + +a4l_rngtab_t rng_ni_E_ai_bipolar4 = {4, { + RANGE_V(-10,10), + RANGE_V(-5, 5), + RANGE_V(-0.5, 0.5), + RANGE_V(-0.05, 0.05), +}}; +a4l_rngdesc_t range_ni_E_ai_bipolar4 = + RNG_GLOBAL(rng_ni_E_ai_bipolar4); + +a4l_rngtab_t rng_ni_E_ai_611x = {8, { + RANGE_V(-50, 50), + RANGE_V(-20, 20), + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-2, 2), + RANGE_V(-1, 1), + RANGE_V(-0.5, 0.5), + RANGE_V(-0.2, 0.2), +}}; +a4l_rngdesc_t range_ni_E_ai_611x = + RNG_GLOBAL(rng_ni_E_ai_611x); + +a4l_rngtab_t rng_ni_M_ai_622x = {4, { + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-1, 1), + RANGE_V(-0.2, 0.2), +}}; +a4l_rngdesc_t range_ni_M_ai_622x = + RNG_GLOBAL(rng_ni_M_ai_622x); + +a4l_rngtab_t rng_ni_M_ai_628x = {7, { + RANGE_V(-10, 10), + RANGE_V(-5, 5), + RANGE_V(-2, 2), + RANGE_V(-1, 1), + RANGE_V(-0.5, 0.5), + RANGE_V(-0.2, 0.2), + RANGE_V(-0.1, 0.1), +}}; +a4l_rngdesc_t range_ni_M_ai_628x = + RNG_GLOBAL(rng_ni_M_ai_628x); + +a4l_rngtab_t rng_ni_S_ai_6143 = {1, { + RANGE_V(-5, 5), +}}; +a4l_rngdesc_t range_ni_S_ai_6143 = + RNG_GLOBAL(rng_ni_S_ai_6143); + + +a4l_rngtab_t rng_ni_E_ao_ext = {4, { + RANGE_V(-10, 10), + RANGE_V(0, 10), + RANGE_ext(-1, 1), + RANGE_ext(0, 1), +}}; +a4l_rngdesc_t range_ni_E_ao_ext = + RNG_GLOBAL(rng_ni_E_ao_ext); + +a4l_rngdesc_t *ni_range_lkup[] = { + &range_ni_E_ai, + &range_ni_E_ai_limited, + &range_ni_E_ai_limited14, + &range_ni_E_ai_bipolar4, + &range_ni_E_ai_611x, + &range_ni_M_ai_622x, + &range_ni_M_ai_628x, + &range_ni_S_ai_6143 +}; + +static const int num_adc_stages_611x = 3; + +static void ni_handle_fifo_dregs(a4l_subd_t *subd); +static void get_last_sample_611x(a4l_subd_t *subd); +static void get_last_sample_6143(a4l_subd_t *subd); +static void handle_cdio_interrupt(a4l_dev_t *dev); +static void ni_load_channelgain_list(a4l_dev_t *dev, + unsigned int n_chan, unsigned int *list); + +#if (!defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) && \ + !defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) +static void ni_handle_fifo_half_full(a4l_subd_t *subd); +static int ni_ao_fifo_half_empty(a4l_subd_t *subd); +#endif /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +static inline void ni_set_bitfield(a4l_dev_t *dev, + int reg, + unsigned int bit_mask, + unsigned int bit_values) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + switch (reg) { + case Interrupt_A_Enable_Register: + devpriv->int_a_enable_reg &= ~bit_mask; + devpriv->int_a_enable_reg |= bit_values & bit_mask; + devpriv->stc_writew(dev, devpriv->int_a_enable_reg, + Interrupt_A_Enable_Register); + break; + case Interrupt_B_Enable_Register: + devpriv->int_b_enable_reg &= ~bit_mask; + devpriv->int_b_enable_reg |= bit_values & bit_mask; + devpriv->stc_writew(dev, devpriv->int_b_enable_reg, + Interrupt_B_Enable_Register); + break; + case IO_Bidirection_Pin_Register: + devpriv->io_bidirection_pin_reg &= ~bit_mask; + devpriv->io_bidirection_pin_reg |= bit_values & bit_mask; + devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg, + IO_Bidirection_Pin_Register); + break; + case AI_AO_Select: + devpriv->ai_ao_select_reg &= ~bit_mask; + devpriv->ai_ao_select_reg |= bit_values & bit_mask; + ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select); + break; + case G0_G1_Select: + devpriv->g0_g1_select_reg &= ~bit_mask; + devpriv->g0_g1_select_reg |= bit_values & bit_mask; + ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select); + break; + default: + a4l_err(dev, + "Warning %s() called with invalid register\n", + __FUNCTION__); + a4l_err(dev,"reg is %d\n", reg); + break; + } + + mmiowb(); + a4l_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); +} + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static int ni_ai_drain_dma(a4l_subd_t *subd); + +static inline void ni_set_ai_dma_channel(a4l_dev_t * dev, int channel) +{ + unsigned bitfield; + + if (channel >= 0) { + bitfield = + (ni_stc_dma_channel_select_bitfield(channel) << + AI_DMA_Select_Shift) & AI_DMA_Select_Mask; + } else { + bitfield = 0; + } + ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield); +} + +static inline void ni_set_ao_dma_channel(a4l_dev_t * dev, int channel) +{ + unsigned bitfield; + + if (channel >= 0) { + bitfield = + (ni_stc_dma_channel_select_bitfield(channel) << + AO_DMA_Select_Shift) & AO_DMA_Select_Mask; + } else { + bitfield = 0; + } + ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield); +} + +static inline void ni_set_gpct_dma_channel(a4l_dev_t * dev, + unsigned gpct_index, int mite_channel) +{ + unsigned bitfield; + + if (mite_channel >= 0) { + bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel); + } else { + bitfield = 0; + } + ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index), + bitfield); +} + +static inline void ni_set_cdo_dma_channel(a4l_dev_t * dev, int mite_channel) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask; + if (mite_channel >= 0) { + /*XXX just guessing + ni_stc_dma_channel_select_bitfield() returns the right + bits, under the assumption the cdio dma selection + works just like ai/ao/gpct. Definitely works for dma + channels 0 and 1. */ + devpriv->cdio_dma_select_reg |= + (ni_stc_dma_channel_select_bitfield(mite_channel) << + CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask; + } + ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select); + mmiowb(); + a4l_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); +} + +static int ni_request_ai_mite_channel(a4l_dev_t * dev) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + BUG_ON(devpriv->ai_mite_chan); + devpriv->ai_mite_chan = + mite_request_channel(devpriv->mite, devpriv->ai_mite_ring); + if (devpriv->ai_mite_chan == NULL) { + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, + flags); + a4l_err(dev, + "ni_request_ai_mite_channel: " + "failed to reserve mite dma channel for analog input."); + return -EBUSY; + } + devpriv->ai_mite_chan->dir = A4L_INPUT; + ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel); + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + return 0; +} + +static int ni_request_ao_mite_channel(a4l_dev_t * dev) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + BUG_ON(devpriv->ao_mite_chan); + devpriv->ao_mite_chan = + mite_request_channel(devpriv->mite, devpriv->ao_mite_ring); + if (devpriv->ao_mite_chan == NULL) { + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, + flags); + a4l_err(dev, + "ni_request_ao_mite_channel: " + "failed to reserve mite dma channel for analog outut."); + return -EBUSY; + } + devpriv->ao_mite_chan->dir = A4L_OUTPUT; + ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel); + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + return 0; +} + +static int ni_request_gpct_mite_channel(a4l_dev_t * dev, + unsigned gpct_index, int direction) +{ + unsigned long flags; + struct mite_channel *mite_chan; + + BUG_ON(gpct_index >= NUM_GPCT); + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + BUG_ON(devpriv->counter_dev->counters[gpct_index]->mite_chan); + mite_chan = mite_request_channel(devpriv->mite, + devpriv->gpct_mite_ring[gpct_index]); + if (mite_chan == NULL) { + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, + flags); + a4l_err(dev, + "ni_request_gpct_mite_channel: " + "failed to reserve mite dma channel for counter."); + return -EBUSY; + } + mite_chan->dir = direction; + ni_tio_set_mite_channel(devpriv->counter_dev->counters[gpct_index], + mite_chan); + ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel); + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + return 0; +} + +static int ni_request_cdo_mite_channel(a4l_dev_t *dev) +{ + unsigned long flags; + int err = 0; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + + /* No channel should be allocated... */ + BUG_ON(devpriv->cdo_mite_chan); + /* ...until now */ + devpriv->cdo_mite_chan = + mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring); + + if (devpriv->cdo_mite_chan) { + devpriv->cdo_mite_chan->dir = A4L_OUTPUT; + ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel); + } else { + err = -EBUSY; + a4l_err(dev, + "ni_request_cdo_mite_channel: " + "failed to reserve mite dma channel " + "for correlated digital outut."); + } + + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + return err; +} + +void ni_release_ai_mite_channel(a4l_dev_t *dev) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->ai_mite_chan) { + ni_set_ai_dma_channel(dev, -1); + mite_release_channel(devpriv->ai_mite_chan); + devpriv->ai_mite_chan = NULL; + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + +} + +void ni_release_ao_mite_channel(a4l_dev_t *dev) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->ao_mite_chan) { + ni_set_ao_dma_channel(dev, -1); + mite_release_channel(devpriv->ao_mite_chan); + devpriv->ao_mite_chan = NULL; + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + +} + +void ni_release_gpct_mite_channel(a4l_dev_t *dev, unsigned gpct_index) +{ + unsigned long flags; + + BUG_ON(gpct_index >= NUM_GPCT); + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->counter_dev->counters[gpct_index]->mite_chan) { + struct mite_channel *mite_chan = + devpriv->counter_dev->counters[gpct_index]->mite_chan; + + ni_set_gpct_dma_channel(dev, gpct_index, -1); + ni_tio_set_mite_channel(devpriv->counter_dev-> + counters[gpct_index], NULL); + mite_release_channel(mite_chan); + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + +} + +void ni_release_cdo_mite_channel(a4l_dev_t *dev) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->cdo_mite_chan) { + ni_set_cdo_dma_channel(dev, -1); + mite_release_channel(devpriv->cdo_mite_chan); + devpriv->cdo_mite_chan = NULL; + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + +} + +void ni_sync_ai_dma(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->ai_mite_chan) + mite_sync_input_dma(devpriv->ai_mite_chan, subd); + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); +} + +void mite_handle_b_linkc(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + unsigned long flags; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->ao_mite_chan) + mite_sync_output_dma(devpriv->ao_mite_chan, subd); + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); +} + +static int ni_ao_wait_for_dma_load(a4l_subd_t *subd) +{ + static const int timeout = 10000; + + a4l_dev_t *dev = subd->dev; + a4l_buf_t *buf = subd->buf; + + int i; + + for (i = 0; i < timeout; i++) { + + int buffer_filled; + unsigned short b_status; + + b_status = devpriv->stc_readw(dev, AO_Status_1_Register); + + buffer_filled = test_bit(A4L_BUF_EOA_NR, &buf->flags); + buffer_filled |= (b_status & AO_FIFO_Half_Full_St); + + if (buffer_filled) + break; + + /* If we poll too often, the pci bus activity seems + to slow the dma transfer down */ + a4l_udelay(10); + } + + if (i == timeout) { + a4l_err(dev, + "ni_ao_wait_for_dma_load: " + "timed out waiting for dma load"); + return -EPIPE; + } + + return 0; +} + + +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +static inline int ni_ai_drain_dma(a4l_subd_t *subd) +{ + return -ENOTSUPP; +} + +static inline int ni_request_ai_mite_channel(a4l_dev_t * dev) +{ + return -ENOTSUPP; +} + +static inline int ni_request_ao_mite_channel(a4l_dev_t * dev) +{ + return -ENOTSUPP; +} + +static inline +int ni_request_gpct_mite_channel(a4l_dev_t * dev, + unsigned gpct_index, int direction) +{ + return -ENOTSUPP; +} + +static inline int ni_request_cdo_mite_channel(a4l_dev_t *dev) +{ + return -ENOTSUPP; +} + +#define ni_release_ai_mite_channel(x) do { } while (0) +#define ni_release_ao_mite_channel(x) do { } while (0) +#define ni_release_gpct_mite_channel(x) do { } while (0) +#define ni_release_cdo_mite_channel(x) do { } while (0) +#define ni_sync_ai_dma(x) do { } while (0) +#define mite_handle_b_linkc(x) do { } while (0) + +static inline int ni_ao_wait_for_dma_load(a4l_subd_t *subd) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +/* E-series boards use the second irq signals to generate dma requests + for their counters */ +void ni_e_series_enable_second_irq(a4l_dev_t *dev, + unsigned gpct_index, short enable) +{ + if (boardtype.reg_type & ni_reg_m_series_mask) + return; + switch (gpct_index) { + case 0: + if (enable) { + devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable, + Second_IRQ_A_Enable_Register); + } else { + devpriv->stc_writew(dev, 0, + Second_IRQ_A_Enable_Register); + } + break; + case 1: + if (enable) { + devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable, + Second_IRQ_B_Enable_Register); + } else { + devpriv->stc_writew(dev, 0, + Second_IRQ_B_Enable_Register); + } + break; + default: + BUG(); + break; + } +} + +void ni_clear_ai_fifo(a4l_dev_t *dev) +{ + if (boardtype.reg_type == ni_reg_6143) { + /* Flush the 6143 data FIFO */ + ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */ + ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */ + while (ni_readl(AIFIFO_Status_6143) & 0x10); /* Wait for complete */ + } else { + devpriv->stc_writew(dev, 1, ADC_FIFO_Clear); + if (boardtype.reg_type == ni_reg_625x) { + ni_writeb(0, M_Offset_Static_AI_Control(0)); + ni_writeb(1, M_Offset_Static_AI_Control(0)); + } + } +} + +#define ao_win_out(data, addr) ni_ao_win_outw(dev, data, addr) +static inline void ni_ao_win_outw(a4l_dev_t *dev, uint16_t data, int addr) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->window_lock, flags); + ni_writew(addr, AO_Window_Address_611x); + ni_writew(data, AO_Window_Data_611x); + a4l_unlock_irqrestore(&devpriv->window_lock, flags); +} + +static inline void ni_ao_win_outl(a4l_dev_t *dev, uint32_t data, int addr) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->window_lock, flags); + ni_writew(addr, AO_Window_Address_611x); + ni_writel(data, AO_Window_Data_611x); + a4l_unlock_irqrestore(&devpriv->window_lock, flags); +} + +static inline unsigned short ni_ao_win_inw(a4l_dev_t *dev, int addr) +{ + unsigned long flags; + unsigned short data; + + a4l_lock_irqsave(&devpriv->window_lock, flags); + ni_writew(addr, AO_Window_Address_611x); + data = ni_readw(AO_Window_Data_611x); + a4l_unlock_irqrestore(&devpriv->window_lock, flags); + return data; +} + +/* + * ni_set_bits( ) allows different parts of the ni_mio_common driver + * to share registers (such as Interrupt_A_Register) without interfering + * with each other. + * + * NOTE: the switch/case statements are optimized out for a constant + * argument so this is actually quite fast--- If you must wrap another + * function around this make it inline to avoid a large speed penalty. + * + * value should only be 1 or 0. + */ + +static inline void ni_set_bits(a4l_dev_t *dev, + int reg, unsigned bits, unsigned value) +{ + unsigned bit_values; + + if (value) + bit_values = bits; + else + bit_values = 0; + + ni_set_bitfield(dev, reg, bits, bit_values); +} + +static void shutdown_ai_command(a4l_subd_t *subd) +{ + ni_ai_drain_dma(subd); + ni_handle_fifo_dregs(subd); + get_last_sample_611x(subd); + get_last_sample_6143(subd); + + /* TODO: stop the acquisiton */ +} + +static void ni_handle_eos(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + + if (devpriv->aimode == AIMODE_SCAN) { + static const int timeout = 10; + int i; + + for (i = 0; i < timeout; i++) { + ni_sync_ai_dma(subd); + /* TODO: stop when the transfer is really over */ + a4l_udelay(1); + } + } + + /* Handle special case of single scan using AI_End_On_End_Of_Scan */ + if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) { + shutdown_ai_command(subd); + } +} + +static void ni_event(a4l_subd_t * subd) +{ + /* Temporary hack */ + a4l_buf_t *buf = subd->buf; + + if(test_bit(A4L_BUF_ERROR_NR, &buf->flags)) { + if (subd->cancel != NULL) + subd->cancel(subd); + } + + a4l_buf_evt(subd, 0); + +} + +static void handle_gpct_interrupt(a4l_dev_t *dev, unsigned short counter_index) +{ +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + ni_tio_handle_interrupt(devpriv->counter_dev->counters[counter_index], + dev); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ +} + +#ifdef CONFIG_DEBUG_MIO_COMMON +static const char *const status_a_strings[] = { + "passthru0", "fifo", "G0_gate", "G0_TC", + "stop", "start", "sc_tc", "start1", + "start2", "sc_tc_error", "overflow", "overrun", + "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a" +}; + +static void ni_mio_print_status_a(int status) +{ + int i; + + __a4l_info("A status:"); + for (i = 15; i >= 0; i--) { + if (status & (1 << i)) { + __a4l_info(" %s", status_a_strings[i]); + } + } + __a4l_info("\n"); +} + +static const char *const status_b_strings[] = { + "passthru1", "fifo", "G1_gate", "G1_TC", + "UI2_TC", "UPDATE", "UC_TC", "BC_TC", + "start1", "overrun", "start", "bc_tc_error", + "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b" +}; + +static void ni_mio_print_status_b(int status) +{ + int i; + + __a4l_info("B status:"); + for (i = 15; i >= 0; i--) { + if (status & (1 << i)) { + __a4l_info(" %s", status_b_strings[i]); + } + } + __a4l_info("\n"); +} + +#else /* !CONFIG_DEBUG_MIO_COMMON */ + +#define ni_mio_print_status_a(x) +#define ni_mio_print_status_b(x) + +#endif /* CONFIG_DEBUG_MIO_COMMON */ + +static void ack_a_interrupt(a4l_dev_t *dev, unsigned short a_status) +{ + unsigned short ack = 0; + + if (a_status & AI_SC_TC_St) { + ack |= AI_SC_TC_Interrupt_Ack; + } + if (a_status & AI_START1_St) { + ack |= AI_START1_Interrupt_Ack; + } + if (a_status & AI_START_St) { + ack |= AI_START_Interrupt_Ack; + } + if (a_status & AI_STOP_St) { + /* not sure why we used to ack the START here also, + instead of doing it independently. Frank Hess + 2007-07-06 */ + ack |= AI_STOP_Interrupt_Ack; + } + if (ack) + devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register); +} + +static void handle_a_interrupt(a4l_dev_t *dev, + unsigned short status,unsigned int ai_mite_status) +{ + + a4l_subd_t *subd = a4l_get_subd(dev, NI_AI_SUBDEV); + + /* 67xx boards don't have ai subdevice, but their gpct0 + might generate an a interrupt. */ + + if((subd->flags & A4L_SUBD_TYPES) == A4L_SUBD_UNUSED) + return; + + a4l_info(dev, "ni_mio_common: interrupt: " + "a_status=%04x ai_mite_status=%08x\n",status, ai_mite_status); + ni_mio_print_status_a(status); + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + if (ai_mite_status & CHSR_LINKC) + ni_sync_ai_dma(subd); + + if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | + CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | + CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) { + a4l_info(dev, "ni_mio_common: interrupt: " + "unknown mite interrupt, ack! (ai_mite_status=%08x)\n", + ai_mite_status); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + /* Test for all uncommon interrupt events at the same time */ + if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St | + AI_SC_TC_St | AI_START1_St)) { + if (status == 0xffff) { + a4l_info(dev, "ni_mio_common: interrupt: " + "a_status=0xffff. Card removed?\n"); + /* TODO: we probably aren't even running a command now, + so it's a good idea to be careful. + we should check the transfer status */ + a4l_buf_evt(subd, A4L_BUF_ERROR); + ni_event(subd); + return; + } + if (status & (AI_Overrun_St | AI_Overflow_St | + AI_SC_TC_Error_St)) { + a4l_info(dev, "ni_mio_common: interrupt: " + "ai error a_status=%04x\n", status); + ni_mio_print_status_a(status); + + shutdown_ai_command(subd); + + a4l_buf_evt(subd, A4L_BUF_ERROR); + ni_event(subd); + + return; + } + if (status & AI_SC_TC_St) { + a4l_info(dev, "ni_mio_common: SC_TC interrupt\n"); + if (!devpriv->ai_continuous) { + shutdown_ai_command(subd); + } + } + } + +#if (!defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) && \ + !defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + + if (status & AI_FIFO_Half_Full_St) { + int i; + static const int timeout = 10; + /* PCMCIA cards (at least 6036) seem to stop producing + interrupts if we fail to get the fifo less than half + full, so loop to be sure. */ + for (i = 0; i < timeout; ++i) { + ni_handle_fifo_half_full(subd); + if ((devpriv->stc_readw(dev, AI_Status_1_Register) & + AI_FIFO_Half_Full_St) == 0) + break; + } + } +#endif /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + if ((status & AI_STOP_St)) { + ni_handle_eos(subd); + } + + ni_event(subd); + + status = devpriv->stc_readw(dev, AI_Status_1_Register); + if (status & Interrupt_A_St) + a4l_info(dev, "ni_mio_common: interrupt: " + " didn't clear interrupt? status=0x%x\n", status); +} + +static void ack_b_interrupt(a4l_dev_t *dev, unsigned short b_status) +{ + unsigned short ack = 0; + if (b_status & AO_BC_TC_St) { + ack |= AO_BC_TC_Interrupt_Ack; + } + if (b_status & AO_Overrun_St) { + ack |= AO_Error_Interrupt_Ack; + } + if (b_status & AO_START_St) { + ack |= AO_START_Interrupt_Ack; + } + if (b_status & AO_START1_St) { + ack |= AO_START1_Interrupt_Ack; + } + if (b_status & AO_UC_TC_St) { + ack |= AO_UC_TC_Interrupt_Ack; + } + if (b_status & AO_UI2_TC_St) { + ack |= AO_UI2_TC_Interrupt_Ack; + } + if (b_status & AO_UPDATE_St) { + ack |= AO_UPDATE_Interrupt_Ack; + } + if (ack) + devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register); +} + +static void handle_b_interrupt(a4l_dev_t * dev, + unsigned short b_status, unsigned int ao_mite_status) +{ + + a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV); + + a4l_dbg(1, drv_dbg, dev, + "ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", + b_status, ao_mite_status); + + ni_mio_print_status_b(b_status); + + if (b_status == 0xffff) + return; + + if (b_status & AO_Overrun_St) { + a4l_err(dev, + "ni_mio_common: interrupt: " + "AO FIFO underrun status=0x%04x status2=0x%04x\n", + b_status, + devpriv->stc_readw(dev, AO_Status_2_Register)); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + + if (b_status & AO_BC_TC_St) { + a4l_dbg(1, drv_dbg, dev, + "ni_mio_common: interrupt: " + "AO BC_TC status=0x%04x status2=0x%04x\n", + b_status, devpriv->stc_readw(dev, AO_Status_2_Register)); + a4l_buf_evt(subd, A4L_BUF_EOA); + } + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + + if (ao_mite_status & CHSR_STOPS) { + a4l_dbg(1, drv_dbg, dev, + "ni_mio_common: interrupt: MITE transfer stopped\n"); + } else if (ao_mite_status & CHSR_LINKC) { + /* Currently, mite.c requires us to handle LINKC */ + mite_handle_b_linkc(subd); + } + + if (ao_mite_status & + ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | + CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | + CHSR_SABORT | CHSR_STOPS | CHSR_XFERR | CHSR_LxERR_mask)) { + a4l_err(dev, + "unknown mite interrupt, ack! (ao_mite_status=%08x)\n", + ao_mite_status); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +#if (!defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) && \ + !defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + + if (b_status & AO_FIFO_Request_St) { + int ret; + + ret = ni_ao_fifo_half_empty(subd); + if (!ret) { + a4l_err(dev, + "ni_mio_common: " + "interrupt: AO buffer underrun\n"); + ni_set_bits(dev, Interrupt_B_Enable_Register, + AO_FIFO_Interrupt_Enable | + AO_Error_Interrupt_Enable, 0); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + } +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + ni_event(subd); +} + +int ni_E_interrupt(unsigned int irq, void *d) +{ + a4l_dev_t *dev = d; + unsigned short a_status; + unsigned short b_status; + unsigned int ai_mite_status = 0; + unsigned int ao_mite_status = 0; + unsigned long flags; + struct mite_struct *mite = devpriv->mite; + + /* Make sure dev->attached is checked before handler does + anything else. */ + smp_mb(); + + /* lock to avoid race with a4l_poll */ + a4l_lock_irqsave(&dev->lock, flags); + a_status = devpriv->stc_readw(dev, AI_Status_1_Register); + b_status = devpriv->stc_readw(dev, AO_Status_1_Register); + if (mite) { +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + a4l_lock(&devpriv->mite_channel_lock); + if (devpriv->ai_mite_chan) { + ai_mite_status = mite_get_status(devpriv->ai_mite_chan); + if (ai_mite_status & CHSR_LINKC) + writel(CHOR_CLRLC, + devpriv->mite->mite_io_addr + + MITE_CHOR(devpriv->ai_mite_chan->channel)); + } + if (devpriv->ao_mite_chan) { + ao_mite_status = mite_get_status(devpriv->ao_mite_chan); + if (ao_mite_status & CHSR_LINKC) + writel(CHOR_CLRLC, + mite->mite_io_addr + + MITE_CHOR(devpriv->ao_mite_chan->channel)); + } + a4l_unlock(&devpriv->mite_channel_lock); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + } + ack_a_interrupt(dev, a_status); + ack_b_interrupt(dev, b_status); + if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT)) + handle_a_interrupt(dev, a_status, ai_mite_status); + if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT)) + handle_b_interrupt(dev, b_status, ao_mite_status); + handle_gpct_interrupt(dev, 0); + handle_gpct_interrupt(dev, 1); + handle_cdio_interrupt(dev); + + a4l_unlock_irqrestore(&dev->lock, flags); + return 0; +} + +#if (!defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) && \ + !defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static void ni_ao_fifo_load(a4l_subd_t *subd, int n) +{ + a4l_dev_t *dev = subd->dev; + sampl_t d; + u32 packed_data; + int i, err = 1; + + for (i = 0; i < n; i++) { + err = a4l_buf_get(subd, &d, sizeof(sampl_t)); + if (err != 0) + break; + + if (boardtype.reg_type & ni_reg_6xxx_mask) { + packed_data = d & 0xffff; + /* 6711 only has 16 bit wide ao fifo */ + if (boardtype.reg_type != ni_reg_6711) { + err = a4l_buf_get(subd, &d, sizeof(sampl_t)); + if (err != 0) + break; + i++; + packed_data |= (d << 16) & 0xffff0000; + } + ni_writel(packed_data, DAC_FIFO_Data_611x); + } else { + ni_writew(d, DAC_FIFO_Data); + } + } + if (err != 0) { + a4l_buf_evt(subd, A4L_BUF_ERROR); + } +} + +/* + * There's a small problem if the FIFO gets really low and we + * don't have the data to fill it. Basically, if after we fill + * the FIFO with all the data available, the FIFO is _still_ + * less than half full, we never clear the interrupt. If the + * IRQ is in edge mode, we never get another interrupt, because + * this one wasn't cleared. If in level mode, we get flooded + * with interrupts that we can't fulfill, because nothing ever + * gets put into the buffer. + * + * This kind of situation is recoverable, but it is easier to + * just pretend we had a FIFO underrun, since there is a good + * chance it will happen anyway. This is _not_ the case for + * RT code, as RT code might purposely be running close to the + * metal. Needs to be fixed eventually. + */ +static int ni_ao_fifo_half_empty(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + int n; + + n = a4l_buf_count(subd); + if (n == 0) { + a4l_buf_evt(subd, A4L_BUF_ERROR); + return 0; + } + + n /= sizeof(sampl_t); + if (n > boardtype.ao_fifo_depth / 2) + n = boardtype.ao_fifo_depth / 2; + + ni_ao_fifo_load(subd, n); + + return 1; +} + +static int ni_ao_prep_fifo(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + int n; + + /* Reset fifo */ + devpriv->stc_writew(dev, 1, DAC_FIFO_Clear); + if (boardtype.reg_type & ni_reg_6xxx_mask) + ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); + + /* Load some data */ + n = a4l_buf_count(subd); + if (n == 0) + return 0; + + n /= sizeof(sampl_t); + if (n > boardtype.ao_fifo_depth) + n = boardtype.ao_fifo_depth; + + ni_ao_fifo_load(subd, n); + + return n; +} + +static void ni_ai_fifo_read(a4l_subd_t *subd, int n) +{ + a4l_dev_t *dev = subd->dev; + int i; + + if (boardtype.reg_type == ni_reg_611x) { + sampl_t data[2]; + u32 dl; + + for (i = 0; i < n / 2; i++) { + dl = ni_readl(ADC_FIFO_Data_611x); + /* This may get the hi/lo data in the wrong order */ + data[0] = (dl >> 16) & 0xffff; + data[1] = dl & 0xffff; + a4l_buf_put(subd, data, sizeof(sampl_t) * 2); + } + /* Check if there's a single sample stuck in the FIFO */ + if (n % 2) { + dl = ni_readl(ADC_FIFO_Data_611x); + data[0] = dl & 0xffff; + a4l_buf_put(subd, &data[0], sizeof(sampl_t)); + } + } else if (boardtype.reg_type == ni_reg_6143) { + sampl_t data[2]; + u32 dl; + + /* This just reads the FIFO assuming the data is + present, no checks on the FIFO status are performed */ + for (i = 0; i < n / 2; i++) { + dl = ni_readl(AIFIFO_Data_6143); + + data[0] = (dl >> 16) & 0xffff; + data[1] = dl & 0xffff; + a4l_buf_put(subd, data, sizeof(sampl_t) * 2); + } + if (n % 2) { + /* Assume there is a single sample stuck in the FIFO. + Get stranded sample into FIFO */ + ni_writel(0x01, AIFIFO_Control_6143); + dl = ni_readl(AIFIFO_Data_6143); + data[0] = (dl >> 16) & 0xffff; + a4l_buf_put(subd, &data[0], sizeof(sampl_t)); + } + } else { + if (n > sizeof(devpriv->ai_fifo_buffer) / + sizeof(devpriv->ai_fifo_buffer[0])) { + a4l_err(dev, + "ni_ai_fifo_read: " + "bug! ai_fifo_buffer too small"); + a4l_buf_evt(subd, A4L_BUF_ERROR); + return; + } + for (i = 0; i < n; i++) { + devpriv->ai_fifo_buffer[i] = + ni_readw(ADC_FIFO_Data_Register); + } + a4l_buf_put(subd, + devpriv->ai_fifo_buffer, + n * sizeof(devpriv->ai_fifo_buffer[0])); + } +} + +static void ni_handle_fifo_half_full(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + ni_ai_fifo_read(subd, boardtype.ai_fifo_depth / 2); +} + +#endif /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static int ni_ai_drain_dma(a4l_subd_t *subd) +{ + int i; + static const int timeout = 10000; + unsigned long flags; + int retval = 0; + a4l_dev_t *dev = subd->dev; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->ai_mite_chan) { + for (i = 0; i < timeout; i++) { + if ((devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St) + && mite_bytes_in_transit(devpriv-> + ai_mite_chan) == 0) + break; + a4l_udelay(5); + } + if (i == timeout) { + a4l_info(dev, + "ni_mio_common: " + "wait for dma drain timed out\n"); + + a4l_info(dev, + "mite_bytes_in_transit=%i, " + "AI_Status1_Register=0x%x\n", + mite_bytes_in_transit(devpriv->ai_mite_chan), + devpriv->stc_readw(dev, AI_Status_1_Register)); + retval = -1; + } + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + ni_sync_ai_dma(subd); + + return retval; +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +/* Empties the AI fifo */ +static void ni_handle_fifo_dregs(a4l_subd_t *subd) +{ + sampl_t data[2]; + u32 dl; + short fifo_empty; + int i; + a4l_dev_t *dev = subd->dev; + + if (boardtype.reg_type == ni_reg_611x) { + while ((devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St) == 0) { + dl = ni_readl(ADC_FIFO_Data_611x); + + /* This may get the hi/lo data in the wrong order */ + data[0] = (dl >> 16); + data[1] = (dl & 0xffff); + a4l_buf_put(subd, data, sizeof(sampl_t) * 2); + } + } else if (boardtype.reg_type == ni_reg_6143) { + i = 0; + while (ni_readl(AIFIFO_Status_6143) & 0x04) { + dl = ni_readl(AIFIFO_Data_6143); + + /* This may get the hi/lo data in the wrong order */ + data[0] = (dl >> 16); + data[1] = (dl & 0xffff); + a4l_buf_put(subd, data, sizeof(sampl_t) * 2); + i += 2; + } + // Check if stranded sample is present + if (ni_readl(AIFIFO_Status_6143) & 0x01) { + ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO + dl = ni_readl(AIFIFO_Data_6143); + data[0] = (dl >> 16) & 0xffff; + a4l_buf_put(subd, &data[0], sizeof(sampl_t)); + } + + } else { + fifo_empty = + devpriv->stc_readw(dev, + AI_Status_1_Register) & AI_FIFO_Empty_St; + while (fifo_empty == 0) { + for (i = 0; + i < + sizeof(devpriv->ai_fifo_buffer) / + sizeof(devpriv->ai_fifo_buffer[0]); i++) { + fifo_empty = + devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St; + if (fifo_empty) + break; + devpriv->ai_fifo_buffer[i] = + ni_readw(ADC_FIFO_Data_Register); + } + a4l_buf_put(subd, + devpriv->ai_fifo_buffer, + i * sizeof(devpriv->ai_fifo_buffer[0])); + } + } +} + +static void get_last_sample_611x(a4l_subd_t *subd) +{ + sampl_t data; + u32 dl; + a4l_dev_t *dev = subd->dev; + + if (boardtype.reg_type != ni_reg_611x) + return; + + /* Check if there's a single sample stuck in the FIFO */ + if (ni_readb(XXX_Status) & 0x80) { + dl = ni_readl(ADC_FIFO_Data_611x); + data = (dl & 0xffff); + a4l_buf_put(subd, &data, sizeof(sampl_t)); + } +} + +static void get_last_sample_6143(a4l_subd_t *subd) +{ + sampl_t data; + u32 dl; + a4l_dev_t *dev = subd->dev; + + if (boardtype.reg_type != ni_reg_6143) + return; + + /* Check if there's a single sample stuck in the FIFO */ + if (ni_readl(AIFIFO_Status_6143) & 0x01) { + /* Get stranded sample into FIFO */ + ni_writel(0x01, AIFIFO_Control_6143); + dl = ni_readl(AIFIFO_Data_6143); + + /* This may get the hi/lo data in the wrong order */ + data = (dl >> 16) & 0xffff; + a4l_buf_put(subd, &data, sizeof(sampl_t)); + } +} + +static void ni_ai_munge16(a4l_subd_t *subd, void *buf, unsigned long size) +{ + a4l_dev_t *dev = subd->dev; + a4l_cmd_t *cmd = a4l_get_cmd(subd); + int chan_idx = a4l_get_chan(subd); + unsigned int i; + sampl_t *array = buf; + + for (i = 0; i < size / sizeof(sampl_t); i++) { +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + array[i] = le16_to_cpu(array[i]); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + array[i] += devpriv->ai_offset[chan_idx]; + chan_idx++; + chan_idx %= cmd->nb_chan; + } +} + +static void ni_ai_munge32(a4l_subd_t *subd, void *buf, unsigned long size) +{ + a4l_dev_t *dev = subd->dev; + a4l_cmd_t *cmd = a4l_get_cmd(subd); + int chan_idx = a4l_get_chan(subd); + unsigned int i; + lsampl_t *larray = buf; + + for (i = 0; i < size / sizeof(lsampl_t); i++) { +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + larray[i] = le32_to_cpu(larray[i]); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + larray[i] += devpriv->ai_offset[chan_idx]; + chan_idx++; + chan_idx %= cmd->nb_chan; + } +} + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static int ni_ai_setup_MITE_dma(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + unsigned long flags; + int err; + + err = ni_request_ai_mite_channel(dev); + if (err < 0) + return err; + + err = mite_buf_change(devpriv->ai_mite_chan->ring, subd); + if (err < 0) + return err; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + + switch (boardtype.reg_type) { + case ni_reg_611x: + case ni_reg_6143: + mite_prep_dma(devpriv->ai_mite_chan, 32, 16); + break; + case ni_reg_628x: + mite_prep_dma(devpriv->ai_mite_chan, 32, 32); + break; + default: + mite_prep_dma(devpriv->ai_mite_chan, 16, 16); + break; + }; + + /* start the MITE */ + mite_dma_arm(devpriv->ai_mite_chan); + + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + return 0; +} + +static int ni_ao_setup_MITE_dma(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + unsigned long flags; + int err; + + err = ni_request_ao_mite_channel(dev); + if (err < 0) + return err; + + err = mite_buf_change(devpriv->ao_mite_chan->ring, subd); + if (err < 0) + return err; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + + if (devpriv->ao_mite_chan) { + + if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) { + mite_prep_dma(devpriv->ao_mite_chan, 32, 32); + } else { + /* Doing 32 instead of 16 bit wide transfers + from memory makes the mite do 32 bit pci + transfers, doubling pci bandwidth. */ + mite_prep_dma(devpriv->ao_mite_chan, 16, 32); + } + mite_dma_arm(devpriv->ao_mite_chan); + } else + err = -EIO; + + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + return err; +} + +static int ni_cdo_setup_MITE_dma(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + unsigned long flags; + int err; + + err = ni_request_cdo_mite_channel(dev); + if (err < 0) + return err; + + /* No need to get a lock to setup the ring buffer */ + err = mite_buf_change(devpriv->cdo_mite_chan->ring, subd); + if (err < 0) + return err; + + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + + /* This test should be useless but one never knows */ + if (devpriv->cdo_mite_chan) { + /* Configure the DMA transfer */ + mite_prep_dma(devpriv->cdo_mite_chan, 32, 32); + mite_dma_arm(devpriv->cdo_mite_chan); + } else + err = -EIO; + + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + return err; +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +static int ni_ai_reset(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + + ni_release_ai_mite_channel(dev); + + /* ai configuration */ + devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset, + Joint_Reset_Register); + + ni_set_bits(dev, Interrupt_A_Enable_Register, + AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable | + AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable | + AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable | + AI_FIFO_Interrupt_Enable, 0); + + ni_clear_ai_fifo(dev); + + if (boardtype.reg_type != ni_reg_6143) + ni_writeb(0, Misc_Command); + + devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */ + devpriv->stc_writew(dev, + AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */ , + AI_Mode_1_Register); + devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register); + /* generate FIFO interrupts on non-empty */ + devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register); + if (boardtype.reg_type == ni_reg_611x) { + devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width | + AI_SOC_Polarity | + AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register); + devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) | + AI_EXTMUX_CLK_Output_Select(0) | + AI_LOCALMUX_CLK_Output_Select(2) | + AI_SC_TC_Output_Select(3) | + AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_High), + AI_Output_Control_Register); + } else if (boardtype.reg_type == ni_reg_6143) { + devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width | + AI_SOC_Polarity | + AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register); + devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) | + AI_EXTMUX_CLK_Output_Select(0) | + AI_LOCALMUX_CLK_Output_Select(2) | + AI_SC_TC_Output_Select(3) | + AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_Low), + AI_Output_Control_Register); + } else { + unsigned int ai_output_control_bits; + devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width | + AI_SOC_Polarity | + AI_CONVERT_Pulse_Width | + AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register); + ai_output_control_bits = AI_SCAN_IN_PROG_Output_Select(3) | + AI_EXTMUX_CLK_Output_Select(0) | + AI_LOCALMUX_CLK_Output_Select(2) | + AI_SC_TC_Output_Select(3); + if (boardtype.reg_type == ni_reg_622x) + ai_output_control_bits |= + AI_CONVERT_Output_Select + (AI_CONVERT_Output_Enable_High); + else + ai_output_control_bits |= + AI_CONVERT_Output_Select + (AI_CONVERT_Output_Enable_Low); + devpriv->stc_writew(dev, ai_output_control_bits, + AI_Output_Control_Register); + } + + /* the following registers should not be changed, because there + * are no backup registers in devpriv. If you want to change + * any of these, add a backup register and other appropriate code: + * AI_Mode_1_Register + * AI_Mode_3_Register + * AI_Personal_Register + * AI_Output_Control_Register + */ + + /* clear interrupts */ + devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | + AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | + AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | + AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); + + devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register); + + return 0; +} + +static int ni_ai_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + const unsigned int mask = (1 << boardtype.adbits) - 1; + int i, n; + unsigned int signbits; + unsigned short d; + unsigned long dl; + uint16_t *data = (uint16_t *)insn->data; + + ni_load_channelgain_list(dev, 1, &insn->chan_desc); + + ni_clear_ai_fifo(dev); + + signbits = devpriv->ai_offset[0]; + if (boardtype.reg_type == ni_reg_611x) { + for (n = 0; n < num_adc_stages_611x; n++) { + devpriv->stc_writew(dev, AI_CONVERT_Pulse, + AI_Command_1_Register); + a4l_udelay(1); + } + for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) { + devpriv->stc_writew(dev, AI_CONVERT_Pulse, + AI_Command_1_Register); + /* The 611x has screwy 32-bit FIFOs. */ + d = 0; + for (i = 0; i < NI_TIMEOUT; i++) { + if (ni_readb(XXX_Status) & 0x80) { + d = (ni_readl(ADC_FIFO_Data_611x) >> 16) + & 0xffff; + break; + } + if (!(devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St)) { + d = ni_readl(ADC_FIFO_Data_611x) & + 0xffff; + break; + } + } + if (i == NI_TIMEOUT) { + a4l_warn(dev, + "ni_mio_common: " + "timeout in 611x ni_ai_insn_read\n"); + return -ETIME; + } + d += signbits; + data[n] = d; + } + } else if (boardtype.reg_type == ni_reg_6143) { + for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) { + devpriv->stc_writew(dev, AI_CONVERT_Pulse, + AI_Command_1_Register); + + /* The 6143 has 32-bit FIFOs. + You need to strobe a bit to move a single + 16bit stranded sample into the FIFO */ + dl = 0; + for (i = 0; i < NI_TIMEOUT; i++) { + if (ni_readl(AIFIFO_Status_6143) & 0x01) { + ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO + dl = ni_readl(AIFIFO_Data_6143); + break; + } + } + if (i == NI_TIMEOUT) { + a4l_warn(dev, + "ni_mio_common: " + "timeout in 6143 ni_ai_insn_read\n"); + return -ETIME; + } + data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF; + } + } else { + for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) { + devpriv->stc_writew(dev, AI_CONVERT_Pulse, + AI_Command_1_Register); + for (i = 0; i < NI_TIMEOUT; i++) { + if (!(devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St)) + break; + } + if (i == NI_TIMEOUT) { + a4l_warn(dev, + "ni_mio_common: " + "timeout in ni_ai_insn_read\n"); + return -ETIME; + } + if (boardtype.reg_type & ni_reg_m_series_mask) { + data[n] = ni_readl(M_Offset_AI_FIFO_Data) & mask; + } else { + d = ni_readw(ADC_FIFO_Data_Register); + /* subtle: needs to be short addition */ + d += signbits; + data[n] = d; + } + } + } + return 0; +} + +void ni_prime_channelgain_list(a4l_dev_t *dev) +{ + int i; + devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); + for (i = 0; i < NI_TIMEOUT; ++i) { + if (!(devpriv->stc_readw(dev, + AI_Status_1_Register) & + AI_FIFO_Empty_St)) { + devpriv->stc_writew(dev, 1, ADC_FIFO_Clear); + return; + } + a4l_udelay(1); + } + a4l_warn(dev, "ni_mio_common: timeout loading channel/gain list\n"); +} + +static void ni_m_series_load_channelgain_list(a4l_dev_t *dev, + unsigned int n_chan, + unsigned int *list) +{ + unsigned int chan, range, aref; + unsigned int i; + unsigned offset; + unsigned int dither; + unsigned range_code; + + devpriv->stc_writew(dev, 1, Configuration_Memory_Clear); + + if ((list[0] & CR_ALT_SOURCE)) { + unsigned bypass_bits; + chan = CR_CHAN(list[0]); + range = CR_RNG(list[0]); + range_code = ni_gainlkup[boardtype.gainlkup][range]; + dither = ((list[0] & CR_ALT_FILTER) != 0); + bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit; + bypass_bits |= chan; + bypass_bits |= + (devpriv-> + ai_calib_source) & (MSeries_AI_Bypass_Cal_Sel_Pos_Mask | + MSeries_AI_Bypass_Cal_Sel_Neg_Mask | + MSeries_AI_Bypass_Mode_Mux_Mask | + MSeries_AO_Bypass_AO_Cal_Sel_Mask); + bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code); + if (dither) + bypass_bits |= MSeries_AI_Bypass_Dither_Bit; + // don't use 2's complement encoding + bypass_bits |= MSeries_AI_Bypass_Polarity_Bit; + ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass); + } else { + ni_writel(0, M_Offset_AI_Config_FIFO_Bypass); + } + offset = 0; + for (i = 0; i < n_chan; i++) { + unsigned config_bits = 0; + chan = CR_CHAN(list[i]); + aref = CR_AREF(list[i]); + range = CR_RNG(list[i]); + dither = ((list[i] & CR_ALT_FILTER) != 0); + + range_code = ni_gainlkup[boardtype.gainlkup][range]; + devpriv->ai_offset[i] = offset; + switch (aref) { + case AREF_DIFF: + config_bits |= + MSeries_AI_Config_Channel_Type_Differential_Bits; + break; + case AREF_COMMON: + config_bits |= + MSeries_AI_Config_Channel_Type_Common_Ref_Bits; + break; + case AREF_GROUND: + config_bits |= + MSeries_AI_Config_Channel_Type_Ground_Ref_Bits; + break; + case AREF_OTHER: + break; + } + config_bits |= MSeries_AI_Config_Channel_Bits(chan); + config_bits |= + MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan); + config_bits |= MSeries_AI_Config_Gain_Bits(range_code); + if (i == n_chan - 1) + config_bits |= MSeries_AI_Config_Last_Channel_Bit; + if (dither) + config_bits |= MSeries_AI_Config_Dither_Bit; + // don't use 2's complement encoding + config_bits |= MSeries_AI_Config_Polarity_Bit; + ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data); + } + ni_prime_channelgain_list(dev); +} + +/* + * Notes on the 6110 and 6111: + * These boards a slightly different than the rest of the series, since + * they have multiple A/D converters. + * From the driver side, the configuration memory is a + * little different. + * Configuration Memory Low: + * bits 15-9: same + * bit 8: unipolar/bipolar (should be 0 for bipolar) + * bits 0-3: gain. This is 4 bits instead of 3 for the other boards + * 1001 gain=0.1 (+/- 50) + * 1010 0.2 + * 1011 0.1 + * 0001 1 + * 0010 2 + * 0011 5 + * 0100 10 + * 0101 20 + * 0110 50 + * Configuration Memory High: + * bits 12-14: Channel Type + * 001 for differential + * 000 for calibration + * bit 11: coupling (this is not currently handled) + * 1 AC coupling + * 0 DC coupling + * bits 0-2: channel + * valid channels are 0-3 + */ +static void ni_load_channelgain_list(a4l_dev_t *dev, + unsigned int n_chan, unsigned int *list) +{ + unsigned int chan, range, aref; + unsigned int i; + unsigned int hi, lo; + unsigned offset; + unsigned int dither; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + ni_m_series_load_channelgain_list(dev, n_chan, list); + return; + } + if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x) + && (boardtype.reg_type != ni_reg_6143)) { + if (devpriv->changain_state + && devpriv->changain_spec == list[0]) { + /* ready to go. */ + return; + } + devpriv->changain_state = 1; + devpriv->changain_spec = list[0]; + } else { + devpriv->changain_state = 0; + } + + devpriv->stc_writew(dev, 1, Configuration_Memory_Clear); + + /* Set up Calibration mode if required */ + if (boardtype.reg_type == ni_reg_6143) { + if ((list[0] & CR_ALT_SOURCE) + && !devpriv->ai_calib_source_enabled) { + /* Strobe Relay enable bit */ + ni_writew(devpriv-> + ai_calib_source | + Calibration_Channel_6143_RelayOn, + Calibration_Channel_6143); + ni_writew(devpriv->ai_calib_source, + Calibration_Channel_6143); + devpriv->ai_calib_source_enabled = 1; + /* Allow relays to change */ + if(a4l_test_rt()) + a4l_task_sleep(100*1000000); + else + msleep_interruptible(100); + } else if (!(list[0] & CR_ALT_SOURCE) + && devpriv->ai_calib_source_enabled) { + /* Strobe Relay disable bit */ + ni_writew(devpriv-> + ai_calib_source | + Calibration_Channel_6143_RelayOff, + Calibration_Channel_6143); + ni_writew(devpriv->ai_calib_source, + Calibration_Channel_6143); + devpriv->ai_calib_source_enabled = 0; + /* Allow relays to change */ + if(a4l_test_rt()) + a4l_task_sleep(100*1000000); + else + msleep_interruptible(100); + } + } + + offset = 1 << (boardtype.adbits - 1); + for (i = 0; i < n_chan; i++) { + if ((boardtype.reg_type != ni_reg_6143) + && (list[i] & CR_ALT_SOURCE)) { + chan = devpriv->ai_calib_source; + } else { + chan = CR_CHAN(list[i]); + } + aref = CR_AREF(list[i]); + range = CR_RNG(list[i]); + dither = ((list[i] & CR_ALT_FILTER) != 0); + + /* fix the external/internal range differences */ + range = ni_gainlkup[boardtype.gainlkup][range]; + if (boardtype.reg_type == ni_reg_611x) + devpriv->ai_offset[i] = offset; + else + devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset; + + hi = 0; + if ((list[i] & CR_ALT_SOURCE)) { + if (boardtype.reg_type == ni_reg_611x) + ni_writew(CR_CHAN(list[i]) & 0x0003, + Calibration_Channel_Select_611x); + } else { + if (boardtype.reg_type == ni_reg_611x) + aref = AREF_DIFF; + else if (boardtype.reg_type == ni_reg_6143) + aref = AREF_OTHER; + switch (aref) { + case AREF_DIFF: + hi |= AI_DIFFERENTIAL; + break; + case AREF_COMMON: + hi |= AI_COMMON; + break; + case AREF_GROUND: + hi |= AI_GROUND; + break; + case AREF_OTHER: + break; + } + } + hi |= AI_CONFIG_CHANNEL(chan); + + ni_writew(hi, Configuration_Memory_High); + + if (boardtype.reg_type != ni_reg_6143) { + lo = range; + if (i == n_chan - 1) + lo |= AI_LAST_CHANNEL; + if (dither) + lo |= AI_DITHER; + + ni_writew(lo, Configuration_Memory_Low); + } + } + + /* prime the channel/gain list */ + if ((boardtype.reg_type != ni_reg_611x) + && (boardtype.reg_type != ni_reg_6143)) { + ni_prime_channelgain_list(dev); + } +} + +static int ni_ns_to_timer(const a4l_dev_t *dev, + unsigned int nanosec, int round_mode) +{ + int divider; + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns; + break; + case TRIG_ROUND_DOWN: + divider = (nanosec) / devpriv->clock_ns; + break; + case TRIG_ROUND_UP: + divider = (nanosec + devpriv->clock_ns - 1) / devpriv->clock_ns; + break; + } + return divider - 1; +} + +static unsigned int ni_timer_to_ns(const a4l_dev_t *dev, int timer) +{ + return devpriv->clock_ns * (timer + 1); +} + +static unsigned int ni_min_ai_scan_period_ns(a4l_dev_t *dev, + unsigned int num_channels) +{ + switch (boardtype.reg_type) { + case ni_reg_611x: + case ni_reg_6143: + /* simultaneously-sampled inputs */ + return boardtype.ai_speed; + break; + default: + /* multiplexed inputs */ + break; + }; + return boardtype.ai_speed * num_channels; +} + +static a4l_cmd_t mio_ai_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_NOW | TRIG_INT | TRIG_EXT, + .scan_begin_src = TRIG_TIMER | TRIG_EXT, + .convert_src = TRIG_TIMER | TRIG_EXT | TRIG_NOW, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_COUNT | TRIG_NONE, +}; + +int ni_ai_inttrig(a4l_subd_t *subd, lsampl_t trignum) +{ + a4l_dev_t *dev = subd->dev; + + if (trignum != 0) + return -EINVAL; + + devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2, + AI_Command_2_Register); + + return 1; +} + +static int ni_ai_cmdtest(a4l_subd_t *subd, a4l_cmd_t * cmd) +{ + a4l_dev_t *dev = subd->dev; + int tmp; + + /* Make sure trigger sources are trivially valid */ + + if ((boardtype.reg_type != ni_reg_611x) && + (boardtype.reg_type != ni_reg_6143) && + (boardtype.reg_type != ni_reg_622x) && + (cmd->scan_begin_src == TRIG_NOW)) + return -EINVAL; + + /* Make sure arguments are trivially compatible */ + + if (cmd->start_src == TRIG_EXT) { + /* external trigger */ + unsigned int tmp = CR_CHAN(cmd->start_arg); + + if (tmp > 16) + tmp = 16; + tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE)); + if (cmd->start_arg != tmp) { + cmd->start_arg = tmp; + return -EINVAL; + } + } else { + if (cmd->start_arg != 0) { + /* true for both TRIG_NOW and TRIG_INT */ + cmd->start_arg = 0; + return -EINVAL; + } + } + if (cmd->scan_begin_src == TRIG_TIMER) { + if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev, + cmd->nb_chan)) { + cmd->scan_begin_arg = + ni_min_ai_scan_period_ns(dev, cmd->nb_chan); + return -EINVAL; + } + if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { + cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; + return -EINVAL; + } + } else if (cmd->scan_begin_src == TRIG_EXT) { + /* external trigger */ + unsigned int tmp = CR_CHAN(cmd->scan_begin_arg); + + if (tmp > 16) + tmp = 16; + tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE)); + if (cmd->scan_begin_arg != tmp) { + cmd->scan_begin_arg = tmp; + return -EINVAL; + } + } else { /* TRIG_OTHER */ + if (cmd->scan_begin_arg) { + cmd->scan_begin_arg = 0; + return -EINVAL; + } + } + if (cmd->convert_src == TRIG_TIMER) { + if ((boardtype.reg_type == ni_reg_611x) + || (boardtype.reg_type == ni_reg_6143)) { + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + return -EINVAL; + } + } else { + if (cmd->convert_arg < boardtype.ai_speed) { + cmd->convert_arg = boardtype.ai_speed; + return -EINVAL; + } + if (cmd->convert_arg > devpriv->clock_ns * 0xffff) { + cmd->convert_arg = devpriv->clock_ns * 0xffff; + return -EINVAL; + } + } + } else if (cmd->convert_src == TRIG_EXT) { + /* external trigger */ + unsigned int tmp = CR_CHAN(cmd->convert_arg); + + if (tmp > 16) + tmp = 16; + tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT)); + if (cmd->convert_arg != tmp) { + cmd->convert_arg = tmp; + return -EINVAL; + } + } else if (cmd->convert_src == TRIG_NOW) { + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + return -EINVAL; + } + } + + if (cmd->scan_end_arg != cmd->nb_chan) { + cmd->scan_end_arg = cmd->nb_chan; + return -EINVAL; + } + if (cmd->stop_src == TRIG_COUNT) { + unsigned int max_count = 0x01000000; + + if (boardtype.reg_type == ni_reg_611x) + max_count -= num_adc_stages_611x; + if (cmd->stop_arg > max_count) { + cmd->stop_arg = max_count; + return -EINVAL; + } + if (cmd->stop_arg < 1) { + cmd->stop_arg = 1; + return -EINVAL; + } + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + return -EINVAL; + } + } + + /* step 4: fix up any arguments */ + + if (cmd->scan_begin_src == TRIG_TIMER) { + tmp = cmd->scan_begin_arg; + cmd->scan_begin_arg = + ni_timer_to_ns(dev, ni_ns_to_timer(dev, + cmd->scan_begin_arg, + cmd->flags & TRIG_ROUND_MASK)); + if (tmp != cmd->scan_begin_arg) + return -EINVAL; + } + if (cmd->convert_src == TRIG_TIMER) { + if ((boardtype.reg_type != ni_reg_611x) + && (boardtype.reg_type != ni_reg_6143)) { + tmp = cmd->convert_arg; + cmd->convert_arg = + ni_timer_to_ns(dev, ni_ns_to_timer(dev, + cmd->convert_arg, + cmd->flags & TRIG_ROUND_MASK)); + if (tmp != cmd->convert_arg) + return -EINVAL; + if (cmd->scan_begin_src == TRIG_TIMER && + cmd->scan_begin_arg < + cmd->convert_arg * cmd->scan_end_arg) { + cmd->scan_begin_arg = + cmd->convert_arg * cmd->scan_end_arg; + return -EINVAL; + } + } + } + + return 0; +} + +static int ni_ai_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_dev_t *dev = subd->dev; + int timer; + int mode1 = 0; /* mode1 is needed for both stop and convert */ + int mode2 = 0; + int start_stop_select = 0; + unsigned int stop_count; + int interrupt_a_enable = 0; + + a4l_info(dev, "ni_ai_cmd: start\n"); + + if (a4l_get_irq(dev) == A4L_IRQ_UNUSED) { + a4l_err(dev, "ni_ai_cmd: cannot run command without an irq"); + return -EIO; + } + ni_clear_ai_fifo(dev); + + ni_load_channelgain_list(dev, cmd->nb_chan, cmd->chan_descs); + + /* start configuration */ + devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register); + + /* disable analog triggering for now, since it + * interferes with the use of pfi0 */ + devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable; + devpriv->stc_writew(dev, devpriv->an_trig_etc_reg, + Analog_Trigger_Etc_Register); + + switch (cmd->start_src) { + case TRIG_INT: + case TRIG_NOW: + devpriv->stc_writew(dev, AI_START2_Select(0) | + AI_START1_Sync | AI_START1_Edge | AI_START1_Select(0), + AI_Trigger_Select_Register); + break; + case TRIG_EXT: + { + int chan = CR_CHAN(cmd->start_arg); + unsigned int bits = AI_START2_Select(0) | + AI_START1_Sync | AI_START1_Select(chan + 1); + + if (cmd->start_arg & CR_INVERT) + bits |= AI_START1_Polarity; + if (cmd->start_arg & CR_EDGE) + bits |= AI_START1_Edge; + devpriv->stc_writew(dev, bits, + AI_Trigger_Select_Register); + break; + } + } + + mode2 &= ~AI_Pre_Trigger; + mode2 &= ~AI_SC_Initial_Load_Source; + mode2 &= ~AI_SC_Reload_Mode; + devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); + + if (cmd->nb_chan == 1 || (boardtype.reg_type == ni_reg_611x) + || (boardtype.reg_type == ni_reg_6143)) { + start_stop_select |= AI_STOP_Polarity; + start_stop_select |= AI_STOP_Select(31);/* logic low */ + start_stop_select |= AI_STOP_Sync; + } else { + start_stop_select |= AI_STOP_Select(19);/* ai configuration memory */ + } + devpriv->stc_writew(dev, start_stop_select, + AI_START_STOP_Select_Register); + + devpriv->ai_cmd2 = 0; + switch (cmd->stop_src) { + case TRIG_COUNT: + stop_count = cmd->stop_arg - 1; + + if (boardtype.reg_type == ni_reg_611x) { + /* have to take 3 stage adc pipeline into account */ + stop_count += num_adc_stages_611x; + } + /* stage number of scans */ + devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers); + + mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once; + devpriv->stc_writew(dev, mode1, AI_Mode_1_Register); + /* load SC (Scan Count) */ + devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register); + + devpriv->ai_continuous = 0; + if (stop_count == 0) { + devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan; + interrupt_a_enable |= AI_STOP_Interrupt_Enable; + /* this is required to get the last sample + for nb_chan > 1, not sure why */ + if (cmd->nb_chan > 1) + start_stop_select |= + AI_STOP_Polarity | AI_STOP_Edge; + } + break; + case TRIG_NONE: + /* stage number of scans */ + devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers); + + mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous; + devpriv->stc_writew(dev, mode1, AI_Mode_1_Register); + + /* load SC (Scan Count) */ + devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register); + + devpriv->ai_continuous = 1; + + break; + } + + switch (cmd->scan_begin_src) { + case TRIG_TIMER: + /* + stop bits for non 611x boards + AI_SI_Special_Trigger_Delay=0 + AI_Pre_Trigger=0 + AI_START_STOP_Select_Register: + AI_START_Polarity=0 (?) rising edge + AI_START_Edge=1 edge triggered + AI_START_Sync=1 (?) + AI_START_Select=0 SI_TC + AI_STOP_Polarity=0 rising edge + AI_STOP_Edge=0 level + AI_STOP_Sync=1 + AI_STOP_Select=19 external pin (configuration mem) + */ + start_stop_select |= AI_START_Edge | AI_START_Sync; + devpriv->stc_writew(dev, start_stop_select, + AI_START_STOP_Select_Register); + + mode2 |= AI_SI_Reload_Mode(0); + /* AI_SI_Initial_Load_Source=A */ + mode2 &= ~AI_SI_Initial_Load_Source; + + devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); + + /* load SI */ + timer = ni_ns_to_timer(dev, cmd->scan_begin_arg, + TRIG_ROUND_NEAREST); + devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers); + devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register); + break; + case TRIG_EXT: + if (cmd->scan_begin_arg & CR_EDGE) + start_stop_select |= AI_START_Edge; + /* AI_START_Polarity==1 is falling edge */ + if (cmd->scan_begin_arg & CR_INVERT) + start_stop_select |= AI_START_Polarity; + if (cmd->scan_begin_src != cmd->convert_src || + (cmd->scan_begin_arg & ~CR_EDGE) != + (cmd->convert_arg & ~CR_EDGE)) + start_stop_select |= AI_START_Sync; + start_stop_select |= + AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg)); + devpriv->stc_writew(dev, start_stop_select, + AI_START_STOP_Select_Register); + break; + } + + switch (cmd->convert_src) { + case TRIG_TIMER: + case TRIG_NOW: + if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW) + timer = 1; + else + timer = ni_ns_to_timer(dev, cmd->convert_arg, + TRIG_ROUND_NEAREST); + devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */ + devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register); + + /* AI_SI2_Reload_Mode = alternate */ + /* AI_SI2_Initial_Load_Source = A */ + mode2 &= ~AI_SI2_Initial_Load_Source; + mode2 |= AI_SI2_Reload_Mode; + devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); + + /* AI_SI2_Load */ + devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register); + + mode2 |= AI_SI2_Reload_Mode; /* alternate */ + mode2 |= AI_SI2_Initial_Load_Source; /* B */ + + devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); + break; + case TRIG_EXT: + mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg); + if ((cmd->convert_arg & CR_INVERT) == 0) + mode1 |= AI_CONVERT_Source_Polarity; + devpriv->stc_writew(dev, mode1, AI_Mode_1_Register); + + mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable; + devpriv->stc_writew(dev, mode2, AI_Mode_2_Register); + + break; + } + + if (a4l_get_irq(dev) != A4L_IRQ_UNUSED) { + + /* interrupt on FIFO, errors, SC_TC */ + interrupt_a_enable |= AI_Error_Interrupt_Enable | + AI_SC_TC_Interrupt_Enable; + +#if (!defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) && \ + !defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + interrupt_a_enable |= AI_FIFO_Interrupt_Enable; +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + if (cmd->flags & TRIG_WAKE_EOS + || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) { + /* wake on end-of-scan */ + devpriv->aimode = AIMODE_SCAN; + } else { + devpriv->aimode = AIMODE_HALF_FULL; + } + + switch (devpriv->aimode) { + case AIMODE_HALF_FULL: + /* generate FIFO interrupts and DMA requests on half-full */ +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E, + AI_Mode_3_Register); +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + devpriv->stc_writew(dev, AI_FIFO_Mode_HF, + AI_Mode_3_Register); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + break; + case AIMODE_SAMPLE: + /* generate FIFO interrupts on non-empty */ + devpriv->stc_writew(dev, AI_FIFO_Mode_NE, + AI_Mode_3_Register); + break; + case AIMODE_SCAN: +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + devpriv->stc_writew(dev, AI_FIFO_Mode_NE, + AI_Mode_3_Register); +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + devpriv->stc_writew(dev, AI_FIFO_Mode_HF, + AI_Mode_3_Register); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + interrupt_a_enable |= AI_STOP_Interrupt_Enable; + break; + default: + break; + } + + /* Clear interrupts */ + devpriv->stc_writew(dev, + AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | + AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | + AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | + AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */ + + ni_set_bits(dev, Interrupt_A_Enable_Register, + interrupt_a_enable, 1); + + a4l_info(dev, + "ni_ai_cmd: Interrupt_A_Enable_Register = 0x%04x\n", + devpriv->int_a_enable_reg); + } else { + /* interrupt on nothing */ + ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0); + + /* XXX start polling if necessary */ + a4l_warn(dev, "ni_ai_cmd: interrupting on nothing\n"); + } + + /* end configuration */ + devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register); + + switch (cmd->scan_begin_src) { + case TRIG_TIMER: + devpriv->stc_writew(dev, + AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm, + AI_Command_1_Register); + break; + case TRIG_EXT: + /* XXX AI_SI_Arm? */ + devpriv->stc_writew(dev, + AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm, + AI_Command_1_Register); + break; + } + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + { + int retval = ni_ai_setup_MITE_dma(subd); + if (retval) + return retval; + } + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + switch (cmd->start_src) { + case TRIG_NOW: + /* AI_START1_Pulse */ + devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2, + AI_Command_2_Register); + break; + case TRIG_EXT: + /* TODO: set trigger callback field to NULL */ + break; + case TRIG_INT: + /* TODO: set trigger callback field to ni_ai_inttrig */ + break; + } + + a4l_info(dev, "ni_ai_cmd: exit\n"); + + return 0; +} + +int ni_ai_config_analog_trig(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int a, b, modebits; + int err = 0; + uint32_t *data = (uint32_t *)insn->data; + + /* data[1] is flags + * data[2] is analog line + * data[3] is set level + * data[4] is reset level */ + if (!boardtype.has_analog_trig) + return -EINVAL; + + if ((data[1] & 0xffff0000) != A4L_EV_SCAN_BEGIN) { + data[1] &= (A4L_EV_SCAN_BEGIN | 0xffff); + err++; + } + if (data[2] >= boardtype.n_adchan) { + data[2] = boardtype.n_adchan - 1; + err++; + } + if (data[3] > 255) { /* a */ + data[3] = 255; + err++; + } + if (data[4] > 255) { /* b */ + data[4] = 255; + err++; + } + /* + * 00 ignore + * 01 set + * 10 reset + * + * modes: + * 1 level: +b- +a- + * high mode 00 00 01 10 + * low mode 00 00 10 01 + * 2 level: (a> 4); + } + devpriv->atrig_low = a; + devpriv->atrig_high = b; + switch (modebits) { + case 0x81: /* low hysteresis mode */ + devpriv->atrig_mode = 6; + break; + case 0x42: /* high hysteresis mode */ + devpriv->atrig_mode = 3; + break; + case 0x96: /* middle window mode */ + devpriv->atrig_mode = 2; + break; + default: + data[1] &= ~0xff; + err++; + } + } else { + /* one level mode */ + if (b != 0) { + data[4] = 0; + err++; + } + switch (modebits) { + case 0x06: /* high window mode */ + devpriv->atrig_high = a; + devpriv->atrig_mode = 0; + break; + case 0x09: /* low window mode */ + devpriv->atrig_low = a; + devpriv->atrig_mode = 1; + break; + default: + data[1] &= ~0xff; + err++; + } + } + + if (err) + return -EAGAIN; + + return 0; +} + +int ni_ai_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int *)insn->data; + + if (insn->data_size < sizeof(unsigned int)) + return -EINVAL; + + switch (data[0]) { + case A4L_INSN_CONFIG_ANALOG_TRIG: + return ni_ai_config_analog_trig(subd, insn); + case A4L_INSN_CONFIG_ALT_SOURCE: + if (boardtype.reg_type & ni_reg_m_series_mask) { + if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask | + MSeries_AI_Bypass_Cal_Sel_Neg_Mask | + MSeries_AI_Bypass_Mode_Mux_Mask | + MSeries_AO_Bypass_AO_Cal_Sel_Mask)) { + return -EINVAL; + } + devpriv->ai_calib_source = data[1]; + } else if (boardtype.reg_type == ni_reg_6143) { + unsigned int calib_source; + + calib_source = data[1] & 0xf; + + if (calib_source > 0xF) + return -EINVAL; + + devpriv->ai_calib_source = calib_source; + ni_writew(calib_source, Calibration_Channel_6143); + } else { + unsigned int calib_source; + unsigned int calib_source_adjust; + + calib_source = data[1] & 0xf; + calib_source_adjust = (data[1] >> 4) & 0xff; + + if (calib_source >= 8) + return -EINVAL; + devpriv->ai_calib_source = calib_source; + if (boardtype.reg_type == ni_reg_611x) { + ni_writeb(calib_source_adjust, + Cal_Gain_Select_611x); + } + } + return 0; + default: + break; + } + + return -EINVAL; +} + +/* munge data from unsigned to 2's complement for analog output bipolar modes */ +static void ni_ao_munge(a4l_subd_t *subd, void *buf, unsigned long size) +{ + a4l_dev_t *dev = subd->dev; + a4l_cmd_t *cmd = a4l_get_cmd(subd); + int chan_idx = a4l_get_chan(subd); + uint16_t *array = buf; + unsigned int i, range, offset; + + offset = 1 << (boardtype.aobits - 1); + for (i = 0; i < size / sizeof(uint16_t); i++) { + + range = CR_RNG(cmd->chan_descs[chan_idx]); + if (boardtype.ao_unipolar == 0 || (range & 1) == 0) + array[i] -= offset; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + array[i] = cpu_to_le16(array[i]); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + chan_idx++; + chan_idx %= cmd->nb_chan; + } +} + +static int ni_m_series_ao_config_chan_descs(a4l_subd_t *subd, + unsigned int chanspec[], + unsigned int n_chans, int timed) +{ + unsigned int range; + unsigned int chan; + unsigned int conf; + int i, invert = 0; + a4l_dev_t *dev = subd->dev; + + for (i = 0; i < boardtype.n_aochan; ++i) { + ni_writeb(0xf, M_Offset_AO_Waveform_Order(i)); + } + for (i = 0; i < n_chans; i++) { + a4l_rng_t *rng; + int idx; + chan = CR_CHAN(chanspec[i]); + range = CR_RNG(chanspec[i]); + + /* TODO: this a huge hack! + Something is missing in the kernel API. We must + allow access on the proper range descriptor */ + idx = (subd->rng_desc->mode != + A4L_RNG_GLOBAL_RNGDESC) ? chan : 0; + rng = &(subd->rng_desc->rngtabs[idx]->rngs[range]); + + invert = 0; + conf = 0; + switch (rng->max - rng->min) { + case 20000000: + conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits; + ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan)); + break; + case 10000000: + conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits; + ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan)); + break; + case 4000000: + conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits; + ni_writeb(MSeries_Attenuate_x5_Bit, + M_Offset_AO_Reference_Attenuation(chan)); + break; + case 2000000: + conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits; + ni_writeb(MSeries_Attenuate_x5_Bit, + M_Offset_AO_Reference_Attenuation(chan)); + break; + default: + a4l_err(subd->dev, + "%s: bug! unhandled ao reference voltage\n", + __FUNCTION__); + break; + } + switch (rng->max + rng->min) { + case 0: + conf |= MSeries_AO_DAC_Offset_0V_Bits; + break; + case 10000000: + conf |= MSeries_AO_DAC_Offset_5V_Bits; + break; + default: + a4l_err(subd->dev, + "%s: bug! unhandled ao offset voltage\n", + __FUNCTION__); + break; + } + if (timed) + conf |= MSeries_AO_Update_Timed_Bit; + ni_writeb(conf, M_Offset_AO_Config_Bank(chan)); + devpriv->ao_conf[chan] = conf; + ni_writeb(i, M_Offset_AO_Waveform_Order(chan)); + } + return invert; +} + +static int ni_old_ao_config_chan_descs(a4l_subd_t *subd, + unsigned int chanspec[], + unsigned int n_chans) +{ + a4l_dev_t *dev = subd->dev; + unsigned int range; + unsigned int chan; + unsigned int conf; + int i, invert = 0; + + for (i = 0; i < n_chans; i++) { + chan = CR_CHAN(chanspec[i]); + range = CR_RNG(chanspec[i]); + conf = AO_Channel(chan); + + if (boardtype.ao_unipolar) { + if ((range & 1) == 0) { + conf |= AO_Bipolar; + invert = (1 << (boardtype.aobits - 1)); + } else { + invert = 0; + } + if (range & 2) + conf |= AO_Ext_Ref; + } else { + conf |= AO_Bipolar; + invert = (1 << (boardtype.aobits - 1)); + } + + /* not all boards can deglitch, but this shouldn't hurt */ + if (chanspec[i] & CR_DEGLITCH) + conf |= AO_Deglitch; + + /* analog reference */ + /* AREF_OTHER connects AO ground to AI ground, i think */ + conf |= (CR_AREF(chanspec[i]) == + AREF_OTHER) ? AO_Ground_Ref : 0; + + ni_writew(conf, AO_Configuration); + devpriv->ao_conf[chan] = conf; + } + return invert; +} + +static int ni_ao_config_chan_descs(a4l_subd_t *subd, + unsigned int chanspec[], + unsigned int n_chans, int timed) +{ + a4l_dev_t *dev = subd->dev; + + if (boardtype.reg_type & ni_reg_m_series_mask) + return ni_m_series_ao_config_chan_descs(subd, + chanspec, + n_chans, timed); + else + return ni_old_ao_config_chan_descs(subd, chanspec, n_chans); +} + +int ni_ao_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint16_t *data = (uint16_t *)insn->data; + + data[0] = devpriv->ao[CR_CHAN(insn->chan_desc)]; + + return 0; +} + +int ni_ao_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int chan = CR_CHAN(insn->chan_desc); + uint16_t *data = (uint16_t *)insn->data; + unsigned int invert; + + invert = ni_ao_config_chan_descs(subd, + &insn->chan_desc, 1, 0); + + devpriv->ao[chan] = data[0]; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + ni_writew(data[0], M_Offset_DAC_Direct_Data(chan)); + } else + ni_writew(data[0] ^ invert, + (chan) ? DAC1_Direct_Data : DAC0_Direct_Data); + + return 0; +} + +int ni_ao_insn_write_671x(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int chan = CR_CHAN(insn->chan_desc); + uint16_t *data = (uint16_t *)insn->data; + unsigned int invert; + + ao_win_out(1 << chan, AO_Immediate_671x); + invert = 1 << (boardtype.aobits - 1); + + ni_ao_config_chan_descs(subd, &insn->chan_desc, 1, 0); + + devpriv->ao[chan] = data[0]; + ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan)); + + return 0; +} + +int ni_ao_inttrig(a4l_subd_t *subd, lsampl_t trignum) +{ + a4l_dev_t *dev = subd->dev; + int ret, interrupt_b_bits, i; + static const int timeout = 1000; + + if (trignum != 0) + return -EINVAL; + + /* TODO: disable trigger until a command is recorded. + Null trig at beginning prevent ao start trigger from executing + more than once per command (and doing things like trying to + allocate the ao dma channel multiple times) */ + + ni_set_bits(dev, Interrupt_B_Enable_Register, + AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0); + interrupt_b_bits = AO_Error_Interrupt_Enable; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + devpriv->stc_writew(dev, 1, DAC_FIFO_Clear); + if (boardtype.reg_type & ni_reg_6xxx_mask) + ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); + ret = ni_ao_setup_MITE_dma(subd); + if (ret) + return ret; + ret = ni_ao_wait_for_dma_load(subd); + if (ret < 0) + return ret; +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + ret = ni_ao_prep_fifo(subd); + if (ret == 0) + return -EPIPE; + + interrupt_b_bits |= AO_FIFO_Interrupt_Enable; +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE, + AO_Mode_3_Register); + devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + /* wait for DACs to be loaded */ + for (i = 0; i < timeout; i++) { + a4l_udelay(1); + if ((devpriv->stc_readw(dev,Joint_Status_2_Register) & + AO_TMRDACWRs_In_Progress_St) == 0) + break; + } + if (i == timeout) { + a4l_err(dev, + "ni_ao_inttrig: timed out " + "waiting for AO_TMRDACWRs_In_Progress_St to clear"); + return -EIO; + } + /* stc manual says we are need to clear error interrupt after + AO_TMRDACWRs_In_Progress_St clears */ + devpriv->stc_writew(dev, AO_Error_Interrupt_Ack, + Interrupt_B_Ack_Register); + + ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1); + + devpriv->stc_writew(dev, + devpriv->ao_cmd1 | + AO_UI_Arm | AO_UC_Arm | + AO_BC_Arm | AO_DAC1_Update_Mode | + AO_DAC0_Update_Mode, + AO_Command_1_Register); + + devpriv->stc_writew(dev, + devpriv->ao_cmd2 | AO_START1_Pulse, + AO_Command_2_Register); + + return 0; +} + +int ni_ao_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_dev_t *dev = subd->dev; + + int bits; + int i; + unsigned trigvar; + + if (a4l_get_irq(dev) == A4L_IRQ_UNUSED) { + a4l_err(dev, "ni_ao_cmd: cannot run command without an irq"); + return -EIO; + } + + devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register); + + devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register); + + if (boardtype.reg_type & ni_reg_6xxx_mask) { + ao_win_out(CLEAR_WG, AO_Misc_611x); + + bits = 0; + for (i = 0; i < cmd->nb_chan; i++) { + int chan; + + chan = CR_CHAN(cmd->chan_descs[i]); + bits |= 1 << chan; + ao_win_out(chan, AO_Waveform_Generation_611x); + } + ao_win_out(bits, AO_Timed_611x); + } + + ni_ao_config_chan_descs(subd, cmd->chan_descs, cmd->nb_chan, 1); + + if (cmd->stop_src == TRIG_NONE) { + devpriv->ao_mode1 |= AO_Continuous; + devpriv->ao_mode1 &= ~AO_Trigger_Once; + } else { + devpriv->ao_mode1 &= ~AO_Continuous; + devpriv->ao_mode1 |= AO_Trigger_Once; + } + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + devpriv->ao_trigger_select &= + ~(AO_START1_Polarity | AO_START1_Select(-1)); + devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync; + devpriv->stc_writew(dev, devpriv->ao_trigger_select, + AO_Trigger_Select_Register); + devpriv->ao_mode3 &= ~AO_Trigger_Length; + devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source; + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + if (cmd->stop_src == TRIG_NONE) { + devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register); + } else { + devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register); + } + devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register); + devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source; + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + switch (cmd->stop_src) { + case TRIG_COUNT: + devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register); + devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register); + devpriv->stc_writel(dev, cmd->stop_arg - 1, + AO_UC_Load_A_Register); + break; + case TRIG_NONE: + devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register); + devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register); + devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register); + break; + default: + devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register); + devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register); + devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register); + } + + devpriv->ao_mode1 &= + ~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity | + AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity); + switch (cmd->scan_begin_src) { + case TRIG_TIMER: + devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable; + trigvar = + ni_ns_to_timer(dev, cmd->scan_begin_arg, + TRIG_ROUND_NEAREST); + devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register); + devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register); + devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register); + break; + case TRIG_EXT: + devpriv->ao_mode1 |= + AO_UPDATE_Source_Select(cmd->scan_begin_arg); + if (cmd->scan_begin_arg & CR_INVERT) + devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity; + devpriv->ao_cmd2 |= AO_BC_Gate_Enable; + break; + default: + BUG(); + break; + } + devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register); + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + devpriv->ao_mode2 &= + ~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source); + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + + if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) { + if (cmd->scan_end_arg > 1) { + devpriv->ao_mode1 |= AO_Multiple_Channels; + devpriv->stc_writew(dev, + AO_Number_Of_Channels(cmd->scan_end_arg - 1) | + AO_UPDATE_Output_Select + (AO_Update_Output_High_Z), + AO_Output_Control_Register); + } else { + unsigned int bits; + devpriv->ao_mode1 &= ~AO_Multiple_Channels; + bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z); + if (boardtype.reg_type & ni_reg_m_series_mask) { + bits |= AO_Number_Of_Channels(0); + } else { + bits |= AO_Number_Of_Channels(CR_CHAN(cmd-> + chan_descs[0])); + } + devpriv->stc_writew(dev, bits, + AO_Output_Control_Register); + } + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + } + + devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode, + AO_Command_1_Register); + + devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error; + devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + + devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F; +#else /* !CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + devpriv->ao_mode2 |= AO_FIFO_Mode_HF; +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable; + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + + bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width | + AO_TMRDACWR_Pulse_Width; + if (boardtype.ao_fifo_depth) + bits |= AO_FIFO_Enable; + else + bits |= AO_DMA_PIO_Control; +#if 0 + /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281, + verified with bus analyzer. */ + if (boardtype.reg_type & ni_reg_m_series_mask) + bits |= AO_Number_Of_DAC_Packages; +#endif + devpriv->stc_writew(dev, bits, AO_Personal_Register); + /* enable sending of ao dma requests */ + devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register); + + devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register); + + if (cmd->stop_src == TRIG_COUNT) { + devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack, + Interrupt_B_Ack_Register); + ni_set_bits(dev, Interrupt_B_Enable_Register, + AO_BC_TC_Interrupt_Enable, 1); + } + + return 0; +} + +a4l_cmd_t mio_ao_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_INT, + .scan_begin_src = TRIG_TIMER | TRIG_EXT, + .convert_src = TRIG_NOW, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_COUNT | TRIG_NONE, +}; + +int ni_ao_cmdtest(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_dev_t *dev = subd->dev; + + /* Make sure trigger sources are unique and mutually compatible */ + + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) + return -EINVAL; + + /* Make sure arguments are trivially compatible */ + + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + return -EINVAL; + } + + if (cmd->scan_begin_src == TRIG_TIMER) { + if (cmd->scan_begin_arg < boardtype.ao_speed) { + cmd->scan_begin_arg = boardtype.ao_speed; + return -EINVAL; + } + if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { + /* XXX check */ + cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; + return -EINVAL; + } + } + + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + return -EINVAL; + } + if (cmd->scan_end_arg != cmd->nb_chan) { + cmd->scan_end_arg = cmd->nb_chan; + return -EINVAL; + } + if (cmd->stop_src == TRIG_COUNT) { + /* XXX check */ + if (cmd->stop_arg > 0x00ffffff) { + cmd->stop_arg = 0x00ffffff; + return -EINVAL; + } + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + return -EINVAL; + } + } + + /* step 4: fix up any arguments */ + if (cmd->scan_begin_src == TRIG_TIMER) { + + if(cmd->scan_begin_arg != + ni_timer_to_ns(dev, + ni_ns_to_timer(dev, + cmd->scan_begin_arg, + cmd->flags & TRIG_ROUND_MASK))) + return -EINVAL; + } + + return 0; +} + +int ni_ao_reset(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + + ni_release_ao_mite_channel(dev); + + devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register); + devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register); + ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0); + devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register); + devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register); + devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width | + AO_TMRDACWR_Pulse_Width, AO_Personal_Register); + devpriv->stc_writew(dev, 0, AO_Output_Control_Register); + devpriv->stc_writew(dev, 0, AO_Start_Select_Register); + devpriv->ao_cmd1 = 0; + devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register); + devpriv->ao_cmd2 = 0; + devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register); + devpriv->ao_mode1 = 0; + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); + devpriv->ao_mode2 = 0; + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); + if (boardtype.reg_type & ni_reg_m_series_mask) + devpriv->ao_mode3 = AO_Last_Gate_Disable; + else + devpriv->ao_mode3 = 0; + devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); + devpriv->ao_trigger_select = 0; + devpriv->stc_writew(dev, devpriv->ao_trigger_select, + AO_Trigger_Select_Register); + if (boardtype.reg_type & ni_reg_6xxx_mask) { + ao_win_out(0x3, AO_Immediate_671x); + ao_win_out(CLEAR_WG, AO_Misc_611x); + } + devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register); + + return 0; +} + +/* digital io */ + +int ni_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int *)insn->data; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_dio_insn_config() chan=%d io=%d\n", + CR_CHAN(insn->chan_desc), data[0]); +#endif /* CONFIG_DEBUG_DIO */ + + switch (data[0]) { + case A4L_INSN_CONFIG_DIO_OUTPUT: + devpriv->io_bits |= 1 << CR_CHAN(insn->chan_desc); + break; + case A4L_INSN_CONFIG_DIO_INPUT: + devpriv->io_bits &= ~(1 << CR_CHAN(insn->chan_desc)); + break; + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = (devpriv->io_bits & + (1 << CR_CHAN(insn->chan_desc))) ? + A4L_OUTPUT : A4L_INPUT; + return 0; + break; + default: + return -EINVAL; + } + + devpriv->dio_control &= ~DIO_Pins_Dir_Mask; + devpriv->dio_control |= DIO_Pins_Dir(devpriv->io_bits); + devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + + return 1; +} + +int ni_dio_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_dio_insn_bits_8() mask=0x%x bits=0x%x\n", + data[0], data[1]); +#endif + + if (insn->data_size != 2 * sizeof(uint8_t)) + return -EINVAL; + + if (data[0]) { + /* Perform check to make sure we're not using the + serial part of the dio */ + if ((data[0] & (DIO_SDIN | DIO_SDOUT)) + && devpriv->serial_interval_ns) + return -EBUSY; + + devpriv->dio_state &= ~data[0]; + devpriv->dio_state |= (data[0] & data[1]); + devpriv->dio_output &= ~DIO_Parallel_Data_Mask; + devpriv->dio_output |= + DIO_Parallel_Data_Out(devpriv->dio_state); + devpriv->stc_writew(dev, devpriv->dio_output, + DIO_Output_Register); + } + + data[1] = (uint8_t) + devpriv->stc_readw(dev, DIO_Parallel_Input_Register); + + return 0; +} + +int ni_m_series_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int *)insn->data; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_m_series_dio_insn_config() chan=%d io=%d\n", + CR_CHAN(insn->chan_desc), data[0]); +#endif + switch (data[0]) { + case A4L_INSN_CONFIG_DIO_OUTPUT: + devpriv->io_bits |= 1 << CR_CHAN(insn->chan_desc); + break; + case A4L_INSN_CONFIG_DIO_INPUT: + devpriv->io_bits &= ~(1 << CR_CHAN(insn->chan_desc)); + break; + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = (devpriv->io_bits & + (1 << CR_CHAN(insn->chan_desc))) ? + A4L_OUTPUT : A4L_INPUT; + return 0; + break; + default: + return -EINVAL; + } + + ni_writel(devpriv->io_bits, M_Offset_DIO_Direction); + + return 0; +} + +int ni_m_series_dio_insn_bits_8(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", + data[0], data[1]); +#endif + + if (insn->data_size != 2 * sizeof(uint8_t)) + return -EINVAL; + + if (data[0]) { + devpriv->dio_state &= ~data[0]; + devpriv->dio_state |= (data[0] & data[1]); + ni_writel(devpriv->dio_state, M_Offset_Static_Digital_Output); + } + + data[1] = (uint8_t) ni_readl(M_Offset_Static_Digital_Input); + + return 0; +} + +int ni_m_series_dio_insn_bits_32(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint32_t *data = (uint32_t *)insn->data; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", + data[0], data[1]); +#endif + + if (insn->data_size != 2 * sizeof(uint32_t)) + return -EINVAL; + + if (data[0]) { + devpriv->dio_state &= ~data[0]; + devpriv->dio_state |= (data[0] & data[1]); + ni_writel(devpriv->dio_state, M_Offset_Static_Digital_Output); + } + + data[1] = ni_readl(M_Offset_Static_Digital_Input); + + return 0; +} + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +a4l_cmd_t mio_dio_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_INT, + .scan_begin_src = TRIG_EXT, + .convert_src = TRIG_NOW, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_NONE, +}; + +int ni_cdio_cmdtest(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + unsigned int i; + + /* Make sure arguments are trivially compatible */ + + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + return -EINVAL; + } + + if ((cmd->scan_begin_arg & + PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, CR_INVERT)) != + cmd->scan_begin_arg) + return -EINVAL; + + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + return -EINVAL; + } + + if (cmd->scan_end_arg != cmd->nb_chan) { + cmd->scan_end_arg = cmd->nb_chan; + return -EINVAL; + } + + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + return -EINVAL; + } + + /* Check chan_descs */ + + for (i = 0; i < cmd->nb_chan; ++i) { + if (cmd->chan_descs[i] != i) + return -EINVAL; + } + + return 0; +} + +int ni_cdio_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_dev_t *dev = subd->dev; + unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit; + + ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command); + switch (cmd->scan_begin_src) { + case TRIG_EXT: + cdo_mode_bits |= + CR_CHAN(cmd->scan_begin_arg) & + CDO_Sample_Source_Select_Mask; + break; + default: + BUG(); + break; + } + if (cmd->scan_begin_arg & CR_INVERT) + cdo_mode_bits |= CDO_Polarity_Bit; + ni_writel(cdo_mode_bits, M_Offset_CDO_Mode); + + if (devpriv->io_bits) { + ni_writel(devpriv->dio_state, M_Offset_CDO_FIFO_Data); + ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command); + ni_writel(devpriv->io_bits, M_Offset_CDO_Mask_Enable); + } else { + a4l_err(dev, + "ni_cdio_cmd: attempted to run digital " + "output command with no lines configured as outputs"); + return -EIO; + } + + return 0; +} + +int ni_cdio_cancel(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit | + CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit | + CDO_FIFO_Request_Interrupt_Enable_Clear_Bit, + M_Offset_CDIO_Command); + + ni_writel(0, M_Offset_CDO_Mask_Enable); + ni_release_cdo_mite_channel(dev); + return 0; +} + +int ni_cdo_inttrig(a4l_subd_t *subd, lsampl_t trignum) +{ + a4l_dev_t *dev = subd->dev; + int err; + unsigned i; + const unsigned timeout = 1000; + + /* TODO: disable trigger until a command is recorded. + Null trig at beginning prevent ao start trigger from executing + more than once per command (and doing things like trying to + allocate the ao dma channel multiple times) */ + + err = ni_cdo_setup_MITE_dma(subd); + if (err < 0) + return err; + + /* wait for dma to fill output fifo */ + for (i = 0; i < timeout; ++i) { + if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit) + break; + a4l_udelay(10); + } + + if (i == timeout) { + a4l_err(dev, "ni_cdo_inttrig: dma failed to fill cdo fifo!"); + ni_cdio_cancel(subd); + return -EIO; + } + + ni_writel(CDO_Arm_Bit | + CDO_Error_Interrupt_Enable_Set_Bit | + CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, + M_Offset_CDIO_Command); + + return 0; +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +static void handle_cdio_interrupt(a4l_dev_t *dev) +{ +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + unsigned cdio_status; + unsigned long flags; + a4l_subd_t *subd = a4l_get_subd(dev, NI_DIO_SUBDEV); + + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { + return; + } + a4l_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->cdo_mite_chan) { + unsigned cdo_mite_status = + mite_get_status(devpriv->cdo_mite_chan); + if (cdo_mite_status & CHSR_LINKC) { + writel(CHOR_CLRLC, + devpriv->mite->mite_io_addr + + MITE_CHOR(devpriv->cdo_mite_chan->channel)); + } + mite_sync_output_dma(devpriv->cdo_mite_chan, subd); + } + a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags); + + cdio_status = ni_readl(M_Offset_CDIO_Status); + if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) { + /* XXX just guessing this is needed and does something useful */ + ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + if (cdio_status & CDO_FIFO_Empty_Bit) { + ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit, + M_Offset_CDIO_Command); + } + a4l_buf_evt(subd, 0); +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ +} + +static int ni_serial_hw_readwrite8(a4l_dev_t * dev, + unsigned char data_out, unsigned char *data_in) +{ + unsigned int status1; + int err = 0, count = 20; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_serial_hw_readwrite8: outputting 0x%x\n", data_out); +#endif + + devpriv->dio_output &= ~DIO_Serial_Data_Mask; + devpriv->dio_output |= DIO_Serial_Data_Out(data_out); + devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register); + + status1 = devpriv->stc_readw(dev, Joint_Status_1_Register); + if (status1 & DIO_Serial_IO_In_Progress_St) { + err = -EBUSY; + goto Error; + } + + devpriv->dio_control |= DIO_HW_Serial_Start; + devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + devpriv->dio_control &= ~DIO_HW_Serial_Start; + + /* Wait until STC says we're done, but don't loop infinitely. */ + while ((status1 = + devpriv->stc_readw(dev, + Joint_Status_1_Register)) & + DIO_Serial_IO_In_Progress_St) { + /* Delay one bit per loop */ + a4l_udelay((devpriv->serial_interval_ns + 999) / 1000); + if (--count < 0) { + a4l_err(dev, + "ni_serial_hw_readwrite8: " + "SPI serial I/O didn't finish in time!\n"); + err = -ETIME; + goto Error; + } + } + + /* Delay for last bit. This delay is absolutely necessary, because + DIO_Serial_IO_In_Progress_St goes high one bit too early. */ + a4l_udelay((devpriv->serial_interval_ns + 999) / 1000); + + if (data_in != NULL) { + *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register); +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_serial_hw_readwrite8: inputted 0x%x\n", + *data_in); +#endif + } + +Error: + devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); + + return err; +} + +static int ni_serial_sw_readwrite8(a4l_dev_t * dev, + unsigned char data_out, unsigned char *data_in) +{ + unsigned char mask, input = 0; + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, + "ni_serial_sw_readwrite8: outputting 0x%x\n", data_out); +#endif + + /* Wait for one bit before transfer */ + a4l_udelay((devpriv->serial_interval_ns + 999) / 1000); + + for (mask = 0x80; mask; mask >>= 1) { + /* Output current bit; note that we cannot touch devpriv->dio_state + because it is a per-subdevice field, and serial is + a separate subdevice from DIO. */ + devpriv->dio_output &= ~DIO_SDOUT; + if (data_out & mask) { + devpriv->dio_output |= DIO_SDOUT; + } + devpriv->stc_writew(dev, devpriv->dio_output, + DIO_Output_Register); + + /* Assert SDCLK (active low, inverted), wait for half of + the delay, deassert SDCLK, and wait for the other half. */ + devpriv->dio_control |= DIO_Software_Serial_Control; + devpriv->stc_writew(dev, devpriv->dio_control, + DIO_Control_Register); + + a4l_udelay((devpriv->serial_interval_ns + 999) / 2000); + + devpriv->dio_control &= ~DIO_Software_Serial_Control; + devpriv->stc_writew(dev, devpriv->dio_control, + DIO_Control_Register); + + a4l_udelay((devpriv->serial_interval_ns + 999) / 2000); + + /* Input current bit */ + if (devpriv->stc_readw(dev, + DIO_Parallel_Input_Register) & DIO_SDIN) { + input |= mask; + } + } +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, "ni_serial_sw_readwrite8: inputted 0x%x\n", input); +#endif + if (data_in) + *data_in = input; + + return 0; +} + +int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + int err = 0; + unsigned char byte_out, byte_in = 0; + unsigned int *data = (unsigned int *)insn->data; + + if (insn->data_size != 2 * sizeof(unsigned int)) + return -EINVAL; + + switch (data[0]) { + case A4L_INSN_CONFIG_SERIAL_CLOCK: + +#ifdef CONFIG_DEBUG_DIO + a4l_info(dev, "SPI serial clock Config cd\n", data[1]); +#endif + + devpriv->serial_hw_mode = 1; + devpriv->dio_control |= DIO_HW_Serial_Enable; + + if (data[1] == SERIAL_DISABLED) { + devpriv->serial_hw_mode = 0; + devpriv->dio_control &= ~(DIO_HW_Serial_Enable | + DIO_Software_Serial_Control); + data[1] = SERIAL_DISABLED; + devpriv->serial_interval_ns = data[1]; + } else if (data[1] <= SERIAL_600NS) { + /* Warning: this clock speed is too fast to reliably + control SCXI. */ + devpriv->dio_control &= ~DIO_HW_Serial_Timebase; + devpriv->clock_and_fout |= Slow_Internal_Timebase; + devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2; + data[1] = SERIAL_600NS; + devpriv->serial_interval_ns = data[1]; + } else if (data[1] <= SERIAL_1_2US) { + devpriv->dio_control &= ~DIO_HW_Serial_Timebase; + devpriv->clock_and_fout |= Slow_Internal_Timebase | + DIO_Serial_Out_Divide_By_2; + data[1] = SERIAL_1_2US; + devpriv->serial_interval_ns = data[1]; + } else if (data[1] <= SERIAL_10US) { + devpriv->dio_control |= DIO_HW_Serial_Timebase; + devpriv->clock_and_fout |= Slow_Internal_Timebase | + DIO_Serial_Out_Divide_By_2; + /* Note: DIO_Serial_Out_Divide_By_2 only affects + 600ns/1.2us. If you turn divide_by_2 off with the + slow clock, you will still get 10us, except then + all your delays are wrong. */ + data[1] = SERIAL_10US; + devpriv->serial_interval_ns = data[1]; + } else { + devpriv->dio_control &= ~(DIO_HW_Serial_Enable | + DIO_Software_Serial_Control); + devpriv->serial_hw_mode = 0; + data[1] = (data[1] / 1000) * 1000; + devpriv->serial_interval_ns = data[1]; + } + + devpriv->stc_writew(dev, devpriv->dio_control, + DIO_Control_Register); + devpriv->stc_writew(dev, devpriv->clock_and_fout, + Clock_and_FOUT_Register); + return 0; + + break; + + case A4L_INSN_CONFIG_BIDIRECTIONAL_DATA: + + if (devpriv->serial_interval_ns == 0) { + return -EINVAL; + } + + byte_out = data[1] & 0xFF; + + if (devpriv->serial_hw_mode) { + err = ni_serial_hw_readwrite8(dev, byte_out, &byte_in); + } else if (devpriv->serial_interval_ns > 0) { + err = ni_serial_sw_readwrite8(dev, byte_out, &byte_in); + } else { + a4l_err(dev, + "ni_serial_insn_config: serial disabled!\n"); + return -EINVAL; + } + if (err < 0) + return err; + data[1] = byte_in & 0xFF; + return 0; + + break; + default: + return -EINVAL; + } + + return -EINVAL; +} + +void mio_common_detach(a4l_dev_t * dev) +{ + if (dev->priv) { + if (devpriv->counter_dev) { + ni_gpct_device_destroy(devpriv->counter_dev); + } + } +} + +static void init_ao_67xx(a4l_dev_t * dev) +{ + a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV); + int i; + + if (subd == NULL) { + a4l_err(dev, "%s: unable to find AO subdevice\n", __FUNCTION__); + return; + } + + for (i = 0; i < subd->chan_desc->length; i++) + ni_ao_win_outw(dev, AO_Channel(i) | 0x0, + AO_Configuration_2_67xx); +} + +static unsigned int ni_gpct_to_stc_register(enum ni_gpct_register reg) +{ + unsigned stc_register; + switch (reg) { + case NITIO_G0_Autoincrement_Reg: + stc_register = G_Autoincrement_Register(0); + break; + case NITIO_G1_Autoincrement_Reg: + stc_register = G_Autoincrement_Register(1); + break; + case NITIO_G0_Command_Reg: + stc_register = G_Command_Register(0); + break; + case NITIO_G1_Command_Reg: + stc_register = G_Command_Register(1); + break; + case NITIO_G0_HW_Save_Reg: + stc_register = G_HW_Save_Register(0); + break; + case NITIO_G1_HW_Save_Reg: + stc_register = G_HW_Save_Register(1); + break; + case NITIO_G0_SW_Save_Reg: + stc_register = G_Save_Register(0); + break; + case NITIO_G1_SW_Save_Reg: + stc_register = G_Save_Register(1); + break; + case NITIO_G0_Mode_Reg: + stc_register = G_Mode_Register(0); + break; + case NITIO_G1_Mode_Reg: + stc_register = G_Mode_Register(1); + break; + case NITIO_G0_LoadA_Reg: + stc_register = G_Load_A_Register(0); + break; + case NITIO_G1_LoadA_Reg: + stc_register = G_Load_A_Register(1); + break; + case NITIO_G0_LoadB_Reg: + stc_register = G_Load_B_Register(0); + break; + case NITIO_G1_LoadB_Reg: + stc_register = G_Load_B_Register(1); + break; + case NITIO_G0_Input_Select_Reg: + stc_register = G_Input_Select_Register(0); + break; + case NITIO_G1_Input_Select_Reg: + stc_register = G_Input_Select_Register(1); + break; + case NITIO_G01_Status_Reg: + stc_register = G_Status_Register; + break; + case NITIO_G01_Joint_Reset_Reg: + stc_register = Joint_Reset_Register; + break; + case NITIO_G01_Joint_Status1_Reg: + stc_register = Joint_Status_1_Register; + break; + case NITIO_G01_Joint_Status2_Reg: + stc_register = Joint_Status_2_Register; + break; + case NITIO_G0_Interrupt_Acknowledge_Reg: + stc_register = Interrupt_A_Ack_Register; + break; + case NITIO_G1_Interrupt_Acknowledge_Reg: + stc_register = Interrupt_B_Ack_Register; + break; + case NITIO_G0_Status_Reg: + stc_register = AI_Status_1_Register; + break; + case NITIO_G1_Status_Reg: + stc_register = AO_Status_1_Register; + break; + case NITIO_G0_Interrupt_Enable_Reg: + stc_register = Interrupt_A_Enable_Register; + break; + case NITIO_G1_Interrupt_Enable_Reg: + stc_register = Interrupt_B_Enable_Register; + break; + default: + __a4l_err("%s: unhandled register 0x%x in switch.\n", + __FUNCTION__, reg); + BUG(); + return 0; + break; + } + return stc_register; +} + +static void ni_gpct_write_register(struct ni_gpct *counter, + unsigned int bits, enum ni_gpct_register reg) +{ + a4l_dev_t *dev = counter->counter_dev->dev; + unsigned stc_register; + /* bits in the join reset register which are relevant to counters */ + static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset; + static const unsigned gpct_interrupt_a_enable_mask = + G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable; + static const unsigned gpct_interrupt_b_enable_mask = + G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable; + + switch (reg) { + /* m-series-only registers */ + case NITIO_G0_Counting_Mode_Reg: + ni_writew(bits, M_Offset_G0_Counting_Mode); + break; + case NITIO_G1_Counting_Mode_Reg: + ni_writew(bits, M_Offset_G1_Counting_Mode); + break; + case NITIO_G0_Second_Gate_Reg: + ni_writew(bits, M_Offset_G0_Second_Gate); + break; + case NITIO_G1_Second_Gate_Reg: + ni_writew(bits, M_Offset_G1_Second_Gate); + break; + case NITIO_G0_DMA_Config_Reg: + ni_writew(bits, M_Offset_G0_DMA_Config); + break; + case NITIO_G1_DMA_Config_Reg: + ni_writew(bits, M_Offset_G1_DMA_Config); + break; + case NITIO_G0_ABZ_Reg: + ni_writew(bits, M_Offset_G0_MSeries_ABZ); + break; + case NITIO_G1_ABZ_Reg: + ni_writew(bits, M_Offset_G1_MSeries_ABZ); + break; + + /* 32 bit registers */ + case NITIO_G0_LoadA_Reg: + case NITIO_G1_LoadA_Reg: + case NITIO_G0_LoadB_Reg: + case NITIO_G1_LoadB_Reg: + stc_register = ni_gpct_to_stc_register(reg); + devpriv->stc_writel(dev, bits, stc_register); + break; + + /* 16 bit registers */ + case NITIO_G0_Interrupt_Enable_Reg: + BUG_ON(bits & ~gpct_interrupt_a_enable_mask); + ni_set_bitfield(dev, Interrupt_A_Enable_Register, + gpct_interrupt_a_enable_mask, bits); + break; + case NITIO_G1_Interrupt_Enable_Reg: + BUG_ON(bits & ~gpct_interrupt_b_enable_mask); + ni_set_bitfield(dev, Interrupt_B_Enable_Register, + gpct_interrupt_b_enable_mask, bits); + break; + case NITIO_G01_Joint_Reset_Reg: + BUG_ON(bits & ~gpct_joint_reset_mask); + /* fall-through */ + default: + stc_register = ni_gpct_to_stc_register(reg); + devpriv->stc_writew(dev, bits, stc_register); + } +} + +static unsigned int ni_gpct_read_register(struct ni_gpct *counter, + enum ni_gpct_register reg) +{ + a4l_dev_t *dev = counter->counter_dev->dev; + unsigned int stc_register; + switch (reg) { + /* m-series only registers */ + case NITIO_G0_DMA_Status_Reg: + return ni_readw(M_Offset_G0_DMA_Status); + break; + case NITIO_G1_DMA_Status_Reg: + return ni_readw(M_Offset_G1_DMA_Status); + break; + + /* 32 bit registers */ + case NITIO_G0_HW_Save_Reg: + case NITIO_G1_HW_Save_Reg: + case NITIO_G0_SW_Save_Reg: + case NITIO_G1_SW_Save_Reg: + stc_register = ni_gpct_to_stc_register(reg); + return devpriv->stc_readl(dev, stc_register); + break; + + /* 16 bit registers */ + default: + stc_register = ni_gpct_to_stc_register(reg); + return devpriv->stc_readw(dev, stc_register); + break; + } + return 0; +} + +int ni_freq_out_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + data[0] = FOUT_Divider(devpriv->clock_and_fout); + + return 0; +} + +int ni_freq_out_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + devpriv->clock_and_fout &= ~FOUT_Enable; + devpriv->stc_writew(dev, devpriv->clock_and_fout, + Clock_and_FOUT_Register); + devpriv->clock_and_fout &= ~FOUT_Divider_mask; + devpriv->clock_and_fout |= FOUT_Divider(data[0]); + devpriv->clock_and_fout |= FOUT_Enable; + devpriv->stc_writew(dev, devpriv->clock_and_fout, + Clock_and_FOUT_Register); + + return 0; +} + +static int ni_set_freq_out_clock(a4l_dev_t * dev, lsampl_t clock_source) +{ + switch (clock_source) { + case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC: + devpriv->clock_and_fout &= ~FOUT_Timebase_Select; + break; + case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC: + devpriv->clock_and_fout |= FOUT_Timebase_Select; + break; + default: + return -EINVAL; + } + devpriv->stc_writew(dev, devpriv->clock_and_fout, + Clock_and_FOUT_Register); + + return 0; +} + +static void ni_get_freq_out_clock(a4l_dev_t * dev, + unsigned int * clock_source, + unsigned int * clock_period_ns) +{ + if (devpriv->clock_and_fout & FOUT_Timebase_Select) { + *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC; + *clock_period_ns = TIMEBASE_2_NS; + } else { + *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC; + *clock_period_ns = TIMEBASE_1_NS * 2; + } +} + +int ni_freq_out_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int *)insn->data; + + switch (data[0]) { + case A4L_INSN_CONFIG_SET_CLOCK_SRC: + return ni_set_freq_out_clock(dev, data[1]); + break; + case A4L_INSN_CONFIG_GET_CLOCK_SRC: + ni_get_freq_out_clock(dev, &data[1], &data[2]); + return 0; + default: + break; + } + + return -EINVAL; +} + +static int ni_8255_callback(int dir, int port, int data, unsigned long arg) +{ + a4l_dev_t *dev = (a4l_dev_t *) arg; + + if (dir) { + ni_writeb(data, Port_A + 2 * port); + return 0; + } else { + return ni_readb(Port_A + 2 * port); + } +} + +/* + reads bytes out of eeprom +*/ + +static int ni_read_eeprom(a4l_dev_t *dev, int addr) +{ + int bit; + int bitstring; + + bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff); + ni_writeb(0x04, Serial_Command); + for (bit = 0x8000; bit; bit >>= 1) { + ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0), + Serial_Command); + ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0), + Serial_Command); + } + bitstring = 0; + for (bit = 0x80; bit; bit >>= 1) { + ni_writeb(0x04, Serial_Command); + ni_writeb(0x05, Serial_Command); + bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0); + } + ni_writeb(0x00, Serial_Command); + + return bitstring; +} + +/* + presents the EEPROM as a subdevice +*/ + +static int ni_eeprom_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chan_desc)); + + return 0; +} + + +static int ni_m_series_eeprom_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint8_t *data = (uint8_t *)insn->data; + + data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chan_desc)]; + + return 0; +} + +static int ni_get_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int*)insn->data; + + data[1] = devpriv->pwm_up_count * devpriv->clock_ns; + data[2] = devpriv->pwm_down_count * devpriv->clock_ns; + + return 0; +} + +static int ni_m_series_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int up_count, down_count; + unsigned int *data = (unsigned int*)insn->data; + + switch (data[0]) { + case A4L_INSN_CONFIG_PWM_OUTPUT: + switch (data[1]) { + case TRIG_ROUND_NEAREST: + up_count = + (data[2] + + devpriv->clock_ns / 2) / devpriv->clock_ns; + break; + case TRIG_ROUND_DOWN: + up_count = data[2] / devpriv->clock_ns; + break; + case TRIG_ROUND_UP: + up_count =(data[2] + devpriv->clock_ns - 1) / + devpriv->clock_ns; + break; + default: + return -EINVAL; + break; + } + switch (data[3]) { + case TRIG_ROUND_NEAREST: + down_count = (data[4] + devpriv->clock_ns / 2) / + devpriv->clock_ns; + break; + case TRIG_ROUND_DOWN: + down_count = data[4] / devpriv->clock_ns; + break; + case TRIG_ROUND_UP: + down_count = + (data[4] + devpriv->clock_ns - 1) / + devpriv->clock_ns; + break; + default: + return -EINVAL; + break; + } + if (up_count * devpriv->clock_ns != data[2] || + down_count * devpriv->clock_ns != data[4]) { + data[2] = up_count * devpriv->clock_ns; + data[4] = down_count * devpriv->clock_ns; + return -EAGAIN; + } + ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) | + MSeries_Cal_PWM_Low_Time_Bits(down_count), + M_Offset_Cal_PWM); + devpriv->pwm_up_count = up_count; + devpriv->pwm_down_count = down_count; + return 0; + break; + case A4L_INSN_CONFIG_GET_PWM_OUTPUT: + return ni_get_pwm_config(subd, insn); + break; + default: + return -EINVAL; + break; + } + return 0; +} + +static int ni_6143_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int *data = (unsigned int*)insn->data; + + unsigned up_count, down_count; + switch (data[0]) { + case A4L_INSN_CONFIG_PWM_OUTPUT: + switch (data[1]) { + case TRIG_ROUND_NEAREST: + up_count = + (data[2] + devpriv->clock_ns / 2) / + devpriv->clock_ns; + break; + case TRIG_ROUND_DOWN: + up_count = data[2] / devpriv->clock_ns; + break; + case TRIG_ROUND_UP: + up_count = (data[2] + devpriv->clock_ns - 1) / + devpriv->clock_ns; + break; + default: + return -EINVAL; + break; + } + switch (data[3]) { + case TRIG_ROUND_NEAREST: + down_count = (data[4] + devpriv->clock_ns / 2) / + devpriv->clock_ns; + break; + case TRIG_ROUND_DOWN: + down_count = data[4] / devpriv->clock_ns; + break; + case TRIG_ROUND_UP: + down_count = (data[4] + devpriv->clock_ns - 1) / + devpriv->clock_ns; + break; + default: + return -EINVAL; + break; + } + if (up_count * devpriv->clock_ns != data[2] || + down_count * devpriv->clock_ns != data[4]) { + data[2] = up_count * devpriv->clock_ns; + data[4] = down_count * devpriv->clock_ns; + return -EAGAIN; + } + ni_writel(up_count, Calibration_HighTime_6143); + devpriv->pwm_up_count = up_count; + ni_writel(down_count, Calibration_LowTime_6143); + devpriv->pwm_down_count = down_count; + return 0; + break; + case A4L_INSN_CONFIG_GET_PWM_OUTPUT: + return ni_get_pwm_config(subd, insn); + default: + return -EINVAL; + break; + } + return 0; +} + +static int pack_mb88341(int addr, int val, int *bitstring) +{ + /* + Fujitsu MB 88341 + Note that address bits are reversed. Thanks to + Ingo Keen for noticing this. + + Note also that the 88341 expects address values from + 1-12, whereas we use channel numbers 0-11. The NI + docs use 1-12, also, so be careful here. + */ + addr++; + *bitstring = ((addr & 0x1) << 11) | + ((addr & 0x2) << 9) | + ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff); + return 12; +} + +static int pack_dac8800(int addr, int val, int *bitstring) +{ + *bitstring = ((addr & 0x7) << 8) | (val & 0xff); + return 11; +} + +static int pack_dac8043(int addr, int val, int *bitstring) +{ + *bitstring = val & 0xfff; + return 12; +} + +static int pack_ad8522(int addr, int val, int *bitstring) +{ + *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000); + return 16; +} + +static int pack_ad8804(int addr, int val, int *bitstring) +{ + *bitstring = ((addr & 0xf) << 8) | (val & 0xff); + return 12; +} + +static int pack_ad8842(int addr, int val, int *bitstring) +{ + *bitstring = ((addr + 1) << 8) | (val & 0xff); + return 12; +} + +struct caldac_struct { + int n_chans; + int n_bits; + int (*packbits) (int, int, int *); +}; + +static struct caldac_struct caldacs[] = { + [mb88341] = {12, 8, pack_mb88341}, + [dac8800] = {8, 8, pack_dac8800}, + [dac8043] = {1, 12, pack_dac8043}, + [ad8522] = {2, 12, pack_ad8522}, + [ad8804] = {12, 8, pack_ad8804}, + [ad8842] = {8, 8, pack_ad8842}, + [ad8804_debug] = {16, 8, pack_ad8804}, +}; + +static void ni_write_caldac(a4l_dev_t * dev, int addr, int val) +{ + unsigned int loadbit = 0, bits = 0, bit, bitstring = 0; + int i; + int type; + + if (devpriv->caldacs[addr] == val) + return; + devpriv->caldacs[addr] = val; + + for (i = 0; i < 3; i++) { + type = boardtype.caldac[i]; + if (type == caldac_none) + break; + if (addr < caldacs[type].n_chans) { + bits = caldacs[type].packbits(addr, val, &bitstring); + loadbit = SerDacLd(i); + break; + } + addr -= caldacs[type].n_chans; + } + + for (bit = 1 << (bits - 1); bit; bit >>= 1) { + ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command); + a4l_udelay(1); + ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command); + a4l_udelay(1); + } + ni_writeb(loadbit, Serial_Command); + a4l_udelay(1); + ni_writeb(0, Serial_Command); +} + +static void caldac_setup(a4l_dev_t *dev, a4l_subd_t *subd) +{ + int i, j; + int n_dacs; + int n_chans = 0; + int n_bits; + int diffbits = 0; + int type; + int chan; + + type = boardtype.caldac[0]; + if (type == caldac_none) + return; + n_bits = caldacs[type].n_bits; + for (i = 0; i < 3; i++) { + type = boardtype.caldac[i]; + if (type == caldac_none) + break; + if (caldacs[type].n_bits != n_bits) + diffbits = 1; + n_chans += caldacs[type].n_chans; + } + n_dacs = i; + + if (diffbits) { + + if (n_chans > MAX_N_CALDACS) { + a4l_err(dev, "BUG! MAX_N_CALDACS too small\n"); + } + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + n_chans * sizeof(a4l_chan_t), GFP_KERNEL); + + memset(subd->chan_desc, + 0, + sizeof(a4l_chdesc_t) + n_chans * sizeof(a4l_chan_t)); + + subd->chan_desc->length = n_chans; + subd->chan_desc->mode = A4L_CHAN_PERCHAN_CHANDESC; + + chan = 0; + for (i = 0; i < n_dacs; i++) { + type = boardtype.caldac[i]; + for (j = 0; j < caldacs[type].n_chans; j++) { + + subd->chan_desc->chans[chan].nb_bits = + caldacs[type].n_bits; + + chan++; + } + } + + for (chan = 0; chan < n_chans; chan++) { + unsigned long tmp = + (1 << subd->chan_desc->chans[chan].nb_bits) / 2; + ni_write_caldac(dev, chan, tmp); + } + } else { + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + + memset(subd->chan_desc, + 0, sizeof(a4l_chdesc_t) + sizeof(a4l_chan_t)); + + subd->chan_desc->length = n_chans; + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + + type = boardtype.caldac[0]; + + subd->chan_desc->chans[0].nb_bits = caldacs[type].n_bits; + + for (chan = 0; chan < n_chans; chan++) + ni_write_caldac(dev, + chan, + (1 << subd->chan_desc->chans[0].nb_bits) / 2); + } +} + +static int ni_calib_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint16_t *data = (uint16_t *)insn->data; + + ni_write_caldac(dev, CR_CHAN(insn->chan_desc), data[0]); + return 0; +} + +static int ni_calib_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint16_t *data = (uint16_t *)insn->data; + + data[0] = devpriv->caldacs[CR_CHAN(insn->chan_desc)]; + + return 0; +} + +static int ni_gpct_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + return ni_tio_insn_config(counter, insn); +} + +static int ni_gpct_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + return ni_tio_rinsn(counter, insn); +} + +static int ni_gpct_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + return ni_tio_winsn(counter, insn); +} + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static int ni_gpct_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + int retval; + a4l_dev_t *dev = subd->dev; + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + struct mite_dma_descriptor_ring *ring; + + retval = ni_request_gpct_mite_channel(dev, + counter->counter_index, + A4L_INPUT); + if (retval) { + a4l_err(dev, + "ni_gpct_cmd: " + "no dma channel available for use by counter\n"); + return retval; + } + + ring = devpriv->gpct_mite_ring[counter->counter_index]; + retval = mite_buf_change(ring, subd); + if (retval) { + a4l_err(dev, + "ni_gpct_cmd: " + "dma ring configuration failed\n"); + return retval; + + } + + ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); + ni_e_series_enable_second_irq(dev, counter->counter_index, 1); + retval = ni_tio_cmd(counter, cmd); + + return retval; +} + +static int ni_gpct_cmdtest(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + return ni_tio_cmdtest(counter, cmd); +} + +static int ni_gpct_cancel(a4l_subd_t *subd) +{ + a4l_dev_t *dev = subd->dev; + struct ni_gpct *counter = (struct ni_gpct *)subd->priv; + int retval; + + retval = ni_tio_cancel(counter); + ni_e_series_enable_second_irq(dev, counter->counter_index, 0); + ni_release_gpct_mite_channel(dev, counter->counter_index); + return retval; +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + +/* + * + * Programmable Function Inputs + * + */ + +static int ni_m_series_set_pfi_routing(a4l_dev_t *dev, + unsigned int chan, unsigned int source) +{ + unsigned int pfi_reg_index; + unsigned int array_offset; + + if ((source & 0x1f) != source) + return -EINVAL; + pfi_reg_index = 1 + chan / 3; + array_offset = pfi_reg_index - 1; + devpriv->pfi_output_select_reg[array_offset] &= + ~MSeries_PFI_Output_Select_Mask(chan); + devpriv->pfi_output_select_reg[array_offset] |= + MSeries_PFI_Output_Select_Bits(chan, source); + ni_writew(devpriv->pfi_output_select_reg[array_offset], + M_Offset_PFI_Output_Select(pfi_reg_index)); + return 2; +} + +static unsigned int ni_old_get_pfi_routing(a4l_dev_t *dev, + unsigned int chan) +{ + /* pre-m-series boards have fixed signals on pfi pins */ + + switch (chan) { + case 0: + return NI_PFI_OUTPUT_AI_START1; + break; + case 1: + return NI_PFI_OUTPUT_AI_START2; + break; + case 2: + return NI_PFI_OUTPUT_AI_CONVERT; + break; + case 3: + return NI_PFI_OUTPUT_G_SRC1; + break; + case 4: + return NI_PFI_OUTPUT_G_GATE1; + break; + case 5: + return NI_PFI_OUTPUT_AO_UPDATE_N; + break; + case 6: + return NI_PFI_OUTPUT_AO_START1; + break; + case 7: + return NI_PFI_OUTPUT_AI_START_PULSE; + break; + case 8: + return NI_PFI_OUTPUT_G_SRC0; + break; + case 9: + return NI_PFI_OUTPUT_G_GATE0; + break; + default: + __a4l_err("%s: bug, unhandled case in switch.\n", + __FUNCTION__); + break; + } + return 0; +} + +static int ni_old_set_pfi_routing(a4l_dev_t *dev, + unsigned int chan, unsigned int source) +{ + /* pre-m-series boards have fixed signals on pfi pins */ + if (source != ni_old_get_pfi_routing(dev, chan)) + return -EINVAL; + + return 2; +} + +static int ni_set_pfi_routing(a4l_dev_t *dev, + unsigned int chan, unsigned int source) +{ + if (boardtype.reg_type & ni_reg_m_series_mask) + return ni_m_series_set_pfi_routing(dev, chan, source); + else + return ni_old_set_pfi_routing(dev, chan, source); +} + +static unsigned int ni_m_series_get_pfi_routing(a4l_dev_t *dev, + unsigned int chan) +{ + const unsigned int array_offset = chan / 3; + return MSeries_PFI_Output_Select_Source(chan, + devpriv->pfi_output_select_reg[array_offset]); +} + +static unsigned int ni_get_pfi_routing(a4l_dev_t *dev, unsigned int chan) +{ + if (boardtype.reg_type & ni_reg_m_series_mask) + return ni_m_series_get_pfi_routing(dev, chan); + else + return ni_old_get_pfi_routing(dev, chan); +} + +static int ni_config_filter(a4l_dev_t *dev, + unsigned int pfi_channel, int filter) +{ + unsigned int bits; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { + return -ENOTSUPP; + } + bits = ni_readl(M_Offset_PFI_Filter); + bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel); + bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter); + ni_writel(bits, M_Offset_PFI_Filter); + return 0; +} + +static int ni_pfi_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint16_t *data = (uint16_t *)insn->data; + + if (data[0]) { + devpriv->pfi_state &= ~data[0]; + devpriv->pfi_state |= (data[0] & data[1]); + ni_writew(devpriv->pfi_state, M_Offset_PFI_DO); + } + + data[1] = ni_readw(M_Offset_PFI_DI); + + return 0; +} + +static int ni_pfi_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + unsigned int chan, *data = (unsigned int *)insn->data; + + if (insn->data_size < sizeof(unsigned int)) + return -EINVAL; + + chan = CR_CHAN(insn->chan_desc); + + switch (data[0]) { + case A4L_OUTPUT: + ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1); + break; + case A4L_INPUT: + ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0); + break; + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = (devpriv->io_bidirection_pin_reg & (1 << chan)) ? + A4L_OUTPUT : A4L_INPUT; + return 0; + break; + case A4L_INSN_CONFIG_SET_ROUTING: + return ni_set_pfi_routing(dev, chan, data[1]); + break; + case A4L_INSN_CONFIG_GET_ROUTING: + data[1] = ni_get_pfi_routing(dev, chan); + break; + case A4L_INSN_CONFIG_FILTER: + return ni_config_filter(dev, chan, data[1]); + break; + default: + return -EINVAL; + } + return 0; +} + +/* + * + * RTSI Bus Functions + * + */ + +/* Find best multiplier/divider to try and get the PLL running at 80 MHz + * given an arbitrary frequency input clock */ +static int ni_mseries_get_pll_parameters(unsigned int reference_period_ns, + unsigned int *freq_divider, + unsigned int *freq_multiplier, + unsigned int *actual_period_ns) +{ + unsigned div; + unsigned best_div = 1; + static const unsigned max_div = 0x10; + unsigned mult; + unsigned best_mult = 1; + static const unsigned max_mult = 0x100; + static const unsigned pico_per_nano = 1000; + + const unsigned reference_picosec = reference_period_ns * pico_per_nano; + /* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to + * 20 MHz for most timing clocks */ + static const unsigned target_picosec = 12500; + static const unsigned fudge_factor_80_to_20Mhz = 4; + int best_period_picosec = 0; + for (div = 1; div <= max_div; ++div) { + for (mult = 1; mult <= max_mult; ++mult) { + unsigned new_period_ps = + (reference_picosec * div) / mult; + if (abs(new_period_ps - target_picosec) < + abs(best_period_picosec - target_picosec)) { + best_period_picosec = new_period_ps; + best_div = div; + best_mult = mult; + } + } + } + if (best_period_picosec == 0) { + __a4l_err("%s: bug, failed to find pll parameters\n", + __FUNCTION__); + return -EIO; + } + *freq_divider = best_div; + *freq_multiplier = best_mult; + *actual_period_ns = + (best_period_picosec * fudge_factor_80_to_20Mhz + + (pico_per_nano / 2)) / pico_per_nano; + return 0; +} + +static int ni_mseries_set_pll_master_clock(a4l_dev_t * dev, + unsigned int source, + unsigned int period_ns) +{ + static const unsigned min_period_ns = 50; + static const unsigned max_period_ns = 1000; + static const unsigned timeout = 1000; + unsigned pll_control_bits; + unsigned freq_divider; + unsigned freq_multiplier; + unsigned i; + int retval; + if (source == NI_MIO_PLL_PXI10_CLOCK) + period_ns = 100; + /* These limits are somewhat arbitrary, but NI advertises 1 to + 20MHz range so we'll use that */ + if (period_ns < min_period_ns || period_ns > max_period_ns) { + a4l_err(dev, + "%s: you must specify an input clock frequency " + "between %i and %i nanosec " + "for the phased-lock loop.\n", + __FUNCTION__, min_period_ns, max_period_ns); + return -EINVAL; + } + devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; + devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, + RTSI_Trig_Direction_Register); + pll_control_bits = + MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits; + devpriv->clock_and_fout2 |= + MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit; + devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask; + switch (source) { + case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK: + devpriv->clock_and_fout2 |= + MSeries_PLL_In_Source_Select_Star_Trigger_Bits; + retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider, + &freq_multiplier, &devpriv->clock_ns); + if (retval < 0) + return retval; + break; + case NI_MIO_PLL_PXI10_CLOCK: + /* pxi clock is 10MHz */ + devpriv->clock_and_fout2 |= + MSeries_PLL_In_Source_Select_PXI_Clock10; + retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider, + &freq_multiplier, &devpriv->clock_ns); + if (retval < 0) + return retval; + break; + default: + { + unsigned rtsi_channel; + static const unsigned max_rtsi_channel = 7; + for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel; + ++rtsi_channel) { + if (source == + NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) { + devpriv->clock_and_fout2 |= + MSeries_PLL_In_Source_Select_RTSI_Bits + (rtsi_channel); + break; + } + } + if (rtsi_channel > max_rtsi_channel) + return -EINVAL; + retval = ni_mseries_get_pll_parameters(period_ns, + &freq_divider, &freq_multiplier, + &devpriv->clock_ns); + if (retval < 0) + return retval; + } + break; + } + ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2); + pll_control_bits |= + MSeries_PLL_Divisor_Bits(freq_divider) | + MSeries_PLL_Multiplier_Bits(freq_multiplier); + ni_writew(pll_control_bits, M_Offset_PLL_Control); + devpriv->clock_source = source; + /* It seems to typically take a few hundred microseconds for PLL to lock */ + for (i = 0; i < timeout; ++i) { + if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) { + break; + } + udelay(1); + } + if (i == timeout) { + a4l_err(dev, + "%s: timed out waiting for PLL to lock " + "to reference clock source %i with period %i ns.\n", + __FUNCTION__, source, period_ns); + return -ETIMEDOUT; + } + return 3; +} + +static int ni_set_master_clock(a4l_dev_t *dev, + unsigned int source, unsigned int period_ns) +{ + if (source == NI_MIO_INTERNAL_CLOCK) { + devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; + devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, + RTSI_Trig_Direction_Register); + devpriv->clock_ns = TIMEBASE_1_NS; + if (boardtype.reg_type & ni_reg_m_series_mask) { + devpriv->clock_and_fout2 &= + ~(MSeries_Timebase1_Select_Bit | + MSeries_Timebase3_Select_Bit); + ni_writew(devpriv->clock_and_fout2, + M_Offset_Clock_and_Fout2); + ni_writew(0, M_Offset_PLL_Control); + } + devpriv->clock_source = source; + } else { + if (boardtype.reg_type & ni_reg_m_series_mask) { + return ni_mseries_set_pll_master_clock(dev, source, + period_ns); + } else { + if (source == NI_MIO_RTSI_CLOCK) { + devpriv->rtsi_trig_direction_reg |= + Use_RTSI_Clock_Bit; + devpriv->stc_writew(dev, + devpriv->rtsi_trig_direction_reg, + RTSI_Trig_Direction_Register); + if (devpriv->clock_ns == 0) { + a4l_err(dev, + "%s: we don't handle an " + "unspecified clock period " + "correctly yet, returning error.\n", + __FUNCTION__); + return -EINVAL; + } else { + devpriv->clock_ns = period_ns; + } + devpriv->clock_source = source; + } else + return -EINVAL; + } + } + return 3; +} + +static void ni_rtsi_init(a4l_dev_t * dev) +{ + /* Initialise the RTSI bus signal switch to a default state */ + + /* Set clock mode to internal */ + devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit; + if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) { + a4l_err(dev, "ni_set_master_clock failed, bug?"); + } + + /* Default internal lines routing to RTSI bus lines */ + devpriv->rtsi_trig_a_output_reg = + RTSI_Trig_Output_Bits(0, NI_RTSI_OUTPUT_ADR_START1) | + RTSI_Trig_Output_Bits(1, NI_RTSI_OUTPUT_ADR_START2) | + RTSI_Trig_Output_Bits(2, NI_RTSI_OUTPUT_SCLKG) | + RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN); + devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg, + RTSI_Trig_A_Output_Register); + devpriv->rtsi_trig_b_output_reg = + RTSI_Trig_Output_Bits(4, NI_RTSI_OUTPUT_DA_START1) | + RTSI_Trig_Output_Bits(5, NI_RTSI_OUTPUT_G_SRC0) | + RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0); + + if (boardtype.reg_type & ni_reg_m_series_mask) + devpriv->rtsi_trig_b_output_reg |= + RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC); + devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg, + RTSI_Trig_B_Output_Register); +} + +int ni_E_init(a4l_dev_t *dev) +{ + int ret; + unsigned int j, counter_variant; + a4l_subd_t *subd; + + if (boardtype.n_aochan > MAX_N_AO_CHAN) { + a4l_err(dev, "bug! boardtype.n_aochan > MAX_N_AO_CHAN\n"); + return -EINVAL; + } + + /* analog input subdevice */ + + a4l_dbg(1, drv_dbg, dev, "mio_common: starting attach procedure...\n"); + + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, "mio_common: registering AI subdevice...\n"); + + if (boardtype.n_adchan) { + + a4l_dbg(1, drv_dbg, dev, + "mio_common: AI: %d channels\n", boardtype.n_adchan); + + subd->flags = A4L_SUBD_AI | A4L_SUBD_CMD | A4L_SUBD_MMAP; + subd->rng_desc = ni_range_lkup[boardtype.gainlkup]; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = boardtype.n_adchan; + subd->chan_desc->chans[0].flags = A4L_CHAN_AREF_DIFF; + if (boardtype.reg_type != ni_reg_611x) + subd->chan_desc->chans[0].flags |= A4L_CHAN_AREF_GROUND | + A4L_CHAN_AREF_COMMON | A4L_CHAN_AREF_OTHER; + subd->chan_desc->chans[0].nb_bits = boardtype.adbits; + + subd->insn_read = ni_ai_insn_read; + subd->insn_config = ni_ai_insn_config; + subd->do_cmdtest = ni_ai_cmdtest; + subd->do_cmd = ni_ai_cmd; + subd->cancel = ni_ai_reset; + subd->trigger = ni_ai_inttrig; + + subd->munge = (boardtype.adbits > 16) ? + ni_ai_munge32 : ni_ai_munge16; + + subd->cmd_mask = &mio_ai_cmd_mask; + } else { + a4l_dbg(1, drv_dbg, dev, + "mio_common: AI subdevice not present\n"); + subd->flags = A4L_SUBD_UNUSED; + } + + ret = a4l_add_subd(dev, subd); + if(ret != NI_AI_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: AI subdevice registered\n"); + + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, "mio_common: registering AO subdevice...\n"); + + /* analog output subdevice */ + if (boardtype.n_aochan) { + + a4l_dbg(1, drv_dbg, dev, + "mio_common: AO: %d channels\n", boardtype.n_aochan); + + subd->flags = A4L_SUBD_AO; + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = boardtype.n_aochan; + subd->chan_desc->chans[0].flags = A4L_CHAN_AREF_GROUND; + subd->chan_desc->chans[0].nb_bits = boardtype.aobits; + + subd->rng_desc = boardtype.ao_range_table; + + subd->insn_read = ni_ao_insn_read; + if (boardtype.reg_type & ni_reg_6xxx_mask) + subd->insn_write = &ni_ao_insn_write_671x; + else + subd->insn_write = &ni_ao_insn_write; + + + if (boardtype.ao_fifo_depth) { + subd->flags |= A4L_SUBD_CMD | A4L_SUBD_MMAP; + subd->do_cmd = &ni_ao_cmd; + subd->cmd_mask = &mio_ao_cmd_mask; + subd->do_cmdtest = &ni_ao_cmdtest; + subd->trigger = ni_ao_inttrig; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) + subd->munge = &ni_ao_munge; + } + + subd->cancel = &ni_ao_reset; + + } else { + a4l_dbg(1, drv_dbg, dev, + "mio_common: AO subdevice not present\n"); + subd->flags = A4L_SUBD_UNUSED; + } + + ret = a4l_add_subd(dev, subd); + if(ret != NI_AO_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: AO subdevice registered\n"); + + if ((boardtype.reg_type & ni_reg_67xx_mask)) + init_ao_67xx(dev); + + /* digital i/o subdevice */ + + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, "mio_common: registering DIO subdevice...\n"); + a4l_dbg(1, drv_dbg, dev, + "mio_common: DIO: %d channels\n", + boardtype.num_p0_dio_channels); + + subd->flags = A4L_SUBD_DIO; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = boardtype.num_p0_dio_channels; + subd->chan_desc->chans[0].flags = A4L_CHAN_AREF_GROUND; + subd->chan_desc->chans[0].nb_bits = 1; + devpriv->io_bits = 0; /* all bits input */ + + subd->rng_desc = &range_digital; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + + if (subd->chan_desc->length == 8) + subd->insn_bits = ni_m_series_dio_insn_bits_8; + else + subd->insn_bits = ni_m_series_dio_insn_bits_32; + + subd->insn_config = ni_m_series_dio_insn_config; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + + a4l_dbg(1, drv_dbg, dev, + "mio_common: DIO: command feature available\n"); + + subd->flags |= A4L_SUBD_CMD; + subd->do_cmd = ni_cdio_cmd; + subd->do_cmdtest = ni_cdio_cmdtest; + subd->cmd_mask = &mio_dio_cmd_mask; + subd->cancel = ni_cdio_cancel; + subd->trigger = ni_cdo_inttrig; + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command); + ni_writel(devpriv->io_bits, M_Offset_DIO_Direction); + } else { + + subd->insn_bits = ni_dio_insn_bits; + subd->insn_config = ni_dio_insn_config; + devpriv->dio_control = DIO_Pins_Dir(devpriv->io_bits); + ni_writew(devpriv->dio_control, DIO_Control_Register); + } + + ret = a4l_add_subd(dev, subd); + if(ret != NI_DIO_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: DIO subdevice registered\n"); + + /* 8255 device */ + subd = a4l_alloc_subd(sizeof(subd_8255_t), NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, "mio_common: registering 8255 subdevice...\n"); + + if (boardtype.has_8255) { + devpriv->subd_8255.cb_arg = (unsigned long)dev; + devpriv->subd_8255.cb_func = ni_8255_callback; + subdev_8255_init(subd); + } else { + a4l_dbg(1, drv_dbg, dev, + "mio_common: 8255 subdevice not present\n"); + subd->flags = A4L_SUBD_UNUSED; + } + + ret = a4l_add_subd(dev, subd); + if(ret != NI_8255_DIO_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: 8255 subdevice registered\n"); + + /* formerly general purpose counter/timer device, but no longer used */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + subd->flags = A4L_SUBD_UNUSED; + ret = a4l_add_subd(dev, subd); + if(ret != NI_UNUSED_SUBDEV) + return ret; + + /* calibration subdevice -- ai and ao */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, "mio_common: registering calib subdevice...\n"); + + subd->flags = A4L_SUBD_CALIB; + if (boardtype.reg_type & ni_reg_m_series_mask) { + /* internal PWM analog output + used for AI nonlinearity calibration */ + a4l_dbg(1, drv_dbg, dev, + "mio_common: calib: M series calibration"); + subd->insn_config = ni_m_series_pwm_config; + ni_writel(0x0, M_Offset_Cal_PWM); + } else if (boardtype.reg_type == ni_reg_6143) { + /* internal PWM analog output + used for AI nonlinearity calibration */ + a4l_dbg(1, drv_dbg, dev, + "mio_common: calib: 6143 calibration"); + subd->insn_config = ni_6143_pwm_config; + } else { + a4l_dbg(1, drv_dbg, dev, + "mio_common: calib: common calibration"); + subd->insn_read = ni_calib_insn_read; + subd->insn_write = ni_calib_insn_write; + caldac_setup(dev, subd); + } + + ret = a4l_add_subd(dev, subd); + if(ret != NI_CALIBRATION_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: calib subdevice registered\n"); + + /* EEPROM */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: registering EEPROM subdevice...\n"); + + subd->flags = A4L_SUBD_MEMORY; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 8; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + subd->chan_desc->length = M_SERIES_EEPROM_SIZE; + subd->insn_read = ni_m_series_eeprom_insn_read; + } else { + subd->chan_desc->length = 512; + subd->insn_read = ni_eeprom_insn_read; + } + + a4l_dbg(1, drv_dbg, dev, + "mio_common: EEPROM: size = %lu\n", subd->chan_desc->length); + + ret = a4l_add_subd(dev, subd); + if(ret != NI_EEPROM_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: EEPROM subdevice registered\n"); + + /* PFI */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: registering PFI(DIO) subdevice...\n"); + + subd->flags = A4L_SUBD_DIO; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 1; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + unsigned int i; + subd->chan_desc->length = 16; + ni_writew(devpriv->dio_state, M_Offset_PFI_DO); + for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) { + ni_writew(devpriv->pfi_output_select_reg[i], + M_Offset_PFI_Output_Select(i + 1)); + } + } else + subd->chan_desc->length = 10; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: PFI: %lu bits...\n", subd->chan_desc->length); + + if (boardtype.reg_type & ni_reg_m_series_mask) { + subd->insn_bits = ni_pfi_insn_bits; + } + + subd->insn_config = ni_pfi_insn_config; + ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0); + + ret = a4l_add_subd(dev, subd); + if(ret != NI_PFI_DIO_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: PFI subdevice registered\n"); + + /* cs5529 calibration adc */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + +#if 0 /* TODO: add subdevices callbacks */ + subd->flags = A4L_SUBD_AI; + + if (boardtype.reg_type & ni_reg_67xx_mask) { + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = boardtype.n_aochan; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 16; + + /* one channel for each analog output channel */ + subd->rng_desc = &range_unknown; /* XXX */ + s->insn_read = cs5529_ai_insn_read; + init_cs5529(dev); + } else +#endif /* TODO: add subdevices callbacks */ + subd->flags = A4L_SUBD_UNUSED; + + ret = a4l_add_subd(dev, subd); + if(ret != NI_CS5529_CALIBRATION_SUBDEV) + return ret; + + /* Serial */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: registering serial subdevice...\n"); + + subd->flags = A4L_SUBD_SERIAL; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = 1; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 8; + + subd->insn_config = ni_serial_insn_config; + + devpriv->serial_interval_ns = 0; + devpriv->serial_hw_mode = 0; + + ret = a4l_add_subd(dev, subd); + if(ret != NI_SERIAL_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, "mio_common: serial subdevice registered\n"); + + /* RTSI */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + +#if 1 /* TODO: add RTSI subdevice */ + subd->flags = A4L_SUBD_UNUSED; + ni_rtsi_init(dev); + +#else /* TODO: add RTSI subdevice */ + subd->flags = A4L_SUBD_DIO; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = 8; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 1; + + subd->insn_bits = ni_rtsi_insn_bits; + subd->insn_config = ni_rtsi_insn_config; + ni_rtsi_init(dev); + +#endif /* TODO: add RTSI subdevice */ + + ret = a4l_add_subd(dev, subd); + if(ret != NI_RTSI_SUBDEV) + return ret; + + if (boardtype.reg_type & ni_reg_m_series_mask) { + counter_variant = ni_gpct_variant_m_series; + } else { + counter_variant = ni_gpct_variant_e_series; + } + devpriv->counter_dev = ni_gpct_device_construct(dev, + &ni_gpct_write_register, &ni_gpct_read_register, + counter_variant, NUM_GPCT); + + /* General purpose counters */ + for (j = 0; j < NUM_GPCT; ++j) { + struct ni_gpct *counter; + + subd = a4l_alloc_subd(sizeof(struct ni_gpct), NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: registering GPCT[%d] subdevice...\n", j); + + subd->flags = A4L_SUBD_COUNTER; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = 3; + subd->chan_desc->chans[0].flags = 0; + + if (boardtype.reg_type & ni_reg_m_series_mask) + subd->chan_desc->chans[0].nb_bits = 32; + else + subd->chan_desc->chans[0].nb_bits = 24; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: GPCT[%d]: %lu bits\n", + j, subd->chan_desc->chans[0].nb_bits); + + subd->insn_read = ni_gpct_insn_read; + subd->insn_write = ni_gpct_insn_write; + subd->insn_config = ni_gpct_insn_config; + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + + a4l_dbg(1, drv_dbg, dev, + "mio_common: GPCT[%d]: command feature available\n", j); + subd->flags |= A4L_SUBD_CMD; + subd->cmd_mask = &ni_tio_cmd_mask; + subd->do_cmd = ni_gpct_cmd; + subd->do_cmdtest = ni_gpct_cmdtest; + subd->cancel = ni_gpct_cancel; +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + + counter = (struct ni_gpct *)subd->priv; + a4l_lock_init(&counter->lock); + counter->chip_index = 0; + counter->counter_index = j; + counter->counter_dev = devpriv->counter_dev; + devpriv->counter_dev->counters[j] = counter; + + ni_tio_init_counter(counter); + + ret = a4l_add_subd(dev, subd); + if(ret != NI_GPCT_SUBDEV(j)) + return ret; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: GCPT[%d] subdevice registered\n", j); + } + + /* Frequency output */ + subd = a4l_alloc_subd(0, NULL); + if(subd == NULL) + return -ENOMEM; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: registering counter subdevice...\n"); + + subd->flags = A4L_SUBD_COUNTER; + + subd->chan_desc = kmalloc(sizeof(a4l_chdesc_t) + + sizeof(a4l_chan_t), GFP_KERNEL); + subd->chan_desc->mode = A4L_CHAN_GLOBAL_CHANDESC; + subd->chan_desc->length = 1; + subd->chan_desc->chans[0].flags = 0; + subd->chan_desc->chans[0].nb_bits = 4; + + subd->insn_read = ni_freq_out_insn_read; + subd->insn_write = ni_freq_out_insn_write; + subd->insn_config = ni_freq_out_insn_config; + + ret = a4l_add_subd(dev, subd); + if(ret != NI_FREQ_OUT_SUBDEV) + return ret; + + a4l_dbg(1, drv_dbg, dev, + "mio_common: counter subdevice registered\n"); + + a4l_dbg(1, drv_dbg, dev, "mio_common: initializing AI...\n"); + + /* ai configuration */ + ni_ai_reset(a4l_get_subd(dev, NI_AI_SUBDEV)); + if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) { + // BEAM is this needed for PCI-6143 ?? + devpriv->clock_and_fout = + Slow_Internal_Time_Divide_By_2 | + Slow_Internal_Timebase | + Clock_To_Board_Divide_By_2 | + Clock_To_Board | + AI_Output_Divide_By_2 | AO_Output_Divide_By_2; + } else { + devpriv->clock_and_fout = + Slow_Internal_Time_Divide_By_2 | + Slow_Internal_Timebase | + Clock_To_Board_Divide_By_2 | Clock_To_Board; + } + devpriv->stc_writew(dev, devpriv->clock_and_fout, + Clock_and_FOUT_Register); + + a4l_dbg(1, drv_dbg, dev, "mio_common: AI initialization OK\n"); + + a4l_dbg(1, drv_dbg, dev, "mio_common: initializing A0...\n"); + + /* analog output configuration */ + ni_ao_reset(a4l_get_subd(dev, NI_AO_SUBDEV)); + + if (a4l_get_irq(dev) != A4L_IRQ_UNUSED) { + devpriv->stc_writew(dev, + (devpriv->irq_polarity ? Interrupt_Output_Polarity : 0) | + (Interrupt_Output_On_3_Pins & 0) | Interrupt_A_Enable | + Interrupt_B_Enable | + Interrupt_A_Output_Select(devpriv->irq_pin) | + Interrupt_B_Output_Select(devpriv->irq_pin), + Interrupt_Control_Register); + } + + a4l_dbg(1, drv_dbg, dev, "mio_common: A0 initialization OK\n"); + + /* DMA setup */ + + a4l_dbg(1, drv_dbg, dev, "mio_common: DMA setup\n"); + + ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select); + ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select); + + if (boardtype.reg_type & ni_reg_6xxx_mask) { + ni_writeb(0, Magic_611x); + } else if (boardtype.reg_type & ni_reg_m_series_mask) { + int channel; + for (channel = 0; channel < boardtype.n_aochan; ++channel) { + ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel)); + ni_writeb(0x0, + M_Offset_AO_Reference_Attenuation(channel)); + } + ni_writeb(0x0, M_Offset_AO_Calibration); + } + + a4l_dbg(1, drv_dbg, dev, "mio_common: attach procedure complete\n"); + + return 0; +} + +MODULE_DESCRIPTION("Analogy support for NI DAQ-STC based boards"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL_GPL(range_ni_E_ai); +EXPORT_SYMBOL_GPL(range_ni_E_ai_limited); +EXPORT_SYMBOL_GPL(range_ni_E_ai_limited14); +EXPORT_SYMBOL_GPL(range_ni_E_ai_bipolar4); +EXPORT_SYMBOL_GPL(range_ni_E_ai_611x); +EXPORT_SYMBOL_GPL(range_ni_M_ai_622x); +EXPORT_SYMBOL_GPL(range_ni_M_ai_628x); +EXPORT_SYMBOL_GPL(range_ni_S_ai_6143); +EXPORT_SYMBOL_GPL(range_ni_E_ao_ext); +EXPORT_SYMBOL_GPL(ni_E_interrupt); +EXPORT_SYMBOL_GPL(ni_E_init); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.c relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,844 @@ +/** + * @file + * Hardware driver for NI Mite PCI interface chip + * + * Copyright (C) 1999 David A. Schleef + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The NI Mite driver was originally written by Tomasz Motylewski + * <...>, and ported to comedi by ds. + * + * References for specifications: + * + * 321747b.pdf Register Level Programmer Manual (obsolete) + * 321747c.pdf Register Level Programmer Manual (new) + * DAQ-STC reference manual + * + * Other possibly relevant info: + * + * 320517c.pdf User manual (obsolete) + * 320517f.pdf User manual (new) + * 320889a.pdf delete + * 320906c.pdf maximum signal ratings + * 321066a.pdf about 16x + * 321791a.pdf discontinuation of at-mio-16e-10 rev. c + * 321808a.pdf about at-mio-16e-10 rev P + * 321837a.pdf discontinuation of at-mio-16de-10 rev d + * 321838a.pdf about at-mio-16de-10 rev N + * + * ISSUES: + */ + +#include + +#include "mite.h" + +#ifdef CONFIG_DEBUG_MITE +#define MDPRINTK(fmt, args...) rtdm_printk(fmt, ##args) +#else /* !CONFIG_DEBUG_MITE */ +#define MDPRINTK(fmt, args...) +#endif /* CONFIG_DEBUG_MITE */ + +static LIST_HEAD(mite_devices); + +static struct pci_device_id mite_id[] = { + {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_ANY_ID), }, + {0, } +}; + +static int mite_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int i; + struct mite_struct *mite; + + mite = kmalloc(sizeof(struct mite_struct), GFP_KERNEL); + if(mite == NULL) + return -ENOMEM; + + memset(mite, 0, sizeof(struct mite_struct)); + + a4l_lock_init(&mite->lock); + mite->pcidev = dev; + + for(i = 0; i < MAX_MITE_DMA_CHANNELS; i++) { + mite->channels[i].mite = mite; + mite->channels[i].channel = i; + mite->channels[i].done = 1; + } + + list_add(&mite->list, &mite_devices); + + return 0; +} + +static void mite_remove(struct pci_dev *dev) +{ + struct list_head *this; + + list_for_each(this, &mite_devices) { + struct mite_struct *mite = + list_entry(this, struct mite_struct, list); + + if(mite->pcidev == dev) { + list_del(this); + kfree(mite); + break; + } + } +} + +static struct pci_driver mite_driver = { + .name = "mite", + .id_table = mite_id, + .probe = mite_probe, + .remove = mite_remove, +}; + +int mite_setup(struct mite_struct *mite, int use_iodwbsr_1) +{ + unsigned long length; + resource_size_t addr; + int i; + u32 csigr_bits; + unsigned unknown_dma_burst_bits; + + __a4l_dbg(1, drv_dbg, "mite: starting setup...\n"); + + if(pci_enable_device(mite->pcidev)){ + __a4l_err("error enabling mite\n"); + return -EIO; + } + + pci_set_master(mite->pcidev); + + if (pci_request_regions( mite->pcidev, "mite")) { + __a4l_err("failed to request mite io regions\n"); + return -EIO; + }; + + + /* The PCI BAR0 is the Mite */ + addr = pci_resource_start(mite->pcidev, 0); + length = pci_resource_len(mite->pcidev, 0); + mite->mite_phys_addr = addr; + mite->mite_io_addr = ioremap(addr, length); + if (!mite->mite_io_addr) { + __a4l_err("failed to remap mite io memory address\n"); + return -ENOMEM; + } + + __a4l_dbg(1, drv_dbg, + "mite: bar0(mite) 0x%08llx mapped to %p\n", + (unsigned long long)mite->mite_phys_addr, + mite->mite_io_addr); + + + /* The PCI BAR1 is the DAQ */ + addr = pci_resource_start(mite->pcidev, 1); + length = pci_resource_len(mite->pcidev, 1); + mite->daq_phys_addr = addr; + mite->daq_io_addr = ioremap(mite->daq_phys_addr, length); + if (!mite->daq_io_addr) { + __a4l_err("failed to remap daq io memory address\n"); + return -ENOMEM; + } + + __a4l_dbg(1, drv_dbg, + "mite: bar0(daq) 0x%08llx mapped to %p\n", + (unsigned long long)mite->daq_phys_addr, + mite->daq_io_addr); + + if (use_iodwbsr_1) { + + __a4l_dbg(1, drv_dbg, + "mite: using I/O Window Base Size register 1\n"); + + writel(0, mite->mite_io_addr + MITE_IODWBSR); + writel(mite-> + daq_phys_addr | WENAB | + MITE_IODWBSR_1_WSIZE_bits(length), + mite->mite_io_addr + MITE_IODWBSR_1); + writel(0, mite->mite_io_addr + MITE_IODWCR_1); + } else { + writel(mite->daq_phys_addr | WENAB, + mite->mite_io_addr + MITE_IODWBSR); + } + + /* Make sure dma bursts work. I got this from running a bus analyzer + on a pxi-6281 and a pxi-6713. 6713 powered up with register value + of 0x61f and bursts worked. 6281 powered up with register value of + 0x1f and bursts didn't work. The NI windows driver reads the register, + then does a bitwise-or of 0x600 with it and writes it back. + */ + unknown_dma_burst_bits = + readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG); + unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS; + writel(unknown_dma_burst_bits, + mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG); + + csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR); + mite->num_channels = mite_csigr_dmac(csigr_bits); + if (mite->num_channels > MAX_MITE_DMA_CHANNELS) { + __a4l_err("MITE: bug? chip claims to have %i dma channels. " + "Setting to %i.\n", + mite->num_channels, MAX_MITE_DMA_CHANNELS); + mite->num_channels = MAX_MITE_DMA_CHANNELS; + } + + __a4l_dbg(1, drv_dbg, + "mite: version = %i, type = %i, mite mode = %i, " + "interface mode = %i\n", + mite_csigr_version(csigr_bits), + mite_csigr_type(csigr_bits), + mite_csigr_mmode(csigr_bits), + mite_csigr_imode(csigr_bits)); + __a4l_dbg(1, drv_dbg, + "mite: num channels = %i, write post fifo depth = %i, " + "wins = %i, iowins = %i\n", + mite_csigr_dmac(csigr_bits), + mite_csigr_wpdep(csigr_bits), + mite_csigr_wins(csigr_bits), + mite_csigr_iowins(csigr_bits)); + + for (i = 0; i < mite->num_channels; i++) { + /* Registers the channel as a free one */ + mite->channel_allocated[i] = 0; + /* Reset the channel */ + writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i)); + /* Disable interrupts */ + writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | + CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | + CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE, + mite->mite_io_addr + MITE_CHCR(i)); + + __a4l_dbg(1, drv_dbg, "mite: channel[%d] initialized\n", i); + } + + mite->used = 1; + + return 0; +} + +void mite_unsetup(struct mite_struct *mite) +{ + if (!mite) + return; + + if (mite->mite_io_addr) { + iounmap(mite->mite_io_addr); + mite->mite_io_addr = NULL; + } + + if (mite->daq_io_addr) { + iounmap(mite->daq_io_addr); + mite->daq_io_addr = NULL; + } + + if(mite->used) + pci_release_regions( mite->pcidev ); + + mite->used = 0; +} + +void mite_list_devices(void) +{ + struct list_head *this; + + printk("Analogy: MITE: Available NI device IDs:"); + list_for_each(this, &mite_devices) { + struct mite_struct *mite = + list_entry(this, struct mite_struct, list); + + printk(" 0x%04x", mite_device_id(mite)); + if(mite->used) + printk("(used)"); + } + + printk("\n"); +} + + + +struct mite_struct * mite_find_device(int bus, int slot, unsigned short device_id) +{ + struct list_head *this; + + list_for_each(this, &mite_devices) { + struct mite_struct *mite = + list_entry(this, struct mite_struct, list); + + if(mite->pcidev->device != device_id) + continue; + + if((bus <= 0 && slot <= 0) || + (bus == mite->pcidev->bus->number && + slot == PCI_SLOT(mite->pcidev->devfn))) + return mite; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(mite_find_device); + +struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, + struct mite_dma_descriptor_ring *ring, + unsigned min_channel, + unsigned max_channel) +{ + int i; + unsigned long flags; + struct mite_channel *channel = NULL; + + __a4l_dbg(1, drv_dbg, + "mite: mite_request_channel_in_range: " + "min_channel = %u, max_channel = %u\n", + min_channel, max_channel); + + /* spin lock so mite_release_channel can be called safely from interrupts */ + a4l_lock_irqsave(&mite->lock, flags); + for (i = min_channel; i <= max_channel; ++i) { + + __a4l_dbg(1, drv_dbg, + "mite: mite_request_channel_in_range: " + "channel[%d] allocated = %d\n", + i, mite->channel_allocated[i]); + + if (mite->channel_allocated[i] == 0) { + mite->channel_allocated[i] = 1; + channel = &mite->channels[i]; + channel->ring = ring; + break; + } + } + a4l_unlock_irqrestore(&mite->lock, flags); + return channel; +} + +void mite_release_channel(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + unsigned long flags; + + /* Spin lock to prevent races with mite_request_channel */ + a4l_lock_irqsave(&mite->lock, flags); + if (mite->channel_allocated[mite_chan->channel]) { + /* disable all channel's interrupts */ + writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | + CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE | + CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | + CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE, + mite->mite_io_addr + MITE_CHCR(mite_chan->channel)); + mite_dma_disarm(mite_chan); + mite_dma_reset(mite_chan); + mite->channel_allocated[mite_chan->channel] = 0; + mite_chan->ring = NULL; + mmiowb(); + } + a4l_unlock_irqrestore(&mite->lock, flags); +} + +void mite_dma_arm(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + int chor; + unsigned long flags; + + MDPRINTK("mite_dma_arm ch%i\n", mite_chan->channel); + /* Memory barrier is intended to insure any twiddling with the buffer + is done before writing to the mite to arm dma transfer */ + smp_mb(); + /* arm */ + chor = CHOR_START; + a4l_lock_irqsave(&mite->lock, flags); + mite_chan->done = 0; + writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); + mmiowb(); + a4l_unlock_irqrestore(&mite->lock, flags); +} + +void mite_dma_disarm(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + unsigned chor; + + /* disarm */ + chor = CHOR_ABORT; + writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); +} + +int mite_buf_change(struct mite_dma_descriptor_ring *ring, a4l_subd_t *subd) +{ + a4l_buf_t *buf = subd->buf; + unsigned int n_links; + int i; + + if (ring->descriptors) { + pci_free_consistent(ring->pcidev, + ring->n_links * sizeof(struct mite_dma_descriptor), + ring->descriptors, ring->descriptors_dma_addr); + } + ring->descriptors = NULL; + ring->descriptors_dma_addr = 0; + ring->n_links = 0; + + if (buf->size == 0) { + return 0; + } + n_links = buf->size >> PAGE_SHIFT; + + MDPRINTK("ring->pcidev=%p, n_links=0x%04x\n", ring->pcidev, n_links); + + ring->descriptors = + pci_alloc_consistent(ring->pcidev, + n_links * sizeof(struct mite_dma_descriptor), + &ring->descriptors_dma_addr); + if (!ring->descriptors) { + printk("MITE: ring buffer allocation failed\n"); + return -ENOMEM; + } + ring->n_links = n_links; + + for (i = 0; i < n_links; i++) { + ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE); + ring->descriptors[i].addr = cpu_to_le32(buf->pg_list[i]); + ring->descriptors[i].next = + cpu_to_le32(ring->descriptors_dma_addr + + (i + 1) * sizeof(struct mite_dma_descriptor)); + } + + ring->descriptors[n_links - 1].next = + cpu_to_le32(ring->descriptors_dma_addr); + + /* Barrier is meant to insure that all the writes to the dma descriptors + have completed before the dma controller is commanded to read them */ + smp_wmb(); + + return 0; +} + +void mite_prep_dma(struct mite_channel *mite_chan, + unsigned int num_device_bits, unsigned int num_memory_bits) +{ + unsigned int chor, chcr, mcr, dcr, lkcr; + struct mite_struct *mite = mite_chan->mite; + + MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel); + + /* reset DMA and FIFO */ + chor = CHOR_DMARESET | CHOR_FRESET; + writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); + + /* short link chaining mode */ + chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE | + CHCR_BURSTEN; + /* + * Link Complete Interrupt: interrupt every time a link + * in MITE_RING is completed. This can generate a lot of + * extra interrupts, but right now we update the values + * of buf_int_ptr and buf_int_count at each interrupt. A + * better method is to poll the MITE before each user + * "read()" to calculate the number of bytes available. + */ + chcr |= CHCR_SET_LC_IE; + if (num_memory_bits == 32 && num_device_bits == 16) { + /* Doing a combined 32 and 16 bit byteswap gets the 16 + bit samples into the fifo in the right order. + Tested doing 32 bit memory to 16 bit device + transfers to the analog out of a pxi-6281, which + has mite version = 1, type = 4. This also works + for dma reads from the counters on e-series boards. + */ + chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY; + } + + if (mite_chan->dir == A4L_INPUT) { + chcr |= CHCR_DEV_TO_MEM; + } + writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel)); + + /* to/from memory */ + mcr = CR_RL(64) | CR_ASEQUP; + switch (num_memory_bits) { + case 8: + mcr |= CR_PSIZE8; + break; + case 16: + mcr |= CR_PSIZE16; + break; + case 32: + mcr |= CR_PSIZE32; + break; + default: + __a4l_err("MITE: bug! " + "invalid mem bit width for dma transfer\n"); + break; + } + writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel)); + + /* from/to device */ + dcr = CR_RL(64) | CR_ASEQUP; + dcr |= CR_PORTIO | CR_AMDEVICE | CR_REQSDRQ(mite_chan->channel); + switch (num_device_bits) { + case 8: + dcr |= CR_PSIZE8; + break; + case 16: + dcr |= CR_PSIZE16; + break; + case 32: + dcr |= CR_PSIZE32; + break; + default: + __a4l_info("MITE: bug! " + "invalid dev bit width for dma transfer\n"); + break; + } + writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel)); + + /* reset the DAR */ + writel(0, mite->mite_io_addr + MITE_DAR(mite_chan->channel)); + + /* the link is 32bits */ + lkcr = CR_RL(64) | CR_ASEQUP | CR_PSIZE32; + writel(lkcr, mite->mite_io_addr + MITE_LKCR(mite_chan->channel)); + + /* starting address for link chaining */ + writel(mite_chan->ring->descriptors_dma_addr, + mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); + + MDPRINTK("exit mite_prep_dma\n"); +} + +u32 mite_device_bytes_transferred(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel)); +} + +u32 mite_bytes_in_transit(struct mite_channel * mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + return readl(mite->mite_io_addr + + MITE_FCR(mite_chan->channel)) & 0x000000FF; +} + +/* Returns lower bound for number of bytes transferred from device to memory */ +u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan) +{ + u32 device_byte_count; + + device_byte_count = mite_device_bytes_transferred(mite_chan); + return device_byte_count - mite_bytes_in_transit(mite_chan); +} + +/* Returns upper bound for number of bytes transferred from device to memory */ +u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan) +{ + u32 in_transit_count; + + in_transit_count = mite_bytes_in_transit(mite_chan); + return mite_device_bytes_transferred(mite_chan) - in_transit_count; +} + +/* Returns lower bound for number of bytes read from memory for transfer to device */ +u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan) +{ + u32 device_byte_count; + + device_byte_count = mite_device_bytes_transferred(mite_chan); + return device_byte_count + mite_bytes_in_transit(mite_chan); +} + +/* Returns upper bound for number of bytes read from memory for transfer to device */ +u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan) +{ + u32 in_transit_count; + + in_transit_count = mite_bytes_in_transit(mite_chan); + return mite_device_bytes_transferred(mite_chan) + in_transit_count; +} + +int mite_sync_input_dma(struct mite_channel *mite_chan, a4l_subd_t *subd) +{ + unsigned int nbytes_lb, nbytes_ub; + + nbytes_lb = mite_bytes_written_to_memory_lb(mite_chan); + nbytes_ub = mite_bytes_written_to_memory_ub(mite_chan); + + if(a4l_buf_prepare_absput(subd, nbytes_ub) != 0) { + __a4l_err("MITE: DMA overwrite of free area\n"); + return -EPIPE; + } + + return a4l_buf_commit_absput(subd, nbytes_lb); +} + +int mite_sync_output_dma(struct mite_channel *mite_chan, a4l_subd_t *subd) +{ + a4l_buf_t *buf = subd->buf; + unsigned int nbytes_ub, nbytes_lb; + int err; + + nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan); + nbytes_ub = mite_bytes_read_from_memory_ub(mite_chan); + + err = a4l_buf_prepare_absget(subd, nbytes_ub); + if(err < 0) { + __a4l_info("MITE: DMA underrun\n"); + return -EPIPE; + } + + err = a4l_buf_commit_absget(subd, nbytes_lb); + + /* If the MITE has already transfered more than required, we + can disable it */ + if (test_bit(A4L_BUF_EOA_NR, &buf->flags)) + writel(CHOR_STOP, + mite_chan->mite->mite_io_addr + + MITE_CHOR(mite_chan->channel)); + + return err; +} + +u32 mite_get_status(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + u32 status; + unsigned long flags; + + a4l_lock_irqsave(&mite->lock, flags); + status = readl(mite->mite_io_addr + MITE_CHSR(mite_chan->channel)); + if (status & CHSR_DONE) { + mite_chan->done = 1; + writel(CHOR_CLRDONE, + mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); + } + mmiowb(); + a4l_unlock_irqrestore(&mite->lock, flags); + return status; +} + +int mite_done(struct mite_channel *mite_chan) +{ + struct mite_struct *mite = mite_chan->mite; + unsigned long flags; + int done; + + mite_get_status(mite_chan); + a4l_lock_irqsave(&mite->lock, flags); + done = mite_chan->done; + a4l_unlock_irqrestore(&mite->lock, flags); + return done; +} + +#ifdef CONFIG_DEBUG_MITE + +static void mite_decode(const char *const bit_str[], unsigned int bits); + +/* names of bits in mite registers */ + +static const char *const mite_CHOR_strings[] = { + "start", "cont", "stop", "abort", + "freset", "clrlc", "clrrb", "clrdone", + "clr_lpause", "set_lpause", "clr_send_tc", + "set_send_tc", "12", "13", "14", + "15", "16", "17", "18", + "19", "20", "21", "22", + "23", "24", "25", "26", + "27", "28", "29", "30", + "dmareset", +}; + +static const char *const mite_CHCR_strings[] = { + "continue", "ringbuff", "2", "3", + "4", "5", "6", "7", + "8", "9", "10", "11", + "12", "13", "bursten", "fifodis", + "clr_cont_rb_ie", "set_cont_rb_ie", "clr_lc_ie", "set_lc_ie", + "clr_drdy_ie", "set_drdy_ie", "clr_mrdy_ie", "set_mrdy_ie", + "clr_done_ie", "set_done_ie", "clr_sar_ie", "set_sar_ie", + "clr_linkp_ie", "set_linkp_ie", "clr_dma_ie", "set_dma_ie", +}; + +static const char *const mite_MCR_strings[] = { + "amdevice", "1", "2", "3", + "4", "5", "portio", "portvxi", + "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "11", + "12", "13", "blocken", "berhand", + "reqsintlim/reqs0", "reqs1", "reqs2", "rd32", + "rd512", "rl1", "rl2", "rl8", + "24", "25", "26", "27", + "28", "29", "30", "stopen", +}; + +static const char *const mite_DCR_strings[] = { + "amdevice", "1", "2", "3", + "4", "5", "portio", "portvxi", + "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "aseqxp2", + "aseqxp8", "13", "blocken", "berhand", + "reqsintlim", "reqs1", "reqs2", "rd32", + "rd512", "rl1", "rl2", "rl8", + "23", "24", "25", "27", + "28", "wsdevc", "wsdevs", "rwdevpack", +}; + +static const char *const mite_LKCR_strings[] = { + "amdevice", "1", "2", "3", + "4", "5", "portio", "portvxi", + "psizebyte", "psizehalf (byte & half = word)", "asequp", "aseqdown", + "12", "13", "14", "berhand", + "16", "17", "18", "rd32", + "rd512", "rl1", "rl2", "rl8", + "24", "25", "26", "27", + "28", "29", "30", "chngend", +}; + +static const char *const mite_CHSR_strings[] = { + "d.err0", "d.err1", "m.err0", "m.err1", + "l.err0", "l.err1", "drq0", "drq1", + "end", "xferr", "operr0", "operr1", + "stops", "habort", "sabort", "error", + "16", "conts_rb", "18", "linkc", + "20", "drdy", "22", "mrdy", + "24", "done", "26", "sars", + "28", "lpauses", "30", "int", +}; + +void mite_dump_regs(struct mite_channel *mite_chan) +{ + unsigned long mite_io_addr = + (unsigned long)mite_chan->mite->mite_io_addr; + unsigned long addr = 0; + unsigned long temp = 0; + + printk("mite_dump_regs ch%i\n", mite_chan->channel); + printk("mite address is =0x%08lx\n", mite_io_addr); + + addr = mite_io_addr + MITE_CHOR(mite_chan->channel); + printk("mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_CHOR_strings, temp); + addr = mite_io_addr + MITE_CHCR(mite_chan->channel); + printk("mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_CHCR_strings, temp); + addr = mite_io_addr + MITE_TCR(mite_chan->channel); + printk("mite status[TCR] at 0x%08lx =0x%08x\n", addr, + readl((void *)addr)); + addr = mite_io_addr + MITE_MCR(mite_chan->channel); + printk("mite status[MCR] at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_MCR_strings, temp); + + addr = mite_io_addr + MITE_MAR(mite_chan->channel); + printk("mite status[MAR] at 0x%08lx =0x%08x\n", addr, + readl((void *)addr)); + addr = mite_io_addr + MITE_DCR(mite_chan->channel); + printk("mite status[DCR] at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_DCR_strings, temp); + addr = mite_io_addr + MITE_DAR(mite_chan->channel); + printk("mite status[DAR] at 0x%08lx =0x%08x\n", addr, + readl((void *)addr)); + addr = mite_io_addr + MITE_LKCR(mite_chan->channel); + printk("mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_LKCR_strings, temp); + addr = mite_io_addr + MITE_LKAR(mite_chan->channel); + printk("mite status[LKAR]at 0x%08lx =0x%08x\n", addr, + readl((void *)addr)); + + addr = mite_io_addr + MITE_CHSR(mite_chan->channel); + printk("mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, temp = + readl((void *)addr)); + mite_decode(mite_CHSR_strings, temp); + addr = mite_io_addr + MITE_FCR(mite_chan->channel); + printk("mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, + readl((void *)addr)); +} + + +static void mite_decode(const char *const bit_str[], unsigned int bits) +{ + int i; + + for (i = 31; i >= 0; i--) { + if (bits & (1 << i)) { + printk(" %s", bit_str[i]); + } + } + printk("\n"); +} + +#endif /* CONFIG_DEBUG_MITE */ + + +static int __init mite_init(void) +{ + int err; + + /* Register the mite's PCI driver */ + err = pci_register_driver(&mite_driver); + + if(err == 0) + mite_list_devices(); + + return err; +} + +static void __exit mite_cleanup(void) +{ + + /* Unregister the PCI structure driver */ + pci_unregister_driver(&mite_driver); + + /* Just paranoia... */ + while(&mite_devices != mite_devices.next) { + struct list_head *this = mite_devices.next; + struct mite_struct *mite = + list_entry(this, struct mite_struct, list); + + list_del(this); + kfree(mite); + } +} + +MODULE_LICENSE("GPL"); +module_init(mite_init); +module_exit(mite_cleanup); + +EXPORT_SYMBOL_GPL(mite_dma_arm); +EXPORT_SYMBOL_GPL(mite_dma_disarm); +EXPORT_SYMBOL_GPL(mite_sync_input_dma); +EXPORT_SYMBOL_GPL(mite_sync_output_dma); +EXPORT_SYMBOL_GPL(mite_setup); +EXPORT_SYMBOL_GPL(mite_unsetup); +EXPORT_SYMBOL_GPL(mite_list_devices); +EXPORT_SYMBOL_GPL(mite_request_channel_in_range); +EXPORT_SYMBOL_GPL(mite_release_channel); +EXPORT_SYMBOL_GPL(mite_prep_dma); +EXPORT_SYMBOL_GPL(mite_buf_change); +EXPORT_SYMBOL_GPL(mite_bytes_written_to_memory_lb); +EXPORT_SYMBOL_GPL(mite_bytes_written_to_memory_ub); +EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_lb); +EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub); +EXPORT_SYMBOL_GPL(mite_bytes_in_transit); +EXPORT_SYMBOL_GPL(mite_get_status); +EXPORT_SYMBOL_GPL(mite_done); +#ifdef CONFIG_DEBUG_MITE +EXPORT_SYMBOL_GPL(mite_decode); +EXPORT_SYMBOL_GPL(mite_dump_regs); +#endif /* CONFIG_DEBUG_MITE */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.h relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/mite.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,436 @@ +/** + * @file + * Hardware driver for NI Mite PCI interface chip + * @note Copyright (C) 1999 David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef __ANALOGY_NI_MITE_H__ +#define __ANALOGY_NI_MITE_H__ + +#include + +#include + +#define PCI_VENDOR_ID_NATINST 0x1093 +#define PCI_MITE_SIZE 4096 +#define PCI_DAQ_SIZE 4096 +#define PCI_DAQ_SIZE_660X 8192 +#define PCIMIO_COMPAT +#define MAX_MITE_DMA_CHANNELS 8 + +#define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK))) + +struct mite_dma_descriptor { + u32 count; + u32 addr; + u32 next; + u32 dar; +}; + +struct mite_dma_descriptor_ring { + struct pci_dev *pcidev; + u32 n_links; + struct mite_dma_descriptor *descriptors; + dma_addr_t descriptors_dma_addr; +}; + +struct mite_channel { + struct mite_struct *mite; + u32 channel; + u32 dir; + u32 done; + struct mite_dma_descriptor_ring *ring; +}; + +struct mite_struct { + struct list_head list; + a4l_lock_t lock; + u32 used; + u32 num_channels; + + struct mite_channel channels[MAX_MITE_DMA_CHANNELS]; + u32 channel_allocated[MAX_MITE_DMA_CHANNELS]; + + struct pci_dev *pcidev; + resource_size_t mite_phys_addr; + void *mite_io_addr; + resource_size_t daq_phys_addr; + void *daq_io_addr; +}; + +static inline +struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite) +{ + struct mite_dma_descriptor_ring *ring = + kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_DMA); + + if (ring == NULL) + return ring; + + memset(ring, 0, sizeof(struct mite_dma_descriptor_ring)); + + ring->pcidev = mite->pcidev; + if (ring->pcidev == NULL) { + kfree(ring); + return NULL; + } + + return ring; +}; + +static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring) +{ + if (ring) { + if (ring->descriptors) { + pci_free_consistent( + ring->pcidev, + ring->n_links * + sizeof(struct mite_dma_descriptor), + ring->descriptors, ring->descriptors_dma_addr); + } + kfree(ring); + } +}; + +static inline unsigned int mite_irq(struct mite_struct *mite) +{ + return mite->pcidev->irq; +}; +static inline unsigned int mite_device_id(struct mite_struct *mite) +{ + return mite->pcidev->device; +}; + +int mite_setup(struct mite_struct *mite, int use_iodwbsr_1); +void mite_unsetup(struct mite_struct *mite); +void mite_list_devices(void); +struct mite_struct * mite_find_device(int bus, + int slot, unsigned short device_id); +struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, + struct mite_dma_descriptor_ring *ring, unsigned min_channel, + unsigned max_channel); +static inline struct mite_channel *mite_request_channel(struct mite_struct + *mite, struct mite_dma_descriptor_ring *ring) +{ + return mite_request_channel_in_range(mite, ring, 0, + mite->num_channels - 1); +} +void mite_release_channel(struct mite_channel *mite_chan); + +void mite_dma_arm(struct mite_channel *mite_chan); +void mite_dma_disarm(struct mite_channel *mite_chan); +int mite_sync_input_dma(struct mite_channel *mite_chan, a4l_subd_t *subd); +int mite_sync_output_dma(struct mite_channel *mite_chan, a4l_subd_t *subd); +u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan); +u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan); +u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan); +u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan); +u32 mite_bytes_in_transit(struct mite_channel *mite_chan); +u32 mite_get_status(struct mite_channel *mite_chan); +int mite_done(struct mite_channel *mite_chan); +void mite_prep_dma(struct mite_channel *mite_chan, + unsigned int num_device_bits, unsigned int num_memory_bits); +int mite_buf_change(struct mite_dma_descriptor_ring *ring, a4l_subd_t *subd); + +#ifdef CONFIG_DEBUG_MITE +void mite_print_chsr(unsigned int chsr); +void mite_dump_regs(struct mite_channel *mite_chan); +#endif + +static inline int CHAN_OFFSET(int channel) +{ + return 0x500 + 0x100 * channel; +}; + +enum mite_registers { + /* The bits 0x90180700 in MITE_UNKNOWN_DMA_BURST_REG can be + written and read back. The bits 0x1f always read as 1. + The rest always read as zero. */ + MITE_UNKNOWN_DMA_BURST_REG = 0x28, + MITE_IODWBSR = 0xc0, //IO Device Window Base Size Register + MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1 + MITE_IODWCR_1 = 0xf4, + MITE_PCI_CONFIG_OFFSET = 0x300, + MITE_CSIGR = 0x460 //chip signature +}; +static inline int MITE_CHOR(int channel) // channel operation +{ + return CHAN_OFFSET(channel) + 0x0; +}; +static inline int MITE_CHCR(int channel) // channel control +{ + return CHAN_OFFSET(channel) + 0x4; +}; +static inline int MITE_TCR(int channel) // transfer count +{ + return CHAN_OFFSET(channel) + 0x8; +}; +static inline int MITE_MCR(int channel) // memory configuration +{ + return CHAN_OFFSET(channel) + 0xc; +}; +static inline int MITE_MAR(int channel) // memory address +{ + return CHAN_OFFSET(channel) + 0x10; +}; +static inline int MITE_DCR(int channel) // device configuration +{ + return CHAN_OFFSET(channel) + 0x14; +}; +static inline int MITE_DAR(int channel) // device address +{ + return CHAN_OFFSET(channel) + 0x18; +}; +static inline int MITE_LKCR(int channel) // link configuration +{ + return CHAN_OFFSET(channel) + 0x1c; +}; +static inline int MITE_LKAR(int channel) // link address +{ + return CHAN_OFFSET(channel) + 0x20; +}; +static inline int MITE_LLKAR(int channel) // see mite section of tnt5002 manual +{ + return CHAN_OFFSET(channel) + 0x24; +}; +static inline int MITE_BAR(int channel) // base address +{ + return CHAN_OFFSET(channel) + 0x28; +}; +static inline int MITE_BCR(int channel) // base count +{ + return CHAN_OFFSET(channel) + 0x2c; +}; +static inline int MITE_SAR(int channel) // ? address +{ + return CHAN_OFFSET(channel) + 0x30; +}; +static inline int MITE_WSCR(int channel) // ? +{ + return CHAN_OFFSET(channel) + 0x34; +}; +static inline int MITE_WSER(int channel) // ? +{ + return CHAN_OFFSET(channel) + 0x38; +}; +static inline int MITE_CHSR(int channel) // channel status +{ + return CHAN_OFFSET(channel) + 0x3c; +}; +static inline int MITE_FCR(int channel) // fifo count +{ + return CHAN_OFFSET(channel) + 0x40; +}; + +enum MITE_IODWBSR_bits { + WENAB = 0x80, // window enable +}; + +static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size) +{ + unsigned order = 0; + while (size >>= 1) + ++order; + BUG_ON(order < 1); + return (order - 1) & 0x1f; +} + +enum MITE_UNKNOWN_DMA_BURST_bits { + UNKNOWN_DMA_BURST_ENABLE_BITS = 0x600 +}; + +static inline int mite_csigr_version(u32 csigr_bits) +{ + return csigr_bits & 0xf; +}; +static inline int mite_csigr_type(u32 csigr_bits) +{ // original mite = 0, minimite = 1 + return (csigr_bits >> 4) & 0xf; +}; +static inline int mite_csigr_mmode(u32 csigr_bits) +{ // mite mode, minimite = 1 + return (csigr_bits >> 8) & 0x3; +}; +static inline int mite_csigr_imode(u32 csigr_bits) +{ // cpu port interface mode, pci = 0x3 + return (csigr_bits >> 12) & 0x3; +}; +static inline int mite_csigr_dmac(u32 csigr_bits) +{ // number of dma channels + return (csigr_bits >> 16) & 0xf; +}; +static inline int mite_csigr_wpdep(u32 csigr_bits) +{ // write post fifo depth + unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7; + if (wpdep_bits == 0) + return 0; + else + return 1 << (wpdep_bits - 1); +}; +static inline int mite_csigr_wins(u32 csigr_bits) +{ + return (csigr_bits >> 24) & 0x1f; +}; +static inline int mite_csigr_iowins(u32 csigr_bits) +{ // number of io windows + return (csigr_bits >> 29) & 0x7; +}; + +enum MITE_MCR_bits { + MCRPON = 0, +}; + +enum MITE_DCR_bits { + DCR_NORMAL = (1 << 29), + DCRPON = 0, +}; + +enum MITE_CHOR_bits { + CHOR_DMARESET = (1 << 31), + CHOR_SET_SEND_TC = (1 << 11), + CHOR_CLR_SEND_TC = (1 << 10), + CHOR_SET_LPAUSE = (1 << 9), + CHOR_CLR_LPAUSE = (1 << 8), + CHOR_CLRDONE = (1 << 7), + CHOR_CLRRB = (1 << 6), + CHOR_CLRLC = (1 << 5), + CHOR_FRESET = (1 << 4), + CHOR_ABORT = (1 << 3), /* stop without emptying fifo */ + CHOR_STOP = (1 << 2), /* stop after emptying fifo */ + CHOR_CONT = (1 << 1), + CHOR_START = (1 << 0), + CHOR_PON = (CHOR_CLR_SEND_TC | CHOR_CLR_LPAUSE), +}; + +enum MITE_CHCR_bits { + CHCR_SET_DMA_IE = (1 << 31), + CHCR_CLR_DMA_IE = (1 << 30), + CHCR_SET_LINKP_IE = (1 << 29), + CHCR_CLR_LINKP_IE = (1 << 28), + CHCR_SET_SAR_IE = (1 << 27), + CHCR_CLR_SAR_IE = (1 << 26), + CHCR_SET_DONE_IE = (1 << 25), + CHCR_CLR_DONE_IE = (1 << 24), + CHCR_SET_MRDY_IE = (1 << 23), + CHCR_CLR_MRDY_IE = (1 << 22), + CHCR_SET_DRDY_IE = (1 << 21), + CHCR_CLR_DRDY_IE = (1 << 20), + CHCR_SET_LC_IE = (1 << 19), + CHCR_CLR_LC_IE = (1 << 18), + CHCR_SET_CONT_RB_IE = (1 << 17), + CHCR_CLR_CONT_RB_IE = (1 << 16), + CHCR_FIFODIS = (1 << 15), + CHCR_FIFO_ON = 0, + CHCR_BURSTEN = (1 << 14), + CHCR_NO_BURSTEN = 0, + CHCR_BYTE_SWAP_DEVICE = (1 << 6), + CHCR_BYTE_SWAP_MEMORY = (1 << 4), + CHCR_DIR = (1 << 3), + CHCR_DEV_TO_MEM = CHCR_DIR, + CHCR_MEM_TO_DEV = 0, + CHCR_NORMAL = (0 << 0), + CHCR_CONTINUE = (1 << 0), + CHCR_RINGBUFF = (2 << 0), + CHCR_LINKSHORT = (4 << 0), + CHCR_LINKLONG = (5 << 0), + CHCRPON = + (CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | + CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | + CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE), +}; + +enum ConfigRegister_bits { + CR_REQS_MASK = 0x7 << 16, + CR_ASEQDONT = 0x0 << 10, + CR_ASEQUP = 0x1 << 10, + CR_ASEQDOWN = 0x2 << 10, + CR_ASEQ_MASK = 0x3 << 10, + CR_PSIZE8 = (1 << 8), + CR_PSIZE16 = (2 << 8), + CR_PSIZE32 = (3 << 8), + CR_PORTCPU = (0 << 6), + CR_PORTIO = (1 << 6), + CR_PORTVXI = (2 << 6), + CR_PORTMXI = (3 << 6), + CR_AMDEVICE = (1 << 0), +}; +static inline int CR_REQS(int source) +{ + return (source & 0x7) << 16; +}; +static inline int CR_REQSDRQ(unsigned drq_line) +{ + /* This also works on m-series when + using channels (drq_line) 4 or 5. */ + return CR_REQS((drq_line & 0x3) | 0x4); +} +static inline int CR_RL(unsigned int retry_limit) +{ + int value = 0; + + while (retry_limit) { + retry_limit >>= 1; + value++; + } + if (value > 0x7) + __a4l_err("bug! retry_limit too large\n"); + + return (value & 0x7) << 21; +} + +enum CHSR_bits { + CHSR_INT = (1 << 31), + CHSR_LPAUSES = (1 << 29), + CHSR_SARS = (1 << 27), + CHSR_DONE = (1 << 25), + CHSR_MRDY = (1 << 23), + CHSR_DRDY = (1 << 21), + CHSR_LINKC = (1 << 19), + CHSR_CONTS_RB = (1 << 17), + CHSR_ERROR = (1 << 15), + CHSR_SABORT = (1 << 14), + CHSR_HABORT = (1 << 13), + CHSR_STOPS = (1 << 12), + CHSR_OPERR_mask = (3 << 10), + CHSR_OPERR_NOERROR = (0 << 10), + CHSR_OPERR_FIFOERROR = (1 << 10), + CHSR_OPERR_LINKERROR = (1 << 10), /* ??? */ + CHSR_XFERR = (1 << 9), + CHSR_END = (1 << 8), + CHSR_DRQ1 = (1 << 7), + CHSR_DRQ0 = (1 << 6), + CHSR_LxERR_mask = (3 << 4), + CHSR_LBERR = (1 << 4), + CHSR_LRERR = (2 << 4), + CHSR_LOERR = (3 << 4), + CHSR_MxERR_mask = (3 << 2), + CHSR_MBERR = (1 << 2), + CHSR_MRERR = (2 << 2), + CHSR_MOERR = (3 << 2), + CHSR_DxERR_mask = (3 << 0), + CHSR_DBERR = (1 << 0), + CHSR_DRERR = (2 << 0), + CHSR_DOERR = (3 << 0), +}; + +static inline void mite_dma_reset(struct mite_channel *mite_chan) +{ + writel(CHOR_DMARESET | CHOR_FRESET, + mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); +}; + +#endif /* !__ANALOGY_NI_MITE_H__ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_mio.h relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_mio.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_mio.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_mio.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,124 @@ +/** + * @file + * Hardware driver for NI Mite PCI interface chip + * @note Copyright (C) 1999 David A. Schleef + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ANALOGY_NI_MIO_H__ +#define __ANALOGY_NI_MIO_H__ + +/* Debug stuff */ + +#ifdef CONFIG_DEBUG_MIO +#define MDPRINTK(fmt, args...) rtdm_printk(format, ##args) +#else /* !CONFIG_DEBUG_MIO */ +#define MDPRINTK(fmt, args...) +#endif /* CONFIG_DEBUG_MIO */ + +/* Subdevice related defines */ + +#define AIMODE_NONE 0 +#define AIMODE_HALF_FULL 1 +#define AIMODE_SCAN 2 +#define AIMODE_SAMPLE 3 + +#define NI_AI_SUBDEV 0 +#define NI_AO_SUBDEV 1 +#define NI_DIO_SUBDEV 2 +#define NI_8255_DIO_SUBDEV 3 +#define NI_UNUSED_SUBDEV 4 +#define NI_CALIBRATION_SUBDEV 5 +#define NI_EEPROM_SUBDEV 6 +#define NI_PFI_DIO_SUBDEV 7 +#define NI_CS5529_CALIBRATION_SUBDEV 8 +#define NI_SERIAL_SUBDEV 9 +#define NI_RTSI_SUBDEV 10 +#define NI_GPCT0_SUBDEV 11 +#define NI_GPCT1_SUBDEV 12 +#define NI_FREQ_OUT_SUBDEV 13 +#define NI_NUM_SUBDEVICES 14 + +#define NI_GPCT_SUBDEV(x) ((x == 1) ? NI_GPCT1_SUBDEV : NI_GPCT0_SUBDEV) + +#define TIMEBASE_1_NS 50 +#define TIMEBASE_2_NS 10000 + +#define SERIAL_DISABLED 0 +#define SERIAL_600NS 600 +#define SERIAL_1_2US 1200 +#define SERIAL_10US 10000 + +/* PFI digital filtering options for ni m-series for use with + INSN_CONFIG_FILTER. */ +#define NI_PFI_FILTER_OFF 0x0 +#define NI_PFI_FILTER_125ns 0x1 +#define NI_PFI_FILTER_6425ns 0x2 +#define NI_PFI_FILTER_2550us 0x3 + +/* Signals which can be routed to an NI PFI pin on an m-series board + with INSN_CONFIG_SET_ROUTING. These numbers are also returned by + INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their + routing cannot be changed. The numbers assigned are not arbitrary, + they correspond to the bits required to program the board. */ +#define NI_PFI_OUTPUT_PFI_DEFAULT 0 +#define NI_PFI_OUTPUT_AI_START1 1 +#define NI_PFI_OUTPUT_AI_START2 2 +#define NI_PFI_OUTPUT_AI_CONVERT 3 +#define NI_PFI_OUTPUT_G_SRC1 4 +#define NI_PFI_OUTPUT_G_GATE1 5 +#define NI_PFI_OUTPUT_AO_UPDATE_N 6 +#define NI_PFI_OUTPUT_AO_START1 7 +#define NI_PFI_OUTPUT_AI_START_PULSE 8 +#define NI_PFI_OUTPUT_G_SRC0 9 +#define NI_PFI_OUTPUT_G_GATE0 10 +#define NI_PFI_OUTPUT_EXT_STROBE 11 +#define NI_PFI_OUTPUT_AI_EXT_MUX_CLK 12 +#define NI_PFI_OUTPUT_GOUT0 13 +#define NI_PFI_OUTPUT_GOUT1 14 +#define NI_PFI_OUTPUT_FREQ_OUT 15 +#define NI_PFI_OUTPUT_PFI_DO 16 +#define NI_PFI_OUTPUT_I_ATRIG 17 +#define NI_PFI_OUTPUT_RTSI0 18 +#define NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN 26 +#define NI_PFI_OUTPUT_SCXI_TRIG1 27 +#define NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI 28 +#define NI_PFI_OUTPUT_CDI_SAMPLE 29 +#define NI_PFI_OUTPUT_CDO_UPDATE 30 + +static inline unsigned int NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) { + return NI_PFI_OUTPUT_RTSI0 + rtsi_channel; +} + +/* Ranges declarations */ + +extern a4l_rngdesc_t range_ni_E_ai; +extern a4l_rngdesc_t range_ni_E_ai_limited; +extern a4l_rngdesc_t range_ni_E_ai_limited14; +extern a4l_rngdesc_t range_ni_E_ai_bipolar4; +extern a4l_rngdesc_t range_ni_E_ai_611x; +extern a4l_rngdesc_t range_ni_E_ai_622x; +extern a4l_rngdesc_t range_ni_E_ai_628x; +extern a4l_rngdesc_t range_ni_S_ai_6143; +extern a4l_rngdesc_t range_ni_E_ao_ext; + +/* Misc functions declarations */ + +int ni_E_interrupt(unsigned int irq, void *d); +int ni_E_init(a4l_dev_t *dev); + + +#endif /* !__ANALOGY_NI_MIO_H__ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_stc.h relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_stc.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_stc.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_stc.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1419 @@ +/** + * @file + * Register descriptions for NI DAQ-STC chip + * + * Copyright (C) 1998-9 David A. Schleef + * + * This code 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 code 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 code; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * References: + * 340934b.pdf DAQ-STC reference manual + * + */ + +#ifndef __ANALOGY_NI_STC_H__ +#define __ANALOGY_NI_STC_H__ + +#include "ni_tio.h" + +#define _bit15 0x8000 +#define _bit14 0x4000 +#define _bit13 0x2000 +#define _bit12 0x1000 +#define _bit11 0x0800 +#define _bit10 0x0400 +#define _bit9 0x0200 +#define _bit8 0x0100 +#define _bit7 0x0080 +#define _bit6 0x0040 +#define _bit5 0x0020 +#define _bit4 0x0010 +#define _bit3 0x0008 +#define _bit2 0x0004 +#define _bit1 0x0002 +#define _bit0 0x0001 + +#define NUM_PFI_OUTPUT_SELECT_REGS 6 + +/* Registers in the National Instruments DAQ-STC chip */ + +#define Interrupt_A_Ack_Register 2 +#define G0_Gate_Interrupt_Ack _bit15 +#define G0_TC_Interrupt_Ack _bit14 +#define AI_Error_Interrupt_Ack _bit13 +#define AI_STOP_Interrupt_Ack _bit12 +#define AI_START_Interrupt_Ack _bit11 +#define AI_START2_Interrupt_Ack _bit10 +#define AI_START1_Interrupt_Ack _bit9 +#define AI_SC_TC_Interrupt_Ack _bit8 +#define AI_SC_TC_Error_Confirm _bit7 +#define G0_TC_Error_Confirm _bit6 +#define G0_Gate_Error_Confirm _bit5 + +#define AI_Status_1_Register 2 +#define Interrupt_A_St _bit15 +#define AI_FIFO_Full_St _bit14 +#define AI_FIFO_Half_Full_St _bit13 +#define AI_FIFO_Empty_St _bit12 +#define AI_Overrun_St _bit11 +#define AI_Overflow_St _bit10 +#define AI_SC_TC_Error_St _bit9 +#define AI_START2_St _bit8 +#define AI_START1_St _bit7 +#define AI_SC_TC_St _bit6 +#define AI_START_St _bit5 +#define AI_STOP_St _bit4 +#define G0_TC_St _bit3 +#define G0_Gate_Interrupt_St _bit2 +#define AI_FIFO_Request_St _bit1 +#define Pass_Thru_0_Interrupt_St _bit0 + +#define AI_Status_2_Register 5 + +#define Interrupt_B_Ack_Register 3 +#define G1_Gate_Error_Confirm _bit1 +#define G1_TC_Error_Confirm _bit2 +#define AO_BC_TC_Trigger_Error_Confirm _bit3 +#define AO_BC_TC_Error_Confirm _bit4 +#define AO_UI2_TC_Error_Confrim _bit5 +#define AO_UI2_TC_Interrupt_Ack _bit6 +#define AO_UC_TC_Interrupt_Ack _bit7 +#define AO_BC_TC_Interrupt_Ack _bit8 +#define AO_START1_Interrupt_Ack _bit9 +#define AO_UPDATE_Interrupt_Ack _bit10 +#define AO_START_Interrupt_Ack _bit11 +#define AO_STOP_Interrupt_Ack _bit12 +#define AO_Error_Interrupt_Ack _bit13 +#define G1_TC_Interrupt_Ack _bit14 +#define G1_Gate_Interrupt_Ack _bit15 + +#define AO_Status_1_Register 3 +#define Interrupt_B_St _bit15 +#define AO_FIFO_Full_St _bit14 +#define AO_FIFO_Half_Full_St _bit13 +#define AO_FIFO_Empty_St _bit12 +#define AO_BC_TC_Error_St _bit11 +#define AO_START_St _bit10 +#define AO_Overrun_St _bit9 +#define AO_START1_St _bit8 +#define AO_BC_TC_St _bit7 +#define AO_UC_TC_St _bit6 +#define AO_UPDATE_St _bit5 +#define AO_UI2_TC_St _bit4 +#define G1_TC_St _bit3 +#define G1_Gate_Interrupt_St _bit2 +#define AO_FIFO_Request_St _bit1 +#define Pass_Thru_1_Interrupt_St _bit0 + + +#define AI_Command_2_Register 4 +#define AI_End_On_SC_TC _bit15 +#define AI_End_On_End_Of_Scan _bit14 +#define AI_START1_Disable _bit11 +#define AI_SC_Save_Trace _bit10 +#define AI_SI_Switch_Load_On_SC_TC _bit9 +#define AI_SI_Switch_Load_On_STOP _bit8 +#define AI_SI_Switch_Load_On_TC _bit7 +#define AI_SC_Switch_Load_On_TC _bit4 +#define AI_STOP_Pulse _bit3 +#define AI_START_Pulse _bit2 +#define AI_START2_Pulse _bit1 +#define AI_START1_Pulse _bit0 + +#define AO_Command_2_Register 5 +#define AO_End_On_BC_TC(x) (((x) & 0x3) << 14) +#define AO_Start_Stop_Gate_Enable _bit13 +#define AO_UC_Save_Trace _bit12 +#define AO_BC_Gate_Enable _bit11 +#define AO_BC_Save_Trace _bit10 +#define AO_UI_Switch_Load_On_BC_TC _bit9 +#define AO_UI_Switch_Load_On_Stop _bit8 +#define AO_UI_Switch_Load_On_TC _bit7 +#define AO_UC_Switch_Load_On_BC_TC _bit6 +#define AO_UC_Switch_Load_On_TC _bit5 +#define AO_BC_Switch_Load_On_TC _bit4 +#define AO_Mute_B _bit3 +#define AO_Mute_A _bit2 +#define AO_UPDATE2_Pulse _bit1 +#define AO_START1_Pulse _bit0 + +#define AO_Status_2_Register 6 + +#define DIO_Parallel_Input_Register 7 + +#define AI_Command_1_Register 8 +#define AI_Analog_Trigger_Reset _bit14 +#define AI_Disarm _bit13 +#define AI_SI2_Arm _bit12 +#define AI_SI2_Load _bit11 +#define AI_SI_Arm _bit10 +#define AI_SI_Load _bit9 +#define AI_DIV_Arm _bit8 +#define AI_DIV_Load _bit7 +#define AI_SC_Arm _bit6 +#define AI_SC_Load _bit5 +#define AI_SCAN_IN_PROG_Pulse _bit4 +#define AI_EXTMUX_CLK_Pulse _bit3 +#define AI_LOCALMUX_CLK_Pulse _bit2 +#define AI_SC_TC_Pulse _bit1 +#define AI_CONVERT_Pulse _bit0 + +#define AO_Command_1_Register 9 +#define AO_Analog_Trigger_Reset _bit15 +#define AO_START_Pulse _bit14 +#define AO_Disarm _bit13 +#define AO_UI2_Arm_Disarm _bit12 +#define AO_UI2_Load _bit11 +#define AO_UI_Arm _bit10 +#define AO_UI_Load _bit9 +#define AO_UC_Arm _bit8 +#define AO_UC_Load _bit7 +#define AO_BC_Arm _bit6 +#define AO_BC_Load _bit5 +#define AO_DAC1_Update_Mode _bit4 +#define AO_LDAC1_Source_Select _bit3 +#define AO_DAC0_Update_Mode _bit2 +#define AO_LDAC0_Source_Select _bit1 +#define AO_UPDATE_Pulse _bit0 + + +#define DIO_Output_Register 10 +#define DIO_Parallel_Data_Out(a) ((a)&0xff) +#define DIO_Parallel_Data_Mask 0xff +#define DIO_SDOUT _bit0 +#define DIO_SDIN _bit4 +#define DIO_Serial_Data_Out(a) (((a)&0xff)<<8) +#define DIO_Serial_Data_Mask 0xff00 + +#define DIO_Control_Register 11 +#define DIO_Software_Serial_Control _bit11 +#define DIO_HW_Serial_Timebase _bit10 +#define DIO_HW_Serial_Enable _bit9 +#define DIO_HW_Serial_Start _bit8 +#define DIO_Pins_Dir(a) ((a)&0xff) +#define DIO_Pins_Dir_Mask 0xff + +#define AI_Mode_1_Register 12 +#define AI_CONVERT_Source_Select(a) (((a) & 0x1f) << 11) +#define AI_SI_Source_select(a) (((a) & 0x1f) << 6) +#define AI_CONVERT_Source_Polarity _bit5 +#define AI_SI_Source_Polarity _bit4 +#define AI_Start_Stop _bit3 +#define AI_Mode_1_Reserved _bit2 +#define AI_Continuous _bit1 +#define AI_Trigger_Once _bit0 + +#define AI_Mode_2_Register 13 +#define AI_SC_Gate_Enable _bit15 +#define AI_Start_Stop_Gate_Enable _bit14 +#define AI_Pre_Trigger _bit13 +#define AI_External_MUX_Present _bit12 +#define AI_SI2_Initial_Load_Source _bit9 +#define AI_SI2_Reload_Mode _bit8 +#define AI_SI_Initial_Load_Source _bit7 +#define AI_SI_Reload_Mode(a) (((a) & 0x7)<<4) +#define AI_SI_Write_Switch _bit3 +#define AI_SC_Initial_Load_Source _bit2 +#define AI_SC_Reload_Mode _bit1 +#define AI_SC_Write_Switch _bit0 + +#define AI_SI_Load_A_Registers 14 +#define AI_SI_Load_B_Registers 16 +#define AI_SC_Load_A_Registers 18 +#define AI_SC_Load_B_Registers 20 +#define AI_SI_Save_Registers 64 +#define AI_SC_Save_Registers 66 + +#define AI_SI2_Load_A_Register 23 +#define AI_SI2_Load_B_Register 25 + +#define Joint_Status_1_Register 27 +#define DIO_Serial_IO_In_Progress_St _bit12 + +#define DIO_Serial_Input_Register 28 +#define Joint_Status_2_Register 29 +#define AO_TMRDACWRs_In_Progress_St _bit5 + +#define AO_Mode_1_Register 38 +#define AO_UPDATE_Source_Select(x) (((x)&0x1f)<<11) +#define AO_UI_Source_Select(x) (((x)&0x1f)<<6) +#define AO_Multiple_Channels _bit5 +#define AO_UPDATE_Source_Polarity _bit4 +#define AO_UI_Source_Polarity _bit3 +#define AO_UC_Switch_Load_Every_TC _bit2 +#define AO_Continuous _bit1 +#define AO_Trigger_Once _bit0 + +#define AO_Mode_2_Register 39 +#define AO_FIFO_Mode_Mask ( 0x3 << 14 ) +#define AO_FIFO_Mode_HF_to_F (3<<14) +#define AO_FIFO_Mode_F (2<<14) +#define AO_FIFO_Mode_HF (1<<14) +#define AO_FIFO_Mode_E (0<<14) +#define AO_FIFO_Retransmit_Enable _bit13 +#define AO_START1_Disable _bit12 +#define AO_UC_Initial_Load_Source _bit11 +#define AO_UC_Write_Switch _bit10 +#define AO_UI2_Initial_Load_Source _bit9 +#define AO_UI2_Reload_Mode _bit8 +#define AO_UI_Initial_Load_Source _bit7 +#define AO_UI_Reload_Mode(x) (((x) & 0x7) << 4) +#define AO_UI_Write_Switch _bit3 +#define AO_BC_Initial_Load_Source _bit2 +#define AO_BC_Reload_Mode _bit1 +#define AO_BC_Write_Switch _bit0 + +#define AO_UI_Load_A_Register 40 +#define AO_UI_Load_A_Register_High 40 +#define AO_UI_Load_A_Register_Low 41 +#define AO_UI_Load_B_Register 42 +#define AO_UI_Save_Registers 16 +#define AO_BC_Load_A_Register 44 +#define AO_BC_Load_A_Register_High 44 +#define AO_BC_Load_A_Register_Low 45 +#define AO_BC_Load_B_Register 46 +#define AO_BC_Load_B_Register_High 46 +#define AO_BC_Load_B_Register_Low 47 +#define AO_BC_Save_Registers 18 +#define AO_UC_Load_A_Register 48 +#define AO_UC_Load_A_Register_High 48 +#define AO_UC_Load_A_Register_Low 49 +#define AO_UC_Load_B_Register 50 +#define AO_UC_Save_Registers 20 + +#define Clock_and_FOUT_Register 56 +#define FOUT_Enable _bit15 +#define FOUT_Timebase_Select _bit14 +#define DIO_Serial_Out_Divide_By_2 _bit13 +#define Slow_Internal_Time_Divide_By_2 _bit12 +#define Slow_Internal_Timebase _bit11 +#define G_Source_Divide_By_2 _bit10 +#define Clock_To_Board_Divide_By_2 _bit9 +#define Clock_To_Board _bit8 +#define AI_Output_Divide_By_2 _bit7 +#define AI_Source_Divide_By_2 _bit6 +#define AO_Output_Divide_By_2 _bit5 +#define AO_Source_Divide_By_2 _bit4 +#define FOUT_Divider_mask 0xf +#define FOUT_Divider(x) (((x) & 0xf) << 0) + +#define IO_Bidirection_Pin_Register 57 +#define RTSI_Trig_Direction_Register 58 +#define Drive_RTSI_Clock_Bit 0x1 +#define Use_RTSI_Clock_Bit 0x2 + +static inline unsigned int RTSI_Output_Bit(unsigned channel, int is_mseries) +{ + unsigned max_channel; + unsigned base_bit_shift; + if(is_mseries) + { + base_bit_shift = 8; + max_channel = 7; + }else + { + base_bit_shift = 9; + max_channel = 6; + } + if(channel > max_channel) + { + rtdm_printk("%s: bug, invalid RTSI_channel=%i\n", + __FUNCTION__, channel); + return 0; + } + return 1 << (base_bit_shift + channel); +} + +#define Interrupt_Control_Register 59 +#define Interrupt_B_Enable _bit15 +#define Interrupt_B_Output_Select(x) ((x)<<12) +#define Interrupt_A_Enable _bit11 +#define Interrupt_A_Output_Select(x) ((x)<<8) +#define Pass_Thru_0_Interrupt_Polarity _bit3 +#define Pass_Thru_1_Interrupt_Polarity _bit2 +#define Interrupt_Output_On_3_Pins _bit1 +#define Interrupt_Output_Polarity _bit0 + +#define AI_Output_Control_Register 60 +#define AI_START_Output_Select _bit10 +#define AI_SCAN_IN_PROG_Output_Select(x) (((x) & 0x3) << 8) +#define AI_EXTMUX_CLK_Output_Select(x) (((x) & 0x3) << 6) +#define AI_LOCALMUX_CLK_Output_Select(x) ((x)<<4) +#define AI_SC_TC_Output_Select(x) ((x)<<2) +#define AI_CONVERT_Output_High_Z 0 +#define AI_CONVERT_Output_Ground 1 +#define AI_CONVERT_Output_Enable_Low 2 +#define AI_CONVERT_Output_Enable_High 3 +#define AI_CONVERT_Output_Select(x) ((x) & 0x3) + +#define AI_START_STOP_Select_Register 62 +#define AI_START_Polarity _bit15 +#define AI_STOP_Polarity _bit14 +#define AI_STOP_Sync _bit13 +#define AI_STOP_Edge _bit12 +#define AI_STOP_Select(a) (((a) & 0x1f)<<7) +#define AI_START_Sync _bit6 +#define AI_START_Edge _bit5 +#define AI_START_Select(a) ((a) & 0x1f) + +#define AI_Trigger_Select_Register 63 +#define AI_START1_Polarity _bit15 +#define AI_START2_Polarity _bit14 +#define AI_START2_Sync _bit13 +#define AI_START2_Edge _bit12 +#define AI_START2_Select(a) (((a) & 0x1f) << 7) +#define AI_START1_Sync _bit6 +#define AI_START1_Edge _bit5 +#define AI_START1_Select(a) ((a) & 0x1f) + +#define AI_DIV_Load_A_Register 64 + +#define AO_Start_Select_Register 66 +#define AO_UI2_Software_Gate _bit15 +#define AO_UI2_External_Gate_Polarity _bit14 +#define AO_START_Polarity _bit13 +#define AO_AOFREQ_Enable _bit12 +#define AO_UI2_External_Gate_Select(a) (((a) & 0x1f) << 7) +#define AO_START_Sync _bit6 +#define AO_START_Edge _bit5 +#define AO_START_Select(a) ((a) & 0x1f) + +#define AO_Trigger_Select_Register 67 +#define AO_UI2_External_Gate_Enable _bit15 +#define AO_Delayed_START1 _bit14 +#define AO_START1_Polarity _bit13 +#define AO_UI2_Source_Polarity _bit12 +#define AO_UI2_Source_Select(x) (((x)&0x1f)<<7) +#define AO_START1_Sync _bit6 +#define AO_START1_Edge _bit5 +#define AO_START1_Select(x) (((x)&0x1f)<<0) + +#define AO_Mode_3_Register 70 +#define AO_UI2_Switch_Load_Next_TC _bit13 +#define AO_UC_Switch_Load_Every_BC_TC _bit12 +#define AO_Trigger_Length _bit11 +#define AO_Stop_On_Overrun_Error _bit5 +#define AO_Stop_On_BC_TC_Trigger_Error _bit4 +#define AO_Stop_On_BC_TC_Error _bit3 +#define AO_Not_An_UPDATE _bit2 +#define AO_Software_Gate _bit1 +#define AO_Last_Gate_Disable _bit0 /* M Series only */ + +#define Joint_Reset_Register 72 +#define Software_Reset _bit11 +#define AO_Configuration_End _bit9 +#define AI_Configuration_End _bit8 +#define AO_Configuration_Start _bit5 +#define AI_Configuration_Start _bit4 +#define G1_Reset _bit3 +#define G0_Reset _bit2 +#define AO_Reset _bit1 +#define AI_Reset _bit0 + +#define Interrupt_A_Enable_Register 73 +#define Pass_Thru_0_Interrupt_Enable _bit9 +#define G0_Gate_Interrupt_Enable _bit8 +#define AI_FIFO_Interrupt_Enable _bit7 +#define G0_TC_Interrupt_Enable _bit6 +#define AI_Error_Interrupt_Enable _bit5 +#define AI_STOP_Interrupt_Enable _bit4 +#define AI_START_Interrupt_Enable _bit3 +#define AI_START2_Interrupt_Enable _bit2 +#define AI_START1_Interrupt_Enable _bit1 +#define AI_SC_TC_Interrupt_Enable _bit0 + +#define Interrupt_B_Enable_Register 75 +#define Pass_Thru_1_Interrupt_Enable _bit11 +#define G1_Gate_Interrupt_Enable _bit10 +#define G1_TC_Interrupt_Enable _bit9 +#define AO_FIFO_Interrupt_Enable _bit8 +#define AO_UI2_TC_Interrupt_Enable _bit7 +#define AO_UC_TC_Interrupt_Enable _bit6 +#define AO_Error_Interrupt_Enable _bit5 +#define AO_STOP_Interrupt_Enable _bit4 +#define AO_START_Interrupt_Enable _bit3 +#define AO_UPDATE_Interrupt_Enable _bit2 +#define AO_START1_Interrupt_Enable _bit1 +#define AO_BC_TC_Interrupt_Enable _bit0 + +#define Second_IRQ_A_Enable_Register 74 +#define AI_SC_TC_Second_Irq_Enable _bit0 +#define AI_START1_Second_Irq_Enable _bit1 +#define AI_START2_Second_Irq_Enable _bit2 +#define AI_START_Second_Irq_Enable _bit3 +#define AI_STOP_Second_Irq_Enable _bit4 +#define AI_Error_Second_Irq_Enable _bit5 +#define G0_TC_Second_Irq_Enable _bit6 +#define AI_FIFO_Second_Irq_Enable _bit7 +#define G0_Gate_Second_Irq_Enable _bit8 +#define Pass_Thru_0_Second_Irq_Enable _bit9 + +#define Second_IRQ_B_Enable_Register 76 +#define AO_BC_TC_Second_Irq_Enable _bit0 +#define AO_START1_Second_Irq_Enable _bit1 +#define AO_UPDATE_Second_Irq_Enable _bit2 +#define AO_START_Second_Irq_Enable _bit3 +#define AO_STOP_Second_Irq_Enable _bit4 +#define AO_Error_Second_Irq_Enable _bit5 +#define AO_UC_TC_Second_Irq_Enable _bit6 +#define AO_UI2_TC_Second_Irq_Enable _bit7 +#define AO_FIFO_Second_Irq_Enable _bit8 +#define G1_TC_Second_Irq_Enable _bit9 +#define G1_Gate_Second_Irq_Enable _bit10 +#define Pass_Thru_1_Second_Irq_Enable _bit11 + +#define AI_Personal_Register 77 +#define AI_SHIFTIN_Pulse_Width _bit15 +#define AI_EOC_Polarity _bit14 +#define AI_SOC_Polarity _bit13 +#define AI_SHIFTIN_Polarity _bit12 +#define AI_CONVERT_Pulse_Timebase _bit11 +#define AI_CONVERT_Pulse_Width _bit10 +#define AI_CONVERT_Original_Pulse _bit9 +#define AI_FIFO_Flags_Polarity _bit8 +#define AI_Overrun_Mode _bit7 +#define AI_EXTMUX_CLK_Pulse_Width _bit6 +#define AI_LOCALMUX_CLK_Pulse_Width _bit5 +#define AI_AIFREQ_Polarity _bit4 + +#define AO_Personal_Register 78 +#define AO_Interval_Buffer_Mode _bit3 +#define AO_BC_Source_Select _bit4 +#define AO_UPDATE_Pulse_Width _bit5 +#define AO_UPDATE_Pulse_Timebase _bit6 +#define AO_UPDATE_Original_Pulse _bit7 +#define AO_DMA_PIO_Control _bit8 /* M Series: reserved */ +#define AO_AOFREQ_Polarity _bit9 /* M Series: reserved */ +#define AO_FIFO_Enable _bit10 +#define AO_FIFO_Flags_Polarity _bit11 /* M Series: reserved */ +#define AO_TMRDACWR_Pulse_Width _bit12 +#define AO_Fast_CPU _bit13 /* M Series: reserved */ +#define AO_Number_Of_DAC_Packages _bit14 /* 1 for "single" mode, + 0 for "dual" */ +#define AO_Multiple_DACS_Per_Package _bit15 /* M Series only */ + +#define RTSI_Trig_A_Output_Register 79 + +#define RTSI_Trig_B_Output_Register 80 +#define RTSI_Sub_Selection_1_Bit _bit15 /* not for M Series */ +#define RTSI_Trig_Output_Bits(x, y) ((y & 0xf) << ((x % 4) * 4)) +#define RTSI_Trig_Output_Mask(x) (0xf << ((x % 4) * 4)) +#define RTSI_Trig_Output_Source(x, y) ((y >> ((x % 4) * 4)) & 0xf) + +#define RTSI_Board_Register 81 +#define Write_Strobe_0_Register 82 +#define Write_Strobe_1_Register 83 +#define Write_Strobe_2_Register 84 +#define Write_Strobe_3_Register 85 + +#define AO_Output_Control_Register 86 +#define AO_External_Gate_Enable _bit15 +#define AO_External_Gate_Select(x) (((x)&0x1f)<<10) +#define AO_Number_Of_Channels(x) (((x)&0xf)<<6) +#define AO_UPDATE2_Output_Select(x) (((x)&0x3)<<4) +#define AO_External_Gate_Polarity _bit3 +#define AO_UPDATE2_Output_Toggle _bit2 +#define AO_Update_Output_High_Z 0 +#define AO_Update_Output_Ground 1 +#define AO_Update_Output_Enable_Low 2 +#define AO_Update_Output_Enable_High 3 +#define AO_UPDATE_Output_Select(x) (x&0x3) + +#define AI_Mode_3_Register 87 +#define AI_Trigger_Length _bit15 +#define AI_Delay_START _bit14 +#define AI_Software_Gate _bit13 +#define AI_SI_Special_Trigger_Delay _bit12 +#define AI_SI2_Source_Select _bit11 +#define AI_Delayed_START2 _bit10 +#define AI_Delayed_START1 _bit9 +#define AI_External_Gate_Mode _bit8 +#define AI_FIFO_Mode_HF_to_E (3<<6) +#define AI_FIFO_Mode_F (2<<6) +#define AI_FIFO_Mode_HF (1<<6) +#define AI_FIFO_Mode_NE (0<<6) +#define AI_External_Gate_Polarity _bit5 +#define AI_External_Gate_Select(a) ((a) & 0x1f) + +#define G_Autoincrement_Register(a) (68+(a)) +#define G_Command_Register(a) (6+(a)) +#define G_HW_Save_Register(a) (8+(a)*2) +#define G_HW_Save_Register_High(a) (8+(a)*2) +#define G_HW_Save_Register_Low(a) (9+(a)*2) +#define G_Input_Select_Register(a) (36+(a)) +#define G_Load_A_Register(a) (28+(a)*4) +#define G_Load_A_Register_High(a) (28+(a)*4) +#define G_Load_A_Register_Low(a) (29+(a)*4) +#define G_Load_B_Register(a) (30+(a)*4) +#define G_Load_B_Register_High(a) (30+(a)*4) +#define G_Load_B_Register_Low(a) (31+(a)*4) +#define G_Mode_Register(a) (26+(a)) +#define G_Save_Register(a) (12+(a)*2) +#define G_Save_Register_High(a) (12+(a)*2) +#define G_Save_Register_Low(a) (13+(a)*2) +#define G_Status_Register 4 +#define Analog_Trigger_Etc_Register 61 + +/* command register */ +#define G_Disarm_Copy _bit15 /* strobe */ +#define G_Save_Trace_Copy _bit14 +#define G_Arm_Copy _bit13 /* strobe */ +#define G_Bank_Switch_Start _bit10 /* strobe */ +#define G_Little_Big_Endian _bit9 +#define G_Synchronized_Gate _bit8 +#define G_Write_Switch _bit7 +#define G_Up_Down(a) (((a)&0x03)<<5) +#define G_Disarm _bit4 /* strobe */ +#define G_Analog_Trigger_Reset _bit3 /* strobe */ +#define G_Save_Trace _bit1 +#define G_Arm _bit0 /* strobe */ + +/* channel agnostic names for the command register #defines */ +#define G_Bank_Switch_Enable _bit12 +#define G_Bank_Switch_Mode _bit11 +#define G_Load _bit2 /* strobe */ + +/* input select register */ +#define G_Gate_Select(a) (((a)&0x1f)<<7) +#define G_Source_Select(a) (((a)&0x1f)<<2) +#define G_Write_Acknowledges_Irq _bit1 +#define G_Read_Acknowledges_Irq _bit0 + +/* same input select register, but with channel agnostic names */ +#define G_Source_Polarity _bit15 +#define G_Output_Polarity _bit14 +#define G_OR_Gate _bit13 +#define G_Gate_Select_Load_Source _bit12 + +/* mode register */ +#define G_Loading_On_TC _bit12 +#define G_Output_Mode(a) (((a)&0x03)<<8) +#define G_Trigger_Mode_For_Edge_Gate(a) (((a)&0x03)<<3) +#define G_Gating_Mode(a) (((a)&0x03)<<0) + +/* same input mode register, but with channel agnostic names */ +#define G_Load_Source_Select _bit7 +#define G_Reload_Source_Switching _bit15 +#define G_Loading_On_Gate _bit14 +#define G_Gate_Polarity _bit13 + +#define G_Counting_Once(a) (((a)&0x03)<<10) +#define G_Stop_Mode(a) (((a)&0x03)<<5) +#define G_Gate_On_Both_Edges _bit2 + +/* G_Status_Register */ +#define G1_Gate_Error_St _bit15 +#define G0_Gate_Error_St _bit14 +#define G1_TC_Error_St _bit13 +#define G0_TC_Error_St _bit12 +#define G1_No_Load_Between_Gates_St _bit11 +#define G0_No_Load_Between_Gates_St _bit10 +#define G1_Armed_St _bit9 +#define G0_Armed_St _bit8 +#define G1_Stale_Data_St _bit7 +#define G0_Stale_Data_St _bit6 +#define G1_Next_Load_Source_St _bit5 +#define G0_Next_Load_Source_St _bit4 +#define G1_Counting_St _bit3 +#define G0_Counting_St _bit2 +#define G1_Save_St _bit1 +#define G0_Save_St _bit0 + +/* general purpose counter timer */ +#define G_Autoincrement(a) ((a)<<0) + +/*Analog_Trigger_Etc_Register*/ +#define Analog_Trigger_Mode(x) ((x) & 0x7) +#define Analog_Trigger_Enable _bit3 +#define Analog_Trigger_Drive _bit4 +#define GPFO_1_Output_Select _bit7 +#define GPFO_0_Output_Select(a) ((a)<<11) +#define GPFO_0_Output_Enable _bit14 +#define GPFO_1_Output_Enable _bit15 + +/* Additional windowed registers unique to E series */ + +/* 16 bit registers shadowed from DAQ-STC */ +#define Window_Address 0x00 +#define Window_Data 0x02 + +#define Configuration_Memory_Clear 82 +#define ADC_FIFO_Clear 83 +#define DAC_FIFO_Clear 84 + +/* i/o port offsets */ + +/* 8 bit registers */ +#define XXX_Status 0x01 +#define PROMOUT _bit0 +#define AI_FIFO_LOWER_NOT_EMPTY _bit3 + +#define Serial_Command 0x0d +#define Misc_Command 0x0f +#define Port_A 0x19 +#define Port_B 0x1b +#define Port_C 0x1d +#define Configuration 0x1f +#define Strobes 0x01 +#define Channel_A_Mode 0x03 +#define Channel_B_Mode 0x05 +#define Channel_C_Mode 0x07 +#define AI_AO_Select 0x09 +#define AI_DMA_Select_Shift 0 +#define AI_DMA_Select_Mask 0xf +#define AO_DMA_Select_Shift 4 +#define AO_DMA_Select_Mask (0xf << AO_DMA_Select_Shift) + +#define G0_G1_Select 0x0b + +static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel) +{ + if(channel < 4) return 1 << channel; + if(channel == 4) return 0x3; + if(channel == 5) return 0x5; + BUG(); + return 0; +} +static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index, unsigned mite_channel) +{ + BUG_ON(gpct_index > 1); + return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 * gpct_index); +} +static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index) +{ + BUG_ON(gpct_index > 1); + return 0xf << (4 * gpct_index); +} + +/* 16 bit registers */ + +#define Configuration_Memory_Low 0x10 +#define AI_DITHER _bit9 +#define AI_LAST_CHANNEL _bit15 + +#define Configuration_Memory_High 0x12 +#define AI_AC_COUPLE _bit11 +#define AI_DIFFERENTIAL _bit12 +#define AI_COMMON _bit13 +#define AI_GROUND (_bit12|_bit13) +#define AI_CONFIG_CHANNEL(x) (x&0x3f) + +#define ADC_FIFO_Data_Register 0x1c + +#define AO_Configuration 0x16 +#define AO_Bipolar _bit0 +#define AO_Deglitch _bit1 +#define AO_Ext_Ref _bit2 +#define AO_Ground_Ref _bit3 +#define AO_Channel(x) ((x) << 8) + +#define DAC_FIFO_Data 0x1e +#define DAC0_Direct_Data 0x18 +#define DAC1_Direct_Data 0x1a + +/* 611x registers (these boards differ from the e-series) */ + +#define Magic_611x 0x19 /* w8 (new) */ +#define Calibration_Channel_Select_611x 0x1a /* w16 (new) */ +#define ADC_FIFO_Data_611x 0x1c /* r32 (incompatible) */ +#define AI_FIFO_Offset_Load_611x 0x05 /* r8 (new) */ +#define DAC_FIFO_Data_611x 0x14 /* w32 (incompatible) */ +#define Cal_Gain_Select_611x 0x05 /* w8 (new) */ + +#define AO_Window_Address_611x 0x18 +#define AO_Window_Data_611x 0x1e + +/* 6143 registers */ +#define Magic_6143 0x19 /* w8 */ +#define G0G1_DMA_Select_6143 0x0B /* w8 */ +#define PipelineDelay_6143 0x1f /* w8 */ +#define EOC_Set_6143 0x1D /* w8 */ +#define AIDMA_Select_6143 0x09 /* w8 */ +#define AIFIFO_Data_6143 0x8C /* w32 */ +#define AIFIFO_Flag_6143 0x84 /* w32 */ +#define AIFIFO_Control_6143 0x88 /* w32 */ +#define AIFIFO_Status_6143 0x88 /* w32 */ +#define AIFIFO_DMAThreshold_6143 0x90 /* w32 */ +#define AIFIFO_Words_Available_6143 0x94 /* w32 */ + +#define Calibration_Channel_6143 0x42 /* w16 */ +#define Calibration_LowTime_6143 0x20 /* w16 */ +#define Calibration_HighTime_6143 0x22 /* w16 */ +#define Relay_Counter_Load_Val__6143 0x4C /* w32 */ +#define Signature_6143 0x50 /* w32 */ +#define Release_Date_6143 0x54 /* w32 */ +#define Release_Oldest_Date_6143 0x58 /* w32 */ + +#define Calibration_Channel_6143_RelayOn 0x8000 /* Calibration relay switch On */ +#define Calibration_Channel_6143_RelayOff 0x4000 /* Calibration relay switch Off */ +#define Calibration_Channel_Gnd_Gnd 0x00 /* Offset Calibration */ +#define Calibration_Channel_2v5_Gnd 0x02 /* 2.5V Reference */ +#define Calibration_Channel_Pwm_Gnd 0x05 /* +/- 5V Self Cal */ +#define Calibration_Channel_2v5_Pwm 0x0a /* PWM Calibration */ +#define Calibration_Channel_Pwm_Pwm 0x0d /* CMRR */ +#define Calibration_Channel_Gnd_Pwm 0x0e /* PWM Calibration */ + +/* 671x, 611x registers */ + +/* 671xi 611x windowed ao registers */ +#define AO_Immediate_671x 0x11 /* W 16 */ +#define AO_Timed_611x 0x10 /* W 16 */ +#define AO_FIFO_Offset_Load_611x 0x13 /* W32 */ +#define AO_Later_Single_Point_Updates 0x14 /* W 16 */ +#define AO_Waveform_Generation_611x 0x15 /* W 16 */ +#define AO_Misc_611x 0x16 /* W 16 */ +#define AO_Calibration_Channel_Select_67xx 0x17 /* W 16 */ +#define AO_Configuration_2_67xx 0x18 /* W 16 */ +#define CAL_ADC_Command_67xx 0x19 /* W 8 */ +#define CAL_ADC_Status_67xx 0x1a /* R 8 */ +#define CAL_ADC_Data_67xx 0x1b /* R 16 */ +#define CAL_ADC_Config_Data_High_Word_67xx 0x1c /* RW 16 */ +#define CAL_ADC_Config_Data_Low_Word_67xx 0x1d /* RW 16 */ + +static inline unsigned int DACx_Direct_Data_671x(int channel) +{ + return channel; +} + +#define CLEAR_WG _bit0 + +#define CSCFG_CAL_CONTROL_MASK 0x7 +#define CSCFG_SELF_CAL_OFFSET 0x1 +#define CSCFG_SELF_CAL_GAIN 0x2 +#define CSCFG_SELF_CAL_OFFSET_GAIN 0x3 +#define CSCFG_SYSTEM_CAL_OFFSET 0x5 +#define CSCFG_SYSTEM_CAL_GAIN 0x6 +#define CSCFG_DONE (1 << 3) +#define CSCFG_POWER_SAVE_SELECT (1 << 4) +#define CSCFG_PORT_MODE (1 << 5) +#define CSCFG_RESET_VALID (1 << 6) +#define CSCFG_RESET (1 << 7) +#define CSCFG_UNIPOLAR (1 << 12) +#define CSCFG_WORD_RATE_2180_CYCLES (0x0 << 13) +#define CSCFG_WORD_RATE_1092_CYCLES (0x1 << 13) +#define CSCFG_WORD_RATE_532_CYCLES (0x2 << 13) +#define CSCFG_WORD_RATE_388_CYCLES (0x3 << 13) +#define CSCFG_WORD_RATE_324_CYCLES (0x4 << 13) +#define CSCFG_WORD_RATE_17444_CYCLES (0x5 << 13) +#define CSCFG_WORD_RATE_8724_CYCLES (0x6 << 13) +#define CSCFG_WORD_RATE_4364_CYCLES (0x7 << 13) +#define CSCFG_WORD_RATE_MASK (0x7 << 13) +#define CSCFG_LOW_POWER (1 << 16) + +#define CS5529_CONFIG_DOUT(x) (1 << (18 + x)) +#define CS5529_CONFIG_AOUT(x) (1 << (22 + x)) + +/* cs5529 command bits */ +#define CSCMD_POWER_SAVE _bit0 +#define CSCMD_REGISTER_SELECT_MASK 0xe +#define CSCMD_OFFSET_REGISTER 0x0 +#define CSCMD_GAIN_REGISTER _bit1 +#define CSCMD_CONFIG_REGISTER _bit2 +#define CSCMD_READ _bit4 +#define CSCMD_CONTINUOUS_CONVERSIONS _bit5 +#define CSCMD_SINGLE_CONVERSION _bit6 +#define CSCMD_COMMAND _bit7 + +/* cs5529 status bits */ +#define CSS_ADC_BUSY _bit0 +#define CSS_OSC_DETECT _bit1 /* indicates adc error */ +#define CSS_OVERRANGE _bit3 + +#define SerDacLd(x) (0x08<<(x)) + +/* + This is stuff unique to the NI E series drivers, + but I thought I'd put it here anyway. +*/ + +enum +{ + ai_gain_16 = 0, + ai_gain_8, + ai_gain_14, + ai_gain_4, + ai_gain_611x, + ai_gain_622x, + ai_gain_628x, + ai_gain_6143 +}; +enum caldac_enum +{ + caldac_none=0, + mb88341, + dac8800, + dac8043, + ad8522, + ad8804, + ad8842, + ad8804_debug +}; +enum ni_reg_type +{ + ni_reg_normal = 0x0, + ni_reg_611x = 0x1, + ni_reg_6711 = 0x2, + ni_reg_6713 = 0x4, + ni_reg_67xx_mask = 0x6, + ni_reg_6xxx_mask = 0x7, + ni_reg_622x = 0x8, + ni_reg_625x = 0x10, + ni_reg_628x = 0x18, + ni_reg_m_series_mask = 0x18, + ni_reg_6143 = 0x20 +}; + +/* M Series registers offsets */ +#define M_Offset_CDIO_DMA_Select 0x7 /* write */ +#define M_Offset_SCXI_Status 0x7 /* read */ +#define M_Offset_AI_AO_Select 0x9 /* write, same offset as e-series */ +#define M_Offset_SCXI_Serial_Data_In 0x9 /* read */ +#define M_Offset_G0_G1_Select 0xb /* write, same offset as e-series */ +#define M_Offset_Misc_Command 0xf +#define M_Offset_SCXI_Serial_Data_Out 0x11 +#define M_Offset_SCXI_Control 0x13 +#define M_Offset_SCXI_Output_Enable 0x15 +#define M_Offset_AI_FIFO_Data 0x1c +#define M_Offset_Static_Digital_Output 0x24 /* write */ +#define M_Offset_Static_Digital_Input 0x24 /* read */ +#define M_Offset_DIO_Direction 0x28 +#define M_Offset_Cal_PWM 0x40 +#define M_Offset_AI_Config_FIFO_Data 0x5e +#define M_Offset_Interrupt_C_Enable 0x88 /* write */ +#define M_Offset_Interrupt_C_Status 0x88 /* read */ +#define M_Offset_Analog_Trigger_Control 0x8c +#define M_Offset_AO_Serial_Interrupt_Enable 0xa0 +#define M_Offset_AO_Serial_Interrupt_Ack 0xa1 /* write */ +#define M_Offset_AO_Serial_Interrupt_Status 0xa1 /* read */ +#define M_Offset_AO_Calibration 0xa3 +#define M_Offset_AO_FIFO_Data 0xa4 +#define M_Offset_PFI_Filter 0xb0 +#define M_Offset_RTSI_Filter 0xb4 +#define M_Offset_SCXI_Legacy_Compatibility 0xbc +#define M_Offset_Interrupt_A_Ack 0x104 /* write */ +#define M_Offset_AI_Status_1 0x104 /* read */ +#define M_Offset_Interrupt_B_Ack 0x106 /* write */ +#define M_Offset_AO_Status_1 0x106 /* read */ +#define M_Offset_AI_Command_2 0x108 /* write */ +#define M_Offset_G01_Status 0x108 /* read */ +#define M_Offset_AO_Command_2 0x10a +#define M_Offset_AO_Status_2 0x10c /* read */ +#define M_Offset_G0_Command 0x10c /* write */ +#define M_Offset_G1_Command 0x10e /* write */ +#define M_Offset_G0_HW_Save 0x110 +#define M_Offset_G0_HW_Save_High 0x110 +#define M_Offset_AI_Command_1 0x110 +#define M_Offset_G0_HW_Save_Low 0x112 +#define M_Offset_AO_Command_1 0x112 +#define M_Offset_G1_HW_Save 0x114 +#define M_Offset_G1_HW_Save_High 0x114 +#define M_Offset_G1_HW_Save_Low 0x116 +#define M_Offset_AI_Mode_1 0x118 +#define M_Offset_G0_Save 0x118 +#define M_Offset_G0_Save_High 0x118 +#define M_Offset_AI_Mode_2 0x11a +#define M_Offset_G0_Save_Low 0x11a +#define M_Offset_AI_SI_Load_A 0x11c +#define M_Offset_G1_Save 0x11c +#define M_Offset_G1_Save_High 0x11c +#define M_Offset_G1_Save_Low 0x11e +#define M_Offset_AI_SI_Load_B 0x120 /* write */ +#define M_Offset_AO_UI_Save 0x120 /* read */ +#define M_Offset_AI_SC_Load_A 0x124 /* write */ +#define M_Offset_AO_BC_Save 0x124 /* read */ +#define M_Offset_AI_SC_Load_B 0x128 /* write */ +#define M_Offset_AO_UC_Save 0x128 /* read */ +#define M_Offset_AI_SI2_Load_A 0x12c +#define M_Offset_AI_SI2_Load_B 0x130 +#define M_Offset_G0_Mode 0x134 +#define M_Offset_G1_Mode 0x136 /* write */ +#define M_Offset_Joint_Status_1 0x136 /* read */ +#define M_Offset_G0_Load_A 0x138 +#define M_Offset_Joint_Status_2 0x13a +#define M_Offset_G0_Load_B 0x13c +#define M_Offset_G1_Load_A 0x140 +#define M_Offset_G1_Load_B 0x144 +#define M_Offset_G0_Input_Select 0x148 +#define M_Offset_G1_Input_Select 0x14a +#define M_Offset_AO_Mode_1 0x14c +#define M_Offset_AO_Mode_2 0x14e +#define M_Offset_AO_UI_Load_A 0x150 +#define M_Offset_AO_UI_Load_B 0x154 +#define M_Offset_AO_BC_Load_A 0x158 +#define M_Offset_AO_BC_Load_B 0x15c +#define M_Offset_AO_UC_Load_A 0x160 +#define M_Offset_AO_UC_Load_B 0x164 +#define M_Offset_Clock_and_FOUT 0x170 +#define M_Offset_IO_Bidirection_Pin 0x172 +#define M_Offset_RTSI_Trig_Direction 0x174 +#define M_Offset_Interrupt_Control 0x176 +#define M_Offset_AI_Output_Control 0x178 +#define M_Offset_Analog_Trigger_Etc 0x17a +#define M_Offset_AI_START_STOP_Select 0x17c +#define M_Offset_AI_Trigger_Select 0x17e +#define M_Offset_AI_SI_Save 0x180 /* read */ +#define M_Offset_AI_DIV_Load_A 0x180 /* write */ +#define M_Offset_AI_SC_Save 0x184 /* read */ +#define M_Offset_AO_Start_Select 0x184 /* write */ +#define M_Offset_AO_Trigger_Select 0x186 +#define M_Offset_AO_Mode_3 0x18c +#define M_Offset_G0_Autoincrement 0x188 +#define M_Offset_G1_Autoincrement 0x18a +#define M_Offset_Joint_Reset 0x190 +#define M_Offset_Interrupt_A_Enable 0x192 +#define M_Offset_Interrupt_B_Enable 0x196 +#define M_Offset_AI_Personal 0x19a +#define M_Offset_AO_Personal 0x19c +#define M_Offset_RTSI_Trig_A_Output 0x19e +#define M_Offset_RTSI_Trig_B_Output 0x1a0 +#define M_Offset_RTSI_Shared_MUX 0x1a2 +#define M_Offset_AO_Output_Control 0x1ac +#define M_Offset_AI_Mode_3 0x1ae +#define M_Offset_Configuration_Memory_Clear 0x1a4 +#define M_Offset_AI_FIFO_Clear 0x1a6 +#define M_Offset_AO_FIFO_Clear 0x1a8 +#define M_Offset_G0_Counting_Mode 0x1b0 +#define M_Offset_G1_Counting_Mode 0x1b2 +#define M_Offset_G0_Second_Gate 0x1b4 +#define M_Offset_G1_Second_Gate 0x1b6 +#define M_Offset_G0_DMA_Config 0x1b8 /* write */ +#define M_Offset_G0_DMA_Status 0x1b8 /* read */ +#define M_Offset_G1_DMA_Config 0x1ba /* write */ +#define M_Offset_G1_DMA_Status 0x1ba /* read */ +#define M_Offset_G0_MSeries_ABZ 0x1c0 +#define M_Offset_G1_MSeries_ABZ 0x1c2 +#define M_Offset_Clock_and_Fout2 0x1c4 +#define M_Offset_PLL_Control 0x1c6 +#define M_Offset_PLL_Status 0x1c8 +#define M_Offset_PFI_Output_Select_1 0x1d0 +#define M_Offset_PFI_Output_Select_2 0x1d2 +#define M_Offset_PFI_Output_Select_3 0x1d4 +#define M_Offset_PFI_Output_Select_4 0x1d6 +#define M_Offset_PFI_Output_Select_5 0x1d8 +#define M_Offset_PFI_Output_Select_6 0x1da +#define M_Offset_PFI_DI 0x1dc +#define M_Offset_PFI_DO 0x1de +#define M_Offset_AI_Config_FIFO_Bypass 0x218 +#define M_Offset_SCXI_DIO_Enable 0x21c +#define M_Offset_CDI_FIFO_Data 0x220 /* read */ +#define M_Offset_CDO_FIFO_Data 0x220 /* write */ +#define M_Offset_CDIO_Status 0x224 /* read */ +#define M_Offset_CDIO_Command 0x224 /* write */ +#define M_Offset_CDI_Mode 0x228 +#define M_Offset_CDO_Mode 0x22c +#define M_Offset_CDI_Mask_Enable 0x230 +#define M_Offset_CDO_Mask_Enable 0x234 +#define M_Offset_AO_Waveform_Order(x) (0xc2 + 0x4 * x) +#define M_Offset_AO_Config_Bank(x) (0xc3 + 0x4 * x) +#define M_Offset_DAC_Direct_Data(x) (0xc0 + 0x4 * x) +#define M_Offset_Gen_PWM(x) (0x44 + 0x2 * x) + +static inline int M_Offset_Static_AI_Control(int i) +{ + int offset[] = + { + 0x64, + 0x261, + 0x262, + 0x263, + }; + if(((unsigned)i) >= sizeof(offset) / sizeof(offset[0])) + { + rtdm_printk("%s: invalid channel=%i\n", __FUNCTION__, i); + return offset[0]; + } + return offset[i]; +}; +static inline int M_Offset_AO_Reference_Attenuation(int channel) +{ + int offset[] = + { + 0x264, + 0x265, + 0x266, + 0x267 + }; + if(((unsigned)channel) >= sizeof(offset) / sizeof(offset[0])) + { + rtdm_printk("%s: invalid channel=%i\n", __FUNCTION__, channel); + return offset[0]; + } + return offset[channel]; +}; +static inline unsigned M_Offset_PFI_Output_Select(unsigned n) +{ + if(n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) + { + rtdm_printk("%s: invalid pfi output select register=%i\n", __FUNCTION__, n); + return M_Offset_PFI_Output_Select_1; + } + return M_Offset_PFI_Output_Select_1 + (n - 1) * 2; +} + +#define MSeries_AI_Config_Channel_Type_Mask (0x7 << 6) +#define MSeries_AI_Config_Channel_Type_Calibration_Bits 0x0 +#define MSeries_AI_Config_Channel_Type_Differential_Bits (0x1 << 6) +#define MSeries_AI_Config_Channel_Type_Common_Ref_Bits (0x2 << 6) +#define MSeries_AI_Config_Channel_Type_Ground_Ref_Bits (0x3 << 6) +#define MSeries_AI_Config_Channel_Type_Aux_Bits (0x5 << 6) +#define MSeries_AI_Config_Channel_Type_Ghost_Bits (0x7 << 6) +#define MSeries_AI_Config_Polarity_Bit 0x1000 /* 0 for 2's complement encoding */ +#define MSeries_AI_Config_Dither_Bit 0x2000 +#define MSeries_AI_Config_Last_Channel_Bit 0x4000 +#define MSeries_AI_Config_Channel_Bits(x) (x & 0xf) +#define MSeries_AI_Config_Gain_Bits(x) ((x & 0x7) << 9) + +static inline +unsigned int MSeries_AI_Config_Bank_Bits(unsigned int reg_type, + unsigned int channel) +{ + unsigned int bits = channel & 0x30; + if (reg_type == ni_reg_622x) { + if (channel & 0x40) + bits |= 0x400; + } + return bits; +} + +#define MSeries_PLL_In_Source_Select_RTSI0_Bits 0xb +#define MSeries_PLL_In_Source_Select_Star_Trigger_Bits 0x14 +#define MSeries_PLL_In_Source_Select_RTSI7_Bits 0x1b +#define MSeries_PLL_In_Source_Select_PXI_Clock10 0x1d +#define MSeries_PLL_In_Source_Select_Mask 0x1f +#define MSeries_Timebase1_Select_Bit 0x20 /* use PLL for timebase 1 */ +#define MSeries_Timebase3_Select_Bit 0x40 /* use PLL for timebase 3 */ +/* Use 10MHz instead of 20MHz for RTSI clock frequency. Appears + to have no effect, at least on pxi-6281, which always uses + 20MHz rtsi clock frequency */ +#define MSeries_RTSI_10MHz_Bit 0x80 + +static inline +unsigned int MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned int RTSI_channel) +{ + if(RTSI_channel > 7) + { + rtdm_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__, RTSI_channel); + return 0; + } + if(RTSI_channel == 7) return MSeries_PLL_In_Source_Select_RTSI7_Bits; + else return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel; +} + +#define MSeries_PLL_Enable_Bit 0x1000 +#define MSeries_PLL_VCO_Mode_200_325MHz_Bits 0x0 +#define MSeries_PLL_VCO_Mode_175_225MHz_Bits 0x2000 +#define MSeries_PLL_VCO_Mode_100_225MHz_Bits 0x4000 +#define MSeries_PLL_VCO_Mode_75_150MHz_Bits 0x6000 + +static inline +unsigned int MSeries_PLL_Divisor_Bits(unsigned int divisor) +{ + static const unsigned int max_divisor = 0x10; + if(divisor < 1 || divisor > max_divisor) + { + rtdm_printk("%s: bug, invalid divisor=%i\n", __FUNCTION__, divisor); + return 0; + } + return (divisor & 0xf) << 8; +} +static inline +unsigned int MSeries_PLL_Multiplier_Bits(unsigned int multiplier) +{ + static const unsigned int max_multiplier = 0x100; + if(multiplier < 1 || multiplier > max_multiplier) + { + rtdm_printk("%s: bug, invalid multiplier=%i\n", __FUNCTION__, multiplier); + return 0; + } + return multiplier & 0xff; +} + +#define MSeries_PLL_Locked_Bit 0x1 + +#define MSeries_AI_Bypass_Channel_Mask 0x7 +#define MSeries_AI_Bypass_Bank_Mask 0x78 +#define MSeries_AI_Bypass_Cal_Sel_Pos_Mask 0x380 +#define MSeries_AI_Bypass_Cal_Sel_Neg_Mask 0x1c00 +#define MSeries_AI_Bypass_Mode_Mux_Mask 0x6000 +#define MSeries_AO_Bypass_AO_Cal_Sel_Mask 0x38000 +#define MSeries_AI_Bypass_Gain_Mask 0x1c0000 +#define MSeries_AI_Bypass_Dither_Bit 0x200000 +#define MSeries_AI_Bypass_Polarity_Bit 0x400000 /* 0 for 2's complement encoding */ +#define MSeries_AI_Bypass_Config_FIFO_Bit 0x80000000 +#define MSeries_AI_Bypass_Cal_Sel_Pos_Bits(x) ((x << 7) & \ + MSeries_AI_Bypass_Cal_Sel_Pos_Mask) +#define MSeries_AI_Bypass_Cal_Sel_Neg_Bits(x) ((x << 10) & \ + MSeries_AI_Bypass_Cal_Sel_Pos_Mask) +#define MSeries_AI_Bypass_Gain_Bits(x) ((x << 18) & \ + MSeries_AI_Bypass_Gain_Mask) + +#define MSeries_AO_DAC_Offset_Select_Mask 0x7 +#define MSeries_AO_DAC_Offset_0V_Bits 0x0 +#define MSeries_AO_DAC_Offset_5V_Bits 0x1 +#define MSeries_AO_DAC_Reference_Mask 0x38 +#define MSeries_AO_DAC_Reference_10V_Internal_Bits 0x0 +#define MSeries_AO_DAC_Reference_5V_Internal_Bits 0x8 +#define MSeries_AO_Update_Timed_Bit 0x40 +#define MSeries_AO_Bipolar_Bit 0x80 /* turns on 2's complement encoding */ + +#define MSeries_Attenuate_x5_Bit 0x1 + +#define MSeries_Cal_PWM_High_Time_Bits(x) ((x << 16) & 0xffff0000) +#define MSeries_Cal_PWM_Low_Time_Bits(x) (x & 0xffff) + +#define MSeries_PFI_Output_Select_Mask(x) (0x1f << (x % 3) * 5) +#define MSeries_PFI_Output_Select_Bits(x, y) ((y & 0x1f) << ((x % 3) * 5)) +// inverse to MSeries_PFI_Output_Select_Bits +#define MSeries_PFI_Output_Select_Source(x, y) ((y >> ((x % 3) * 5)) & 0x1f) + +#define Gi_DMA_BankSW_Error_Bit 0x10 +#define Gi_DMA_Reset_Bit 0x8 +#define Gi_DMA_Int_Enable_Bit 0x4 +#define Gi_DMA_Write_Bit 0x2 +#define Gi_DMA_Enable_Bit 0x1 + +#define MSeries_PFI_Filter_Select_Mask(x) (0x3 << (x * 2)) +#define MSeries_PFI_Filter_Select_Bits(x, y) ((y << (x * 2)) & \ + MSeries_PFI_Filter_Select_Mask(x)) + +/* CDIO DMA select bits */ +#define CDI_DMA_Select_Shift 0 +#define CDI_DMA_Select_Mask 0xf +#define CDO_DMA_Select_Shift 4 +#define CDO_DMA_Select_Mask 0xf << CDO_DMA_Select_Shift + +/* CDIO status bits */ +#define CDO_FIFO_Empty_Bit 0x1 +#define CDO_FIFO_Full_Bit 0x2 +#define CDO_FIFO_Request_Bit 0x4 +#define CDO_Overrun_Bit 0x8 +#define CDO_Underflow_Bit 0x10 +#define CDI_FIFO_Empty_Bit 0x10000 +#define CDI_FIFO_Full_Bit 0x20000 +#define CDI_FIFO_Request_Bit 0x40000 +#define CDI_Overrun_Bit 0x80000 +#define CDI_Overflow_Bit 0x100000 + +/* CDIO command bits */ +#define CDO_Disarm_Bit 0x1 +#define CDO_Arm_Bit 0x2 +#define CDI_Disarm_Bit 0x4 +#define CDI_Arm_Bit 0x8 +#define CDO_Reset_Bit 0x10 +#define CDI_Reset_Bit 0x20 +#define CDO_Error_Interrupt_Enable_Set_Bit 0x40 +#define CDO_Error_Interrupt_Enable_Clear_Bit 0x80 +#define CDI_Error_Interrupt_Enable_Set_Bit 0x100 +#define CDI_Error_Interrupt_Enable_Clear_Bit 0x200 +#define CDO_FIFO_Request_Interrupt_Enable_Set_Bit 0x400 +#define CDO_FIFO_Request_Interrupt_Enable_Clear_Bit 0x800 +#define CDI_FIFO_Request_Interrupt_Enable_Set_Bit 0x1000 +#define CDI_FIFO_Request_Interrupt_Enable_Clear_Bit 0x2000 +#define CDO_Error_Interrupt_Confirm_Bit 0x4000 +#define CDI_Error_Interrupt_Confirm_Bit 0x8000 +#define CDO_Empty_FIFO_Interrupt_Enable_Set_Bit 0x10000 +#define CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit 0x20000 +#define CDO_SW_Update_Bit 0x80000 +#define CDI_SW_Update_Bit 0x100000 + +/* CDIO mode bits */ +#define CDI_Sample_Source_Select_Mask 0x3f +#define CDI_Halt_On_Error_Bit 0x200 +/* sample clock on falling edge */ +#define CDI_Polarity_Bit 0x400 +/* set for half full mode, clear for not empty mode */ +#define CDI_FIFO_Mode_Bit 0x800 +/* data lanes specify which dio channels map to byte or word accesses + to the dio fifos */ +#define CDI_Data_Lane_Mask 0x3000 +#define CDI_Data_Lane_0_15_Bits 0x0 +#define CDI_Data_Lane_16_31_Bits 0x1000 +#define CDI_Data_Lane_0_7_Bits 0x0 +#define CDI_Data_Lane_8_15_Bits 0x1000 +#define CDI_Data_Lane_16_23_Bits 0x2000 +#define CDI_Data_Lane_24_31_Bits 0x3000 + +/* CDO mode bits */ +#define CDO_Sample_Source_Select_Mask 0x3f +#define CDO_Retransmit_Bit 0x100 +#define CDO_Halt_On_Error_Bit 0x200 +/* sample clock on falling edge */ +#define CDO_Polarity_Bit 0x400 +/* set for half full mode, clear for not full mode */ +#define CDO_FIFO_Mode_Bit 0x800 +/* data lanes specify which dio channels map to byte or word accesses + to the dio fifos */ +#define CDO_Data_Lane_Mask 0x3000 +#define CDO_Data_Lane_0_15_Bits 0x0 +#define CDO_Data_Lane_16_31_Bits 0x1000 +#define CDO_Data_Lane_0_7_Bits 0x0 +#define CDO_Data_Lane_8_15_Bits 0x1000 +#define CDO_Data_Lane_16_23_Bits 0x2000 +#define CDO_Data_Lane_24_31_Bits 0x3000 + +/* Interrupt C bits */ +#define Interrupt_Group_C_Enable_Bit 0x1 +#define Interrupt_Group_C_Status_Bit 0x1 + +#define M_SERIES_EEPROM_SIZE 1024 + +typedef struct ni_board_struct{ + unsigned short device_id; + int isapnp_id; + char *name; + + int n_adchan; + int adbits; + + int ai_fifo_depth; + unsigned int alwaysdither : 1; + int gainlkup; + int ai_speed; + + int n_aochan; + int aobits; + a4l_rngdesc_t *ao_range_table; + int ao_fifo_depth; + + unsigned ao_speed; + + unsigned num_p0_dio_channels; + + int reg_type; + unsigned int ao_unipolar : 1; + unsigned int has_8255 : 1; + unsigned int has_analog_trig : 1; + + enum caldac_enum caldac[3]; +} ni_board; + +#define n_ni_boards (sizeof(ni_boards)/sizeof(ni_board)) + +#define MAX_N_CALDACS 34 +#define MAX_N_AO_CHAN 8 +#define NUM_GPCT 2 + +#define NI_PRIVATE_COMMON \ + uint16_t (*stc_readw)(a4l_dev_t *dev, int register); \ + uint32_t (*stc_readl)(a4l_dev_t *dev, int register); \ + void (*stc_writew)(a4l_dev_t *dev, uint16_t value, int register); \ + void (*stc_writel)(a4l_dev_t *dev, uint32_t value, int register); \ + \ + int dio_state; \ + int pfi_state; \ + int io_bits; \ + unsigned short dio_output; \ + unsigned short dio_control; \ + int ao0p,ao1p; \ + int lastchan; \ + int last_do; \ + int rt_irq; \ + int irq_polarity; \ + int irq_pin; \ + int aimode; \ + int ai_continuous; \ + int blocksize; \ + int n_left; \ + unsigned int ai_calib_source; \ + unsigned int ai_calib_source_enabled; \ + a4l_lock_t window_lock; \ + a4l_lock_t soft_reg_copy_lock; \ + a4l_lock_t mite_channel_lock; \ + \ + int changain_state; \ + unsigned int changain_spec; \ + \ + unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \ + unsigned short ao[MAX_N_AO_CHAN]; \ + unsigned short caldacs[MAX_N_CALDACS]; \ + \ + unsigned short ai_cmd2; \ + \ + unsigned short ao_conf[MAX_N_AO_CHAN]; \ + unsigned short ao_mode1; \ + unsigned short ao_mode2; \ + unsigned short ao_mode3; \ + unsigned short ao_cmd1; \ + unsigned short ao_cmd2; \ + unsigned short ao_cmd3; \ + unsigned short ao_trigger_select; \ + \ + struct ni_gpct_device *counter_dev; \ + unsigned short an_trig_etc_reg; \ + \ + unsigned ai_offset[512]; \ + \ + unsigned long serial_interval_ns; \ + unsigned char serial_hw_mode; \ + unsigned short clock_and_fout; \ + unsigned short clock_and_fout2; \ + \ + unsigned short int_a_enable_reg; \ + unsigned short int_b_enable_reg; \ + unsigned short io_bidirection_pin_reg; \ + unsigned short rtsi_trig_direction_reg; \ + unsigned short rtsi_trig_a_output_reg; \ + unsigned short rtsi_trig_b_output_reg; \ + unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \ + unsigned short ai_ao_select_reg; \ + unsigned short g0_g1_select_reg; \ + unsigned short cdio_dma_select_reg; \ + \ + unsigned clock_ns; \ + unsigned clock_source; \ + \ + unsigned short atrig_mode; \ + unsigned short atrig_high; \ + unsigned short atrig_low; \ + \ + unsigned short pwm_up_count; \ + unsigned short pwm_down_count; \ + \ + sampl_t ai_fifo_buffer[0x2000]; \ + uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \ + \ + struct mite_struct *mite; \ + struct mite_channel *ai_mite_chan; \ + struct mite_channel *ao_mite_chan;\ + struct mite_channel *cdo_mite_chan;\ + struct mite_dma_descriptor_ring *ai_mite_ring; \ + struct mite_dma_descriptor_ring *ao_mite_ring; \ + struct mite_dma_descriptor_ring *cdo_mite_ring; \ + struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT]; \ + subd_8255_t subd_8255 + + +typedef struct { + ni_board *board_ptr; + NI_PRIVATE_COMMON; +} ni_private; + +#define devpriv ((ni_private *)dev->priv) +#define boardtype (*(ni_board *)devpriv->board_ptr) + +/* How we access registers */ + +#define ni_writel(a,b) (writel((a), devpriv->mite->daq_io_addr + (b))) +#define ni_readl(a) (readl(devpriv->mite->daq_io_addr + (a))) +#define ni_writew(a,b) (writew((a), devpriv->mite->daq_io_addr + (b))) +#define ni_readw(a) (readw(devpriv->mite->daq_io_addr + (a))) +#define ni_writeb(a,b) (writeb((a), devpriv->mite->daq_io_addr + (b))) +#define ni_readb(a) (readb(devpriv->mite->daq_io_addr + (a))) + +/* INSN_CONFIG_SET_CLOCK_SRC argument for NI cards */ +#define NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC 0 /* 10 MHz */ +#define NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC 1 /* 100 KHz */ + +#endif /* _ANALOGY_NI_STC_H */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_tio.h relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_tio.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_tio.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/ni_tio.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1194 @@ +/** + * @file + * Hardware driver for NI general purpose counter + * @note Copyright (C) 2006 Frank Mori Hess + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ANALOGY_NI_TIO_H__ +#define __ANALOGY_NI_TIO_H__ + +#include + +#ifdef CONFIG_PCI +#include "mite.h" +#endif + +enum ni_gpct_register { + NITIO_G0_Autoincrement_Reg, + NITIO_G1_Autoincrement_Reg, + NITIO_G2_Autoincrement_Reg, + NITIO_G3_Autoincrement_Reg, + NITIO_G0_Command_Reg, + NITIO_G1_Command_Reg, + NITIO_G2_Command_Reg, + NITIO_G3_Command_Reg, + NITIO_G0_HW_Save_Reg, + NITIO_G1_HW_Save_Reg, + NITIO_G2_HW_Save_Reg, + NITIO_G3_HW_Save_Reg, + NITIO_G0_SW_Save_Reg, + NITIO_G1_SW_Save_Reg, + NITIO_G2_SW_Save_Reg, + NITIO_G3_SW_Save_Reg, + NITIO_G0_Mode_Reg, + NITIO_G1_Mode_Reg, + NITIO_G2_Mode_Reg, + NITIO_G3_Mode_Reg, + NITIO_G0_LoadA_Reg, + NITIO_G1_LoadA_Reg, + NITIO_G2_LoadA_Reg, + NITIO_G3_LoadA_Reg, + NITIO_G0_LoadB_Reg, + NITIO_G1_LoadB_Reg, + NITIO_G2_LoadB_Reg, + NITIO_G3_LoadB_Reg, + NITIO_G0_Input_Select_Reg, + NITIO_G1_Input_Select_Reg, + NITIO_G2_Input_Select_Reg, + NITIO_G3_Input_Select_Reg, + NITIO_G0_Counting_Mode_Reg, + NITIO_G1_Counting_Mode_Reg, + NITIO_G2_Counting_Mode_Reg, + NITIO_G3_Counting_Mode_Reg, + NITIO_G0_Second_Gate_Reg, + NITIO_G1_Second_Gate_Reg, + NITIO_G2_Second_Gate_Reg, + NITIO_G3_Second_Gate_Reg, + NITIO_G01_Status_Reg, + NITIO_G23_Status_Reg, + NITIO_G01_Joint_Reset_Reg, + NITIO_G23_Joint_Reset_Reg, + NITIO_G01_Joint_Status1_Reg, + NITIO_G23_Joint_Status1_Reg, + NITIO_G01_Joint_Status2_Reg, + NITIO_G23_Joint_Status2_Reg, + NITIO_G0_DMA_Config_Reg, + NITIO_G1_DMA_Config_Reg, + NITIO_G2_DMA_Config_Reg, + NITIO_G3_DMA_Config_Reg, + NITIO_G0_DMA_Status_Reg, + NITIO_G1_DMA_Status_Reg, + NITIO_G2_DMA_Status_Reg, + NITIO_G3_DMA_Status_Reg, + NITIO_G0_ABZ_Reg, + NITIO_G1_ABZ_Reg, + NITIO_G0_Interrupt_Acknowledge_Reg, + NITIO_G1_Interrupt_Acknowledge_Reg, + NITIO_G2_Interrupt_Acknowledge_Reg, + NITIO_G3_Interrupt_Acknowledge_Reg, + NITIO_G0_Status_Reg, + NITIO_G1_Status_Reg, + NITIO_G2_Status_Reg, + NITIO_G3_Status_Reg, + NITIO_G0_Interrupt_Enable_Reg, + NITIO_G1_Interrupt_Enable_Reg, + NITIO_G2_Interrupt_Enable_Reg, + NITIO_G3_Interrupt_Enable_Reg, + NITIO_Num_Registers, +}; + +static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Autoincrement_Reg; + break; + case 1: + return NITIO_G1_Autoincrement_Reg; + break; + case 2: + return NITIO_G2_Autoincrement_Reg; + break; + case 3: + return NITIO_G3_Autoincrement_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Command_Reg; + break; + case 1: + return NITIO_G1_Command_Reg; + break; + case 2: + return NITIO_G2_Command_Reg; + break; + case 3: + return NITIO_G3_Command_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Counting_Mode_Reg; + break; + case 1: + return NITIO_G1_Counting_Mode_Reg; + break; + case 2: + return NITIO_G2_Counting_Mode_Reg; + break; + case 3: + return NITIO_G3_Counting_Mode_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Input_Select_Reg; + break; + case 1: + return NITIO_G1_Input_Select_Reg; + break; + case 2: + return NITIO_G2_Input_Select_Reg; + break; + case 3: + return NITIO_G3_Input_Select_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + case 1: + return NITIO_G01_Joint_Reset_Reg; + break; + case 2: + case 3: + return NITIO_G23_Joint_Reset_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + case 1: + return NITIO_G01_Joint_Status1_Reg; + break; + case 2: + case 3: + return NITIO_G23_Joint_Status1_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned + counter_index) +{ + switch (counter_index) { + case 0: + case 1: + return NITIO_G01_Joint_Status2_Reg; + break; + case 2: + case 3: + return NITIO_G23_Joint_Status2_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index) +{ + switch (counter_index) { + case 0: + case 1: + return NITIO_G01_Status_Reg; + break; + case 2: + case 3: + return NITIO_G23_Status_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_LoadA_Reg(unsigned counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_LoadA_Reg; + break; + case 1: + return NITIO_G1_LoadA_Reg; + break; + case 2: + return NITIO_G2_LoadA_Reg; + break; + case 3: + return NITIO_G3_LoadA_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_LoadB_Reg(unsigned counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_LoadB_Reg; + break; + case 1: + return NITIO_G1_LoadB_Reg; + break; + case 2: + return NITIO_G2_LoadB_Reg; + break; + case 3: + return NITIO_G3_LoadB_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Mode_Reg(unsigned counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Mode_Reg; + break; + case 1: + return NITIO_G1_Mode_Reg; + break; + case 2: + return NITIO_G2_Mode_Reg; + break; + case 3: + return NITIO_G3_Mode_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_SW_Save_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_SW_Save_Reg; + break; + case 1: + return NITIO_G1_SW_Save_Reg; + break; + case 2: + return NITIO_G2_SW_Save_Reg; + break; + case 3: + return NITIO_G3_SW_Save_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Second_Gate_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Second_Gate_Reg; + break; + case 1: + return NITIO_G1_Second_Gate_Reg; + break; + case 2: + return NITIO_G2_Second_Gate_Reg; + break; + case 3: + return NITIO_G3_Second_Gate_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_DMA_Config_Reg; + break; + case 1: + return NITIO_G1_DMA_Config_Reg; + break; + case 2: + return NITIO_G2_DMA_Config_Reg; + break; + case 3: + return NITIO_G3_DMA_Config_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_DMA_Status_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_DMA_Status_Reg; + break; + case 1: + return NITIO_G1_DMA_Status_Reg; + break; + case 2: + return NITIO_G2_DMA_Status_Reg; + break; + case 3: + return NITIO_G3_DMA_Status_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_ABZ_Reg; + break; + case 1: + return NITIO_G1_ABZ_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int + counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Interrupt_Acknowledge_Reg; + break; + case 1: + return NITIO_G1_Interrupt_Acknowledge_Reg; + break; + case 2: + return NITIO_G2_Interrupt_Acknowledge_Reg; + break; + case 3: + return NITIO_G3_Interrupt_Acknowledge_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Status_Reg; + break; + case 1: + return NITIO_G1_Status_Reg; + break; + case 2: + return NITIO_G2_Status_Reg; + break; + case 3: + return NITIO_G3_Status_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int + counter_index) +{ + switch (counter_index) { + case 0: + return NITIO_G0_Interrupt_Enable_Reg; + break; + case 1: + return NITIO_G1_Interrupt_Enable_Reg; + break; + case 2: + return NITIO_G2_Interrupt_Enable_Reg; + break; + case 3: + return NITIO_G3_Interrupt_Enable_Reg; + break; + default: + BUG(); + break; + } + return 0; +} + +enum ni_gpct_variant { + ni_gpct_variant_e_series, + ni_gpct_variant_m_series, + ni_gpct_variant_660x +}; + +struct ni_gpct { + struct ni_gpct_device *counter_dev; + unsigned counter_index; + unsigned chip_index; + uint64_t clock_period_ps; /* clock period in picoseconds */ + struct mite_channel *mite_chan; + a4l_lock_t lock; +}; + +struct ni_gpct_device { + a4l_dev_t *dev; + void (*write_register)(struct ni_gpct * counter, + unsigned int bits, enum ni_gpct_register reg); + unsigned (*read_register)(struct ni_gpct * counter, + enum ni_gpct_register reg); + enum ni_gpct_variant variant; + struct ni_gpct **counters; + unsigned num_counters; + unsigned regs[NITIO_Num_Registers]; + a4l_lock_t regs_lock; +}; + +#define Gi_Auto_Increment_Mask 0xff +#define Gi_Up_Down_Shift 5 + +#define Gi_Arm_Bit 0x1 +#define Gi_Save_Trace_Bit 0x2 +#define Gi_Load_Bit 0x4 +#define Gi_Disarm_Bit 0x10 +#define Gi_Up_Down_Mask (0x3 << Gi_Up_Down_Shift) +#define Gi_Always_Down_Bits (0x0 << Gi_Up_Down_Shift) +#define Gi_Always_Up_Bits (0x1 << Gi_Up_Down_Shift) +#define Gi_Up_Down_Hardware_IO_Bits (0x2 << Gi_Up_Down_Shift) +#define Gi_Up_Down_Hardware_Gate_Bits (0x3 << Gi_Up_Down_Shift) +#define Gi_Write_Switch_Bit 0x80 +#define Gi_Synchronize_Gate_Bit 0x100 +#define Gi_Little_Big_Endian_Bit 0x200 +#define Gi_Bank_Switch_Start_Bit 0x400 +#define Gi_Bank_Switch_Mode_Bit 0x800 +#define Gi_Bank_Switch_Enable_Bit 0x1000 +#define Gi_Arm_Copy_Bit 0x2000 +#define Gi_Save_Trace_Copy_Bit 0x4000 +#define Gi_Disarm_Copy_Bit 0x8000 + +#define Gi_Index_Phase_Bitshift 5 +#define Gi_HW_Arm_Select_Shift 8 + +#define Gi_Counting_Mode_Mask 0x7 +#define Gi_Counting_Mode_Normal_Bits 0x0 +#define Gi_Counting_Mode_QuadratureX1_Bits 0x1 +#define Gi_Counting_Mode_QuadratureX2_Bits 0x2 +#define Gi_Counting_Mode_QuadratureX4_Bits 0x3 +#define Gi_Counting_Mode_Two_Pulse_Bits 0x4 +#define Gi_Counting_Mode_Sync_Source_Bits 0x6 +#define Gi_Index_Mode_Bit 0x10 +#define Gi_Index_Phase_Mask (0x3 << Gi_Index_Phase_Bitshift) +#define Gi_Index_Phase_LowA_LowB (0x0 << Gi_Index_Phase_Bitshift) +#define Gi_Index_Phase_LowA_HighB (0x1 << Gi_Index_Phase_Bitshift) +#define Gi_Index_Phase_HighA_LowB (0x2 << Gi_Index_Phase_Bitshift) +#define Gi_Index_Phase_HighA_HighB (0x3 << Gi_Index_Phase_Bitshift) + +/* From m-series example code, + not documented in 660x register level manual */ +#define Gi_HW_Arm_Enable_Bit 0x80 +/* From m-series example code, + not documented in 660x register level manual */ +#define Gi_660x_HW_Arm_Select_Mask (0x7 << Gi_HW_Arm_Select_Shift) +#define Gi_660x_Prescale_X8_Bit 0x1000 +#define Gi_M_Series_Prescale_X8_Bit 0x2000 +#define Gi_M_Series_HW_Arm_Select_Mask (0x1f << Gi_HW_Arm_Select_Shift) +/* Must be set for clocks over 40MHz, + which includes synchronous counting and quadrature modes */ +#define Gi_660x_Alternate_Sync_Bit 0x2000 +#define Gi_M_Series_Alternate_Sync_Bit 0x4000 +/* From m-series example code, + not documented in 660x register level manual */ +#define Gi_660x_Prescale_X2_Bit 0x4000 +#define Gi_M_Series_Prescale_X2_Bit 0x8000 + +static inline unsigned int Gi_Alternate_Sync_Bit(enum ni_gpct_variant variant) +{ + switch (variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + return Gi_M_Series_Alternate_Sync_Bit; + break; + case ni_gpct_variant_660x: + return Gi_660x_Alternate_Sync_Bit; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline unsigned int Gi_Prescale_X2_Bit(enum ni_gpct_variant variant) +{ + switch (variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + return Gi_M_Series_Prescale_X2_Bit; + break; + case ni_gpct_variant_660x: + return Gi_660x_Prescale_X2_Bit; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline unsigned int Gi_Prescale_X8_Bit(enum ni_gpct_variant variant) +{ + switch (variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + return Gi_M_Series_Prescale_X8_Bit; + break; + case ni_gpct_variant_660x: + return Gi_660x_Prescale_X8_Bit; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline unsigned int Gi_HW_Arm_Select_Mask(enum ni_gpct_variant variant) +{ + switch (variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + return Gi_M_Series_HW_Arm_Select_Mask; + break; + case ni_gpct_variant_660x: + return Gi_660x_HW_Arm_Select_Mask; + break; + default: + BUG(); + break; + } + return 0; +} + +#define NI_660x_Timebase_1_Clock 0x0 /* 20MHz */ +#define NI_660x_Source_Pin_i_Clock 0x1 +#define NI_660x_Next_Gate_Clock 0xa +#define NI_660x_Timebase_2_Clock 0x12 /* 100KHz */ +#define NI_660x_Next_TC_Clock 0x13 +#define NI_660x_Timebase_3_Clock 0x1e /* 80MHz */ +#define NI_660x_Logic_Low_Clock 0x1f + +#define ni_660x_max_rtsi_channel 6 +#define ni_660x_max_source_pin 7 + +static inline unsigned int NI_660x_RTSI_Clock(unsigned int n) +{ + BUG_ON(n > ni_660x_max_rtsi_channel); + return (0xb + n); +} + +static inline unsigned int NI_660x_Source_Pin_Clock(unsigned int n) +{ + BUG_ON(n > ni_660x_max_source_pin); + return (0x2 + n); +} + +/* Clock sources for ni e and m series boards, + get bits with Gi_Source_Select_Bits() */ +#define NI_M_Series_Timebase_1_Clock 0x0 /* 20MHz */ +#define NI_M_Series_Timebase_2_Clock 0x12 /* 100KHz */ +#define NI_M_Series_Next_TC_Clock 0x13 +#define NI_M_Series_Next_Gate_Clock 0x14 /* when Gi_Src_SubSelect = 0 */ +#define NI_M_Series_PXI_Star_Trigger_Clock 0x14 /* when Gi_Src_SubSelect = 1 */ +#define NI_M_Series_PXI10_Clock 0x1d +#define NI_M_Series_Timebase_3_Clock 0x1e /* 80MHz, when Gi_Src_SubSelect = 0 */ +#define NI_M_Series_Analog_Trigger_Out_Clock 0x1e /* when Gi_Src_SubSelect = 1 */ +#define NI_M_Series_Logic_Low_Clock 0x1f + +#define ni_m_series_max_pfi_channel 15 +#define ni_m_series_max_rtsi_channel 7 + +static inline unsigned int NI_M_Series_PFI_Clock(unsigned int n) +{ + BUG_ON(n > ni_m_series_max_pfi_channel); + if (n < 10) + return 1 + n; + else + return 0xb + n; +} + +static inline unsigned int NI_M_Series_RTSI_Clock(unsigned int n) +{ + BUG_ON(n > ni_m_series_max_rtsi_channel); + if (n == 7) + return 0x1b; + else + return 0xb + n; +} + +#define NI_660x_Source_Pin_i_Gate_Select 0x0 +#define NI_660x_Gate_Pin_i_Gate_Select 0x1 +#define NI_660x_Next_SRC_Gate_Select 0xa +#define NI_660x_Next_Out_Gate_Select 0x14 +#define NI_660x_Logic_Low_Gate_Select 0x1f +#define ni_660x_max_gate_pin 7 + +static inline unsigned int NI_660x_Gate_Pin_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_660x_max_gate_pin); + return 0x2 + n; +} + +static inline unsigned int NI_660x_RTSI_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_660x_max_rtsi_channel); + return 0xb + n; +} + + +#define NI_M_Series_Timestamp_Mux_Gate_Select 0x0 +#define NI_M_Series_AI_START2_Gate_Select 0x12 +#define NI_M_Series_PXI_Star_Trigger_Gate_Select 0x13 +#define NI_M_Series_Next_Out_Gate_Select 0x14 +#define NI_M_Series_AI_START1_Gate_Select 0x1c +#define NI_M_Series_Next_SRC_Gate_Select 0x1d +#define NI_M_Series_Analog_Trigger_Out_Gate_Select 0x1e +#define NI_M_Series_Logic_Low_Gate_Select 0x1f + +static inline unsigned int NI_M_Series_RTSI_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_m_series_max_rtsi_channel); + if (n == 7) + return 0x1b; + return 0xb + n; +} + +static inline unsigned int NI_M_Series_PFI_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_m_series_max_pfi_channel); + if (n < 10) + return 1 + n; + return 0xb + n; +} + + +#define Gi_Source_Select_Shift 2 +#define Gi_Gate_Select_Shift 7 + +#define Gi_Read_Acknowledges_Irq 0x1 /* not present on 660x */ +#define Gi_Write_Acknowledges_Irq 0x2 /* not present on 660x */ +#define Gi_Source_Select_Mask 0x7c +#define Gi_Gate_Select_Mask (0x1f << Gi_Gate_Select_Shift) +#define Gi_Gate_Select_Load_Source_Bit 0x1000 +#define Gi_Or_Gate_Bit 0x2000 +#define Gi_Output_Polarity_Bit 0x4000 /* set to invert */ +#define Gi_Source_Polarity_Bit 0x8000 /* set to invert */ + +#define Gi_Source_Select_Bits(x) ((x << Gi_Source_Select_Shift) & \ + Gi_Source_Select_Mask) +#define Gi_Gate_Select_Bits(x) ((x << Gi_Gate_Select_Shift) & \ + Gi_Gate_Select_Mask) + +#define Gi_Gating_Mode_Mask 0x3 +#define Gi_Gating_Disabled_Bits 0x0 +#define Gi_Level_Gating_Bits 0x1 +#define Gi_Rising_Edge_Gating_Bits 0x2 +#define Gi_Falling_Edge_Gating_Bits 0x3 +#define Gi_Gate_On_Both_Edges_Bit 0x4 /* used in conjunction with + rising edge gating mode */ +#define Gi_Trigger_Mode_for_Edge_Gate_Mask 0x18 +#define Gi_Edge_Gate_Starts_Stops_Bits 0x0 +#define Gi_Edge_Gate_Stops_Starts_Bits 0x8 +#define Gi_Edge_Gate_Starts_Bits 0x10 +#define Gi_Edge_Gate_No_Starts_or_Stops_Bits 0x18 +#define Gi_Stop_Mode_Mask 0x60 +#define Gi_Stop_on_Gate_Bits 0x00 +#define Gi_Stop_on_Gate_or_TC_Bits 0x20 +#define Gi_Stop_on_Gate_or_Second_TC_Bits 0x40 +#define Gi_Load_Source_Select_Bit 0x80 +#define Gi_Output_Mode_Mask 0x300 +#define Gi_Output_TC_Pulse_Bits 0x100 +#define Gi_Output_TC_Toggle_Bits 0x200 +#define Gi_Output_TC_or_Gate_Toggle_Bits 0x300 +#define Gi_Counting_Once_Mask 0xc00 +#define Gi_No_Hardware_Disarm_Bits 0x000 +#define Gi_Disarm_at_TC_Bits 0x400 +#define Gi_Disarm_at_Gate_Bits 0x800 +#define Gi_Disarm_at_TC_or_Gate_Bits 0xc00 +#define Gi_Loading_On_TC_Bit 0x1000 +#define Gi_Gate_Polarity_Bit 0x2000 +#define Gi_Loading_On_Gate_Bit 0x4000 +#define Gi_Reload_Source_Switching_Bit 0x8000 + +#define NI_660x_Source_Pin_i_Second_Gate_Select 0x0 +#define NI_660x_Up_Down_Pin_i_Second_Gate_Select 0x1 +#define NI_660x_Next_SRC_Second_Gate_Select 0xa +#define NI_660x_Next_Out_Second_Gate_Select 0x14 +#define NI_660x_Selected_Gate_Second_Gate_Select 0x1e +#define NI_660x_Logic_Low_Second_Gate_Select 0x1f + +#define ni_660x_max_up_down_pin 7 + +static inline +unsigned int NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_660x_max_up_down_pin); + return 0x2 + n; +} +static inline +unsigned int NI_660x_RTSI_Second_Gate_Select(unsigned int n) +{ + BUG_ON(n > ni_660x_max_rtsi_channel); + return 0xb + n; +} + +#define Gi_Second_Gate_Select_Shift 7 + +/*FIXME: m-series has a second gate subselect bit */ +/*FIXME: m-series second gate sources are undocumented (by NI)*/ +#define Gi_Second_Gate_Mode_Bit 0x1 +#define Gi_Second_Gate_Select_Mask (0x1f << Gi_Second_Gate_Select_Shift) +#define Gi_Second_Gate_Polarity_Bit 0x2000 +#define Gi_Second_Gate_Subselect_Bit 0x4000 /* m-series only */ +#define Gi_Source_Subselect_Bit 0x8000 /* m-series only */ + +static inline +unsigned int Gi_Second_Gate_Select_Bits(unsigned int second_gate_select) +{ + return (second_gate_select << Gi_Second_Gate_Select_Shift) & + Gi_Second_Gate_Select_Mask; +} + +#define G0_Save_Bit 0x1 +#define G1_Save_Bit 0x2 +#define G0_Counting_Bit 0x4 +#define G1_Counting_Bit 0x8 +#define G0_Next_Load_Source_Bit 0x10 +#define G1_Next_Load_Source_Bit 0x20 +#define G0_Stale_Data_Bit 0x40 +#define G1_Stale_Data_Bit 0x80 +#define G0_Armed_Bit 0x100 +#define G1_Armed_Bit 0x200 +#define G0_No_Load_Between_Gates_Bit 0x400 +#define G1_No_Load_Between_Gates_Bit 0x800 +#define G0_TC_Error_Bit 0x1000 +#define G1_TC_Error_Bit 0x2000 +#define G0_Gate_Error_Bit 0x4000 +#define G1_Gate_Error_Bit 0x8000 + +static inline unsigned int Gi_Counting_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_Counting_Bit; + return G0_Counting_Bit; +} + +static inline unsigned int Gi_Armed_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_Armed_Bit; + return G0_Armed_Bit; +} + +static inline unsigned int Gi_Next_Load_Source_Bit(unsigned counter_index) +{ + if (counter_index % 2) + return G1_Next_Load_Source_Bit; + return G0_Next_Load_Source_Bit; +} + +static inline unsigned int Gi_Stale_Data_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_Stale_Data_Bit; + return G0_Stale_Data_Bit; +} + +static inline unsigned int Gi_TC_Error_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_TC_Error_Bit; + return G0_TC_Error_Bit; +} + +static inline unsigned int Gi_Gate_Error_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_Gate_Error_Bit; + return G0_Gate_Error_Bit; +} + +/* Joint reset register bits */ +static inline unsigned Gi_Reset_Bit(unsigned int counter_index) +{ + return 0x1 << (2 + (counter_index % 2)); +} + +#define G0_Output_Bit 0x1 +#define G1_Output_Bit 0x2 +#define G0_HW_Save_Bit 0x1000 +#define G1_HW_Save_Bit 0x2000 +#define G0_Permanent_Stale_Bit 0x4000 +#define G1_Permanent_Stale_Bit 0x8000 + +static inline unsigned int Gi_Permanent_Stale_Bit(unsigned + counter_index) +{ + if (counter_index % 2) + return G1_Permanent_Stale_Bit; + return G0_Permanent_Stale_Bit; +} + +#define Gi_DMA_Enable_Bit 0x1 +#define Gi_DMA_Write_Bit 0x2 +#define Gi_DMA_Int_Bit 0x4 + +#define Gi_DMA_Readbank_Bit 0x2000 +#define Gi_DRQ_Error_Bit 0x4000 +#define Gi_DRQ_Status_Bit 0x8000 + +#define G0_Gate_Error_Confirm_Bit 0x20 +#define G0_TC_Error_Confirm_Bit 0x40 + +#define G1_Gate_Error_Confirm_Bit 0x2 +#define G1_TC_Error_Confirm_Bit 0x4 + +static inline unsigned int Gi_Gate_Error_Confirm_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_Gate_Error_Confirm_Bit; + return G0_Gate_Error_Confirm_Bit; +} + +static inline unsigned int Gi_TC_Error_Confirm_Bit(unsigned int counter_index) +{ + if (counter_index % 2) + return G1_TC_Error_Confirm_Bit; + return G0_TC_Error_Confirm_Bit; +} + +/* Bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers */ +#define Gi_TC_Interrupt_Ack_Bit 0x4000 +#define Gi_Gate_Interrupt_Ack_Bit 0x8000 + +#define Gi_Gate_Interrupt_Bit 0x4 +#define Gi_TC_Bit 0x8 +#define Gi_Interrupt_Bit 0x8000 + +#define G0_TC_Interrupt_Enable_Bit 0x40 +#define G0_Gate_Interrupt_Enable_Bit 0x100 + +#define G1_TC_Interrupt_Enable_Bit 0x200 +#define G1_Gate_Interrupt_Enable_Bit 0x400 + +static inline unsigned int Gi_Gate_Interrupt_Enable_Bit(unsigned int counter_index) +{ + unsigned int bit; + + if (counter_index % 2) { + bit = G1_Gate_Interrupt_Enable_Bit; + } else { + bit = G0_Gate_Interrupt_Enable_Bit; + } + return bit; +} + +#define counter_status_mask (A4L_COUNTER_ARMED | A4L_COUNTER_COUNTING) + +#define NI_USUAL_PFI_SELECT(x) ((x < 10) ? (0x1 + x) : (0xb + x)) +#define NI_USUAL_RTSI_SELECT(x) ((x < 7 ) ? (0xb + x) : (0x1b + x)) + +/* Mode bits for NI general-purpose counters, set with + INSN_CONFIG_SET_COUNTER_MODE */ +#define NI_GPCT_COUNTING_MODE_SHIFT 16 +#define NI_GPCT_INDEX_PHASE_BITSHIFT 20 +#define NI_GPCT_COUNTING_DIRECTION_SHIFT 24 + +#define NI_GPCT_GATE_ON_BOTH_EDGES_BIT 0x4 +#define NI_GPCT_EDGE_GATE_MODE_MASK 0x18 +#define NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS 0x0 +#define NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS 0x8 +#define NI_GPCT_EDGE_GATE_STARTS_BITS 0x10 +#define NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS 0x18 +#define NI_GPCT_STOP_MODE_MASK 0x60 +#define NI_GPCT_STOP_ON_GATE_BITS 0x00 +#define NI_GPCT_STOP_ON_GATE_OR_TC_BITS 0x20 +#define NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS 0x40 +#define NI_GPCT_LOAD_B_SELECT_BIT 0x80 +#define NI_GPCT_OUTPUT_MODE_MASK 0x300 +#define NI_GPCT_OUTPUT_TC_PULSE_BITS 0x100 +#define NI_GPCT_OUTPUT_TC_TOGGLE_BITS 0x200 +#define NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS 0x300 +#define NI_GPCT_HARDWARE_DISARM_MASK 0xc00 +#define NI_GPCT_NO_HARDWARE_DISARM_BITS 0x000 +#define NI_GPCT_DISARM_AT_TC_BITS 0x400 +#define NI_GPCT_DISARM_AT_GATE_BITS 0x800 +#define NI_GPCT_DISARM_AT_TC_OR_GATE_BITS 0xc00 +#define NI_GPCT_LOADING_ON_TC_BIT 0x1000 +#define NI_GPCT_LOADING_ON_GATE_BIT 0x4000 +#define NI_GPCT_COUNTING_MODE_MASK 0x7 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_NORMAL_BITS 0x0 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS 0x1 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS 0x2 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS 0x3 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS 0x4 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS 0x6 << NI_GPCT_COUNTING_MODE_SHIFT +#define NI_GPCT_INDEX_PHASE_MASK 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT +#define NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT +#define NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT +#define NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT +#define NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT +#define NI_GPCT_INDEX_ENABLE_BIT 0x400000 +#define NI_GPCT_COUNTING_DIRECTION_MASK 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT +#define NI_GPCT_COUNTING_DIRECTION_DOWN_BITS 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT +#define NI_GPCT_COUNTING_DIRECTION_UP_BITS 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT +#define NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT +#define NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT +#define NI_GPCT_RELOAD_SOURCE_MASK 0xc000000 +#define NI_GPCT_RELOAD_SOURCE_FIXED_BITS 0x0 +#define NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS 0x4000000 +#define NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS 0x8000000 +#define NI_GPCT_OR_GATE_BIT 0x10000000 +#define NI_GPCT_INVERT_OUTPUT_BIT 0x20000000 + +/* Bits for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC when + using NI general-purpose counters. */ +#define NI_GPCT_CLOCK_SRC_SELECT_MASK 0x3f +#define NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS 0x0 +#define NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS 0x1 +#define NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS 0x2 +#define NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS 0x3 +#define NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS 0x4 +#define NI_GPCT_NEXT_TC_CLOCK_SRC_BITS 0x5 +#define NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS 0x6 /* NI 660x-specific */ +#define NI_GPCT_PXI10_CLOCK_SRC_BITS 0x7 +#define NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS 0x8 +#define NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS 0x9 +#define NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK 0x30000000 +#define NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS 0x0 +#define NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS 0x10000000 /* divide source by 2 */ +#define NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS 0x20000000 /* divide source by 8 */ +#define NI_GPCT_INVERT_CLOCK_SRC_BIT 0x80000000 +#define NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(x) (0x10 + x) +#define NI_GPCT_RTSI_CLOCK_SRC_BITS(x) (0x18 + x) +#define NI_GPCT_PFI_CLOCK_SRC_BITS(x) (0x20 + x) + +/* Possibilities for setting a gate source with + INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters. + May be bitwise-or'd with CR_EDGE or CR_INVERT. */ +/* M-series gates */ +#define NI_GPCT_TIMESTAMP_MUX_GATE_SELECT 0x0 +#define NI_GPCT_AI_START2_GATE_SELECT 0x12 +#define NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT 0x13 +#define NI_GPCT_NEXT_OUT_GATE_SELECT 0x14 +#define NI_GPCT_AI_START1_GATE_SELECT 0x1c +#define NI_GPCT_NEXT_SOURCE_GATE_SELECT 0x1d +#define NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT 0x1e +#define NI_GPCT_LOGIC_LOW_GATE_SELECT 0x1f +/* More gates for 660x */ +#define NI_GPCT_SOURCE_PIN_i_GATE_SELECT 0x100 +#define NI_GPCT_GATE_PIN_i_GATE_SELECT 0x101 +/* More gates for 660x "second gate" */ +#define NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT 0x201 +#define NI_GPCT_SELECTED_GATE_GATE_SELECT 0x21e +/* M-series "second gate" sources are unknown, we should add them here + with an offset of 0x300 when known. */ +#define NI_GPCT_DISABLED_GATE_SELECT 0x8000 +#define NI_GPCT_GATE_PIN_GATE_SELECT(x) (0x102 + x) +#define NI_GPCT_RTSI_GATE_SELECT(x) NI_USUAL_RTSI_SELECT(x) +#define NI_GPCT_PFI_GATE_SELECT(x) NI_USUAL_PFI_SELECT(x) +#define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x) (0x202 + x) + +/* Possibilities for setting a source with INSN_CONFIG_SET_OTHER_SRC + when using NI general-purpose counters. */ +#define NI_GPCT_SOURCE_ENCODER_A 0 +#define NI_GPCT_SOURCE_ENCODER_B 1 +#define NI_GPCT_SOURCE_ENCODER_Z 2 +/* M-series gates */ +/* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */ +#define NI_GPCT_DISABLED_OTHER_SELECT 0x8000 +#define NI_GPCT_PFI_OTHER_SELECT(x) NI_USUAL_PFI_SELECT(x) + +/* Start sources for ni general-purpose counters for use with + INSN_CONFIG_ARM */ +#define NI_GPCT_ARM_IMMEDIATE 0x0 +/* Start both the counter and the adjacent paired counter + simultaneously */ +#define NI_GPCT_ARM_PAIRED_IMMEDIATE 0x1 +/* NI doesn't document bits for selecting hardware arm triggers. If + the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least significant + bits (3 bits for 660x or 5 bits for m-series) through to the + hardware. This will at least allow someone to figure out what the bits + do later. */ +#define NI_GPCT_ARM_UNKNOWN 0x1000 + +/* Digital filtering options for ni 660x for use with + INSN_CONFIG_FILTER. */ +#define NI_GPCT_FILTER_OFF 0x0 +#define NI_GPCT_FILTER_TIMEBASE_3_SYNC 0x1 +#define NI_GPCT_FILTER_100x_TIMEBASE_1 0x2 +#define NI_GPCT_FILTER_20x_TIMEBASE_1 0x3 +#define NI_GPCT_FILTER_10x_TIMEBASE_1 0x4 +#define NI_GPCT_FILTER_2x_TIMEBASE_1 0x5 +#define NI_GPCT_FILTER_2x_TIMEBASE_3 0x6 + +/* Master clock sources for ni mio boards and + INSN_CONFIG_SET_CLOCK_SRC */ +#define NI_MIO_INTERNAL_CLOCK 0 +#define NI_MIO_RTSI_CLOCK 1 +/* Doesn't work for m-series, use NI_MIO_PLL_RTSI_CLOCK() the + NI_MIO_PLL_* sources are m-series only */ +#define NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK 2 +#define NI_MIO_PLL_PXI10_CLOCK 3 +#define NI_MIO_PLL_RTSI0_CLOCK 4 + +#define NI_MIO_PLL_RTSI_CLOCK(x) (NI_MIO_PLL_RTSI0_CLOCK + (x)) + +/* Signals which can be routed to an NI RTSI pin with + INSN_CONFIG_SET_ROUTING. The numbers assigned are not arbitrary, they + correspond to the bits required to program the board. */ +#define NI_RTSI_OUTPUT_ADR_START1 0 +#define NI_RTSI_OUTPUT_ADR_START2 1 +#define NI_RTSI_OUTPUT_SCLKG 2 +#define NI_RTSI_OUTPUT_DACUPDN 3 +#define NI_RTSI_OUTPUT_DA_START1 4 +#define NI_RTSI_OUTPUT_G_SRC0 5 +#define NI_RTSI_OUTPUT_G_GATE0 6 +#define NI_RTSI_OUTPUT_RGOUT0 7 +#define NI_RTSI_OUTPUT_RTSI_BRD_0 8 +/* Pre-m-series always have RTSI clock on line 7 */ +#define NI_RTSI_OUTPUT_RTSI_OSC 12 + +#define NI_RTSI_OUTPUT_RTSI_BRD(x) (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x)) + + +int ni_tio_rinsn(struct ni_gpct *counter, a4l_kinsn_t *insn); +int ni_tio_winsn(struct ni_gpct *counter, a4l_kinsn_t *insn); +int ni_tio_insn_config(struct ni_gpct *counter, a4l_kinsn_t *insn); +void ni_tio_init_counter(struct ni_gpct *counter); + +struct ni_gpct_device *ni_gpct_device_construct(a4l_dev_t * dev, + void (*write_register) (struct ni_gpct * counter, unsigned int bits, + enum ni_gpct_register reg), + unsigned int (*read_register) (struct ni_gpct * counter, + enum ni_gpct_register reg), enum ni_gpct_variant variant, + unsigned int num_counters); +void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev); + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +extern a4l_cmd_t ni_tio_cmd_mask; + +int ni_tio_input_inttrig(struct ni_gpct *counter, lsampl_t trignum); +int ni_tio_cmd(struct ni_gpct *counter, a4l_cmd_t *cmd); +int ni_tio_cmdtest(struct ni_gpct *counter, a4l_cmd_t *cmd); +int ni_tio_cancel(struct ni_gpct *counter); + +void ni_tio_handle_interrupt(struct ni_gpct *counter, a4l_dev_t *dev); +void ni_tio_set_mite_channel(struct ni_gpct *counter, + struct mite_channel *mite_chan); +void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, + int *gate_error, + int *tc_error, + int *perm_stale_data, int *stale_data); + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +#endif /* !__ANALOGY_NI_TIO_H__ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/pcimio.c relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/pcimio.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/pcimio.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/pcimio.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1599 @@ +/** + * @file + * Hardware driver for NI PCI-MIO E series cards + * + * Copyright (C) 1997-8 David A. Schleef + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Description: National Instruments PCI-MIO-E series and M series + * (all boards) + * + * Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans, + * Herman Bruyninckx, Terry Barnaby + * Status: works + * Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio), + * PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, + * PCI-6040E,PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, + * PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, + * PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, PCI-6220, PCI-6221, + * PCI-6224, PCI-6225, PCI-6229, PCI-6250, PCI-6251, PCIe-6251, + * PCI-6254, PCI-6259, PCIe-6259, PCI-6280, PCI-6281, PXI-6281, + * PCI-6284, PCI-6289, PCI-6711, PXI-6711, PCI-6713, PXI-6713, + * PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E, PCI-6036E, PCI-6731, + * PCI-6733, PXI-6733, PCI-6143, PXI-6143 + * + * These boards are almost identical to the AT-MIO E series, except that + * they use the PCI bus instead of ISA (i.e., AT). See the notes for + * the ni_atmio.o driver for additional information about these boards. + * + * By default, the driver uses DMA to transfer analog input data to + * memory. When DMA is enabled, not all triggering features are + * supported. + * + * Note that the PCI-6143 is a simultaneous sampling device with 8 + * convertors. With this board all of the convertors perform one + * simultaneous sample during a scan interval. The period for a scan + * is used for the convert time in an Analgoy cmd. The convert trigger + * source is normally set to TRIG_NOW by default. + * + * The RTSI trigger bus is supported on these cards on subdevice + * 10. See the Analogy library documentation for details. + * + * References: + * 341079b.pdf PCI E Series Register-Level Programmer Manual + * 340934b.pdf DAQ-STC reference manual + * 322080b.pdf 6711/6713/6715 User Manual + * 320945c.pdf PCI E Series User Manual + * 322138a.pdf PCI-6052E and DAQPad-6052E User Manual + * + * ISSUES: + * - When DMA is enabled, XXX_EV_CONVERT does not work correctly. + * - Calibration is not fully implemented + * - SCXI is probably broken for m-series boards + * - Digital I/O may not work on 673x. + * - Information (number of channels, bits, etc.) for some devices may + * be incorrect. Please check this and submit a bug if there are + * problems for your device. + * - Need to deal with external reference for DAC, and other DAC + * properties in board properties + * - Deal with at-mio-16de-10 revision D to N changes, etc. + * - Need to add other CALDAC type + * - Need to slow down DAC loading. I don't trust NI's claim that two + * writes to the PCI bus slows IO enough. I would prefer to use + * a4l_udelay(). Timing specs: (clock) + * AD8522 30ns + * DAC8043 120ns + * DAC8800 60ns + * MB88341 ? + * + */ + +#include +#include + +#include "../intel/8255.h" +#include "ni_stc.h" +#include "ni_mio.h" +#include "mite.h" + +#define PCIMIO_IRQ_POLARITY 1 + +/* The following two tables must be in the same order */ +static struct pci_device_id ni_pci_table[] __devinitdata = { + { PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x28c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2b80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2b90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70aa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70ab, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70ac, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70af, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70b4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70b6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70b7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ni_pci_table); + +/* These are not all the possible ao ranges for 628x boards. + They can do OFFSET +- REFERENCE where OFFSET can be + 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can + be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's + 63 different possibilities. An AO channel + can not act as it's own OFFSET or REFERENCE. +*/ + +#if 0 +static a4l_rngtab_t rng_ni_M_628x_ao = { 8, { + RANGE(-10, 10), + RANGE(-5, 5), + RANGE(-2, 2), + RANGE(-1, 1), + RANGE(-5, 15), + RANGE(0, 10), + RANGE(3, 7), + RANGE(4, 6), + RANGE_ext(-1, 1) +}}; +static a4l_rngdesc_t range_ni_M_628x_ao = + RNG_GLOBAL(rng_ni_M_628x_ao); +#endif + +static a4l_rngtab_t rng_ni_M_625x_ao = { 3, { + RANGE(-10, 10), + RANGE(-5, 5), + RANGE_ext(-1, 1) +}}; +static a4l_rngdesc_t range_ni_M_625x_ao = + RNG_GLOBAL(rng_ni_M_625x_ao); + +static a4l_rngtab_t rng_ni_M_622x_ao = { 1, { + RANGE(-10, 10), +}}; +static a4l_rngdesc_t range_ni_M_622x_ao = + RNG_GLOBAL(rng_ni_M_622x_ao); + +static ni_board ni_boards[]={ + { device_id: 0x0162, // NI also says 0x1620. typo? + name: "pci-mio-16xe-50", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 2048, + alwaysdither: 1, + gainlkup: ai_gain_8, + ai_speed: 50000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 50000, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043}, + has_8255: 0, + }, + { device_id: 0x1170, + name: "pci-mio-16xe-10", // aka pci-6030E + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 10000, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + has_8255: 0, + }, + { device_id: 0x28c0, + name: "pci-6014", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x11d0, + name: "pxi-6030e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 10000, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + has_8255: 0, + }, + + { device_id: 0x1180, + name: "pci-mio-16e-1", /* aka pci-6070e */ + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_16, + ai_speed: 800, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {mb88341}, + has_8255: 0, + }, + { device_id: 0x1190, + name: "pci-mio-16e-4", /* aka pci-6040e */ + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_16, + /* Note: there have been reported problems with full speed + * on this board */ + ai_speed: 2000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 512, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, // doc says mb88341 + has_8255: 0, + }, + { device_id: 0x11c0, + name: "pxi-6040e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_16, + ai_speed: 2000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 512, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {mb88341}, + has_8255: 0, + }, + + { device_id: 0x1330, + name: "pci-6031e", + n_adchan: 64, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 10000, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + has_8255: 0, + }, + { device_id: 0x1270, + name: "pci-6032e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + has_8255: 0, + }, + { device_id: 0x1340, + name: "pci-6033e", + n_adchan: 64, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + has_8255: 0, + }, + { device_id: 0x1350, + name: "pci-6071e", + n_adchan: 64, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_16, + ai_speed: 800, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x2a60, + name: "pci-6023e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 0, + aobits: 0, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, /* manual is wrong */ + has_8255: 0, + }, + { device_id: 0x2a70, + name: "pci-6024e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, /* manual is wrong */ + has_8255: 0, + }, + { device_id: 0x2a80, + name: "pci-6025e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, /* manual is wrong */ + has_8255: 1, + }, + { device_id: 0x2ab0, + name: "pxi-6025e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 0, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 0, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, /* manual is wrong */ + has_8255: 1, + }, + + { device_id: 0x2ca0, + name: "pci-6034e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x2c80, + name: "pci-6035e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x18b0, + name: "pci-6052e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_16, + ai_speed: 3000, + n_aochan: 2, + aobits: 16, + ao_unipolar: 1, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_speed: 3000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug,ad8804_debug,ad8522}, /* manual is wrong */ + }, + { device_id: 0x14e0, + name: "pci-6110", + n_adchan: 4, + adbits: 12, + ai_fifo_depth: 8192, + alwaysdither: 0, + gainlkup: ai_gain_611x, + ai_speed: 200, + n_aochan: 2, + aobits: 16, + reg_type: ni_reg_611x, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_fifo_depth: 2048, + ao_speed: 250, + .num_p0_dio_channels = 8, + caldac: {ad8804,ad8804}, + }, + { device_id: 0x14f0, + name: "pci-6111", + n_adchan: 2, + adbits: 12, + ai_fifo_depth: 8192, + alwaysdither: 0, + gainlkup: ai_gain_611x, + ai_speed: 200, + n_aochan: 2, + aobits: 16, + reg_type: ni_reg_611x, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_fifo_depth: 2048, + ao_speed: 250, + .num_p0_dio_channels = 8, + caldac: {ad8804,ad8804}, + }, +#if 0 /* Need device IDs */ + /* The 6115 boards probably need their own driver */ + { device_id: 0x2ed0, + name: "pci-6115", + n_adchan: 4, + adbits: 12, + ai_fifo_depth: 8192, + alwaysdither: 0, + gainlkup: ai_gain_611x, + ai_speed: 100, + n_aochan: 2, + aobits: 16, + ao_671x: 1, + ao_unipolar: 0, + ao_fifo_depth: 2048, + ao_speed: 250, + .num_p0_dio_channels = 8, + reg_611x: 1, + caldac: {ad8804_debug,ad8804_debug,ad8804_debug},/* XXX */ + }, +#endif +#if 0 /* Need device IDs */ + { device_id: 0x0000, + name: "pxi-6115", + n_adchan: 4, + adbits: 12, + ai_fifo_depth: 8192, + alwaysdither: 0, + gainlkup: ai_gain_611x, + ai_speed: 100, + n_aochan: 2, + aobits: 16, + ao_671x: 1, + ao_unipolar: 0, + ao_fifo_depth: 2048, + ao_speed: 250, + reg_611x: 1, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug,ad8804_debug,ad8804_debug},/* XXX */ + }, +#endif + { device_id: 0x1880, + name: "pci-6711", + n_adchan: 0, /* no analog input */ + n_aochan: 4, + aobits: 12, + ao_unipolar: 0, + ao_fifo_depth: 16384, /* data sheet says 8192, but fifo really holds 16384 samples */ + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6711, + caldac: {ad8804_debug}, + }, + { device_id: 0x2b90, + name: "pxi-6711", + n_adchan: 0, /* no analog input */ + n_aochan: 4, + aobits: 12, + ao_unipolar: 0, + ao_fifo_depth: 16384, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6711, + caldac: {ad8804_debug}, + }, + { device_id: 0x1870, + name: "pci-6713", + n_adchan: 0, /* no analog input */ + n_aochan: 8, + aobits: 12, + ao_unipolar: 0, + ao_fifo_depth: 16384, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6713, + caldac: {ad8804_debug,ad8804_debug}, + }, + { device_id: 0x2b80, + name: "pxi-6713", + n_adchan: 0, /* no analog input */ + n_aochan: 8, + aobits: 12, + ao_unipolar: 0, + ao_fifo_depth: 16384, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6713, + caldac: {ad8804_debug,ad8804_debug}, + }, + { device_id: 0x2430, + name: "pci-6731", + n_adchan: 0, /* no analog input */ + n_aochan: 4, + aobits: 16, + ao_unipolar: 0, + ao_fifo_depth: 8192, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6711, + caldac: {ad8804_debug}, + }, +#if 0 /* Need device IDs */ + { device_id: 0x0, + name: "pxi-6731", + n_adchan: 0, /* no analog input */ + n_aochan: 4, + aobits: 16, + ao_unipolar: 0, + ao_fifo_depth: 8192, + .ao_range_table = &range_bipolar10, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6711, + caldac: {ad8804_debug}, + }, +#endif + { device_id: 0x2410, + name: "pci-6733", + n_adchan: 0, /* no analog input */ + n_aochan: 8, + aobits: 16, + ao_unipolar: 0, + ao_fifo_depth: 16384, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6713, + caldac: {ad8804_debug,ad8804_debug}, + }, + { device_id: 0x2420, + name: "pxi-6733", + n_adchan: 0, /* no analog input */ + n_aochan: 8, + aobits: 16, + ao_unipolar: 0, + ao_fifo_depth: 16384, + .ao_range_table = &range_bipolar10, + ao_speed: 1000, + .num_p0_dio_channels = 8, + reg_type: ni_reg_6713, + caldac: {ad8804_debug,ad8804_debug}, + }, + { device_id: 0x15b0, + name: "pxi-6071e", + n_adchan: 64, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_16, + ai_speed: 800, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x11b0, + name: "pxi-6070e", + n_adchan: 16, + adbits: 12, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_16, + ai_speed: 800, + n_aochan: 2, + aobits: 12, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 1000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x18c0, + name: "pxi-6052e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_16, + ai_speed: 3000, + n_aochan: 2, + aobits: 16, + ao_unipolar: 1, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_speed: 3000, + .num_p0_dio_channels = 8, + caldac: {mb88341,mb88341,ad8522}, + }, + { device_id: 0x1580, + name: "pxi-6031e", + n_adchan: 64, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_14, + ai_speed: 10000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 2048, + .ao_range_table = &range_ni_E_ao_ext, + ao_unipolar: 1, + ao_speed: 10000, + .num_p0_dio_channels = 8, + caldac: {dac8800,dac8043,ad8522}, + }, + { device_id: 0x2890, + name: "pci-6036e", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, + alwaysdither: 1, + gainlkup: ai_gain_4, + ai_speed: 5000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 0, + .ao_range_table = &range_bipolar10, + ao_unipolar: 0, + ao_speed: 100000, + .num_p0_dio_channels = 8, + caldac: {ad8804_debug}, + has_8255: 0, + }, + { device_id: 0x70b0, + name: "pci-6220", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 512, //FIXME: guess + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + .num_p0_dio_channels = 8, + reg_type: ni_reg_622x, + ao_unipolar: 0, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70af, + name: "pci-6221", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 4095, + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_622x_ao, + reg_type: ni_reg_622x, + ao_unipolar: 0, + ao_speed: 1200, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x71bc, + name: "pci-6221_37pin", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 4095, + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_622x_ao, + reg_type: ni_reg_622x, + ao_unipolar: 0, + ao_speed: 1200, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70f2, + name: "pci-6224", + n_adchan: 32, + adbits: 16, + ai_fifo_depth: 4095, + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + reg_type: ni_reg_622x, + ao_unipolar: 0, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x716c, + name: "pci-6225", + n_adchan: 80, + adbits: 16, + ai_fifo_depth: 4095, + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_622x_ao, + reg_type: ni_reg_622x, + ao_unipolar: 0, + ao_speed: 1200, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70aa, + name: "pci-6229", + n_adchan: 32, + adbits: 16, + ai_fifo_depth: 4095, + gainlkup: ai_gain_622x, + ai_speed: 4000, + n_aochan: 4, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_622x_ao, + reg_type: ni_reg_622x, + ao_unipolar: 0, + ao_speed: 1200, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70b4, + name: "pci-6250", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + reg_type: ni_reg_625x, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70b8, + name: "pci-6251", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_625x_ao, + reg_type: ni_reg_625x, + ao_unipolar: 0, + ao_speed: 357, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x717d, + name: "pcie-6251", + n_adchan: 16, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_625x_ao, + reg_type: ni_reg_625x, + ao_unipolar: 0, + ao_speed: 357, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70b7, + name: "pci-6254", + n_adchan: 32, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + reg_type: ni_reg_625x, + ao_unipolar: 0, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70ab, + name: "pci-6259", + n_adchan: 32, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 4, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_625x_ao, + reg_type: ni_reg_625x, + ao_unipolar: 0, + ao_speed: 357, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x717f, + name: "pcie-6259", + n_adchan: 32, + adbits: 16, + ai_fifo_depth: 4095, + .gainlkup = ai_gain_628x, + ai_speed: 800, + n_aochan: 4, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_625x_ao, + reg_type: ni_reg_625x, + ao_unipolar: 0, + ao_speed: 357, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, +#if 0 /* TODO: fix data size */ + { device_id: 0x70b6, + name: "pci-6280", + n_adchan: 16, + adbits: 18, + ai_fifo_depth: 2047, + .gainlkup = ai_gain_628x, + ai_speed: 1600, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 8191, + reg_type: ni_reg_628x, + ao_unipolar: 0, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70bd, + name: "pci-6281", + n_adchan: 16, + adbits: 18, + ai_fifo_depth: 2047, + .gainlkup = ai_gain_628x, + ai_speed: 1600, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_628x_ao, + reg_type: ni_reg_628x, + ao_unipolar: 1, + ao_speed: 357, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70bf, + name: "pxi-6281", + n_adchan: 16, + adbits: 18, + ai_fifo_depth: 2047, + .gainlkup = ai_gain_628x, + ai_speed: 1600, + n_aochan: 2, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_628x_ao, + reg_type: ni_reg_628x, + ao_unipolar: 1, + ao_speed: 357, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70bc, + name: "pci-6284", + n_adchan: 32, + adbits: 18, + ai_fifo_depth: 2047, + .gainlkup = ai_gain_628x, + ai_speed: 1600, + n_aochan: 0, + aobits: 0, + ao_fifo_depth: 0, + reg_type: ni_reg_628x, + ao_unipolar: 0, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, + { device_id: 0x70ac, + name: "pci-6289", + n_adchan: 32, + adbits: 18, + ai_fifo_depth: 2047, + .gainlkup = ai_gain_628x, + ai_speed: 1600, + n_aochan: 4, + aobits: 16, + ao_fifo_depth: 8191, + .ao_range_table = &range_ni_M_628x_ao, + reg_type: ni_reg_628x, + ao_unipolar: 1, + ao_speed: 357, + .num_p0_dio_channels = 32, + .caldac = {caldac_none}, + has_8255: 0, + }, +#endif /* TODO: fix data size */ + { device_id: 0x70C0, + name: "pci-6143", + n_adchan: 8, + adbits: 16, + ai_fifo_depth: 1024, + alwaysdither: 0, + gainlkup: ai_gain_6143, + ai_speed: 4000, + n_aochan: 0, + aobits: 0, + reg_type: ni_reg_6143, + ao_unipolar: 0, + ao_fifo_depth: 0, + .num_p0_dio_channels = 8, + .caldac = {ad8804_debug,ad8804_debug}, + }, + { device_id: 0x710D, + name: "pxi-6143", + n_adchan: 8, + adbits: 16, + ai_fifo_depth: 1024, + alwaysdither: 0, + gainlkup: ai_gain_6143, + ai_speed: 4000, + n_aochan: 0, + aobits: 0, + reg_type: ni_reg_6143, + ao_unipolar: 0, + ao_fifo_depth: 0, + .num_p0_dio_channels = 8, + .caldac = {ad8804_debug,ad8804_debug}, + }, +}; +#define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0]))) + +/* How we access STC registers */ + +/* We automatically take advantage of STC registers that can be + * read/written directly in the I/O space of the board. Most + * PCIMIO devices map the low 8 STC registers to iobase+addr*2. + * The 611x devices map the write registers to iobase+addr*2, and + * the read registers to iobase+(addr-1)*2. */ +/* However, the 611x boards still aren't working, so I'm disabling + * non-windowed STC access temporarily */ + +static void e_series_win_out(a4l_dev_t *dev, uint16_t data, int reg) +{ + unsigned long flags; + + a4l_lock_irqsave(&devpriv->window_lock, flags); + ni_writew(reg, Window_Address); + ni_writew(data, Window_Data); + a4l_unlock_irqrestore(&devpriv->window_lock, flags); +} + +static uint16_t e_series_win_in(a4l_dev_t *dev, int reg) +{ + unsigned long flags; + uint16_t ret; + + a4l_lock_irqsave(&devpriv->window_lock, flags); + ni_writew(reg, Window_Address); + ret = ni_readw(Window_Data); + a4l_unlock_irqrestore(&devpriv->window_lock,flags); + + return ret; +} + +static void m_series_stc_writew(a4l_dev_t *dev, uint16_t data, int reg) +{ + unsigned offset; + switch(reg) + { + case ADC_FIFO_Clear: + offset = M_Offset_AI_FIFO_Clear; + break; + case AI_Command_1_Register: + offset = M_Offset_AI_Command_1; + break; + case AI_Command_2_Register: + offset = M_Offset_AI_Command_2; + break; + case AI_Mode_1_Register: + offset = M_Offset_AI_Mode_1; + break; + case AI_Mode_2_Register: + offset = M_Offset_AI_Mode_2; + break; + case AI_Mode_3_Register: + offset = M_Offset_AI_Mode_3; + break; + case AI_Output_Control_Register: + offset = M_Offset_AI_Output_Control; + break; + case AI_Personal_Register: + offset = M_Offset_AI_Personal; + break; + case AI_SI2_Load_A_Register: + /* This is actually a 32 bit register on m series boards */ + ni_writel(data, M_Offset_AI_SI2_Load_A); + return; + break; + case AI_SI2_Load_B_Register: + /* This is actually a 32 bit register on m series boards */ + ni_writel(data, M_Offset_AI_SI2_Load_B); + return; + break; + case AI_START_STOP_Select_Register: + offset = M_Offset_AI_START_STOP_Select; + break; + case AI_Trigger_Select_Register: + offset = M_Offset_AI_Trigger_Select; + break; + case Analog_Trigger_Etc_Register: + offset = M_Offset_Analog_Trigger_Etc; + break; + case AO_Command_1_Register: + offset = M_Offset_AO_Command_1; + break; + case AO_Command_2_Register: + offset = M_Offset_AO_Command_2; + break; + case AO_Mode_1_Register: + offset = M_Offset_AO_Mode_1; + break; + case AO_Mode_2_Register: + offset = M_Offset_AO_Mode_2; + break; + case AO_Mode_3_Register: + offset = M_Offset_AO_Mode_3; + break; + case AO_Output_Control_Register: + offset = M_Offset_AO_Output_Control; + break; + case AO_Personal_Register: + offset = M_Offset_AO_Personal; + break; + case AO_Start_Select_Register: + offset = M_Offset_AO_Start_Select; + break; + case AO_Trigger_Select_Register: + offset = M_Offset_AO_Trigger_Select; + break; + case Clock_and_FOUT_Register: + offset = M_Offset_Clock_and_FOUT; + break; + case Configuration_Memory_Clear: + offset = M_Offset_Configuration_Memory_Clear; + break; + case DAC_FIFO_Clear: + offset = M_Offset_AO_FIFO_Clear; + break; + case DIO_Control_Register: + rtdm_printk("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n", __FUNCTION__, reg); + return; + break; + case G_Autoincrement_Register(0): + offset = M_Offset_G0_Autoincrement; + break; + case G_Autoincrement_Register(1): + offset = M_Offset_G1_Autoincrement; + break; + case G_Command_Register(0): + offset = M_Offset_G0_Command; + break; + case G_Command_Register(1): + offset = M_Offset_G1_Command; + break; + case G_Input_Select_Register(0): + offset = M_Offset_G0_Input_Select; + break; + case G_Input_Select_Register(1): + offset = M_Offset_G1_Input_Select; + break; + case G_Mode_Register(0): + offset = M_Offset_G0_Mode; + break; + case G_Mode_Register(1): + offset = M_Offset_G1_Mode; + break; + case Interrupt_A_Ack_Register: + offset = M_Offset_Interrupt_A_Ack; + break; + case Interrupt_A_Enable_Register: + offset = M_Offset_Interrupt_A_Enable; + break; + case Interrupt_B_Ack_Register: + offset = M_Offset_Interrupt_B_Ack; + break; + case Interrupt_B_Enable_Register: + offset = M_Offset_Interrupt_B_Enable; + break; + case Interrupt_Control_Register: + offset = M_Offset_Interrupt_Control; + break; + case IO_Bidirection_Pin_Register: + offset = M_Offset_IO_Bidirection_Pin; + break; + case Joint_Reset_Register: + offset = M_Offset_Joint_Reset; + break; + case RTSI_Trig_A_Output_Register: + offset = M_Offset_RTSI_Trig_A_Output; + break; + case RTSI_Trig_B_Output_Register: + offset = M_Offset_RTSI_Trig_B_Output; + break; + case RTSI_Trig_Direction_Register: + offset = M_Offset_RTSI_Trig_Direction; + break; + /* FIXME: DIO_Output_Register (16 bit reg) is replaced + by M_Offset_Static_Digital_Output (32 bit) and + M_Offset_SCXI_Serial_Data_Out (8 bit) */ + default: + rtdm_printk("%s: bug! unhandled register=0x%x in switch.\n", + __FUNCTION__, reg); + BUG(); + return; + } + ni_writew(data, offset); +} + +static uint16_t m_series_stc_readw(a4l_dev_t *dev, int reg) +{ + unsigned offset; + switch(reg) + { + case AI_Status_1_Register: + offset = M_Offset_AI_Status_1; + break; + case AO_Status_1_Register: + offset = M_Offset_AO_Status_1; + break; + case AO_Status_2_Register: + offset = M_Offset_AO_Status_2; + break; + case DIO_Serial_Input_Register: + return ni_readb(M_Offset_SCXI_Serial_Data_In); + break; + case Joint_Status_1_Register: + offset = M_Offset_Joint_Status_1; + break; + case Joint_Status_2_Register: + offset = M_Offset_Joint_Status_2; + break; + case G_Status_Register: + offset = M_Offset_G01_Status; + break; + default: + rtdm_printk("%s: bug! " + "unhandled register=0x%x in switch.\n", + __FUNCTION__, reg); + BUG(); + return 0; + break; + } + return ni_readw(offset); +} + +static void m_series_stc_writel(a4l_dev_t *dev, uint32_t data, int reg) +{ + unsigned offset; + + switch(reg) + { + case AI_SC_Load_A_Registers: + offset = M_Offset_AI_SC_Load_A; + break; + case AI_SI_Load_A_Registers: + offset = M_Offset_AI_SI_Load_A; + break; + case AO_BC_Load_A_Register: + offset = M_Offset_AO_BC_Load_A; + break; + case AO_UC_Load_A_Register: + offset = M_Offset_AO_UC_Load_A; + break; + case AO_UI_Load_A_Register: + offset = M_Offset_AO_UI_Load_A; + break; + case G_Load_A_Register(0): + offset = M_Offset_G0_Load_A; + break; + case G_Load_A_Register(1): + offset = M_Offset_G1_Load_A; + break; + case G_Load_B_Register(0): + offset = M_Offset_G0_Load_B; + break; + case G_Load_B_Register(1): + offset = M_Offset_G1_Load_B; + break; + default: + rtdm_printk("%s: bug! unhandled register=0x%x in switch.\n", + __FUNCTION__, reg); + BUG(); + return; + } + ni_writel(data, offset); +} + +static uint32_t m_series_stc_readl(a4l_dev_t *dev, int reg) +{ + unsigned offset; + switch(reg) + { + case G_HW_Save_Register(0): + offset = M_Offset_G0_HW_Save; + break; + case G_HW_Save_Register(1): + offset = M_Offset_G1_HW_Save; + break; + case G_Save_Register(0): + offset = M_Offset_G0_Save; + break; + case G_Save_Register(1): + offset = M_Offset_G1_Save; + break; + default: + rtdm_printk("%s: bug! unhandled register=0x%x in switch.\n", + __FUNCTION__, reg); + BUG(); + return 0; + } + return ni_readl(offset); +} + +static void win_out2(a4l_dev_t *dev, uint32_t data, int reg) +{ + devpriv->stc_writew(dev, data >> 16, reg); + devpriv->stc_writew(dev, data & 0xffff, reg + 1); +} + +static uint32_t win_in2(a4l_dev_t *dev, int reg) +{ + uint32_t bits; + bits = devpriv->stc_readw(dev, reg) << 16; + bits |= devpriv->stc_readw(dev, reg + 1); + return bits; +} + +static void m_series_init_eeprom_buffer(a4l_dev_t *dev) +{ + static const int Start_Cal_EEPROM = 0x400; + static const unsigned window_size = 10; + unsigned old_iodwbsr_bits; + unsigned old_iodwbsr1_bits; + unsigned old_iodwcr1_bits; + int i; + + old_iodwbsr_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR); + old_iodwbsr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR_1); + old_iodwcr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWCR_1); + writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWBSR); + writel(((0x80 | window_size) | devpriv->mite->daq_phys_addr), + devpriv->mite->mite_io_addr + MITE_IODWBSR_1); + writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWCR_1); + writel(0xf, devpriv->mite->mite_io_addr + 0x30); + + for(i = 0; i < M_SERIES_EEPROM_SIZE; ++i) + { + devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i); + } + + writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1); + writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR); + writel(old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1); + writel(0x0, devpriv->mite->mite_io_addr + 0x30); +} + +static void init_6143(a4l_dev_t *dev) +{ + /* Disable interrupts */ + devpriv->stc_writew(dev, 0, Interrupt_Control_Register); + + /* Initialise 6143 AI specific bits */ + + /* Set G0,G1 DMA mode to E series version */ + ni_writeb(0x00, Magic_6143); + /* Set EOCMode, ADCMode and pipelinedelay */ + ni_writeb(0x80, PipelineDelay_6143); + /* Set EOC Delay */ + ni_writeb(0x00, EOC_Set_6143); + + /* Set the FIFO half full level */ + ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143); + + /* Strobe Relay disable bit */ + devpriv->ai_calib_source_enabled = 0; + ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff, + Calibration_Channel_6143); + ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143); +} + +static int pcimio_attach(a4l_dev_t *dev, a4l_lnkdesc_t *arg) +{ + int ret, bus, slot, i, irq; + struct mite_struct *mite = NULL; + struct ni_board_struct * board = NULL; + + if(arg->opts == NULL || arg->opts_size == 0) + bus = slot = 0; + else { + bus = arg->opts_size >= sizeof(unsigned long) ? + ((unsigned long *)arg->opts)[0] : 0; + slot = arg->opts_size >= sizeof(unsigned long) * 2 ? + ((unsigned long *)arg->opts)[1] : 0; + } + + for(i = 0; i < n_pcimio_boards && mite == NULL; i++) { + mite = mite_find_device(bus, slot, ni_boards[i].device_id); + board = &ni_boards[i]; + } + + if(mite == 0) + return -ENOENT; + + devpriv->irq_polarity = PCIMIO_IRQ_POLARITY; + devpriv->irq_pin = 0; + + devpriv->mite = mite; + devpriv->board_ptr = board; + + devpriv->ai_mite_ring = mite_alloc_ring(mite); + devpriv->ao_mite_ring = mite_alloc_ring(mite); + devpriv->cdo_mite_ring = mite_alloc_ring(mite); + devpriv->gpct_mite_ring[0] = mite_alloc_ring(mite); + devpriv->gpct_mite_ring[1] = mite_alloc_ring(mite); + + if(devpriv->ai_mite_ring == NULL || + devpriv->ao_mite_ring == NULL || + devpriv->cdo_mite_ring == NULL || + devpriv->gpct_mite_ring[0] == NULL || + devpriv->gpct_mite_ring[1] == NULL) + return -ENOMEM; + + a4l_info(dev, "pcimio_attach: found %s board\n", boardtype.name); + + if(boardtype.reg_type & ni_reg_m_series_mask) + { + devpriv->stc_writew = &m_series_stc_writew; + devpriv->stc_readw = &m_series_stc_readw; + devpriv->stc_writel = &m_series_stc_writel; + devpriv->stc_readl = &m_series_stc_readl; + }else + { + devpriv->stc_writew = &e_series_win_out; + devpriv->stc_readw = &e_series_win_in; + devpriv->stc_writel = &win_out2; + devpriv->stc_readl = &win_in2; + } + + ret = mite_setup(devpriv->mite, 0); + if(ret < 0) + { + a4l_err(dev, "pcmio_attach: error setting up mite\n"); + return ret; + } + + if(boardtype.reg_type & ni_reg_m_series_mask) + m_series_init_eeprom_buffer(dev); + if(boardtype.reg_type == ni_reg_6143) + init_6143(dev); + + irq = mite_irq(devpriv->mite); + + if(irq == 0){ + a4l_warn(dev, "pcimio_attach: unknown irq (bad)\n\n"); + }else{ + a4l_info(dev, "pcimio_attach: found irq %u\n", irq); + ret = a4l_request_irq(dev, + irq, + ni_E_interrupt, A4L_IRQ_SHARED, dev); + if(ret < 0) + a4l_err(dev, "pcimio_attach: irq not available\n"); + } + + ret = ni_E_init(dev); + if(ret < 0) + return ret; + + return ret; +} + +static int pcimio_detach(a4l_dev_t *dev) +{ + if(a4l_get_irq(dev)!=A4L_IRQ_UNUSED){ + a4l_free_irq(dev,a4l_get_irq(dev)); + } + + if(dev->priv != NULL && devpriv->mite != NULL) + { + mite_free_ring(devpriv->ai_mite_ring); + mite_free_ring(devpriv->ao_mite_ring); + mite_free_ring(devpriv->gpct_mite_ring[0]); + mite_free_ring(devpriv->gpct_mite_ring[1]); + mite_unsetup(devpriv->mite); + } + + return 0; +} + +static a4l_drv_t pcimio_drv = { + .owner = THIS_MODULE, + .board_name = "analogy_ni_pcimio", + .attach = pcimio_attach, + .detach = pcimio_detach, + .privdata_size = sizeof(ni_private), +}; + +static int __init pcimio_init(void) +{ + return a4l_register_drv(&pcimio_drv); +} + +static void __exit pcimio_cleanup(void) +{ + a4l_unregister_drv(&pcimio_drv); +} + +MODULE_DESCRIPTION("Analogy driver for NI PCI-MIO series cards"); +MODULE_LICENSE("GPL"); + +module_init(pcimio_init); +module_exit(pcimio_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/tio_common.c relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/tio_common.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/tio_common.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/national_instruments/tio_common.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1996 @@ +/** + * @file + * Hardware driver for NI general purpose counter + * @note Copyright (C) 2006 Frank Mori Hess + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Description: National Instruments general purpose counters + * This module is not used directly by end-users. Rather, it is used + * by other drivers (for example ni_660x and ni_pcimio) to provide + * support for NI's general purpose counters. It was originally based + * on the counter code from ni_660x.c and ni_mio_common.c. + * + * Author: + * J.P. Mellor + * Herman.Bruyninckx@mech.kuleuven.ac.be + * Wim.Meeussen@mech.kuleuven.ac.be, + * Klaas.Gadeyne@mech.kuleuven.ac.be, + * Frank Mori Hess + * + * References: + * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) + * DAQ 6601/6602 User Manual (NI 322137B-01) + * 340934b.pdf DAQ-STC reference manual + * + * TODO: + * - Support use of both banks X and Y + * + */ + +#include + +#include "ni_tio.h" +#include "ni_mio.h" + +static inline void write_register(struct ni_gpct *counter, + unsigned int bits, enum ni_gpct_register reg) +{ + BUG_ON(reg >= NITIO_Num_Registers); + counter->counter_dev->write_register(counter, bits, reg); +} + +static inline unsigned int read_register(struct ni_gpct *counter, + enum ni_gpct_register reg) +{ + BUG_ON(reg >= NITIO_Num_Registers); + return counter->counter_dev->read_register(counter, reg); +} + +struct ni_gpct_device *ni_gpct_device_construct(a4l_dev_t * dev, + void (*write_register) (struct ni_gpct * counter, unsigned int bits, + enum ni_gpct_register reg), + unsigned int (*read_register) (struct ni_gpct * counter, + enum ni_gpct_register reg), enum ni_gpct_variant variant, + unsigned int num_counters) +{ + struct ni_gpct_device *counter_dev = + kmalloc(sizeof(struct ni_gpct_device), GFP_KERNEL); + if (counter_dev == NULL) + return NULL; + + memset(counter_dev, 0, sizeof(struct ni_gpct_device)); + + counter_dev->dev = dev; + counter_dev->write_register = write_register; + counter_dev->read_register = read_register; + counter_dev->variant = variant; + a4l_lock_init(&counter_dev->regs_lock); + BUG_ON(num_counters == 0); + + counter_dev->counters = + kmalloc(sizeof(struct ni_gpct *) * num_counters, GFP_KERNEL); + + if (counter_dev->counters == NULL) { + kfree(counter_dev); + return NULL; + } + + memset(counter_dev->counters, 0, sizeof(struct ni_gpct *) * num_counters); + + counter_dev->num_counters = num_counters; + return counter_dev; +} + +void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) +{ + if (counter_dev->counters == NULL) + return; + kfree(counter_dev->counters); + kfree(counter_dev); +} + +static +int ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev) +{ + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + return 1; + break; + default: + BUG(); + break; + } + return 0; +} + +static +int ni_tio_second_gate_registers_present(const struct ni_gpct_device *counter_dev) +{ + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + return 0; + break; + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + return 1; + break; + default: + BUG(); + break; + } + return 0; +} + +static inline +void ni_tio_set_bits_transient(struct ni_gpct *counter, + enum ni_gpct_register register_index, + unsigned int bit_mask, + unsigned int bit_values, + unsigned transient_bit_values) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned long flags; + + BUG_ON(register_index >= NITIO_Num_Registers); + a4l_lock_irqsave(&counter_dev->regs_lock, flags); + counter_dev->regs[register_index] &= ~bit_mask; + counter_dev->regs[register_index] |= (bit_values & bit_mask); + write_register(counter, + counter_dev->regs[register_index] | transient_bit_values, + register_index); + mmiowb(); + a4l_unlock_irqrestore(&counter_dev->regs_lock, flags); +} + +/* ni_tio_set_bits( ) is for safely writing to registers whose bits + may be twiddled in interrupt context, or whose software copy may be + read in interrupt context. */ +static inline void ni_tio_set_bits(struct ni_gpct *counter, + enum ni_gpct_register register_index, + unsigned int bit_mask, + unsigned int bit_values) +{ + ni_tio_set_bits_transient(counter, + register_index, + bit_mask, bit_values, 0x0); +} + +/* ni_tio_get_soft_copy( ) is for safely reading the software copy of + a register whose bits might be modified in interrupt context, or whose + software copy might need to be read in interrupt context. */ +static inline +unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, + enum ni_gpct_register register_index) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned long flags; + unsigned value; + + BUG_ON(register_index >= NITIO_Num_Registers); + a4l_lock_irqsave(&counter_dev->regs_lock, flags); + value = counter_dev->regs[register_index]; + a4l_unlock_irqrestore(&counter_dev->regs_lock, flags); + return value; +} + +static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) +{ + write_register(counter, Gi_Reset_Bit(counter->counter_index), + NITIO_Gxx_Joint_Reset_Reg(counter->counter_index)); +} + +void ni_tio_init_counter(struct ni_gpct *counter) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + + ni_tio_reset_count_and_disarm(counter); + /* Initialize counter registers */ + counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] = + 0x0; + write_register(counter, + counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter-> + counter_index)], + NITIO_Gi_Autoincrement_Reg(counter->counter_index)); + ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), + ~0, Gi_Synchronize_Gate_Bit); + ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0, + 0); + counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0; + write_register(counter, + counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)], + NITIO_Gi_LoadA_Reg(counter->counter_index)); + counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0; + write_register(counter, + counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)], + NITIO_Gi_LoadB_Reg(counter->counter_index)); + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0, 0); + if (ni_tio_counting_mode_registers_present(counter_dev)) { + ni_tio_set_bits(counter, + NITIO_Gi_Counting_Mode_Reg(counter->counter_index), ~0, + 0); + } + if (ni_tio_second_gate_registers_present(counter_dev)) { + counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter-> + counter_index)] = 0x0; + write_register(counter, + counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter-> + counter_index)], + NITIO_Gi_Second_Gate_Reg(counter->counter_index)); + } + ni_tio_set_bits(counter, + NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0, 0x0); + ni_tio_set_bits(counter, + NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), ~0, 0x0); +} + +static lsampl_t ni_tio_counter_status(struct ni_gpct *counter) +{ + lsampl_t status = 0; + unsigned int bits; + + bits = read_register(counter,NITIO_Gxx_Status_Reg(counter->counter_index)); + if (bits & Gi_Armed_Bit(counter->counter_index)) { + status |= A4L_COUNTER_ARMED; + if (bits & Gi_Counting_Bit(counter->counter_index)) + status |= A4L_COUNTER_COUNTING; + } + return status; +} + +static +uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, + unsigned int generic_clock_source); +static +unsigned int ni_tio_generic_clock_src_select(const struct ni_gpct *counter); + +static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned counting_mode_reg = + NITIO_Gi_Counting_Mode_Reg(counter->counter_index); + static const uint64_t min_normal_sync_period_ps = 25000; + const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter, + ni_tio_generic_clock_src_select(counter)); + + if (ni_tio_counting_mode_registers_present(counter_dev) == 0) + return; + + switch (ni_tio_get_soft_copy(counter, + counting_mode_reg) & Gi_Counting_Mode_Mask) { + case Gi_Counting_Mode_QuadratureX1_Bits: + case Gi_Counting_Mode_QuadratureX2_Bits: + case Gi_Counting_Mode_QuadratureX4_Bits: + case Gi_Counting_Mode_Sync_Source_Bits: + force_alt_sync = 1; + break; + default: + break; + } + + /* It's not clear what we should do if clock_period is + unknown, so we are not using the alt sync bit in that case, + but allow the caller to decide by using the force_alt_sync + parameter. */ + if (force_alt_sync || + (clock_period_ps + && clock_period_ps < min_normal_sync_period_ps)) { + ni_tio_set_bits(counter, counting_mode_reg, + Gi_Alternate_Sync_Bit(counter_dev->variant), + Gi_Alternate_Sync_Bit(counter_dev->variant)); + } else { + ni_tio_set_bits(counter, counting_mode_reg, + Gi_Alternate_Sync_Bit(counter_dev->variant), 0x0); + } +} + +static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned mode_reg_mask; + unsigned mode_reg_values; + unsigned input_select_bits = 0; + + /* these bits map directly on to the mode register */ + static const unsigned mode_reg_direct_mask = + NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK | + NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK | + NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT | + NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT; + + mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit; + mode_reg_values = mode & mode_reg_direct_mask; + switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) { + case NI_GPCT_RELOAD_SOURCE_FIXED_BITS: + break; + case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS: + mode_reg_values |= Gi_Reload_Source_Switching_Bit; + break; + case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS: + input_select_bits |= Gi_Gate_Select_Load_Source_Bit; + mode_reg_mask |= Gi_Gating_Mode_Mask; + mode_reg_values |= Gi_Level_Gating_Bits; + break; + default: + break; + } + ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), + mode_reg_mask, mode_reg_values); + + if (ni_tio_counting_mode_registers_present(counter_dev)) { + unsigned counting_mode_bits = 0; + counting_mode_bits |= + (mode >> NI_GPCT_COUNTING_MODE_SHIFT) & + Gi_Counting_Mode_Mask; + counting_mode_bits |= + ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) << + Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask; + if (mode & NI_GPCT_INDEX_ENABLE_BIT) { + counting_mode_bits |= Gi_Index_Mode_Bit; + } + ni_tio_set_bits(counter, + NITIO_Gi_Counting_Mode_Reg(counter->counter_index), + Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask | + Gi_Index_Mode_Bit, counting_mode_bits); + ni_tio_set_sync_mode(counter, 0); + } + + ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), + Gi_Up_Down_Mask, + (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift); + + if (mode & NI_GPCT_OR_GATE_BIT) { + input_select_bits |= Gi_Or_Gate_Bit; + } + if (mode & NI_GPCT_INVERT_OUTPUT_BIT) { + input_select_bits |= Gi_Output_Polarity_Bit; + } + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), + Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit | + Gi_Output_Polarity_Bit, input_select_bits); + + return 0; +} + +static int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned int start_trigger) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + + unsigned int command_transient_bits = 0; + + if (arm) { + switch (start_trigger) { + case NI_GPCT_ARM_IMMEDIATE: + command_transient_bits |= Gi_Arm_Bit; + break; + case NI_GPCT_ARM_PAIRED_IMMEDIATE: + command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit; + break; + default: + break; + } + if (ni_tio_counting_mode_registers_present(counter_dev)) { + unsigned counting_mode_bits = 0; + + switch (start_trigger) { + case NI_GPCT_ARM_IMMEDIATE: + case NI_GPCT_ARM_PAIRED_IMMEDIATE: + break; + default: + if (start_trigger & NI_GPCT_ARM_UNKNOWN) { + /* Pass-through the least + significant bits so we can + figure out what select later + */ + unsigned hw_arm_select_bits = + (start_trigger << + Gi_HW_Arm_Select_Shift) & + Gi_HW_Arm_Select_Mask + (counter_dev->variant); + + counting_mode_bits |= + Gi_HW_Arm_Enable_Bit | + hw_arm_select_bits; + } else { + return -EINVAL; + } + break; + } + ni_tio_set_bits(counter, + NITIO_Gi_Counting_Mode_Reg(counter-> + counter_index), + Gi_HW_Arm_Select_Mask(counter_dev-> + variant) | Gi_HW_Arm_Enable_Bit, + counting_mode_bits); + } + } else { + command_transient_bits |= Gi_Disarm_Bit; + } + ni_tio_set_bits_transient(counter, + NITIO_Gi_Command_Reg(counter->counter_index), 0, 0, + command_transient_bits); + return 0; +} + +static unsigned int ni_660x_source_select_bits(lsampl_t clock_source) +{ + unsigned int ni_660x_clock; + unsigned int i; + const unsigned int clock_select_bits = + clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; + + switch (clock_select_bits) { + case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Timebase_1_Clock; + break; + case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Timebase_2_Clock; + break; + case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Timebase_3_Clock; + break; + case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Logic_Low_Clock; + break; + case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Source_Pin_i_Clock; + break; + case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Next_Gate_Clock; + break; + case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: + ni_660x_clock = NI_660x_Next_TC_Clock; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { + ni_660x_clock = NI_660x_RTSI_Clock(i); + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_source_pin; ++i) { + if (clock_select_bits == + NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) { + ni_660x_clock = NI_660x_Source_Pin_Clock(i); + break; + } + } + if (i <= ni_660x_max_source_pin) + break; + ni_660x_clock = 0; + BUG(); + break; + } + return Gi_Source_Select_Bits(ni_660x_clock); +} + +static unsigned int ni_m_series_source_select_bits(lsampl_t clock_source) +{ + unsigned int ni_m_series_clock; + unsigned int i; + const unsigned int clock_select_bits = + clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; + switch (clock_select_bits) { + case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Timebase_1_Clock; + break; + case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Timebase_2_Clock; + break; + case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Timebase_3_Clock; + break; + case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Logic_Low_Clock; + break; + case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Next_Gate_Clock; + break; + case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Next_TC_Clock; + break; + case NI_GPCT_PXI10_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_PXI10_Clock; + break; + case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock; + break; + case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: + ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock; + break; + default: + for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { + if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { + ni_m_series_clock = NI_M_Series_RTSI_Clock(i); + break; + } + } + if (i <= ni_m_series_max_rtsi_channel) + break; + for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { + if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) { + ni_m_series_clock = NI_M_Series_PFI_Clock(i); + break; + } + } + if (i <= ni_m_series_max_pfi_channel) + break; + __a4l_err("invalid clock source 0x%lx\n", + (unsigned long)clock_source); + BUG(); + ni_m_series_clock = 0; + break; + } + return Gi_Source_Select_Bits(ni_m_series_clock); +} + +static void ni_tio_set_source_subselect(struct ni_gpct *counter, + lsampl_t clock_source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + + if (counter_dev->variant != ni_gpct_variant_m_series) + return; + switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { + /* Gi_Source_Subselect is zero */ + case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: + case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: + counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit; + break; + /* Gi_Source_Subselect is one */ + case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: + case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: + counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit; + break; + /* Gi_Source_Subselect doesn't matter */ + default: + return; + break; + } + write_register(counter, counter_dev->regs[second_gate_reg], + second_gate_reg); +} + +static int ni_tio_set_clock_src(struct ni_gpct *counter, + lsampl_t clock_source, lsampl_t period_ns) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned input_select_bits = 0; + static const uint64_t pico_per_nano = 1000; + + /* FIXME: validate clock source */ + switch (counter_dev->variant) { + case ni_gpct_variant_660x: + input_select_bits |= ni_660x_source_select_bits(clock_source); + break; + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + input_select_bits |= + ni_m_series_source_select_bits(clock_source); + break; + default: + BUG(); + break; + } + if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) + input_select_bits |= Gi_Source_Polarity_Bit; + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), + Gi_Source_Select_Mask | Gi_Source_Polarity_Bit, + input_select_bits); + ni_tio_set_source_subselect(counter, clock_source); + if (ni_tio_counting_mode_registers_present(counter_dev)) { + const unsigned prescaling_mode = + clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK; + unsigned counting_mode_bits = 0; + + switch (prescaling_mode) { + case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: + break; + case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: + counting_mode_bits |= + Gi_Prescale_X2_Bit(counter_dev->variant); + break; + case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: + counting_mode_bits |= + Gi_Prescale_X8_Bit(counter_dev->variant); + break; + default: + return -EINVAL; + break; + } + ni_tio_set_bits(counter, + NITIO_Gi_Counting_Mode_Reg(counter->counter_index), + Gi_Prescale_X2_Bit(counter_dev-> + variant) | Gi_Prescale_X8_Bit(counter_dev-> + variant), counting_mode_bits); + } + counter->clock_period_ps = pico_per_nano * period_ns; + ni_tio_set_sync_mode(counter, 0); + return 0; +} + +static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter, + NITIO_Gi_Counting_Mode_Reg(counter->counter_index)); + unsigned int bits = 0; + + if (ni_tio_get_soft_copy(counter, + NITIO_Gi_Input_Select_Reg(counter-> + counter_index)) & Gi_Source_Polarity_Bit) + bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT; + if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant)) + bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS; + if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant)) + bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS; + return bits; +} + +static unsigned int ni_m_series_clock_src_select(const struct ni_gpct *counter) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned int i, clock_source = 0; + + const unsigned int input_select = (ni_tio_get_soft_copy(counter, + NITIO_Gi_Input_Select_Reg(counter-> + counter_index)) & Gi_Source_Select_Mask) >> + Gi_Source_Select_Shift; + + switch (input_select) { + case NI_M_Series_Timebase_1_Clock: + clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; + break; + case NI_M_Series_Timebase_2_Clock: + clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; + break; + case NI_M_Series_Timebase_3_Clock: + if (counter_dev-> + regs[second_gate_reg] & Gi_Source_Subselect_Bit) + clock_source = + NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; + else + clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; + break; + case NI_M_Series_Logic_Low_Clock: + clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; + break; + case NI_M_Series_Next_Gate_Clock: + if (counter_dev-> + regs[second_gate_reg] & Gi_Source_Subselect_Bit) + clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; + else + clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; + break; + case NI_M_Series_PXI10_Clock: + clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS; + break; + case NI_M_Series_Next_TC_Clock: + clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; + break; + default: + for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { + if (input_select == NI_M_Series_RTSI_Clock(i)) { + clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= ni_m_series_max_rtsi_channel) + break; + for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { + if (input_select == NI_M_Series_PFI_Clock(i)) { + clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= ni_m_series_max_pfi_channel) + break; + BUG(); + break; + } + clock_source |= ni_tio_clock_src_modifiers(counter); + return clock_source; +} + +static unsigned int ni_660x_clock_src_select(const struct ni_gpct *counter) +{ + unsigned int i, clock_source = 0; + const unsigned input_select = (ni_tio_get_soft_copy(counter, + NITIO_Gi_Input_Select_Reg(counter-> + counter_index)) & Gi_Source_Select_Mask) >> + Gi_Source_Select_Shift; + + switch (input_select) { + case NI_660x_Timebase_1_Clock: + clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; + break; + case NI_660x_Timebase_2_Clock: + clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; + break; + case NI_660x_Timebase_3_Clock: + clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; + break; + case NI_660x_Logic_Low_Clock: + clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; + break; + case NI_660x_Source_Pin_i_Clock: + clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS; + break; + case NI_660x_Next_Gate_Clock: + clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; + break; + case NI_660x_Next_TC_Clock: + clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (input_select == NI_660x_RTSI_Clock(i)) { + clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_source_pin; ++i) { + if (input_select == NI_660x_Source_Pin_Clock(i)) { + clock_source = + NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= ni_660x_max_source_pin) + break; + BUG(); + break; + } + clock_source |= ni_tio_clock_src_modifiers(counter); + return clock_source; +} + +static unsigned int ni_tio_generic_clock_src_select(const struct ni_gpct *counter) +{ + switch (counter->counter_dev->variant) { + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + return ni_m_series_clock_src_select(counter); + break; + case ni_gpct_variant_660x: + return ni_660x_clock_src_select(counter); + break; + default: + BUG(); + break; + } + return 0; +} + +static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, + unsigned int generic_clock_source) +{ + uint64_t clock_period_ps; + + switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { + case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: + clock_period_ps = 50000; + break; + case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: + clock_period_ps = 10000000; + break; + case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: + clock_period_ps = 12500; + break; + case NI_GPCT_PXI10_CLOCK_SRC_BITS: + clock_period_ps = 100000; + break; + default: + /* Clock period is specified by user with prescaling + already taken into account. */ + return counter->clock_period_ps; + break; + } + + switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { + case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: + break; + case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: + clock_period_ps *= 2; + break; + case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: + clock_period_ps *= 8; + break; + default: + BUG(); + break; + } + return clock_period_ps; +} + +static void ni_tio_get_clock_src(struct ni_gpct *counter, + unsigned int * clock_source, + unsigned int * period_ns) +{ + static const unsigned int pico_per_nano = 1000; + uint64_t temp64; + + *clock_source = ni_tio_generic_clock_src_select(counter); + temp64 = ni_tio_clock_period_ps(counter, *clock_source); + do_div(temp64, pico_per_nano); + *period_ns = temp64; +} + +static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter, + lsampl_t gate_source) +{ + const unsigned int mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask; + unsigned int mode_values = 0; + + if (gate_source & CR_INVERT) { + mode_values |= Gi_Gate_Polarity_Bit; + } + if (gate_source & CR_EDGE) { + mode_values |= Gi_Rising_Edge_Gating_Bits; + } else { + mode_values |= Gi_Level_Gating_Bits; + } + ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), + mode_mask, mode_values); +} + +static int ni_660x_set_first_gate(struct ni_gpct *counter, lsampl_t gate_source) +{ + const unsigned int selected_gate = CR_CHAN(gate_source); + /* Bits of selected_gate that may be meaningful to + input select register */ + const unsigned int selected_gate_mask = 0x1f; + unsigned ni_660x_gate_select; + unsigned i; + + switch (selected_gate) { + case NI_GPCT_NEXT_SOURCE_GATE_SELECT: + ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select; + break; + case NI_GPCT_NEXT_OUT_GATE_SELECT: + case NI_GPCT_LOGIC_LOW_GATE_SELECT: + case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: + case NI_GPCT_GATE_PIN_i_GATE_SELECT: + ni_660x_gate_select = selected_gate & selected_gate_mask; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { + ni_660x_gate_select = + selected_gate & selected_gate_mask; + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_gate_pin; ++i) { + if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) { + ni_660x_gate_select = + selected_gate & selected_gate_mask; + break; + } + } + if (i <= ni_660x_max_gate_pin) + break; + return -EINVAL; + break; + } + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), + Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select)); + return 0; +} + +static int ni_m_series_set_first_gate(struct ni_gpct *counter, + lsampl_t gate_source) +{ + const unsigned int selected_gate = CR_CHAN(gate_source); + /* bits of selected_gate that may be meaningful to input select register */ + const unsigned int selected_gate_mask = 0x1f; + unsigned int i, ni_m_series_gate_select; + + switch (selected_gate) { + case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT: + case NI_GPCT_AI_START2_GATE_SELECT: + case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT: + case NI_GPCT_NEXT_OUT_GATE_SELECT: + case NI_GPCT_AI_START1_GATE_SELECT: + case NI_GPCT_NEXT_SOURCE_GATE_SELECT: + case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT: + case NI_GPCT_LOGIC_LOW_GATE_SELECT: + ni_m_series_gate_select = selected_gate & selected_gate_mask; + break; + default: + for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { + if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { + ni_m_series_gate_select = + selected_gate & selected_gate_mask; + break; + } + } + if (i <= ni_m_series_max_rtsi_channel) + break; + for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { + if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) { + ni_m_series_gate_select = + selected_gate & selected_gate_mask; + break; + } + } + if (i <= ni_m_series_max_pfi_channel) + break; + return -EINVAL; + break; + } + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), + Gi_Gate_Select_Mask, + Gi_Gate_Select_Bits(ni_m_series_gate_select)); + return 0; +} + +static int ni_660x_set_second_gate(struct ni_gpct *counter, + lsampl_t gate_source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + const unsigned int selected_second_gate = CR_CHAN(gate_source); + /* bits of second_gate that may be meaningful to second gate register */ + static const unsigned int selected_second_gate_mask = 0x1f; + unsigned int i, ni_660x_second_gate_select; + + switch (selected_second_gate) { + case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: + case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT: + case NI_GPCT_SELECTED_GATE_GATE_SELECT: + case NI_GPCT_NEXT_OUT_GATE_SELECT: + case NI_GPCT_LOGIC_LOW_GATE_SELECT: + ni_660x_second_gate_select = + selected_second_gate & selected_second_gate_mask; + break; + case NI_GPCT_NEXT_SOURCE_GATE_SELECT: + ni_660x_second_gate_select = + NI_660x_Next_SRC_Second_Gate_Select; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { + ni_660x_second_gate_select = + selected_second_gate & + selected_second_gate_mask; + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_up_down_pin; ++i) { + if (selected_second_gate == + NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) { + ni_660x_second_gate_select = + selected_second_gate & + selected_second_gate_mask; + break; + } + } + if (i <= ni_660x_max_up_down_pin) + break; + return -EINVAL; + break; + }; + counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit; + counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask; + counter_dev->regs[second_gate_reg] |= + Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select); + write_register(counter, counter_dev->regs[second_gate_reg], + second_gate_reg); + return 0; +} + +static int ni_m_series_set_second_gate(struct ni_gpct *counter, + lsampl_t gate_source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + const unsigned int selected_second_gate = CR_CHAN(gate_source); + /* Bits of second_gate that may be meaningful to second gate register */ + static const unsigned int selected_second_gate_mask = 0x1f; + unsigned int ni_m_series_second_gate_select; + + /* FIXME: We don't know what the m-series second gate codes + are, so we'll just pass the bits through for now. */ + switch (selected_second_gate) { + default: + ni_m_series_second_gate_select = + selected_second_gate & selected_second_gate_mask; + break; + }; + counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit; + counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask; + counter_dev->regs[second_gate_reg] |= + Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select); + write_register(counter, counter_dev->regs[second_gate_reg], + second_gate_reg); + return 0; +} + +static int ni_tio_set_gate_src(struct ni_gpct *counter, + unsigned int gate_index, lsampl_t gate_source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + + switch (gate_index) { + case 0: + if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) { + ni_tio_set_bits(counter, + NITIO_Gi_Mode_Reg(counter->counter_index), + Gi_Gating_Mode_Mask, Gi_Gating_Disabled_Bits); + return 0; + } + ni_tio_set_first_gate_modifiers(counter, gate_source); + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + return ni_m_series_set_first_gate(counter, gate_source); + break; + case ni_gpct_variant_660x: + return ni_660x_set_first_gate(counter, gate_source); + break; + default: + BUG(); + break; + } + break; + case 1: + if (ni_tio_second_gate_registers_present(counter_dev) == 0) + return -EINVAL; + if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) { + counter_dev->regs[second_gate_reg] &= + ~Gi_Second_Gate_Mode_Bit; + write_register(counter, + counter_dev->regs[second_gate_reg], + second_gate_reg); + return 0; + } + if (gate_source & CR_INVERT) { + counter_dev->regs[second_gate_reg] |= + Gi_Second_Gate_Polarity_Bit; + } else { + counter_dev->regs[second_gate_reg] &= + ~Gi_Second_Gate_Polarity_Bit; + } + switch (counter_dev->variant) { + case ni_gpct_variant_m_series: + return ni_m_series_set_second_gate(counter, + gate_source); + break; + case ni_gpct_variant_660x: + return ni_660x_set_second_gate(counter, gate_source); + break; + default: + BUG(); + break; + } + break; + default: + return -EINVAL; + break; + } + return 0; +} + +static int ni_tio_set_other_src(struct ni_gpct *counter, + unsigned int index, unsigned int source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + + if (counter_dev->variant == ni_gpct_variant_m_series) { + unsigned int abz_reg, shift, mask; + + abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index); + switch (index) { + case NI_GPCT_SOURCE_ENCODER_A: + shift = 10; + break; + case NI_GPCT_SOURCE_ENCODER_B: + shift = 5; + break; + case NI_GPCT_SOURCE_ENCODER_Z: + shift = 0; + break; + default: + return -EINVAL; + break; + } + mask = 0x1f << shift; + if (source > 0x1f) { + /* Disable gate */ + source = 0x1f; + } + counter_dev->regs[abz_reg] &= ~mask; + counter_dev->regs[abz_reg] |= (source << shift) & mask; + write_register(counter, counter_dev->regs[abz_reg], abz_reg); + return 0; + } + return -EINVAL; +} + +static unsigned int ni_660x_first_gate_to_generic_gate_source(unsigned int ni_660x_gate_select) +{ + unsigned int i; + + switch (ni_660x_gate_select) { + case NI_660x_Source_Pin_i_Gate_Select: + return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + break; + case NI_660x_Gate_Pin_i_Gate_Select: + return NI_GPCT_GATE_PIN_i_GATE_SELECT; + break; + case NI_660x_Next_SRC_Gate_Select: + return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; + case NI_660x_Next_Out_Gate_Select: + return NI_GPCT_NEXT_OUT_GATE_SELECT; + break; + case NI_660x_Logic_Low_Gate_Select: + return NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) { + return NI_GPCT_RTSI_GATE_SELECT(i); + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_gate_pin; ++i) { + if (ni_660x_gate_select == + NI_660x_Gate_Pin_Gate_Select(i)) { + return NI_GPCT_GATE_PIN_GATE_SELECT(i); + break; + } + } + if (i <= ni_660x_max_gate_pin) + break; + BUG(); + break; + } + return 0; +} + +static unsigned int ni_m_series_first_gate_to_generic_gate_source(unsigned int + ni_m_series_gate_select) +{ + unsigned int i; + + switch (ni_m_series_gate_select) { + case NI_M_Series_Timestamp_Mux_Gate_Select: + return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT; + break; + case NI_M_Series_AI_START2_Gate_Select: + return NI_GPCT_AI_START2_GATE_SELECT; + break; + case NI_M_Series_PXI_Star_Trigger_Gate_Select: + return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT; + break; + case NI_M_Series_Next_Out_Gate_Select: + return NI_GPCT_NEXT_OUT_GATE_SELECT; + break; + case NI_M_Series_AI_START1_Gate_Select: + return NI_GPCT_AI_START1_GATE_SELECT; + break; + case NI_M_Series_Next_SRC_Gate_Select: + return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; + case NI_M_Series_Analog_Trigger_Out_Gate_Select: + return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT; + break; + case NI_M_Series_Logic_Low_Gate_Select: + return NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; + default: + for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { + if (ni_m_series_gate_select == + NI_M_Series_RTSI_Gate_Select(i)) { + return NI_GPCT_RTSI_GATE_SELECT(i); + break; + } + } + if (i <= ni_m_series_max_rtsi_channel) + break; + for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { + if (ni_m_series_gate_select == + NI_M_Series_PFI_Gate_Select(i)) { + return NI_GPCT_PFI_GATE_SELECT(i); + break; + } + } + if (i <= ni_m_series_max_pfi_channel) + break; + BUG(); + break; + } + return 0; +} + +static unsigned int ni_660x_second_gate_to_generic_gate_source(unsigned int + ni_660x_gate_select) +{ + unsigned int i; + + switch (ni_660x_gate_select) { + case NI_660x_Source_Pin_i_Second_Gate_Select: + return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; + break; + case NI_660x_Up_Down_Pin_i_Second_Gate_Select: + return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT; + break; + case NI_660x_Next_SRC_Second_Gate_Select: + return NI_GPCT_NEXT_SOURCE_GATE_SELECT; + break; + case NI_660x_Next_Out_Second_Gate_Select: + return NI_GPCT_NEXT_OUT_GATE_SELECT; + break; + case NI_660x_Selected_Gate_Second_Gate_Select: + return NI_GPCT_SELECTED_GATE_GATE_SELECT; + break; + case NI_660x_Logic_Low_Second_Gate_Select: + return NI_GPCT_LOGIC_LOW_GATE_SELECT; + break; + default: + for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { + if (ni_660x_gate_select == + NI_660x_RTSI_Second_Gate_Select(i)) { + return NI_GPCT_RTSI_GATE_SELECT(i); + break; + } + } + if (i <= ni_660x_max_rtsi_channel) + break; + for (i = 0; i <= ni_660x_max_up_down_pin; ++i) { + if (ni_660x_gate_select == + NI_660x_Up_Down_Pin_Second_Gate_Select(i)) { + return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i); + break; + } + } + if (i <= ni_660x_max_up_down_pin) + break; + BUG(); + break; + } + return 0; +} + +static unsigned int ni_m_series_second_gate_to_generic_gate_source(unsigned int + ni_m_series_gate_select) +{ + /* FIXME: the second gate sources for the m series are + undocumented, so we just return the raw bits for now. */ + switch (ni_m_series_gate_select) { + default: + return ni_m_series_gate_select; + break; + } + return 0; +}; + +static int ni_tio_get_gate_src(struct ni_gpct *counter, + unsigned int gate_index, + unsigned int * gate_source) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int mode_bits = ni_tio_get_soft_copy(counter, + NITIO_Gi_Mode_Reg(counter->counter_index)); + const unsigned int second_gate_reg = + NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned int gate_select_bits; + + switch (gate_index) { + case 0: + if ((mode_bits & Gi_Gating_Mode_Mask) == + Gi_Gating_Disabled_Bits) { + *gate_source = NI_GPCT_DISABLED_GATE_SELECT; + return 0; + } else { + gate_select_bits = + (ni_tio_get_soft_copy(counter, + NITIO_Gi_Input_Select_Reg(counter-> + counter_index)) & + Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift; + } + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + *gate_source = + ni_m_series_first_gate_to_generic_gate_source + (gate_select_bits); + break; + case ni_gpct_variant_660x: + *gate_source = + ni_660x_first_gate_to_generic_gate_source + (gate_select_bits); + break; + default: + BUG(); + break; + } + if (mode_bits & Gi_Gate_Polarity_Bit) { + *gate_source |= CR_INVERT; + } + if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) { + *gate_source |= CR_EDGE; + } + break; + case 1: + if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits + || (counter_dev-> + regs[second_gate_reg] & Gi_Second_Gate_Mode_Bit) + == 0) { + *gate_source = NI_GPCT_DISABLED_GATE_SELECT; + return 0; + } else { + gate_select_bits = + (counter_dev-> + regs[second_gate_reg] & + Gi_Second_Gate_Select_Mask) >> + Gi_Second_Gate_Select_Shift; + } + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + *gate_source = + ni_m_series_second_gate_to_generic_gate_source + (gate_select_bits); + break; + case ni_gpct_variant_660x: + *gate_source = + ni_660x_second_gate_to_generic_gate_source + (gate_select_bits); + break; + default: + BUG(); + break; + } + if (counter_dev-> + regs[second_gate_reg] & Gi_Second_Gate_Polarity_Bit) { + *gate_source |= CR_INVERT; + } + /* Second gate can't have edge/level mode set independently */ + if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) { + *gate_source |= CR_EDGE; + } + break; + default: + return -EINVAL; + break; + } + return 0; +} + +int ni_tio_insn_config(struct ni_gpct *counter, a4l_kinsn_t *insn) +{ + unsigned int *data = (unsigned int *)insn->data; + + switch (data[0]) { + case A4L_INSN_CONFIG_SET_COUNTER_MODE: + return ni_tio_set_counter_mode(counter, data[1]); + break; + case A4L_INSN_CONFIG_ARM: + return ni_tio_arm(counter, 1, data[1]); + break; + case A4L_INSN_CONFIG_DISARM: + ni_tio_arm(counter, 0, 0); + return 0; + break; + case A4L_INSN_CONFIG_GET_COUNTER_STATUS: + data[1] = ni_tio_counter_status(counter); + data[2] = counter_status_mask; + return 0; + break; + case A4L_INSN_CONFIG_SET_CLOCK_SRC: + return ni_tio_set_clock_src(counter, data[1], data[2]); + break; + case A4L_INSN_CONFIG_GET_CLOCK_SRC: + ni_tio_get_clock_src(counter, &data[1], &data[2]); + return 0; + break; + case A4L_INSN_CONFIG_SET_GATE_SRC: + return ni_tio_set_gate_src(counter, data[1], data[2]); + break; + case A4L_INSN_CONFIG_GET_GATE_SRC: + return ni_tio_get_gate_src(counter, data[1], &data[2]); + break; + case A4L_INSN_CONFIG_SET_OTHER_SRC: + return ni_tio_set_other_src(counter, data[1], data[2]); + break; + case A4L_INSN_CONFIG_RESET: + ni_tio_reset_count_and_disarm(counter); + return 0; + break; + default: + break; + } + return -EINVAL; +} + +int ni_tio_rinsn(struct ni_gpct *counter, a4l_kinsn_t *insn) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int channel = CR_CHAN(insn->chan_desc); + unsigned int first_read; + unsigned int second_read; + unsigned int correct_read; + + uint32_t *data = (uint32_t *)insn->data; + + if (insn->data_size != sizeof(uint32_t)) + return -EINVAL; + + switch (channel) { + case 0: + ni_tio_set_bits(counter, + NITIO_Gi_Command_Reg(counter->counter_index), + Gi_Save_Trace_Bit, 0); + ni_tio_set_bits(counter, + NITIO_Gi_Command_Reg(counter->counter_index), + Gi_Save_Trace_Bit, Gi_Save_Trace_Bit); + /* The count doesn't get latched until the next clock + edge, so it is possible the count may change (once) + while we are reading. Since the read of the + SW_Save_Reg isn't atomic (apparently even when it's a + 32 bit register according to 660x docs), we need to + read twice and make sure the reading hasn't changed. + If it has, a third read will be correct since the + count value will definitely have latched by then. */ + first_read = + read_register(counter, + NITIO_Gi_SW_Save_Reg(counter->counter_index)); + second_read = + read_register(counter, + NITIO_Gi_SW_Save_Reg(counter->counter_index)); + if (first_read != second_read) + correct_read = + read_register(counter, + NITIO_Gi_SW_Save_Reg(counter->counter_index)); + else + correct_read = first_read; + data[0] = correct_read; + return 0; + break; + case 1: + data[0] = counter_dev->regs + [NITIO_Gi_LoadA_Reg(counter->counter_index)]; + break; + case 2: + data[0] = counter_dev->regs + [NITIO_Gi_LoadB_Reg(counter->counter_index)]; + break; + }; + + return 0; +} + +static unsigned int ni_tio_next_load_register(struct ni_gpct *counter) +{ + const unsigned int bits = read_register(counter, + NITIO_Gxx_Status_Reg(counter->counter_index)); + + if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) { + return NITIO_Gi_LoadB_Reg(counter->counter_index); + } else { + return NITIO_Gi_LoadA_Reg(counter->counter_index); + } +} + +int ni_tio_winsn(struct ni_gpct *counter, a4l_kinsn_t *insn) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + const unsigned int channel = CR_CHAN(insn->chan_desc); + unsigned int load_reg; + + uint32_t *data = (uint32_t *)insn->data; + + if (insn->data_size != sizeof(uint32_t)) + return -EINVAL; + + switch (channel) { + case 0: + /* Unsafe if counter is armed. Should probably check + status and return -EBUSY if armed. */ + /* Don't disturb load source select, just use + whichever load register is already selected. */ + load_reg = ni_tio_next_load_register(counter); + write_register(counter, data[0], load_reg); + ni_tio_set_bits_transient(counter, + NITIO_Gi_Command_Reg(counter->counter_index), 0, 0, + Gi_Load_Bit); + /* Restore state of load reg to whatever the user set + last set it to */ + write_register(counter, counter_dev->regs[load_reg], load_reg); + break; + case 1: + counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = + data[0]; + write_register(counter, data[0], + NITIO_Gi_LoadA_Reg(counter->counter_index)); + break; + case 2: + counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = + data[0]; + write_register(counter, data[0], + NITIO_Gi_LoadB_Reg(counter->counter_index)); + break; + default: + return -EINVAL; + break; + } + + return 0; +} + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +static void ni_tio_configure_dma(struct ni_gpct *counter, + short enable, short read_not_write) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned int input_select_bits = 0; + + if (enable) { + if (read_not_write) { + input_select_bits |= Gi_Read_Acknowledges_Irq; + } else { + input_select_bits |= Gi_Write_Acknowledges_Irq; + } + } + ni_tio_set_bits(counter, + NITIO_Gi_Input_Select_Reg(counter->counter_index), + Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq, + input_select_bits); + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + break; + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + { + unsigned gi_dma_config_bits = 0; + + if (enable) { + gi_dma_config_bits |= Gi_DMA_Enable_Bit; + gi_dma_config_bits |= Gi_DMA_Int_Bit; + } + if (read_not_write == 0) { + gi_dma_config_bits |= Gi_DMA_Write_Bit; + } + ni_tio_set_bits(counter, + NITIO_Gi_DMA_Config_Reg(counter->counter_index), + Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit | + Gi_DMA_Write_Bit, gi_dma_config_bits); + } + break; + } +} + +/* TODO: ni_tio_input_inttrig is left unused because the trigger + callback cannot be changed at run time */ +int ni_tio_input_inttrig(struct ni_gpct *counter, lsampl_t trignum) +{ + unsigned long flags; + int retval = 0; + + BUG_ON(counter == NULL); + if (trignum != 0) + return -EINVAL; + + a4l_lock_irqsave(&counter->lock, flags); + if (counter->mite_chan) + mite_dma_arm(counter->mite_chan); + else + retval = -EIO; + a4l_unlock_irqrestore(&counter->lock, flags); + if (retval < 0) + return retval; + retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); + + /* TODO: disable trigger until a command is recorded. + Null trig at beginning prevent ao start trigger from executing + more than once per command (and doing things like trying to + allocate the ao dma channel multiple times) */ + + return retval; +} + +static int ni_tio_input_cmd(struct ni_gpct *counter, a4l_cmd_t *cmd) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + int retval = 0; + + counter->mite_chan->dir = A4L_INPUT; + switch (counter_dev->variant) { + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + mite_prep_dma(counter->mite_chan, 32, 32); + break; + case ni_gpct_variant_e_series: + mite_prep_dma(counter->mite_chan, 16, 32); + break; + default: + BUG(); + break; + } + ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), + Gi_Save_Trace_Bit, 0); + ni_tio_configure_dma(counter, 1, 1); + switch (cmd->start_src) { + case TRIG_NOW: + mite_dma_arm(counter->mite_chan); + retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); + break; + case TRIG_INT: + break; + case TRIG_EXT: + mite_dma_arm(counter->mite_chan); + retval = ni_tio_arm(counter, 1, cmd->start_arg); + case TRIG_OTHER: + mite_dma_arm(counter->mite_chan); + break; + default: + BUG(); + break; + } + return retval; +} + +static int ni_tio_output_cmd(struct ni_gpct *counter, a4l_cmd_t *cmd) +{ + __a4l_err("ni_tio: output commands not yet implemented.\n"); + return -ENOTSUPP; +} + +static int ni_tio_cmd_setup(struct ni_gpct *counter, a4l_cmd_t *cmd) +{ + int retval = 0, set_gate_source = 0; + unsigned int gate_source; + + if (cmd->scan_begin_src == TRIG_EXT) { + set_gate_source = 1; + gate_source = cmd->scan_begin_arg; + } else if (cmd->convert_src == TRIG_EXT) { + set_gate_source = 1; + gate_source = cmd->convert_arg; + } + if (set_gate_source) { + retval = ni_tio_set_gate_src(counter, 0, gate_source); + } + if (cmd->flags & TRIG_WAKE_EOS) { + ni_tio_set_bits(counter, + NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), + Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), + Gi_Gate_Interrupt_Enable_Bit(counter->counter_index)); + } + return retval; +} + +int ni_tio_cmd(struct ni_gpct *counter, a4l_cmd_t *cmd) +{ + int retval = 0; + unsigned long flags; + + a4l_lock_irqsave(&counter->lock, flags); + if (counter->mite_chan == NULL) { + __a4l_err("ni_tio_cmd: commands only supported with DMA." + " Interrupt-driven commands not yet implemented.\n"); + retval = -EIO; + } else { + retval = ni_tio_cmd_setup(counter, cmd); + if (retval == 0) { + if (cmd->flags & A4L_CMD_WRITE) { + retval = ni_tio_output_cmd(counter, cmd); + } else { + retval = ni_tio_input_cmd(counter, cmd); + } + } + } + a4l_unlock_irqrestore(&counter->lock, flags); + return retval; +} + +a4l_cmd_t ni_tio_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_NOW | TRIG_INT | TRIG_OTHER | TRIG_EXT, + .scan_begin_src = TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER, + .convert_src = TRIG_NOW | TRIG_EXT | TRIG_OTHER, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_NONE, +}; + +int ni_tio_cmdtest(struct ni_gpct *counter, a4l_cmd_t *cmd) +{ + /* Make sure trigger sources are trivially valid */ + + if ((cmd->start_src & TRIG_EXT) != 0 && + ni_tio_counting_mode_registers_present(counter->counter_dev) == 0) + return -EINVAL; + + /* Make sure trigger sources are mutually compatible */ + + if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW) + return -EINVAL; + + /* Make sure arguments are trivially compatible */ + + if (cmd->start_src != TRIG_EXT) { + if (cmd->start_arg != 0) { + return -EINVAL; + } + } + + if (cmd->scan_begin_src != TRIG_EXT) { + if (cmd->scan_begin_arg) { + return -EINVAL; + } + } + + if (cmd->convert_src != TRIG_EXT) { + if (cmd->convert_arg) { + return -EINVAL; + } + } + + if (cmd->scan_end_arg != cmd->nb_chan) { + return -EINVAL; + } + + if (cmd->stop_src == TRIG_NONE) { + if (cmd->stop_arg != 0) { + return -EINVAL; + } + } + + return 0; +} + +int ni_tio_cancel(struct ni_gpct *counter) +{ + unsigned long flags; + + ni_tio_arm(counter, 0, 0); + a4l_lock_irqsave(&counter->lock, flags); + if (counter->mite_chan) { + mite_dma_disarm(counter->mite_chan); + } + a4l_unlock_irqrestore(&counter->lock, flags); + ni_tio_configure_dma(counter, 0, 0); + + ni_tio_set_bits(counter, + NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), + Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), 0x0); + return 0; +} + +/* During buffered input counter operation for e-series, the gate + interrupt is acked automatically by the dma controller, due to the + Gi_Read/Write_Acknowledges_IRQ bits in the input select + register. */ +static int should_ack_gate(struct ni_gpct *counter) +{ + unsigned long flags; + int retval = 0; + + switch (counter->counter_dev->variant) { + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + /* Not sure if 660x really supports gate interrupts + (the bits are not listed in register-level manual) */ + return 1; + break; + case ni_gpct_variant_e_series: + a4l_lock_irqsave(&counter->lock, flags); + { + if (counter->mite_chan == NULL || + counter->mite_chan->dir != A4L_INPUT || + (mite_done(counter->mite_chan))) { + retval = 1; + } + } + a4l_unlock_irqrestore(&counter->lock, flags); + break; + } + return retval; +} + +void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, + int *gate_error, + int *tc_error, + int *perm_stale_data, int *stale_data) +{ + const unsigned short gxx_status = read_register(counter, + NITIO_Gxx_Status_Reg(counter->counter_index)); + const unsigned short gi_status = read_register(counter, + NITIO_Gi_Status_Reg(counter->counter_index)); + unsigned ack = 0; + + if (gate_error) + *gate_error = 0; + if (tc_error) + *tc_error = 0; + if (perm_stale_data) + *perm_stale_data = 0; + if (stale_data) + *stale_data = 0; + + if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) { + ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index); + if (gate_error) { + /* 660x don't support automatic + acknowledgement of gate interrupt via dma + read/write and report bogus gate errors */ + if (counter->counter_dev->variant != + ni_gpct_variant_660x) { + *gate_error = 1; + } + } + } + if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) { + ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index); + if (tc_error) + *tc_error = 1; + } + if (gi_status & Gi_TC_Bit) { + ack |= Gi_TC_Interrupt_Ack_Bit; + } + if (gi_status & Gi_Gate_Interrupt_Bit) { + if (should_ack_gate(counter)) + ack |= Gi_Gate_Interrupt_Ack_Bit; + } + if (ack) + write_register(counter, ack, + NITIO_Gi_Interrupt_Acknowledge_Reg(counter-> + counter_index)); + if (ni_tio_get_soft_copy(counter, + NITIO_Gi_Mode_Reg(counter-> + counter_index)) & Gi_Loading_On_Gate_Bit) { + if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) { + if (stale_data) + *stale_data = 1; + } + if (read_register(counter, + NITIO_Gxx_Joint_Status2_Reg(counter-> + counter_index)) & + Gi_Permanent_Stale_Bit(counter->counter_index)) { + __a4l_err("%s: Gi_Permanent_Stale_Data detected.\n", + __FUNCTION__); + if (perm_stale_data) + *perm_stale_data = 1; + } + } +} + +/* TODO: to be adapted after a4l_buf_evt review */ +void ni_tio_handle_interrupt(struct ni_gpct *counter, a4l_dev_t *dev) +{ + unsigned gpct_mite_status; + unsigned long flags; + int gate_error; + int tc_error; + int perm_stale_data; + a4l_subd_t *subd = + a4l_get_subd(dev, NI_GPCT_SUBDEV(counter->counter_index)); + + ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, + &perm_stale_data, NULL); + if (gate_error) { + __a4l_err("%s: Gi_Gate_Error detected.\n", __FUNCTION__); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + if (perm_stale_data) { + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + switch (counter->counter_dev->variant) { + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + if (read_register(counter, + NITIO_Gi_DMA_Status_Reg(counter->counter_index)) + & Gi_DRQ_Error_Bit) { + __a4l_err("%s: Gi_DRQ_Error detected.\n", __FUNCTION__); + a4l_buf_evt(subd, A4L_BUF_ERROR); + } + break; + case ni_gpct_variant_e_series: + break; + } + a4l_lock_irqsave(&counter->lock, flags); + if (counter->mite_chan == NULL) { + a4l_unlock_irqrestore(&counter->lock, flags); + return; + } + gpct_mite_status = mite_get_status(counter->mite_chan); + if (gpct_mite_status & CHSR_LINKC) { + writel(CHOR_CLRLC, + counter->mite_chan->mite->mite_io_addr + + MITE_CHOR(counter->mite_chan->channel)); + } + mite_sync_input_dma(counter->mite_chan, subd); + a4l_unlock_irqrestore(&counter->lock, flags); +} + +void ni_tio_set_mite_channel(struct ni_gpct *counter, + struct mite_channel *mite_chan) +{ + unsigned long flags; + + a4l_lock_irqsave(&counter->lock, flags); + counter->mite_chan = mite_chan; + a4l_unlock_irqrestore(&counter->lock, flags); +} + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + +static int __init ni_tio_init_module(void) +{ + return 0; +} + +static void __exit ni_tio_cleanup_module(void) +{ +} + +MODULE_DESCRIPTION("Analogy support for NI general-purpose counters"); +MODULE_LICENSE("GPL"); + +module_init(ni_tio_init_module); +module_exit(ni_tio_cleanup_module); + +EXPORT_SYMBOL_GPL(ni_tio_rinsn); +EXPORT_SYMBOL_GPL(ni_tio_winsn); +EXPORT_SYMBOL_GPL(ni_tio_insn_config); +EXPORT_SYMBOL_GPL(ni_tio_init_counter); +EXPORT_SYMBOL_GPL(ni_gpct_device_construct); +EXPORT_SYMBOL_GPL(ni_gpct_device_destroy); + +#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ + defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) + +EXPORT_SYMBOL_GPL(ni_tio_input_inttrig); +EXPORT_SYMBOL_GPL(ni_tio_cmd); +EXPORT_SYMBOL_GPL(ni_tio_cmd_mask); +EXPORT_SYMBOL_GPL(ni_tio_cmdtest); +EXPORT_SYMBOL_GPL(ni_tio_cancel); +EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt); +EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel); +EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm); + +#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/os_facilities.c relase/linux-2.6.35.9//drivers/xenomai/analogy/os_facilities.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/os_facilities.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/os_facilities.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,223 @@ +/** + * @file + * Analogy for Linux, OS facilities + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include + +#include + +/* --- Time section --- */ + +static nanosecs_abs_t a4l_clkofs; + +void a4l_init_time(void) +{ + nanosecs_abs_t t1, t2; + struct timeval tv; + t1 = a4l_get_rawtime(); + do_gettimeofday(&tv); + t2 = 1000000000 * ((nanosecs_abs_t)tv.tv_sec) + + 1000000 * ((nanosecs_abs_t)tv.tv_usec); + a4l_clkofs = t2 - t1; +} + +nanosecs_abs_t a4l_get_time(void) +{ + return a4l_clkofs + a4l_get_rawtime(); +} + +/* --- IRQ section --- */ + +static int a4l_handle_irq(rtdm_irq_t *irq_handle) +{ + a4l_irq_desc_t *dsc = + rtdm_irq_get_arg(irq_handle, a4l_irq_desc_t); + + if (dsc->handler((unsigned int)irq_handle->irq, dsc->cookie) == 0) + return RTDM_IRQ_HANDLED; + else + return RTDM_IRQ_NONE; +} + +int __a4l_request_irq(a4l_irq_desc_t *dsc, + unsigned int irq, + a4l_irq_hdlr_t handler, + unsigned long flags, void *cookie) +{ + /* Fills the IRQ descriptor */ + dsc->handler = handler; + dsc->cookie = cookie; + dsc->irq = irq; + + /* Registers the RT IRQ handler */ + return rtdm_irq_request(&dsc->rtdm_desc, + (int)irq, + a4l_handle_irq, flags, "Analogy device", dsc); +} + +int __a4l_free_irq(a4l_irq_desc_t * dsc) +{ + return rtdm_irq_free(&dsc->rtdm_desc); +} + +/* --- Synchronization section --- */ + +static void a4l_nrt_sync_handler(rtdm_nrtsig_t nrt_sig, void *arg) +{ + a4l_sync_t *snc = (a4l_sync_t *) arg; + wake_up_interruptible(&snc->wq); +} + +int a4l_init_sync(a4l_sync_t *snc) +{ + int ret = 0; + + /* Initializes the flags field */ + snc->status = 0; + + /* If the process is NRT, we need a wait queue structure */ + init_waitqueue_head(&snc->wq); + + /* Initializes the RTDM event */ + rtdm_event_init(&snc->rtdm_evt, 0); + + /* Initializes the gateway to NRT context */ + ret = rtdm_nrtsig_init(&snc->nrt_sig, a4l_nrt_sync_handler, snc); + + return ret; +} + +void a4l_cleanup_sync(a4l_sync_t *snc) +{ + rtdm_nrtsig_destroy(&snc->nrt_sig); + rtdm_event_destroy(&snc->rtdm_evt); +} + +int a4l_wait_sync(a4l_sync_t *snc, int rt) +{ + int ret = 0; + + if (test_bit(__EVT_PDING, &snc->status)) + goto out_wait; + + if (rt != 0) { + /* If the calling process is in primary mode, + we can use RTDM API ... */ + set_bit(__RT_WAITER, &snc->status); + ret = rtdm_event_wait(&snc->rtdm_evt); + } else { + /* ... else if the process is NRT, + the Linux wait queue system is used */ + set_bit(__NRT_WAITER, &snc->status); + ret = wait_event_interruptible(snc->wq, + test_bit(__EVT_PDING, + &snc->status)); + } + +out_wait: + + clear_bit(__EVT_PDING, &snc->status); + + return ret; +} + +int a4l_timedwait_sync(a4l_sync_t * snc, + int rt, unsigned long long ns_timeout) +{ + int ret = 0; + unsigned long timeout; + + if (test_bit(__EVT_PDING, &snc->status)) + goto out_wait; + + if (rt != 0) { + /* If the calling process is in primary mode, + we can use RTDM API ... */ + set_bit(__RT_WAITER, &snc->status); + ret = rtdm_event_timedwait(&snc->rtdm_evt, ns_timeout, NULL); + } else { + /* ... else if the process is NRT, + the Linux wait queue system is used */ + + timeout = do_div(ns_timeout, 1000); + + /* We consider the Linux kernel cannot tick at a frequency + higher than 1 MHz + If the timeout value is lower than 1us, we round up to 1us */ + timeout = (timeout == 0) ? 1 : usecs_to_jiffies(timeout); + + set_bit(__NRT_WAITER, &snc->status); + + ret = wait_event_interruptible_timeout(snc->wq, + test_bit(__EVT_PDING, + &snc->status), + timeout); + } + +out_wait: + + clear_bit(__EVT_PDING, &snc->status); + + return ret; +} + +void a4l_flush_sync(a4l_sync_t * snc) +{ + /* Clear the status bitfield */ + snc->status = 0; + + /* Flush the RTDM event */ + rtdm_event_clear(&snc->rtdm_evt); +} + +void a4l_signal_sync(a4l_sync_t * snc) +{ + int hit = 0; + + set_bit(__EVT_PDING, &snc->status); + + /* a4l_signal_sync() is bound not to be called upon the right + user process context; so, the status flags stores its mode. + Thus the proper event signaling function is called */ + if (test_and_clear_bit(__RT_WAITER, &snc->status)) { + rtdm_event_signal(&snc->rtdm_evt); + hit++; + } + + if (test_and_clear_bit(__NRT_WAITER, &snc->status)) { + rtdm_nrtsig_pend(&snc->nrt_sig); + hit++; + } + + if (hit == 0) { + /* At first signaling, we may not know the proper way + to send the event */ + rtdm_event_signal(&snc->rtdm_evt); + rtdm_nrtsig_pend(&snc->nrt_sig); + } +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/proc.h relase/linux-2.6.35.9//drivers/xenomai/analogy/proc.h --- orig/linux-2.6.35.9//drivers/xenomai/analogy/proc.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/proc.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,34 @@ +/** + * @file + * Analogy for Linux, procfs related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ANALOGY_PROC_H__ +#define __ANALOGY_PROC_H__ + +#ifdef __KERNEL__ + +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *a4l_proc_root; +#endif /* CONFIG_PROC_FS */ + +#endif /* __KERNEL__ */ + +#endif /* __ANALOGY_PROC_H__ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/rtdm_interface.c relase/linux-2.6.35.9//drivers/xenomai/analogy/rtdm_interface.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/rtdm_interface.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/rtdm_interface.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,323 @@ +/** + * @file + * Analogy for Linux, user interface (open, read, write, ioctl, proc) + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +int (*a4l_ioctl_functions[NB_IOCTL_FUNCTIONS]) (a4l_cxt_t *, void *) = { + a4l_ioctl_devcfg, + a4l_ioctl_devinfo, + a4l_ioctl_subdinfo, + a4l_ioctl_chaninfo, + a4l_ioctl_rnginfo, + a4l_ioctl_cmd, + a4l_ioctl_cancel, + a4l_ioctl_insnlist, + a4l_ioctl_insn, + a4l_ioctl_bufcfg, + a4l_ioctl_bufinfo, + a4l_ioctl_poll, + a4l_ioctl_mmap, + a4l_ioctl_nbchaninfo, + a4l_ioctl_nbrnginfo +}; + +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *a4l_proc_root; + +int a4l_init_proc(void) +{ + int ret = 0; + struct proc_dir_entry *entry; + + /* Creates the global directory */ + a4l_proc_root = create_proc_entry("analogy", S_IFDIR, 0); + if (a4l_proc_root == NULL) { + __a4l_err("a4l_proc_init: " + "failed to create /proc/analogy\n"); + return -ENOMEM; + } + + /* Creates the devices related file */ + entry = create_proc_entry("devices", 0444, a4l_proc_root); + if (entry == NULL) { + __a4l_err("a4l_proc_init: " + "failed to create /proc/analogy/devices\n"); + ret = -ENOMEM; + goto err_proc_init; + } + + entry->nlink = 1; + entry->data = NULL; + entry->write_proc = NULL; + entry->read_proc = a4l_rdproc_devs; + wrap_proc_dir_entry_owner(entry); + + /* Creates the drivers related file */ + entry = create_proc_entry("drivers", 0444, a4l_proc_root); + if (entry == NULL) { + __a4l_err("a4l_proc_init: " + "failed to create /proc/analogy/drivers\n"); + ret = -ENOMEM; + goto err_proc_init; + } + + entry->nlink = 1; + entry->data = NULL; + entry->write_proc = NULL; + entry->read_proc = a4l_rdproc_drvs; + wrap_proc_dir_entry_owner(entry); + + return 0; + +err_proc_init: + remove_proc_entry("devices", a4l_proc_root); + remove_proc_entry("analogy", NULL); + return ret; +} + +void a4l_cleanup_proc(void) +{ + remove_proc_entry("drivers", a4l_proc_root); + remove_proc_entry("devices", a4l_proc_root); + remove_proc_entry("analogy", NULL); +} + +#else /* !CONFIG_PROC_FS */ + +#define a4l_init_proc() 0 +#define a4l_cleanup_proc() + +#endif /* CONFIG_PROC_FS */ + +int a4l_open(struct rtdm_dev_context *context, + rtdm_user_info_t * user_info, int flags) +{ + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + /* Get a pointer on the selected device + (thanks to minor index) */ + a4l_set_dev(cxt); + + /* Initialize the buffer structure */ + cxt->buffer = rtdm_malloc(sizeof(a4l_buf_t)); + a4l_init_buffer(cxt->buffer); + + /* Allocate the asynchronous buffer + NOTE: it should be interesting to allocate the buffer only + on demand especially if the system is short of memory */ + if (cxt->dev->transfer.default_bufsize) + a4l_alloc_buffer(cxt->buffer, + cxt->dev->transfer.default_bufsize); + + return 0; +} + +int a4l_close(struct rtdm_dev_context *context, rtdm_user_info_t * user_info) +{ + int err; + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + /* Cancel the maybe occuring asynchronous transfer */ + err = a4l_cancel_buffer(cxt); + if (err < 0) { + __a4l_err("close: unable to stop the asynchronous transfer\n"); + return err; + } + + /* Free the buffer which was linked with this context and... */ + a4l_free_buffer(cxt->buffer); + + /* ...free the other buffer resources (sync) and... */ + a4l_cleanup_buffer(cxt->buffer); + + /* ...free the structure */ + rtdm_free(cxt->buffer); + + return 0; +} + +ssize_t a4l_read(struct rtdm_dev_context * context, + rtdm_user_info_t * user_info, void *buf, size_t nbytes) +{ + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + /* Jump into the RT domain if possible */ + if (!rtdm_in_rt_context() && rtdm_rt_capable(user_info)) + return -ENOSYS; + + if (nbytes == 0) + return 0; + + cxt->user_info = user_info; + + return a4l_read_buffer(cxt, buf, nbytes); +} + +ssize_t a4l_write(struct rtdm_dev_context * context, + rtdm_user_info_t *user_info, const void *buf, size_t nbytes) +{ + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + /* Jump into the RT domain if possible */ + if (!rtdm_in_rt_context() && rtdm_rt_capable(user_info)) + return -ENOSYS; + + if (nbytes == 0) + return 0; + + cxt->user_info = user_info; + + return a4l_write_buffer(cxt, buf, nbytes); +} + +int a4l_ioctl(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, unsigned int request, void *arg) +{ + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + cxt->user_info = user_info; + + return a4l_ioctl_functions[_IOC_NR(request)] (cxt, arg); +} + +int a4l_rt_select(struct rtdm_dev_context *context, + rtdm_selector_t *selector, + enum rtdm_selecttype type, unsigned fd_index) +{ + a4l_cxt_t *cxt = (a4l_cxt_t *)rtdm_context_to_private(context); + + return a4l_select(cxt, selector, type, fd_index); +} + +static struct rtdm_device rtdm_devs[A4L_NB_DEVICES] = +{[0 ... A4L_NB_DEVICES - 1] = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + .device_flags = RTDM_NAMED_DEVICE, + .context_size = sizeof(struct a4l_device_context), + .device_name = "", + + .open_nrt = a4l_open, + + .ops = { + .ioctl_rt = a4l_ioctl, + .read_rt = a4l_read, + .write_rt = a4l_write, + + .close_nrt = a4l_close, + .ioctl_nrt = a4l_ioctl, + .read_nrt = a4l_read, + .write_nrt = a4l_write, + + .select_bind = a4l_rt_select, + }, + + .device_class = RTDM_CLASS_EXPERIMENTAL, + .device_sub_class = RTDM_SUBCLASS_ANALOGY, + .driver_name = "rtdm_analogy", + .driver_version = RTDM_DRIVER_VER(1, 0, 0), + .peripheral_name = "Analogy", + .provider_name = "Alexis Berlemont", + } +}; + +int a4l_register(void) +{ + int i, ret = 0; + + for (i = 0; i < A4L_NB_DEVICES && ret == 0; i++) { + + /* Sets the device name through which + user process can access the Analogy layer */ + snprintf(rtdm_devs[i].device_name, + RTDM_MAX_DEVNAME_LEN, "analogy%d", i); + rtdm_devs[i].proc_name = rtdm_devs[i].device_name; + + /* To keep things simple, the RTDM device ID + is the Analogy device index */ + rtdm_devs[i].device_id = i; + + ret = rtdm_dev_register(&(rtdm_devs[i])); + } + + return ret; +} + +void a4l_unregister(void) +{ + int i; + for (i = 0; i < A4L_NB_DEVICES; i++) + rtdm_dev_unregister(&(rtdm_devs[i]), 1000); +} + +MODULE_DESCRIPTION("Analogy"); +MODULE_LICENSE("GPL"); + +static int __init a4l_init(void) +{ + int ret; + + /* Initializes the devices */ + a4l_init_devs(); + + /* Initializes Analogy time management */ + a4l_init_time(); + + /* Registers RTDM / fops interface */ + ret = a4l_register(); + if (ret != 0) { + a4l_unregister(); + goto out_a4l_init; + } + + /* Initializes Analogy proc layer */ + ret = a4l_init_proc(); + +out_a4l_init: + return ret; +} + +static void __exit a4l_cleanup(void) +{ + /* Removes Analogy proc files */ + a4l_cleanup_proc(); + + /* Unregisters RTDM / fops interface */ + a4l_unregister(); +} + +module_init(a4l_init); +module_exit(a4l_cleanup); + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Kconfig relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,5 @@ + +config XENO_DRIVERS_ANALOGY_S526 + depends on XENO_DRIVERS_ANALOGY + tristate "Sensoray Model 526 driver" + default n diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Makefile relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,30 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile flag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_S526) += analogy_s526.o + +analogy_s526-y := s526.o + +else + +# Makefile flag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_S526) += analogy_s526.o + +analogy_s526-objs := s526.o + +export-objs := $(analogy_s526-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +analogy_s526.o: $(analogy_s526-objs) + $(LD) -r -o $@ $(analogy_s526-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/s526.c relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/s526.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/s526.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/sensoray/s526.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,755 @@ +/** + * @file + * Analogy driver for Sensoray Model 526 board + * + * Copyright (C) 2009 Simon Boulay + * + * Derived from comedi: + * Copyright (C) 2000 David A. Schleef + * 2006 Everett Wang + * 2009 Ian Abbott + * + * This code 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 code 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* + * Original code comes from comedi linux-next staging driver (2009.12.20) + * Board documentation: http://www.sensoray.com/products/526data.htm + * Everything should work as in comedi: + * - Encoder works + * - Analog input works + * - Analog output works + * - PWM output works + * - Commands are not supported yet. + */ + +#include +#include +#include +#include + +/* Board description */ +#define S526_GPCT_CHANS 4 +#define S526_GPCT_BITS 24 +#define S526_AI_CHANS 10 /* 8 regular differential inputs + * channel 8 is "reference 0" (+10V) + * channel 9 is "reference 1" (0V) */ +#define S526_AI_BITS 16 +#define S526_AI_TIMEOUT 100 +#define S526_AO_CHANS 4 +#define S526_AO_BITS 16 +#define S526_DIO_CHANS 8 +#define S526_DIO_BITS 1 + +/* Ports */ +#define S526_IOSIZE 0x40 /* 64 bytes */ +#define S526_DEFAULT_ADDRESS 0x2C0 /* Manufacturing default */ + +/* Registers */ +#define REG_TCR 0x00 +#define REG_WDC 0x02 +#define REG_DAC 0x04 +#define REG_ADC 0x06 +#define REG_ADD 0x08 +#define REG_DIO 0x0A +#define REG_IER 0x0C +#define REG_ISR 0x0E +#define REG_MSC 0x10 +#define REG_C0L 0x12 +#define REG_C0H 0x14 +#define REG_C0M 0x16 +#define REG_C0C 0x18 +#define REG_C1L 0x1A +#define REG_C1H 0x1C +#define REG_C1M 0x1E +#define REG_C1C 0x20 +#define REG_C2L 0x22 +#define REG_C2H 0x24 +#define REG_C2M 0x26 +#define REG_C2C 0x28 +#define REG_C3L 0x2A +#define REG_C3H 0x2C +#define REG_C3M 0x2E +#define REG_C3C 0x30 +#define REG_EED 0x32 +#define REG_EEC 0x34 + +#define ISR_ADC_DONE 0x4 + +struct counter_mode_register_t { +#if defined (__LITTLE_ENDIAN_BITFIELD) + unsigned short coutSource:1; + unsigned short coutPolarity:1; + unsigned short autoLoadResetRcap:3; + unsigned short hwCtEnableSource:2; + unsigned short ctEnableCtrl:2; + unsigned short clockSource:2; + unsigned short countDir:1; + unsigned short countDirCtrl:1; + unsigned short outputRegLatchCtrl:1; + unsigned short preloadRegSel:1; + unsigned short reserved:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned short reserved:1; + unsigned short preloadRegSel:1; + unsigned short outputRegLatchCtrl:1; + unsigned short countDirCtrl:1; + unsigned short countDir:1; + unsigned short clockSource:2; + unsigned short ctEnableCtrl:2; + unsigned short hwCtEnableSource:2; + unsigned short autoLoadResetRcap:3; + unsigned short coutPolarity:1; + unsigned short coutSource:1; +#else +#error Unknown bit field order +#endif +}; + +union cmReg { + struct counter_mode_register_t reg; + unsigned short value; +}; + +/* Application Classes for GPCT Subdevices */ +enum S526_GPCT_APP_CLASS { + CountingAndTimeMeasurement, + SinglePulseGeneration, + PulseTrainGeneration, + PositionMeasurement, + Miscellaneous +}; + +/* GPCT subdevices configuration */ +#define MAX_GPCT_CONFIG_DATA 6 +struct s526GPCTConfig { + enum S526_GPCT_APP_CLASS app; + int data[MAX_GPCT_CONFIG_DATA]; +}; + +typedef struct s526_priv { + unsigned long io_base; +} s526_priv_t; + +struct s526_subd_gpct_priv { + struct s526GPCTConfig config[4]; +}; + +struct s526_subd_ai_priv { + uint16_t config; +}; + +struct s526_subd_ao_priv { + uint16_t readback[2]; +}; + +struct s526_subd_dio_priv { + int io_bits; + unsigned int state; +}; + +#define devpriv ((s526_priv_t*)(dev->priv)) + +#define ADDR_REG(reg) (devpriv->io_base + (reg)) +#define ADDR_CHAN_REG(reg, chan) (devpriv->io_base + (reg) + (chan) * 8) + + +static int s526_gpct_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_gpct_priv *subdpriv = + (struct s526_subd_gpct_priv *)subd->priv; + unsigned int *data = (unsigned int *)insn->data; + int subdev_channel = CR_CHAN(insn->chan_desc); + int i; + short value; + union cmReg cmReg; + + a4l_dbg(1, drv_dbg, dev, + "s526_gpct_insn_config: Configuring Channel %d\n", + subdev_channel); + + for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) { + subdpriv->config[subdev_channel].data[i] = data[i]; + a4l_dbg(1, drv_dbg, dev, "data[%d]=%x\n", i, data[i]); + } + + switch (data[0]) { + case A4L_INSN_CONFIG_GPCT_QUADRATURE_ENCODER: + /* + * data[0]: Application Type + * data[1]: Counter Mode Register Value + * data[2]: Pre-load Register Value + * data[3]: Conter Control Register + */ + a4l_dbg(1, drv_dbg, dev, "s526_gpct_insn_config: Configuring Encoder\n"); + subdpriv->config[subdev_channel].app = PositionMeasurement; + + /* Set Counter Mode Register */ + cmReg.value = data[1] & 0xFFFF; + + a4l_dbg(1, drv_dbg, dev, "Counter Mode register=%x\n", cmReg.value); + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + /* Reset the counter if it is software preload */ + if (cmReg.reg.autoLoadResetRcap == 0) { + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset the counter */ + /* outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /\* Load the counter from PR0 *\/ */ + } + break; + + case A4L_INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR: + /* + * data[0]: Application Type + * data[1]: Counter Mode Register Value + * data[2]: Pre-load Register 0 Value + * data[3]: Pre-load Register 1 Value + * data[4]: Conter Control Register + */ + a4l_dbg(1, drv_dbg, dev, "s526_gpct_insn_config: Configuring SPG\n"); + subdpriv->config[subdev_channel].app = SinglePulseGeneration; + + /* Set Counter Mode Register */ + cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.reg.preloadRegSel = 0; /* PR0 */ + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + /* Load the pre-load register 0 high word */ + value = (short)((data[2] >> 16) & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + + /* Load the pre-load register 0 low word */ + value = (short)(data[2] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + + /* Set Counter Mode Register */ + cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.reg.preloadRegSel = 1; /* PR1 */ + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + /* Load the pre-load register 1 high word */ + value = (short)((data[3] >> 16) & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + + /* Load the pre-load register 1 low word */ + value = (short)(data[3] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + + /* Write the Counter Control Register */ + if (data[4] != 0) { + value = (short)(data[4] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + } + break; + + case A4L_INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR: + /* + * data[0]: Application Type + * data[1]: Counter Mode Register Value + * data[2]: Pre-load Register 0 Value + * data[3]: Pre-load Register 1 Value + * data[4]: Conter Control Register + */ + a4l_dbg(1, drv_dbg, dev, "s526_gpct_insn_config: Configuring PTG\n"); + subdpriv->config[subdev_channel].app = PulseTrainGeneration; + + /* Set Counter Mode Register */ + cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.reg.preloadRegSel = 0; /* PR0 */ + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + /* Load the pre-load register 0 high word */ + value = (short)((data[2] >> 16) & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + + /* Load the pre-load register 0 low word */ + value = (short)(data[2] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + + /* Set Counter Mode Register */ + cmReg.value = (short)(data[1] & 0xFFFF); + cmReg.reg.preloadRegSel = 1; /* PR1 */ + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + /* Load the pre-load register 1 high word */ + value = (short)((data[3] >> 16) & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + + /* Load the pre-load register 1 low word */ + value = (short)(data[3] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + + /* Write the Counter Control Register */ + if (data[4] != 0) { + value = (short)(data[4] & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + } + break; + + default: + a4l_err(dev, "s526_gpct_insn_config: unsupported GPCT_insn_config\n"); + return -EINVAL; + break; + } + + return 0; +} + +static int s526_gpct_rinsn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + uint32_t *data = (uint32_t *)insn->data; + int counter_channel = CR_CHAN(insn->chan_desc); + unsigned short datalow; + unsigned short datahigh; + int i; + + if (insn->data_size <= 0) { + a4l_err(dev, "s526_gpct_rinsn: data size should be > 0\n"); + return -EINVAL; + } + + for (i = 0; i < insn->data_size / sizeof(uint32_t); i++) { + datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel)); + datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel)); + data[i] = (int)(datahigh & 0x00FF); + data[i] = (data[i] << 16) | (datalow & 0xFFFF); + a4l_dbg(1, drv_dbg, dev, + "s526_gpct_rinsn GPCT[%d]: %x(0x%04x, 0x%04x)\n", + counter_channel, data[i], datahigh, datalow); + } + + return 0; +} + +static int s526_gpct_winsn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_gpct_priv *subdpriv = + (struct s526_subd_gpct_priv *)subd->priv; + uint32_t *data = (uint32_t *)insn->data; + int subdev_channel = CR_CHAN(insn->chan_desc); + short value; + union cmReg cmReg; + + a4l_dbg(1, drv_dbg, dev, + "s526_gpct_winsn: GPCT_INSN_WRITE on channel %d\n", + subdev_channel); + + cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel)); + a4l_dbg(1, drv_dbg, dev, + "s526_gpct_winsn: Counter Mode Register: %x\n", cmReg.value); + + /* Check what Application of Counter this channel is configured for */ + switch (subdpriv->config[subdev_channel].app) { + case PositionMeasurement: + a4l_dbg(1, drv_dbg, dev, "s526_gpct_winsn: INSN_WRITE: PM\n"); + outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, + subdev_channel)); + outw(0xFFFF & (*data), + ADDR_CHAN_REG(REG_C0L, subdev_channel)); + break; + + case SinglePulseGeneration: + a4l_dbg(1, drv_dbg, dev, "s526_gpct_winsn: INSN_WRITE: SPG\n"); + outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, + subdev_channel)); + outw(0xFFFF & (*data), + ADDR_CHAN_REG(REG_C0L, subdev_channel)); + break; + + case PulseTrainGeneration: + /* + * data[0] contains the PULSE_WIDTH + * data[1] contains the PULSE_PERIOD + * @pre PULSE_PERIOD > PULSE_WIDTH > 0 + * The above periods must be expressed as a multiple of the + * pulse frequency on the selected source + */ + a4l_dbg(1, drv_dbg, dev, "s526_gpct_winsn: INSN_WRITE: PTG\n"); + if ((data[1] > data[0]) && (data[0] > 0)) { + (subdpriv->config[subdev_channel]).data[0] = data[0]; + (subdpriv->config[subdev_channel]).data[1] = data[1]; + } else { + a4l_err(dev, + "s526_gpct_winsn: INSN_WRITE: PTG: Problem with Pulse params -> %du %du\n", + data[0], data[1]); + return -EINVAL; + } + + value = (short)((*data >> 16) & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + value = (short)(*data & 0xFFFF); + outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + break; + default: /* Impossible */ + a4l_err(dev, + "s526_gpct_winsn: INSN_WRITE: Functionality %d not implemented yet\n", + subdpriv->config[subdev_channel].app); + return -EINVAL; + } + + return 0; +} + +static int s526_ai_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_ai_priv *subdpriv = + (struct s526_subd_ai_priv *)subd->priv; + unsigned int *data = (unsigned int *)insn->data; + + if (insn->data_size < sizeof(unsigned int)) + return -EINVAL; + + /* data[0] : channels was set in relevant bits. + * data[1] : delay + */ + /* COMMENT: abbotti 2008-07-24: I don't know why you'd want to + * enable channels here. The channel should be enabled in the + * INSN_READ handler. */ + + /* Enable ADC interrupt */ + outw(ISR_ADC_DONE, ADDR_REG(REG_IER)); + a4l_dbg(1, drv_dbg, dev, + "s526_ai_insn_config: ADC current value: 0x%04x\n", + inw(ADDR_REG(REG_ADC))); + + subdpriv->config = (data[0] & 0x3FF) << 5; + if (data[1] > 0) + subdpriv->config |= 0x8000; /* set the delay */ + + subdpriv->config |= 0x0001; /* ADC start bit. */ + + return 0; +} + +static int s526_ai_rinsn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_ai_priv *subdpriv = + (struct s526_subd_ai_priv *)subd->priv; + uint16_t *data = (uint16_t *)insn->data; + int n, i; + int chan = CR_CHAN(insn->chan_desc); + uint16_t value; + uint16_t d; + uint16_t status; + + /* Set configured delay, enable channel for this channel only, + * select "ADC read" channel, set "ADC start" bit. */ + value = (subdpriv->config & 0x8000) | + ((1 << 5) << chan) | (chan << 1) | 0x0001; + + /* convert n samples */ + for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) { + /* trigger conversion */ + outw(value, ADDR_REG(REG_ADC)); + a4l_dbg(1, drv_dbg, dev, "s526_ai_rinsn: Wrote 0x%04x to ADC\n", + value); + + /* wait for conversion to end */ + for (i = 0; i < S526_AI_TIMEOUT; i++) { + status = inw(ADDR_REG(REG_ISR)); + if (status & ISR_ADC_DONE) { + outw(ISR_ADC_DONE, ADDR_REG(REG_ISR)); + break; + } + } + if (i == S526_AI_TIMEOUT) { + a4l_warn(dev, "s526_ai_rinsn: ADC(0x%04x) timeout\n", + inw(ADDR_REG(REG_ISR))); + return -ETIMEDOUT; + } + + /* read data */ + d = inw(ADDR_REG(REG_ADD)); + a4l_dbg(1, drv_dbg, dev, "s526_ai_rinsn: AI[%d]=0x%04x\n", + n, (uint16_t)(d & 0xFFFF)); + + /* munge data */ + data[n] = d ^ 0x8000; + } + + return 0; +} + +static int s526_ao_winsn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_ao_priv *subdpriv = + (struct s526_subd_ao_priv *)subd->priv; + uint16_t *data = (uint16_t *)insn->data; + int i; + int chan = CR_CHAN(insn->chan_desc); + uint16_t val; + + val = chan << 1; + outw(val, ADDR_REG(REG_DAC)); + + for (i = 0; i < insn->data_size / sizeof(uint16_t); i++) { + outw(data[i], ADDR_REG(REG_ADD)); /* write the data to preload register */ + subdpriv->readback[chan] = data[i]; + outw(val + 1, ADDR_REG(REG_DAC)); /* starts the D/A conversion. */ + } + + return 0; +} + +static int s526_ao_rinsn(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct s526_subd_ao_priv *subdpriv = + (struct s526_subd_ao_priv *)subd->priv; + uint16_t *data = (uint16_t *)insn->data; + int i; + int chan = CR_CHAN(insn->chan_desc); + + for (i = 0; i < insn->data_size / sizeof(uint16_t); i++) + data[i] = subdpriv->readback[chan]; + + return 0; +} + +static int s526_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_dio_priv *subdpriv = + (struct s526_subd_dio_priv *)subd->priv; + unsigned int *data = (unsigned int *)insn->data; + int chan = CR_CHAN(insn->chan_desc); + int group, mask; + + group = chan >> 2; + mask = 0xF << (group << 2); + + switch (data[0]) { + case A4L_INSN_CONFIG_DIO_OUTPUT: + subdpriv->state |= 1 << (group + 10); /* bit 10/11 set the + * group 1/2's mode */ + subdpriv->io_bits |= mask; + break; + case A4L_INSN_CONFIG_DIO_INPUT: + subdpriv->state &= ~(1 << (group + 10)); /* 1 is output, 0 is + * input. */ + subdpriv->io_bits &= ~mask; + break; + case A4L_INSN_CONFIG_DIO_QUERY: + data[1] = + (subdpriv->io_bits & mask) ? A4L_OUTPUT : A4L_INPUT; + return 0; + default: + return -EINVAL; + } + + outw(subdpriv->state, ADDR_REG(REG_DIO)); + + return 0; +} + +static int s526_dio_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + a4l_dev_t *dev = subd->dev; + struct s526_subd_dio_priv *subdpriv = + (struct s526_subd_dio_priv *)subd->priv; + uint8_t *data = (uint8_t *)insn->data; + + if (insn->data_size != 2 * sizeof(uint8_t)) + return -EINVAL; + + if (data[0]) { + subdpriv->state &= ~(data[0]); + subdpriv->state |= data[0] & data[1]; + + outw(subdpriv->state, ADDR_REG(REG_DIO)); + } + + data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ + + return 0; +} + +/* --- Channels descriptor --- */ + +static a4l_chdesc_t s526_chan_desc_gpct = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = S526_GPCT_CHANS, + .chans = { + {A4L_CHAN_AREF_GROUND, S526_GPCT_BITS}, + }, +}; + +static a4l_chdesc_t s526_chan_desc_ai = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = S526_AI_CHANS, + .chans = { + {A4L_CHAN_AREF_GROUND, S526_AI_BITS}, + }, +}; + +static a4l_chdesc_t s526_chan_desc_ao = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = S526_AO_CHANS, + .chans = { + {A4L_CHAN_AREF_GROUND, S526_AO_BITS}, + }, +}; + +static a4l_chdesc_t s526_chan_desc_dio = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = S526_DIO_CHANS, + .chans = { + {A4L_CHAN_AREF_GROUND, S526_DIO_BITS}, + }, +}; + +/* --- Subdevice initialization functions --- */ + +/* General purpose counter/timer (gpct) */ +static void setup_subd_gpct(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_COUNTER; + subd->chan_desc = &s526_chan_desc_gpct; + subd->insn_read = s526_gpct_rinsn; + subd->insn_config = s526_gpct_insn_config; + subd->insn_write = s526_gpct_winsn; +} + +/* Analog input subdevice */ +static void setup_subd_ai(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_AI; + subd->chan_desc = &s526_chan_desc_ai; + subd->rng_desc = &range_bipolar10; + subd->insn_read = s526_ai_rinsn; + subd->insn_config = s526_ai_insn_config; +} + +/* Analog output subdevice */ +static void setup_subd_ao(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_AO; + subd->chan_desc = &s526_chan_desc_ao; + subd->rng_desc = &range_bipolar10; + subd->insn_write = s526_ao_winsn; + subd->insn_read = s526_ao_rinsn; +} + +/* Digital i/o subdevice */ +static void setup_subd_dio(a4l_subd_t *subd) +{ + subd->flags = A4L_SUBD_DIO; + subd->chan_desc = &s526_chan_desc_dio; + subd->rng_desc = &range_digital; + subd->insn_bits = s526_dio_insn_bits; + subd->insn_config = s526_dio_insn_config; +} + +struct setup_subd { + void (*setup_func) (a4l_subd_t *); + int sizeof_priv; +}; + +static struct setup_subd setup_subds[4] = { + { + .setup_func = setup_subd_gpct, + .sizeof_priv = sizeof(struct s526_subd_gpct_priv), + }, + { + .setup_func = setup_subd_ai, + .sizeof_priv = sizeof(struct s526_subd_ai_priv), + }, + { + .setup_func = setup_subd_ao, + .sizeof_priv = sizeof(struct s526_subd_ao_priv), + }, + { + .setup_func = setup_subd_dio, + .sizeof_priv = sizeof(struct s526_subd_dio_priv), + }, +}; + +static int dev_s526_attach(a4l_dev_t *dev, a4l_lnkdesc_t *arg) +{ + int io_base; + int i; + int err = 0; + + if (arg->opts == NULL || arg->opts_size < sizeof(unsigned long)) { + a4l_warn(dev, + "dev_s526_attach: no attach options specified; " + "using defaults: addr=0x%x\n", + S526_DEFAULT_ADDRESS); + io_base = S526_DEFAULT_ADDRESS; + } else { + io_base = ((unsigned long *)arg->opts)[0]; + } + + if (!request_region(io_base, S526_IOSIZE, "s526")) { + a4l_err(dev, "dev_s526_attach: I/O port conflict\n"); + return -EIO; + } + + /* Allocate the subdevice structures. */ + for (i = 0; i < 4; i++) { + a4l_subd_t *subd = a4l_alloc_subd(setup_subds[i].sizeof_priv, + setup_subds[i].setup_func); + + if (subd == NULL) + return -ENOMEM; + + err = a4l_add_subd(dev, subd); + if (err != i) + return err; + } + + devpriv->io_base = io_base; + + a4l_info(dev, "dev_s526_attach: attached (address = 0x%x)\n", io_base); + + return 0; +} + +static int dev_s526_detach(a4l_dev_t *dev) +{ + int err = 0; + + if (devpriv->io_base != 0) + release_region(devpriv->io_base, S526_IOSIZE); + + return err; +} + +static a4l_drv_t drv_s526 = { + .owner = THIS_MODULE, + .board_name = "analogy_s526", + .attach = dev_s526_attach, + .detach = dev_s526_detach, + .privdata_size = sizeof(s526_priv_t), +}; + +static int __init drv_s526_init(void) +{ + return a4l_register_drv(&drv_s526); +} + +static void __exit drv_s526_cleanup(void) +{ + a4l_unregister_drv(&drv_s526); +} + +MODULE_DESCRIPTION("Analogy driver for Sensoray Model 526 board."); +MODULE_LICENSE("GPL"); + +module_init(drv_s526_init); +module_exit(drv_s526_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/subdevice.c relase/linux-2.6.35.9//drivers/xenomai/analogy/subdevice.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/subdevice.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/subdevice.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,454 @@ +/** + * @file + * Analogy for Linux, subdevice, channel and range related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* --- Common ranges declarations --- */ + +a4l_rngtab_t rng_bipolar10 = { 1, { + RANGE_V(-10, 10), + }}; +a4l_rngdesc_t range_bipolar10 = RNG_GLOBAL(rng_bipolar10); + +a4l_rngtab_t rng_bipolar5 = { 1, { + RANGE_V(-5, 5), + }}; +a4l_rngdesc_t range_bipolar5 = RNG_GLOBAL(rng_bipolar5); + +a4l_rngtab_t rng_unipolar10 = { 1, { + RANGE_V(0, 10), + }}; +a4l_rngdesc_t range_unipolar10 = RNG_GLOBAL(rng_unipolar10); + +a4l_rngtab_t rng_unipolar5 = { 1, { + RANGE_V(0, 5), + }}; +a4l_rngdesc_t range_unipolar5 = RNG_GLOBAL(rng_unipolar5); + +a4l_rngtab_t rng_unknown = { 1, { + RANGE(0, 1), + }}; +a4l_rngdesc_t range_unknown = RNG_GLOBAL(rng_unknown); + +a4l_rngtab_t rng_fake = { 0, { + RANGE(0, 0), + }}; +a4l_rngdesc_t range_fake = RNG_GLOBAL(rng_fake); + +/* --- Basic channel / range management functions --- */ + +a4l_chan_t *a4l_get_chfeat(a4l_subd_t *sb, int idx) +{ + int i = (sb->chan_desc->mode != A4L_CHAN_GLOBAL_CHANDESC) ? idx : 0; + return &(sb->chan_desc->chans[i]); +} + +a4l_rng_t *a4l_get_rngfeat(a4l_subd_t *sb, int chidx, int rngidx) +{ + int i = (sb->rng_desc->mode != A4L_RNG_GLOBAL_RNGDESC) ? chidx : 0; + return &(sb->rng_desc->rngtabs[i]->rngs[rngidx]); +} + +int a4l_check_chanlist(a4l_subd_t *subd, + unsigned char nb_chan, unsigned int *chans) +{ + int i, j; + + if (nb_chan > subd->chan_desc->length) + return -EINVAL; + + for (i = 0; i < nb_chan; i++) { + j = (subd->chan_desc->mode != A4L_CHAN_GLOBAL_CHANDESC) ? i : 0; + + if (CR_CHAN(chans[i]) >= subd->chan_desc->length) { + __a4l_err("a4l_check_chanlist: " + "chan idx out_of range (%u>=%lu)\n", + CR_CHAN(chans[i]), subd->chan_desc->length); + return -EINVAL; + } + if (CR_AREF(chans[i]) != 0 && + (CR_AREF(chans[i]) & subd->chan_desc->chans[j].flags) == 0) + { + __a4l_err("a4l_check_chanlist: " + "bad channel type\n"); + return -EINVAL; + } + } + + if (subd->rng_desc == NULL) + return 0; + + for (i = 0; i < nb_chan; i++) { + j = (subd->rng_desc->mode != A4L_RNG_GLOBAL_RNGDESC) ? i : 0; + + if (CR_RNG(chans[i]) > subd->rng_desc->rngtabs[j]->length) { + __a4l_err("a4l_check_chanlist: " + "rng idx out_of range (%u>=%u)\n", + CR_RNG(chans[i]), + subd->rng_desc->rngtabs[j]->length); + return -EINVAL; + } + } + + return 0; +} + +/* --- Upper layer functions --- */ + +a4l_subd_t * a4l_alloc_subd(int sizeof_priv, + void (*setup)(a4l_subd_t *)) +{ + a4l_subd_t *subd; + + subd = rtdm_malloc(sizeof(a4l_subd_t) + sizeof_priv); + + if(subd != NULL) { + memset(subd, 0 , sizeof(a4l_subd_t) + sizeof_priv); + if(setup != NULL) + setup(subd); + } + + return subd; +} + +int a4l_add_subd(a4l_dev_t * dev, a4l_subd_t * subd) +{ + struct list_head *this; + int i = 0; + + /* Basic checking */ + if (dev == NULL || subd == NULL) + return -EINVAL; + + list_add_tail(&subd->list, &dev->subdvsq); + + subd->dev = dev; + + list_for_each(this, &dev->subdvsq) { + i++; + } + + subd->idx = --i; + + return i; +} + +a4l_subd_t *a4l_get_subd(a4l_dev_t *dev, int idx) +{ + int i = 0; + a4l_subd_t *subd = NULL; + struct list_head *this; + + /* This function is not optimized as we do not go through the + transfer structure */ + + list_for_each(this, &dev->subdvsq) { + if(idx == i++) + subd = list_entry(this, a4l_subd_t, list); + } + + return subd; +} + +/* --- IOCTL / FOPS functions --- */ + +int a4l_ioctl_subdinfo(a4l_cxt_t * cxt, void *arg) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + int i, ret = 0; + a4l_sbinfo_t *subd_info; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_subdinfo: unattached device\n"); + return -EINVAL; + } + + subd_info = rtdm_malloc(dev->transfer.nb_subd * + sizeof(a4l_sbinfo_t)); + if (subd_info == NULL) + return -ENOMEM; + + for (i = 0; i < dev->transfer.nb_subd; i++) { + subd_info[i].flags = dev->transfer.subds[i]->flags; + subd_info[i].status = dev->transfer.subds[i]->status; + subd_info[i].nb_chan = + (dev->transfer.subds[i]->chan_desc != NULL) ? + dev->transfer.subds[i]->chan_desc->length : 0; + } + + if (rtdm_safe_copy_to_user(cxt->user_info, + arg, + subd_info, dev->transfer.nb_subd * + sizeof(a4l_sbinfo_t)) != 0) + ret = -EFAULT; + + rtdm_free(subd_info); + + return ret; + +} + +int a4l_ioctl_nbchaninfo(a4l_cxt_t * cxt, void *arg) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_chinfo_arg_t inarg; + + /* Basic checking */ + if (!dev->flags & A4L_DEV_ATTACHED_NR) { + __a4l_err("a4l_ioctl_nbchaninfo: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &inarg, arg, + sizeof(a4l_chinfo_arg_t)) != 0) + return -EFAULT; + + if (inarg.idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_ioctl_nbchaninfo: subdevice index " + "out of range\n"); + return -EINVAL; + } + + if(dev->transfer.subds[inarg.idx_subd]->chan_desc == NULL) + inarg.info = (void *)0; + else + inarg.info = (void *)(unsigned long) + dev->transfer.subds[inarg.idx_subd]->chan_desc->length; + + if (rtdm_safe_copy_to_user(cxt->user_info, + arg, + &inarg, sizeof(a4l_chinfo_arg_t)) != 0) + return -EFAULT; + + return 0; +} + +int a4l_ioctl_chaninfo(a4l_cxt_t * cxt, void *arg) +{ + int i, ret = 0; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_chinfo_t *chan_info; + a4l_chinfo_arg_t inarg; + a4l_chdesc_t *chan_desc; + a4l_rngdesc_t *rng_desc; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_chaninfo: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &inarg, arg, + sizeof(a4l_chinfo_arg_t)) != 0) + return -EFAULT; + + if (inarg.idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_ioctl_chaninfo: bad subdevice index\n"); + return -EINVAL; + } + + chan_desc = dev->transfer.subds[inarg.idx_subd]->chan_desc; + rng_desc = dev->transfer.subds[inarg.idx_subd]->rng_desc; + + if (chan_desc == NULL) { + __a4l_err("a4l_ioctl_chaninfo: no channel descriptor " + "for subdevice %d\n", inarg.idx_subd); + return -EINVAL; + } + + if(rng_desc == NULL) + rng_desc = &range_fake; + + chan_info = rtdm_malloc(chan_desc->length * sizeof(a4l_chinfo_t)); + if (chan_info == NULL) + return -ENOMEM; + + /* If the channel descriptor is global, the fields are filled + with the same instance of channel descriptor */ + for (i = 0; i < chan_desc->length; i++) { + int j = + (chan_desc->mode != A4L_CHAN_GLOBAL_CHANDESC) ? i : 0; + int k = (rng_desc->mode != A4L_RNG_GLOBAL_RNGDESC) ? i : 0; + + chan_info[i].chan_flags = chan_desc->chans[j].flags; + chan_info[i].nb_bits = chan_desc->chans[j].nb_bits; + chan_info[i].nb_rng = rng_desc->rngtabs[k]->length; + + if (chan_desc->mode == A4L_CHAN_GLOBAL_CHANDESC) + chan_info[i].chan_flags |= A4L_CHAN_GLOBAL; + } + + if (rtdm_safe_copy_to_user(cxt->user_info, + inarg.info, + chan_info, + chan_desc->length * + sizeof(a4l_chinfo_t)) != 0) + return -EFAULT; + + rtdm_free(chan_info); + + return ret; +} + +int a4l_ioctl_nbrnginfo(a4l_cxt_t * cxt, void *arg) +{ + int i; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_rnginfo_arg_t inarg; + a4l_rngdesc_t *rng_desc; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_nbrnginfo: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &inarg, + arg, sizeof(a4l_rnginfo_arg_t)) != 0) + return -EFAULT; + + if (inarg.idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_ioctl_nbrnginfo: bad subdevice index\n"); + return -EINVAL; + } + + if (dev->transfer.subds[inarg.idx_subd]->chan_desc == NULL) { + __a4l_err("a4l_ioctl_nbrnginfo: no channel descriptor " + "for subdevice %d\n", inarg.idx_subd); + return -EINVAL; + } + + if (inarg.idx_chan >= + dev->transfer.subds[inarg.idx_subd]->chan_desc->length) { + __a4l_err("a4l_ioctl_nbrnginfo: bad channel index\n"); + return -EINVAL; + } + + rng_desc = dev->transfer.subds[inarg.idx_subd]->rng_desc; + if (rng_desc != NULL) { + i = (rng_desc->mode != A4L_RNG_GLOBAL_RNGDESC) ? + inarg.idx_chan : 0; + inarg.info = (void *)(unsigned long) + rng_desc->rngtabs[i]->length; + } else + inarg.info = (void *)0; + + + if (rtdm_safe_copy_to_user(cxt->user_info, + arg, + &inarg, sizeof(a4l_rnginfo_arg_t)) != 0) + return -EFAULT; + + return 0; +} + +int a4l_ioctl_rnginfo(a4l_cxt_t * cxt, void *arg) +{ + int i, ret = 0; + unsigned int tmp; + a4l_dev_t *dev = a4l_get_dev(cxt); + a4l_rngdesc_t *rng_desc; + a4l_rnginfo_t *rng_info; + a4l_rnginfo_arg_t inarg; + + /* Basic checking */ + if (!test_bit(A4L_DEV_ATTACHED_NR, &dev->flags)) { + __a4l_err("a4l_ioctl_rnginfo: unattached device\n"); + return -EINVAL; + } + + if (rtdm_safe_copy_from_user(cxt->user_info, + &inarg, + arg, sizeof(a4l_rnginfo_arg_t)) != 0) + return -EFAULT; + + if (inarg.idx_subd >= dev->transfer.nb_subd) { + __a4l_err("a4l_ioctl_rnginfo: bad subdevice index\n"); + return -EINVAL; + } + + if (dev->transfer.subds[inarg.idx_subd]->chan_desc == NULL) { + __a4l_err("a4l_ioctl_rnginfo: no channel descriptor " + "for subdevice %d\n", inarg.idx_subd); + return -EINVAL; + } + + if (inarg.idx_chan >= + dev->transfer.subds[inarg.idx_subd]->chan_desc->length) { + __a4l_err("a4l_ioctl_rnginfo: bad channel index\n"); + return -EINVAL; + } + + rng_desc = dev->transfer.subds[inarg.idx_subd]->rng_desc; + if (rng_desc == NULL) { + __a4l_err("a4l_ioctl_rnginfo: no range descriptor " + "for channel %d\n", inarg.idx_chan); + return -EINVAL; + } + + /* If the range descriptor is global, + we take the first instance */ + tmp = (rng_desc->mode != A4L_RNG_GLOBAL_RNGDESC) ? + inarg.idx_chan : 0; + + rng_info = rtdm_malloc(rng_desc->rngtabs[tmp]->length * + sizeof(a4l_rnginfo_t)); + if (rng_info == NULL) + return -ENOMEM; + + for (i = 0; i < rng_desc->rngtabs[tmp]->length; i++) { + rng_info[i].min = rng_desc->rngtabs[tmp]->rngs[i].min; + rng_info[i].max = rng_desc->rngtabs[tmp]->rngs[i].max; + rng_info[i].flags = rng_desc->rngtabs[tmp]->rngs[i].flags; + + if (rng_desc->mode == A4L_RNG_GLOBAL_RNGDESC) + rng_info[i].flags |= A4L_RNG_GLOBAL; + } + + if (rtdm_safe_copy_to_user(cxt->user_info, + inarg.info, + rng_info, + rng_desc->rngtabs[tmp]->length * + sizeof(a4l_rnginfo_t)) != 0) + return -EFAULT; + + rtdm_free(rng_info); + + return ret; +} + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/fake.c relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/fake.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/fake.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/fake.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,375 @@ +#include +#include + +#define AI_TASK_PERIOD 1000000 + +#define AI_SUBD 0 +#define DIO_SUBD 1 + +/* --- Driver related structures --- */ + +struct fake_priv { + /* Configuration parameters */ + unsigned long amplitude_div; + unsigned long quanta_cnt; +}; + +struct ai_priv { + + /* Task descriptor */ + a4l_task_t timer_task; + + /* Specific timing fields */ + unsigned long scan_period_ns; + unsigned long convert_period_ns; + unsigned long current_ns; + unsigned long reminder_ns; + unsigned long long last_ns; + + /* Misc fields */ + unsigned long amplitude_div; + unsigned long quanta_cnt; + int timer_running; + +}; + +struct dio_priv { + /* Bits status */ + uint16_t bits_values; +}; + +/* --- Channels / ranges part --- */ + +/* Channels descriptor */ +static a4l_chdesc_t ai_chandesc = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 8, + .chans = { + {A4L_CHAN_AREF_GROUND, 16}, + }, +}; + +static a4l_chdesc_t dio_chandesc = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 16, + .chans = { + {A4L_CHAN_AREF_GROUND, 1}, + }, +}; + +/* Ranges tab */ +static a4l_rngtab_t ai_rngtab = { + .length = 2, + .rngs = { + RANGE_V(-5,5), + RANGE_V(-10,10), + }, +}; +/* Ranges descriptor */ +static a4l_rngdesc_t ai_rngdesc = RNG_GLOBAL(ai_rngtab); + +/* Command options mask */ +static a4l_cmd_t test_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_NOW, + .scan_begin_src = TRIG_TIMER, + .convert_src = TRIG_NOW|TRIG_TIMER, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_COUNT|TRIG_NONE, +}; + +/* --- Analog input simulation --- */ + +static uint16_t ai_value_output(struct ai_priv *priv) +{ + static uint16_t output_tab[8] = { + 0x0001, 0x2000, 0x4000, 0x6000, + 0x8000, 0xa000, 0xc000, 0xffff + }; + static unsigned int output_idx; + static a4l_lock_t output_lock = A4L_LOCK_UNLOCKED; + + unsigned long flags; + unsigned int idx; + + a4l_lock_irqsave(&output_lock, flags); + + output_idx += priv->quanta_cnt; + if(output_idx == 8) + output_idx = 0; + idx = output_idx; + + a4l_unlock_irqrestore(&output_lock, flags); + + return output_tab[idx] / priv->amplitude_div; +} + +/* --- Task part --- */ + +/* Timer task routine */ +static void ai_task_proc(void *arg) +{ + a4l_subd_t *subd = (a4l_subd_t *)arg; + struct ai_priv *priv = (struct ai_priv *)subd->priv; + a4l_cmd_t *cmd = NULL; + uint64_t now_ns, elapsed_ns=0; + + while(1) { + int running; + + RTDM_EXECUTE_ATOMICALLY(running = priv->timer_running); + + if(running) + { + int i = 0; + + cmd = a4l_get_cmd(subd); + + now_ns = a4l_get_time(); + elapsed_ns += now_ns - priv->last_ns + priv->reminder_ns; + priv->last_ns = now_ns; + + while(elapsed_ns >= priv->scan_period_ns) { + int j; + + for(j = 0; j < cmd->nb_chan; j++) { + uint16_t value = ai_value_output(priv); + a4l_buf_put(subd, &value, sizeof(uint16_t)); + } + + elapsed_ns -= priv->scan_period_ns; + i++; + + } + + priv->current_ns += i * priv->scan_period_ns; + priv->reminder_ns = elapsed_ns; + + if (i != 0) + a4l_buf_evt(subd, 0); + } + + a4l_task_sleep(AI_TASK_PERIOD); + } +} + +/* --- Asynchronous AI functions --- */ + +static int ai_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + struct ai_priv *priv = (struct ai_priv *)subd->priv; + + priv->scan_period_ns = cmd->scan_begin_arg; + priv->convert_period_ns = (cmd->convert_src==TRIG_TIMER)? + cmd->convert_arg:0; + + a4l_dbg(1, drv_dbg, subd->dev, + "ai_cmd: scan_period=%luns convert_period=%luns\n", + priv->scan_period_ns, priv->convert_period_ns); + + priv->last_ns = a4l_get_time(); + + priv->current_ns = ((unsigned long)priv->last_ns); + priv->reminder_ns = 0; + + RTDM_EXECUTE_ATOMICALLY(priv->timer_running = 1); + + return 0; + +} + +static int ai_cmdtest(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + if(cmd->scan_begin_src == TRIG_TIMER) + { + if (cmd->scan_begin_arg < 1000) + return -EINVAL; + + if (cmd->convert_src == TRIG_TIMER && + cmd->scan_begin_arg < (cmd->convert_arg * cmd->nb_chan)) + return -EINVAL; + } + + return 0; +} + +static int ai_cancel(a4l_subd_t *subd) +{ + struct ai_priv *priv = (struct ai_priv *)subd->priv; + + RTDM_EXECUTE_ATOMICALLY(priv->timer_running = 0); + + return 0; +} + +static void ai_munge(a4l_subd_t *subd, void *buf, unsigned long size) +{ + int i; + + for(i = 0; i < size / sizeof(uint16_t); i++) + ((uint16_t *)buf)[i] += 1; +} + +/* --- Synchronous AI functions --- */ + +static int ai_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct ai_priv *priv = (struct ai_priv *)subd->priv; + uint16_t *data = (uint16_t *)insn->data; + int i; + + for(i = 0; i < insn->data_size / sizeof(uint16_t); i++) + data[i] = ai_value_output(priv); + + return 0; +} + +/* --- Synchronous DIO function --- */ + +static int dio_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + struct dio_priv *priv = (struct dio_priv *)subd->priv; + uint16_t *data = (uint16_t *)insn->data; + + if (insn->data_size != 2 * sizeof(uint16_t)) + return -EINVAL; + + if (data[0] != 0) { + priv->bits_values &= ~(data[0]); + priv->bits_values |= (data[0] & data[1]); + } + + data[1] = priv->bits_values; + + return 0; +} + +/* --- Initialization functions --- */ + +void setup_ai_subd(a4l_subd_t *subd) +{ + /* Fill the subdevice structure */ + subd->flags |= A4L_SUBD_AI; + subd->flags |= A4L_SUBD_CMD; + subd->flags |= A4L_SUBD_MMAP; + subd->rng_desc = &ai_rngdesc; + subd->chan_desc = &ai_chandesc; + subd->do_cmd = ai_cmd; + subd->do_cmdtest = ai_cmdtest; + subd->cancel = ai_cancel; + subd->munge = ai_munge; + subd->cmd_mask = &test_cmd_mask; + subd->insn_read = ai_insn_read; +} + +void setup_dio_subd(a4l_subd_t *subd) +{ + /* Fill the subdevice structure */ + subd->flags |= A4L_SUBD_DIO; + subd->chan_desc = &dio_chandesc; + subd->rng_desc = &range_digital; + subd->insn_bits = dio_insn_bits; +} + +/* --- Attach / detach functions --- */ + +int test_attach(a4l_dev_t *dev, a4l_lnkdesc_t *arg) +{ + int ret = 0; + a4l_subd_t *subd; + struct fake_priv *priv = (struct fake_priv *)dev->priv; + struct ai_priv * ai_priv; + + a4l_dbg(1, drv_dbg, dev, "starting attach procedure...\n"); + + if (arg->opts_size < sizeof(unsigned long)) { + priv->amplitude_div = 1; + priv->quanta_cnt = 1; + } else { + unsigned long *args = (unsigned long *)arg->opts; + priv->amplitude_div = args[0]; + + if (arg->opts_size == 2 * sizeof(unsigned long)) + priv->quanta_cnt = (args[1] > 7 || args[1] == 0) ? + 1 : args[1]; + } + + a4l_dbg(1, drv_dbg, dev, + "amplitude divisor = %lu\n", priv->amplitude_div); + a4l_dbg(1, drv_dbg, dev, + "quanta count = %lu\n", priv->quanta_cnt); + + /* Add the AI subdevice to the device */ + subd = a4l_alloc_subd(sizeof(struct ai_priv), setup_ai_subd); + if(subd == NULL) + return -ENOMEM; + + ai_priv = (struct ai_priv*)subd->priv; + ai_priv->timer_running = 0; + ai_priv->amplitude_div = priv->amplitude_div; + ai_priv->quanta_cnt = priv->quanta_cnt; + + ret = a4l_task_init(&ai_priv->timer_task, + "Fake AI task", + ai_task_proc, + subd, A4L_TASK_HIGHEST_PRIORITY); + + ret = a4l_add_subd(dev, subd); + if(ret != AI_SUBD) + return (ret < 0) ? ret : -EINVAL; + + a4l_dbg(1, drv_dbg, dev, "AI subdevice registered\n"); + + /* Add the DIO subdevice to the device */ + subd = a4l_alloc_subd(sizeof(struct dio_priv), setup_dio_subd); + if(subd == NULL) + return -ENOMEM; + + ret = a4l_add_subd(dev, subd); + if(ret != DIO_SUBD) + return (ret < 0) ? ret : -EINVAL; + + a4l_dbg(1, drv_dbg, dev, "DIO subdevice registered\n"); + + a4l_dbg(1, drv_dbg, dev, "attach procedure complete\n"); + + return 0; +} + +int test_detach(a4l_dev_t *dev) +{ + a4l_subd_t *subd = a4l_get_subd(dev, AI_SUBD); + struct ai_priv *priv = (struct ai_priv *)subd->priv; + + a4l_task_destroy(&priv->timer_task); + + a4l_dbg(1, drv_dbg, dev, "detach procedure complete\n"); + + return 0; +} + +/* --- Module stuff --- */ + +static a4l_drv_t test_drv = { + .owner = THIS_MODULE, + .board_name = "analogy_fake", + .attach = test_attach, + .detach = test_detach, + .privdata_size = sizeof(struct fake_priv), +}; + +static int __init a4l_fake_init(void) +{ + return a4l_register_drv(&test_drv); +} + +static void __exit a4l_fake_cleanup(void) +{ + a4l_unregister_drv(&test_drv); +} + +MODULE_DESCRIPTION("Analogy fake driver"); +MODULE_LICENSE("GPL"); + +module_init(a4l_fake_init); +module_exit(a4l_fake_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/Kconfig relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,10 @@ + +config XENO_DRIVERS_ANALOGY_FAKE + depends on XENO_DRIVERS_ANALOGY + tristate "Fake driver" + default n + +config XENO_DRIVERS_ANALOGY_LOOP + depends on XENO_DRIVERS_ANALOGY + tristate "Loop driver" + default n diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/loop.c relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/loop.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/loop.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/loop.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,287 @@ +#include +#include + +#define LOOP_TASK_PERIOD 1000000 +#define LOOP_NB_BITS 16 + +#define LOOP_INPUT_SUBD 0 +#define LOOP_OUTPUT_SUBD 1 + +/* Channels descriptor */ +static a4l_chdesc_t loop_chandesc = { + .mode = A4L_CHAN_GLOBAL_CHANDESC, + .length = 8, + .chans = { + {A4L_CHAN_AREF_GROUND, LOOP_NB_BITS}, + }, +}; + +/* Ranges tab */ +static a4l_rngtab_t loop_rngtab = { + .length = 2, + .rngs = { + RANGE_V(-5,5), + RANGE_V(-10,10), + }, +}; +/* Ranges descriptor */ +a4l_rngdesc_t loop_rngdesc = RNG_GLOBAL(loop_rngtab); + +/* Command options mask */ +static a4l_cmd_t loop_cmd_mask = { + .idx_subd = 0, + .start_src = TRIG_NOW | TRIG_INT, + .scan_begin_src = TRIG_TIMER, + .convert_src = TRIG_NOW | TRIG_TIMER, + .scan_end_src = TRIG_COUNT, + .stop_src = TRIG_COUNT| TRIG_NONE, +}; + +/* Private data organization */ +struct loop_priv { + + /* Task descriptor */ + a4l_task_t loop_task; + + /* Misc fields */ + int loop_running; + uint16_t loop_insn_value; +}; +typedef struct loop_priv lpprv_t; + +/* Attach arguments contents */ +struct loop_attach_arg { + unsigned long period; +}; +typedef struct loop_attach_arg lpattr_t; + +static void loop_task_proc(void *arg); + +/* --- Task part --- */ + +/* Timer task routine */ +static void loop_task_proc(void *arg) +{ + a4l_dev_t *dev = (a4l_dev_t*)arg; + a4l_subd_t *input_subd, *output_subd; + lpprv_t *priv = (lpprv_t *)dev->priv; + + input_subd = a4l_get_subd(dev, LOOP_INPUT_SUBD); + output_subd = a4l_get_subd(dev, LOOP_OUTPUT_SUBD); + + if (input_subd == NULL || output_subd == NULL) { + a4l_err(dev, "loop_task_proc: subdevices unavailable\n"); + return; + } + + while (1) { + + int running; + + RTDM_EXECUTE_ATOMICALLY(running = priv->loop_running); + + if (running) { + uint16_t value; + int ret=0; + + while (ret==0) { + + ret = a4l_buf_get(output_subd, + &value, sizeof(uint16_t)); + if (ret == 0) { + + a4l_info(dev, + "loop_task_proc: " + "data available\n"); + + a4l_buf_evt(output_subd, 0); + + ret = a4l_buf_put(input_subd, + &value, + sizeof(uint16_t)); + + if (ret==0) + a4l_buf_evt(input_subd, 0); + } + } + } + + a4l_task_sleep(LOOP_TASK_PERIOD); + } +} + +/* --- Analogy Callbacks --- */ + +/* Command callback */ +int loop_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd) +{ + a4l_info(subd->dev, "loop_cmd: (subd=%d)\n", subd->idx); + + return 0; + +} + +/* Trigger callback */ +int loop_trigger(a4l_subd_t *subd, lsampl_t trignum) +{ + lpprv_t *priv = (lpprv_t *)subd->dev->priv; + + a4l_info(subd->dev, "loop_trigger: (subd=%d)\n", subd->idx); + + RTDM_EXECUTE_ATOMICALLY(priv->loop_running = 1); + + return 0; +} + +/* Cancel callback */ +int loop_cancel(a4l_subd_t *subd) +{ + lpprv_t *priv = (lpprv_t *)subd->dev->priv; + + a4l_info(subd->dev, "loop_cancel: (subd=%d)\n", subd->idx); + + RTDM_EXECUTE_ATOMICALLY(priv->loop_running = 0); + + return 0; +} + +/* Read instruction callback */ +int loop_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + lpprv_t *priv = (lpprv_t*)subd->dev->priv; + uint16_t *data = (uint16_t *)insn->data; + + /* Checks the buffer size */ + if (insn->data_size != sizeof(uint16_t)) + return -EINVAL; + + /* Sets the memorized value */ + data[0] = priv->loop_insn_value; + + return 0; +} + +/* Write instruction callback */ +int loop_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn) +{ + lpprv_t *priv = (lpprv_t*)subd->dev->priv; + uint16_t *data = (uint16_t *)insn->data; + + /* Checks the buffer size */ + if (insn->data_size != sizeof(uint16_t)) + return -EINVAL; + + /* Retrieves the value to memorize */ + priv->loop_insn_value = data[0]; + + return 0; +} + +void setup_input_subd(a4l_subd_t *subd) +{ + memset(subd, 0, sizeof(a4l_subd_t)); + + subd->flags |= A4L_SUBD_AI; + subd->flags |= A4L_SUBD_CMD; + subd->flags |= A4L_SUBD_MMAP; + subd->rng_desc = &loop_rngdesc; + subd->chan_desc = &loop_chandesc; + subd->do_cmd = loop_cmd; + subd->cancel = loop_cancel; + subd->cmd_mask = &loop_cmd_mask; + subd->insn_read = loop_insn_read; + subd->insn_write = loop_insn_write; +} + +void setup_output_subd(a4l_subd_t *subd) +{ + memset(subd, 0, sizeof(a4l_subd_t)); + + subd->flags = A4L_SUBD_AO; + subd->flags |= A4L_SUBD_CMD; + subd->flags |= A4L_SUBD_MMAP; + subd->rng_desc = &loop_rngdesc; + subd->chan_desc = &loop_chandesc; + subd->do_cmd = loop_cmd; + subd->cancel = loop_cancel; + subd->trigger = loop_trigger; + subd->cmd_mask = &loop_cmd_mask; + subd->insn_read = loop_insn_read; + subd->insn_write = loop_insn_write; +} + +/* Attach callback */ +int loop_attach(a4l_dev_t *dev, + a4l_lnkdesc_t *arg) +{ + int ret = 0; + a4l_subd_t *subd; + lpprv_t *priv = (lpprv_t *)dev->priv; + + /* Add the fake input subdevice */ + subd = a4l_alloc_subd(0, setup_input_subd); + if (subd == NULL) + return -ENOMEM; + + ret = a4l_add_subd(dev, subd); + if (ret != LOOP_INPUT_SUBD) + /* Let Analogy free the lately allocated subdevice */ + return (ret < 0) ? ret : -EINVAL; + + /* Add the fake output subdevice */ + subd = a4l_alloc_subd(0, setup_output_subd); + if (subd == NULL) + /* Let Analogy free the lately allocated subdevice */ + return -ENOMEM; + + ret = a4l_add_subd(dev, subd); + if (ret != LOOP_OUTPUT_SUBD) + /* Let Analogy free the lately allocated subdevices */ + return (ret < 0) ? ret : -EINVAL; + + priv->loop_running = 0; + priv->loop_insn_value = 0; + + ret = a4l_task_init(&priv->loop_task, + "a4l_loop task", + loop_task_proc, + dev, A4L_TASK_HIGHEST_PRIORITY); + + return ret; +} + +/* Detach callback */ +int loop_detach(a4l_dev_t *dev) +{ + lpprv_t *priv = (lpprv_t *)dev->priv; + + a4l_task_destroy(&priv->loop_task); + + return 0; +} + +/* --- Module part --- */ + +static a4l_drv_t loop_drv = { + .owner = THIS_MODULE, + .board_name = "analogy_loop", + .attach = loop_attach, + .detach = loop_detach, + .privdata_size = sizeof(lpprv_t), +}; + +static int __init a4l_loop_init(void) +{ + return a4l_register_drv(&loop_drv); +} + +static void __exit a4l_loop_cleanup(void) +{ + a4l_unregister_drv(&loop_drv); +} + +MODULE_DESCRIPTION("Analogy loop driver"); +MODULE_LICENSE("GPL"); + +module_init(a4l_loop_init); +module_exit(a4l_loop_cleanup); diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/Makefile relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/analogy/testing/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/testing/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,39 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_FAKE) += analogy_fake.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_LOOP) += analogy_loop.o + +analogy_fake-y := fake.o + +analogy_loop-y := loop.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_FAKE) += analogy_fake.o +obj-$(CONFIG_XENO_DRIVERS_ANALOGY_LOOP) += analogy_loop.o + +analogy_fake-objs := fake.o + +analogy_loop-objs := loop.o + +export-objs := $(analogy_fake-objs) $(analogy_loop-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +analogy_fake.o: $(analogy_fake-objs) + $(LD) -r -o $@ $(analogy_fake-objs) + +analogy_loop.o: $(analogy_loop-objs) + $(LD) -r -o $@ $(analogy_loop-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/analogy/transfer.c relase/linux-2.6.35.9//drivers/xenomai/analogy/transfer.c --- orig/linux-2.6.35.9//drivers/xenomai/analogy/transfer.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/analogy/transfer.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,296 @@ +/** + * @file + * Analogy for Linux, transfer related features + * + * Copyright (C) 1997-2000 David A. Schleef + * Copyright (C) 2008 Alexis Berlemont + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOXYGEN_CPP + +#include +#include +#include + +#include +#include + +#include "proc.h" + +/* --- Initialization / cleanup / cancel functions --- */ + +int a4l_precleanup_transfer(a4l_cxt_t * cxt) +{ + a4l_dev_t *dev; + a4l_trf_t *tsf; + int i, err = 0; + + dev = a4l_get_dev(cxt); + tsf = &dev->transfer; + + if (tsf == NULL) { + __a4l_err("a4l_precleanup_transfer: " + "incoherent status, transfer block not reachable\n"); + return -ENODEV; + } + + for (i = 0; i < tsf->nb_subd; i++) { + unsigned long *status = &tsf->subds[i]->status; + + __a4l_dbg(1, core_dbg, + "a4l_precleanup_transfer: " + "subd[%d]->status=0x%08lx\n", i, *status); + + if (test_and_set_bit(A4L_SUBD_BUSY, status)) { + __a4l_err("a4l_precleanup_transfer: " + "device busy, acquisition occuring\n"); + err = -EBUSY; + goto out_error; + } else + set_bit(A4L_SUBD_CLEAN, status); + } + + return 0; + +out_error: + for (i = 0; i < tsf->nb_subd; i++) { + unsigned long *status = &tsf->subds[i]->status; + + if (test_bit(A4L_SUBD_CLEAN, status)){ + clear_bit(A4L_SUBD_BUSY, status); + clear_bit(A4L_SUBD_CLEAN, status); + } + } + + return err; +} + +int a4l_cleanup_transfer(a4l_cxt_t * cxt) +{ + a4l_dev_t *dev; + a4l_trf_t *tsf; + + dev = a4l_get_dev(cxt); + tsf = &dev->transfer; + + /* Releases the pointers tab, if need be */ + if (tsf->subds != NULL) { + rtdm_free(tsf->subds); + } + + memset(tsf, 0, sizeof(a4l_trf_t)); + + return 0; +} + +void a4l_presetup_transfer(a4l_cxt_t *cxt) +{ + a4l_dev_t *dev = NULL; + a4l_trf_t *tsf; + + dev = a4l_get_dev(cxt); + tsf = &dev->transfer; + + /* Clear the structure */ + memset(tsf, 0, sizeof(a4l_trf_t)); + + tsf->default_bufsize = A4L_BUF_DEFSIZE; + + /* 0 is also considered as a valid IRQ, then + the IRQ number must be initialized with another value */ + tsf->irq_desc.irq = A4L_IRQ_UNUSED; +} + +int a4l_setup_transfer(a4l_cxt_t * cxt) +{ + a4l_dev_t *dev = NULL; + a4l_trf_t *tsf; + struct list_head *this; + int i = 0, ret = 0; + + dev = a4l_get_dev(cxt); + tsf = &dev->transfer; + + /* Recovers the subdevices count + (as they are registered in a linked list */ + list_for_each(this, &dev->subdvsq) { + tsf->nb_subd++; + } + + __a4l_dbg(1, core_dbg, + "a4l_setup_transfer: nb_subd=%d\n", tsf->nb_subd); + + /* Allocates a suitable tab for the subdevices */ + tsf->subds = rtdm_malloc(tsf->nb_subd * sizeof(a4l_subd_t *)); + if (tsf->subds == NULL) { + __a4l_err("a4l_setup_transfer: call1(alloc) failed \n"); + ret = -ENOMEM; + goto out_setup_tsf; + } + + /* Recovers the subdevices pointers */ + list_for_each(this, &dev->subdvsq) { + tsf->subds[i++] = list_entry(this, a4l_subd_t, list); + } + +out_setup_tsf: + + if (ret != 0) + a4l_cleanup_transfer(cxt); + + return ret; +} + +/* --- IRQ handling section --- */ + +int a4l_request_irq(a4l_dev_t * dev, + unsigned int irq, + a4l_irq_hdlr_t handler, + unsigned long flags, void *cookie) +{ + int ret; + unsigned long __flags; + + if (dev->transfer.irq_desc.irq != A4L_IRQ_UNUSED) + return -EBUSY; + + /* A spinlock is used so as to prevent race conditions + on the field "irq" of the IRQ descriptor + (even if such a case is bound not to happen) */ + a4l_lock_irqsave(&dev->lock, __flags); + + ret = __a4l_request_irq(&dev->transfer.irq_desc, + irq, handler, flags, cookie); + + if (ret != 0) { + __a4l_err("a4l_request_irq: IRQ registration failed\n"); + dev->transfer.irq_desc.irq = A4L_IRQ_UNUSED; + } + + a4l_unlock_irqrestore(&dev->lock, __flags); + + return ret; +} + +int a4l_free_irq(a4l_dev_t * dev, unsigned int irq) +{ + + int ret = 0; + + if (dev->transfer.irq_desc.irq != irq) + return -EINVAL; + + /* There is less need to use a spinlock + than for a4l_request_irq() */ + ret = __a4l_free_irq(&dev->transfer.irq_desc); + + if (ret == 0) + dev->transfer.irq_desc.irq = A4L_IRQ_UNUSED; + + return 0; +} + +unsigned int a4l_get_irq(a4l_dev_t * dev) +{ + return dev->transfer.irq_desc.irq; +} + +/* --- Proc section --- */ + +#ifdef CONFIG_PROC_FS + +int a4l_rdproc_transfer(char *page, + char **start, + off_t off, int count, int *eof, void *data) +{ + int i, len = 0; + char *p = page; + a4l_trf_t *transfer = (a4l_trf_t *) data; + + p += sprintf(p, "-- Subdevices --\n\n"); + p += sprintf(p, "| idx | type\n"); + + /* Gives the subdevice type's name */ + for (i = 0; i < transfer->nb_subd; i++) { + char *type; + switch (transfer->subds[i]->flags & A4L_SUBD_TYPES) { + case A4L_SUBD_UNUSED: + type = "Unused subdevice"; + break; + case A4L_SUBD_AI: + type = "Analog input subdevice"; + break; + case A4L_SUBD_AO: + type = "Analog output subdevice"; + break; + case A4L_SUBD_DI: + type = "Digital input subdevice"; + break; + case A4L_SUBD_DO: + type = "Digital output subdevice"; + break; + case A4L_SUBD_DIO: + type = "Digital input/output subdevice"; + break; + case A4L_SUBD_COUNTER: + type = "Counter subdevice"; + break; + case A4L_SUBD_TIMER: + type = "Timer subdevice"; + break; + case A4L_SUBD_MEMORY: + type = "Memory subdevice"; + break; + case A4L_SUBD_CALIB: + type = "Calibration subdevice"; + break; + case A4L_SUBD_PROC: + type = "Processor subdevice"; + break; + case A4L_SUBD_SERIAL: + type = "Serial subdevice"; + break; + default: + type = "Unknown subdevice"; + } + + p += sprintf(p, "| %02d | %s\n", i, type); + } + + /* Handles any proc-file reading way */ + len = p - page - off; + /* If the requested size is greater than we provide, + the read operation is over */ + if (len <= off + count) + *eof = 1; + /* In case the read operation is performed in many steps, + the start pointer must be redefined */ + *start = page + off; + /* If the requested size is lower than we provide, + the read operation will be done in more than one step */ + if (len > count) + len = count; + /* In case the offset is not correct (too high) */ + if (len < 0) + len = 0; + + return len; +} + +#endif /* CONFIG_PROC_FS */ + +#endif /* !DOXYGEN_CPP */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/Kconfig relase/linux-2.6.35.9//drivers/xenomai/can/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/can/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,76 @@ +menu "CAN drivers" + +config XENO_DRIVERS_CAN + depends on XENO_SKIN_RTDM + tristate "RT-Socket-CAN, CAN raw socket interface" + help + RT-Socket-CAN is a real-time socket interface for CAN controllers. + +config XENO_DRIVERS_CAN_DEBUG + depends on XENO_DRIVERS_CAN + bool "Enable debug output" + default y + help + + This option activates debugging checks and enhanced output for the + RT-Socket-CAN driver. It also allows to list the hardware registers + of the registered CAN controllers. It is a recommended option for + getting started and analysing potential problems. For production + purposes, it should be switched off (for the sake of latency). + +config XENO_DRIVERS_CAN_LOOPBACK + depends on XENO_DRIVERS_CAN + bool "Enable TX loopback to local sockets" + default n + help + + This options adds support for TX loopback to local sockets. Normally, + messages sent to the CAN bus are not visible to sockets listening to + the same local device. When this option is enabled, TX messages are + looped back locally when the transmit has been done by default. This + behaviour can be deactivated or reactivated with "setsockopt". Enable + this option, if you want to have a "net-alike" behaviour. + +config XENO_DRIVERS_CAN_RXBUF_SIZE + depends on XENO_DRIVERS_CAN + int "Size of receive ring buffers (must be 2^N)" + default 1024 + +config XENO_DRIVERS_CAN_MAX_DEVICES + depends on XENO_DRIVERS_CAN + int "Maximum number of devices" + default 4 + +config XENO_DRIVERS_CAN_MAX_RECEIVERS + depends on XENO_DRIVERS_CAN + int "Maximum number of receive filters per device" + default 16 + help + + The driver maintains a receive filter list per device for fast access. + +config XENO_DRIVERS_CAN_BUS_ERR + depends on XENO_DRIVERS_CAN + bool + default n + help + + To avoid unnecessary bus error interrupt flooding, this option enables + bus error interrupts when an application is calling a receive function + on a socket listening on bus errors. After one bus error has occured, + the interrupt will be disabled to allow the application time for error + processing. This option is automatically selected for CAN controllers + supporting bus error interrupts like the SJA1000. + +config XENO_DRIVERS_CAN_VIRT + depends on XENO_DRIVERS_CAN + tristate "Virtual CAN bus driver" + help + + This driver provides two CAN ports that are virtually interconnected. + More ports can be enabled with the module parameter "devices". + +source drivers/xenomai/can/mscan/Kconfig +source drivers/xenomai/can/sja1000/Kconfig + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/Makefile relase/linux-2.6.35.9//drivers/xenomai/can/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/can/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,44 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can + +obj-$(CONFIG_XENO_DRIVERS_CAN) += xeno_can.o mscan/ sja1000/ +obj-$(CONFIG_XENO_DRIVERS_CAN_VIRT) += xeno_can_virt.o + +xeno_can-y := rtcan_dev.o rtcan_socket.o rtcan_module.o rtcan_raw.o rtcan_raw_dev.o rtcan_raw_filter.o +xeno_can_virt-y := rtcan_virt.o + +else + +# Makefile frag for Linux v2.4 + +mod-subdirs := mscan sja1000 + +subdir-$(CONFIG_XENO_DRIVERS_CAN_MSCAN) += mscan +subdir-$(CONFIG_XENO_DRIVERS_CAN_SJA1000) += sja1000 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_CAN) += xeno_can.o +obj-$(CONFIG_XENO_DRIVERS_CAN_VIRT) += xeno_can_virt.o + +list-multi := xeno_can.o + +xeno_can-objs := rtcan_dev.o rtcan_socket.o rtcan_module.o rtcan_raw.o rtcan_raw_dev.o rtcan_raw_filter.o +xeno_can_virt-objs := rtcan_virt.o + +export-objs := $(xeno_can-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat -I. + +include $(TOPDIR)/Rules.make + +xeno_can.o: $(xeno_can-objs) + $(LD) -r -o $@ $(xeno_can-objs) + +xeno_can_virt.o: $(xeno_can_virt-objs) + $(LD) -r -o $@ $(xeno_can_virt-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/Kconfig relase/linux-2.6.35.9//drivers/xenomai/can/mscan/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,60 @@ +config XENO_DRIVERS_CAN_MSCAN + depends on XENO_DRIVERS_CAN && (PPC_MPC52xx || PPC_MPC512x) + tristate "MSCAN driver for MPC52xx and MPC512x" + default n + help + + This driver is for the MSCAN on the MPC5200 and MPC512x processor + from Freescale. + +config XENO_DRIVERS_CAN_MSCAN_OLD + depends on XENO_DRIVERS_CAN_MSCAN && PPC_MPC52xx + bool "Use old MSCAN driver for old kernel version" + default n + help + + For backward compatibility with older kernel versions, you may + want to select the old MSCAN driver for the MPC5200. + +if XENO_DRIVERS_CAN_MSCAN_OLD + +config XENO_DRIVERS_CAN_MSCAN_1 + depends on XENO_DRIVERS_CAN_MSCAN + bool "Enable CAN 1" + default y + +config XENO_DRIVERS_CAN_MSCAN_2 + depends on XENO_DRIVERS_CAN_MSCAN + bool "Enable CAN 2" + default y + +config XENO_DRIVERS_CAN_MSCAN_CLOCK + depends on XENO_DRIVERS_CAN_MSCAN + int "Clock Frequency in Hz" + default 66000000 + help + + The MSCAN driver selects the oscillator clock (SYS_XTAL_IN) as clock + source for MSCAN, which is typically 33 MHz. Due to a hardware bug on + the MPC5200 Rev. A chips, the IP bus clock (IP_CLK) is used instead, + which is typically 66 or 132 MHz. + +choice + depends on XENO_DRIVERS_CAN_MSCAN + prompt "Pin Configuration" + default XENO_DRIVERS_CAN_MSCAN_PRE + help + +config XENO_DRIVERS_CAN_MSCAN_PRE + bool "Use pre-configured CAN routing" + +config XENO_DRIVERS_CAN_MSCAN_ALT + bool "CAN 1 on I2C1 pins, CAN 2 on TMR01 pins" + +config XENO_DRIVERS_CAN_MSCAN_PSC2 + bool "CAN 1 and 2 on PSC2 pins" + +endchoice + +endif + diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/Makefile relase/linux-2.6.35.9//drivers/xenomai/can/mscan/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,37 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can -Idrivers/xenomai/can/mscan + +obj-$(CONFIG_XENO_DRIVERS_CAN_MSCAN) += xeno_can_mscan.o + +xeno_can_mscan-y := rtcan_mscan.o rtcan_mscan_proc.o +ifdef CONFIG_XENO_DRIVERS_CAN_MSCAN_OLD +xeno_can_mscan-y += rtcan_mscan_mpc52xx.o +else +xeno_can_mscan-y += rtcan_mscan_mpc5xxx.o +endif + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_CAN_MSCAN) := xeno_can_mscan.o + +list-multi := xeno_can_mscan.o + +xeno_can_mscan-objs := rtcan_mscan.o rtcan_mscan_proc.o rtcan_mscan_mpc52xx.o + +export-objs := $(xeno_can_mscan-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat -I.. + +include $(TOPDIR)/Rules.make + +xeno_can_mscan.o: $(xeno_can_mscan-objs) + $(LD) -r -o $@ $(xeno_can_mscan-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.c relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.c --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,746 @@ +/* + * Copyright (C) 2006-2010 Wolfgang Grandegger + * + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * Derived from the PCAN project file driver/src/pcan_mpc5200.c: + * + * Copyright (c) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (c) 2005 Felix Daners, Plugit AG, felix.daners@plugit.ch + * + * + * 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 +#include +#include + +#include + +/* CAN device profile */ +#include +#include "rtcan_dev.h" +#include "rtcan_raw.h" +#include "rtcan_internal.h" +#include "rtcan_mscan_regs.h" +#include "rtcan_mscan.h" + +/** + * Reception Interrupt handler + * + * Inline function first called within @ref rtcan_mscan_interrupt when an RX + * interrupt was detected. Here the HW registers are read out and composed + * to a struct rtcan_skb. + * + * @param[out] skb Pointer to an instance of struct rtcan_skb which will be + * filled with received CAN message + * @param[in] dev Device ID + */ +static inline void rtcan_mscan_rx_interrupt(struct rtcan_device *dev, + struct rtcan_skb *skb) +{ + int i; + unsigned char size; + struct rtcan_rb_frame *frame = &skb->rb_frame; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + skb->rb_frame_size = EMPTY_RB_FRAME_SIZE; + + frame->can_dlc = in_8(®s->canrxfg.dlr) & 0x0F; + + /* If DLC exceeds 8 bytes adjust it to 8 (for the payload size) */ + size = (frame->can_dlc > 8) ? 8 : frame->can_dlc; + + if (in_8(®s->canrxfg.idr[1]) & MSCAN_BUF_EXTENDED) { + frame->can_id = ((in_8(®s->canrxfg.idr[0]) << 21) | + ((in_8(®s->canrxfg.idr[1]) & 0xE0) << 13) | + ((in_8(®s->canrxfg.idr[1]) & 0x07) << 15) | + (in_8(®s->canrxfg.idr[4]) << 7) | + (in_8(®s->canrxfg.idr[5]) >> 1)); + + frame->can_id |= CAN_EFF_FLAG; + + if ((in_8(®s->canrxfg.idr[5]) & MSCAN_BUF_EXT_RTR)) { + frame->can_id |= CAN_RTR_FLAG; + } else { + for (i = 0; i < size; i++) + frame->data[i] = + in_8(®s->canrxfg.dsr[i + + (i / 2) * 2]); + skb->rb_frame_size += size; + } + + } else { + frame->can_id = ((in_8(®s->canrxfg.idr[0]) << 3) | + (in_8(®s->canrxfg.idr[1]) >> 5)); + + if ((in_8(®s->canrxfg.idr[1]) & MSCAN_BUF_STD_RTR)) { + frame->can_id |= CAN_RTR_FLAG; + } else { + for (i = 0; i < size; i++) + frame->data[i] = + in_8(®s->canrxfg.dsr[i + + (i / 2) * 2]); + skb->rb_frame_size += size; + } + } + + + /* Store the interface index */ + frame->can_ifindex = dev->ifindex; +} + +static can_state_t mscan_stat_map[4] = { + CAN_STATE_ACTIVE, + CAN_STATE_BUS_WARNING, + CAN_STATE_BUS_PASSIVE, + CAN_STATE_BUS_OFF +}; + +static inline void rtcan_mscan_err_interrupt(struct rtcan_device *dev, + struct rtcan_skb *skb, + int r_status) +{ + u8 rstat, tstat; + struct rtcan_rb_frame *frame = &skb->rb_frame; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + skb->rb_frame_size = EMPTY_RB_FRAME_SIZE + CAN_ERR_DLC; + + frame->can_id = CAN_ERR_FLAG; + frame->can_dlc = CAN_ERR_DLC; + + memset(&frame->data[0], 0, frame->can_dlc); + + if ((r_status & MSCAN_OVRIF)) { + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + + } else if ((r_status & (MSCAN_CSCIF))) { + + rstat = (r_status & (MSCAN_TSTAT0 | + MSCAN_TSTAT1)) >> 2 & 0x3; + tstat = (r_status & (MSCAN_RSTAT0 | + MSCAN_RSTAT1)) >> 4 & 0x3; + dev->state = mscan_stat_map[max(rstat, tstat)]; + + switch (dev->state) { + case CAN_STATE_BUS_OFF: + /* Bus-off condition */ + frame->can_id |= CAN_ERR_BUSOFF; + dev->state = CAN_STATE_BUS_OFF; + /* Disable receiver interrupts */ + out_8(®s->canrier, 0); + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + break; + + case CAN_STATE_BUS_PASSIVE: + frame->can_id |= CAN_ERR_CRTL; + if (tstat > rstat) + frame->data[1] = CAN_ERR_CRTL_TX_PASSIVE; + else + frame->data[1] = CAN_ERR_CRTL_RX_PASSIVE; + break; + + case CAN_STATE_BUS_WARNING: + frame->can_id |= CAN_ERR_CRTL; + if (tstat > rstat) + frame->data[1] = CAN_ERR_CRTL_TX_WARNING; + else + frame->data[1] = CAN_ERR_CRTL_RX_WARNING; + break; + + default: + break; + + } + } + /* Store the interface index */ + frame->can_ifindex = dev->ifindex; +} + +/** Interrupt handler */ +static int rtcan_mscan_interrupt(rtdm_irq_t *irq_handle) +{ + struct rtcan_skb skb; + struct rtcan_device *dev; + struct mscan_regs *regs; + u8 canrflg; + int recv_lock_free = 1; + int ret = RTDM_IRQ_NONE; + + + dev = (struct rtcan_device *)rtdm_irq_get_arg(irq_handle, void); + regs = (struct mscan_regs *)dev->base_addr; + + rtdm_lock_get(&dev->device_lock); + + canrflg = in_8(®s->canrflg); + + ret = RTDM_IRQ_HANDLED; + + /* Transmit Interrupt? */ + if ((in_8(®s->cantier) & MSCAN_TXIE0) && + (in_8(®s->cantflg) & MSCAN_TXE0)) { + out_8(®s->cantier, 0); + /* Wake up a sender */ + rtdm_sem_up(&dev->tx_sem); + + if (rtcan_loopback_pending(dev)) { + + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + + rtcan_loopback(dev); + } + } + + /* Wakeup interrupt? */ + if ((canrflg & MSCAN_WUPIF)) { + rtdm_printk("WUPIF interrupt\n"); + } + + /* Receive Interrupt? */ + if ((canrflg & MSCAN_RXF)) { + + /* Read out HW registers */ + rtcan_mscan_rx_interrupt(dev, &skb); + + /* Take more locks. Ensure that they are taken and + * released only once in the IRQ handler. */ + /* WARNING: Nested locks are dangerous! But they are + * nested only in this routine so a deadlock should + * not be possible. */ + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + + /* Pass received frame out to the sockets */ + rtcan_rcv(dev, &skb); + } + + /* Error Interrupt? */ + if ((canrflg & (MSCAN_CSCIF | MSCAN_OVRIF))) { + /* Check error condition and fill error frame */ + rtcan_mscan_err_interrupt(dev, &skb, canrflg); + + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + + /* Pass error frame out to the sockets */ + rtcan_rcv(dev, &skb); + } + + /* Acknowledge the handled interrupt within the controller. + * Only do so for the receiver interrupts. + */ + if (canrflg) + out_8(®s->canrflg, canrflg); + + if (!recv_lock_free) { + rtdm_lock_put(&rtcan_socket_lock); + rtdm_lock_put(&rtcan_recv_list_lock); + } + rtdm_lock_put(&dev->device_lock); + + return ret; +} + +/** + * Set controller into reset mode. Called from @ref rtcan_mscan_ioctl + * (main usage), init_module and cleanup_module. + * + * @param dev_id Device ID + * @param lock_ctx Pointer to saved IRQ context (if stored before calling + * this function). Only evaluated if @c locked is true. + * @param locked Boolean value indicating if function was called in an + * spin locked and IRQ disabled context + * + * @return 0 on success, otherwise: + * - -EAGAIN: Reset mode bit could not be verified after setting it. + * See also note. + * + * @note According to the MSCAN specification, it is necessary to check + * the reset mode bit in PeliCAN mode after having set it. So we do. But if + * using a ISA card like the PHYTEC eNET card this should not be necessary + * because the CAN controller clock of this card (16 MHz) is twice as high + * as the ISA bus clock. + */ +static int rtcan_mscan_mode_stop(struct rtcan_device *dev, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0; + int rinit = 0; + can_state_t state; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + u8 reg; + + state = dev->state; + /* If controller is not operating anyway, go out */ + if (!CAN_STATE_OPERATING(state)) + goto out; + + /* Switch to sleep mode */ + setbits8(®s->canctl0, MSCAN_SLPRQ); + setbits8(®s->canctl0, MSCAN_INITRQ); + + reg = in_8(®s->canctl1); + while (!(reg & MSCAN_SLPAK) || + !(reg & MSCAN_INITAK)) { + if (likely(lock_ctx != NULL)) + rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx); + /* Busy sleep 1 microsecond */ + rtdm_task_busy_sleep(1000); + if (likely(lock_ctx != NULL)) + rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx); + rinit++; + reg = in_8(®s->canctl1); + } + + /* Volatile state could have changed while we slept busy. */ + dev->state = CAN_STATE_STOPPED; + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + +out: + return ret; +} + +/** + * Set controller into operating mode. + * + * Called from @ref rtcan_mscan_ioctl in spin locked and IRQ disabled + * context. + * + * @param dev_id Device ID + * @param lock_ctx Pointer to saved IRQ context (only used when coming + * from @ref CAN_STATE_SLEEPING, see also note) + * + * @return 0 on success, otherwise: + * - -EINVAL: No Baud rate set before request to set start mode + * + * @note If coming from @c CAN_STATE_SLEEPING, the controller must wait + * some time to avoid bus errors. Measured on an PHYTEC eNET card, + * this time was 110 microseconds. + */ +static int rtcan_mscan_mode_start(struct rtcan_device *dev, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0, retries = 0; + can_state_t state; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + /* We won't forget that state in the device structure is volatile and + * access to it will not be optimized by the compiler. So ... */ + state = dev->state; + + switch (state) { + case CAN_STATE_ACTIVE: + case CAN_STATE_BUS_WARNING: + case CAN_STATE_BUS_PASSIVE: + break; + + case CAN_STATE_SLEEPING: + case CAN_STATE_STOPPED: + /* Set error active state */ + state = CAN_STATE_ACTIVE; + /* Set up sender "mutex" */ + rtdm_sem_init(&dev->tx_sem, 1); + + if ((dev->ctrl_mode & CAN_CTRLMODE_LISTENONLY)) { + setbits8(®s->canctl1, MSCAN_LISTEN); + } else { + clrbits8(®s->canctl1, MSCAN_LISTEN); + } + if ((dev->ctrl_mode & CAN_CTRLMODE_LOOPBACK)) { + setbits8(®s->canctl1, MSCAN_LOOPB); + } else { + clrbits8(®s->canctl1, MSCAN_LOOPB); + } + + /* Switch to normal mode */ + clrbits8(®s->canctl0, MSCAN_INITRQ); + clrbits8(®s->canctl0, MSCAN_SLPRQ); + while ((in_8(®s->canctl1) & MSCAN_INITAK) || + (in_8(®s->canctl1) & MSCAN_SLPAK)) { + if (likely(lock_ctx != NULL)) + rtdm_lock_put_irqrestore(&dev->device_lock, + *lock_ctx); + /* Busy sleep 1 microsecond */ + rtdm_task_busy_sleep(1000); + if (likely(lock_ctx != NULL)) + rtdm_lock_get_irqsave(&dev->device_lock, + *lock_ctx); + retries++; + } + /* Enable interrupts */ + setbits8(®s->canrier, MSCAN_RIER); + + break; + + case CAN_STATE_BUS_OFF: + /* Trigger bus-off recovery */ + out_8(®s->canrier, MSCAN_RIER); + /* Set up sender "mutex" */ + rtdm_sem_init(&dev->tx_sem, 1); + /* Set error active state */ + state = CAN_STATE_ACTIVE; + + break; + + default: + /* Never reached, but we don't want nasty compiler warnings */ + break; + } + /* Store new state in device structure (or old state) */ + dev->state = state; + + return ret; +} + +static int rtcan_mscan_set_bit_time(struct rtcan_device *dev, + struct can_bittime *bit_time, + rtdm_lockctx_t *lock_ctx) +{ + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + u8 btr0, btr1; + + switch (bit_time->type) { + case CAN_BITTIME_BTR: + btr0 = bit_time->btr.btr0; + btr1 = bit_time->btr.btr1; + break; + + case CAN_BITTIME_STD: + btr0 = (BTR0_SET_BRP(bit_time->std.brp) | + BTR0_SET_SJW(bit_time->std.sjw)); + btr1 = (BTR1_SET_TSEG1(bit_time->std.prop_seg + + bit_time->std.phase_seg1) | + BTR1_SET_TSEG2(bit_time->std.phase_seg2) | + BTR1_SET_SAM(bit_time->std.sam)); + break; + + default: + return -EINVAL; + } + + out_8(®s->canbtr0, btr0); + out_8(®s->canbtr1, btr1); + + rtdm_printk("%s: btr0=0x%02x btr1=0x%02x\n", dev->name, btr0, btr1); + + return 0; +} + +static int rtcan_mscan_set_mode(struct rtcan_device *dev, + can_mode_t mode, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0, retries = 0; + can_state_t state; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + switch (mode) { + + case CAN_MODE_STOP: + ret = rtcan_mscan_mode_stop(dev, lock_ctx); + break; + + case CAN_MODE_START: + ret = rtcan_mscan_mode_start(dev, lock_ctx); + break; + + case CAN_MODE_SLEEP: + + state = dev->state; + + /* Controller must operate, otherwise go out */ + if (!CAN_STATE_OPERATING(state)) { + ret = -ENETDOWN; + goto mode_sleep_out; + } + + /* Is controller sleeping yet? If yes, go out */ + if (state == CAN_STATE_SLEEPING) + goto mode_sleep_out; + + /* Remember into which state to return when we + * wake up */ + dev->state_before_sleep = state; + state = CAN_STATE_SLEEPING; + + /* Let's take a nap. (Now I REALLY understand + * the meaning of interrupts ...) */ + out_8(®s->canrier, 0); + out_8(®s->cantier, 0); + setbits8(®s->canctl0, + MSCAN_SLPRQ /*| MSCAN_INITRQ*/ | MSCAN_WUPE); + while (!(in_8(®s->canctl1) & MSCAN_SLPAK)) { + rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx); + /* Busy sleep 1 microsecond */ + rtdm_task_busy_sleep(1000); + rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx); + if (retries++ >= 1000) + break; + } + rtdm_printk("Fallen asleep after %d tries.\n", retries); + clrbits8(®s->canctl0, MSCAN_INITRQ); + while ((in_8(®s->canctl1) & MSCAN_INITAK)) { + rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx); + /* Busy sleep 1 microsecond */ + rtdm_task_busy_sleep(1000); + rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx); + if (retries++ >= 1000) + break; + } + rtdm_printk("Back to normal after %d tries.\n", retries); + out_8(®s->canrier, MSCAN_WUPIE); + + mode_sleep_out: + dev->state = state; + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +/** + * Start a transmission to a MSCAN + * + * Inline function called within @ref rtcan_mscan_sendmsg. + * This is the completion of a send call when hardware access is granted. + * Spinlock is taken before calling this function. + * + * @param[in] frame Pointer to CAN frame which is about to be sent + * @param[in] dev Device ID + */ +static int rtcan_mscan_start_xmit(struct rtcan_device *dev, can_frame_t *frame) +{ + int i, id; + /* "Real" size of the payload */ + unsigned char size; + /* Content of frame information register */ + unsigned char dlc; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + /* Is TX buffer empty? */ + if (!(in_8(®s->cantflg) & MSCAN_TXE0)) { + rtdm_printk("rtcan_mscan_start_xmit: TX buffer not empty"); + return -EIO; + } + /* Select the buffer we've found. */ + out_8(®s->cantbsel, MSCAN_TXE0); + + /* Get DLC and ID */ + dlc = frame->can_dlc; + + /* If DLC exceeds 8 bytes adjust it to 8 (for the payload) */ + size = (dlc > 8) ? 8 : dlc; + + id = frame->can_id; + if (frame->can_id & CAN_EFF_FLAG) { + out_8(®s->cantxfg.idr[0], (id & 0x1fe00000) >> 21); + out_8(®s->cantxfg.idr[1], ((id & 0x001c0000) >> 13) | + ((id & 0x00038000) >> 15) | + 0x18); /* set SRR and IDE bits */ + + out_8(®s->cantxfg.idr[4], (id & 0x00007f80) >> 7); + out_8(®s->cantxfg.idr[5], (id & 0x0000007f) << 1); + + /* RTR? */ + if (frame->can_id & CAN_RTR_FLAG) + setbits8(®s->cantxfg.idr[5], 0x1); + else { + clrbits8(®s->cantxfg.idr[5], 0x1); + /* No RTR, write data bytes */ + for (i = 0; i < size; i++) + out_8(®s->cantxfg.dsr[i + (i / 2) * 2], + frame->data[i]); + } + + } else { + /* Send standard frame */ + + out_8(®s->cantxfg.idr[0], (id & 0x000007f8) >> 3); + out_8(®s->cantxfg.idr[1], (id & 0x00000007) << 5); + + /* RTR? */ + if (frame->can_id & CAN_RTR_FLAG) + setbits8(®s->cantxfg.idr[1], 0x10); + else { + clrbits8(®s->cantxfg.idr[1], 0x10); + /* No RTR, write data bytes */ + for (i = 0; i < size; i++) + out_8(®s->cantxfg.dsr[i + (i / 2) * 2], + frame->data[i]); + } + } + + out_8(®s->cantxfg.dlr, frame->can_dlc); + out_8(®s->cantxfg.tbpr, 0); /* all messages have the same prio */ + + /* Trigger transmission. */ + out_8(®s->cantflg, MSCAN_TXE0); + + /* Enable interrupt. */ + setbits8(®s->cantier, MSCAN_TXIE0); + + return 0; +} + +/** + * MSCAN Chip configuration + * + * Called during @ref init_module. Here, the configuration registers which + * must be set only once are written with the right values. The controller + * is left in reset mode and goes into operating mode not until the IOCTL + * for starting it is triggered. + * + * @param[in] dev Device ID of the controller to be configured + */ +static inline void __init mscan_chip_config(struct mscan_regs *regs, + int mscan_clksrc) +{ + /* Choose IP bus as clock source. + */ + if (mscan_clksrc) + setbits8(®s->canctl1, MSCAN_CLKSRC); + clrbits8(®s->canctl1, MSCAN_LISTEN); + + /* Configure MSCAN to accept all incoming messages. + */ + out_8(®s->canidar0, 0x00); + out_8(®s->canidar1, 0x00); + out_8(®s->canidar2, 0x00); + out_8(®s->canidar3, 0x00); + out_8(®s->canidmr0, 0xFF); + out_8(®s->canidmr1, 0xFF); + out_8(®s->canidmr2, 0xFF); + out_8(®s->canidmr3, 0xFF); + out_8(®s->canidar4, 0x00); + out_8(®s->canidar5, 0x00); + out_8(®s->canidar6, 0x00); + out_8(®s->canidar7, 0x00); + out_8(®s->canidmr4, 0xFF); + out_8(®s->canidmr5, 0xFF); + out_8(®s->canidmr6, 0xFF); + out_8(®s->canidmr7, 0xFF); + clrbits8(®s->canidac, MSCAN_IDAM0 | MSCAN_IDAM1); +} + +/** + * MSCAN Chip registration + * + * Called during @ref init_module. + * + * @param[in] dev Device ID of the controller to be registered + * @param[in] mscan_clksrc clock source to be used + */ +int rtcan_mscan_register(struct rtcan_device *dev, int irq, int mscan_clksrc) +{ + int ret; + struct mscan_regs *regs; + + regs = (struct mscan_regs *)dev->base_addr; + + /* Enable MSCAN module. */ + setbits8(®s->canctl1, MSCAN_CANE); + udelay(100); + + /* Set dummy state for following call */ + dev->state = CAN_STATE_ACTIVE; + + /* Enter reset mode */ + rtcan_mscan_mode_stop(dev, NULL); + + /* Give device an interface name (so that programs using this driver + don't need to know the device ID) */ + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + dev->hard_start_xmit = rtcan_mscan_start_xmit; + dev->do_set_mode = rtcan_mscan_set_mode; + dev->do_set_bit_time = rtcan_mscan_set_bit_time; + + /* Register IRQ handler and pass device structure as arg */ + ret = rtdm_irq_request(&dev->irq_handle, irq, rtcan_mscan_interrupt, + 0, RTCAN_DRV_NAME, (void *)dev); + if (ret) { + printk("ERROR! rtdm_irq_request for IRQ %d failed\n", irq); + goto out_can_disable; + } + + mscan_chip_config(regs, mscan_clksrc); + + /* Register RTDM device */ + ret = rtcan_dev_register(dev); + if (ret) { + printk(KERN_ERR + "ERROR while trying to register RTCAN device!\n"); + goto out_irq_free; + } + + rtcan_mscan_create_proc(dev); + + return 0; + +out_irq_free: + rtdm_irq_free(&dev->irq_handle); + +out_can_disable: + /* Disable MSCAN module. */ + clrbits8(®s->canctl1, MSCAN_CANE); + + return ret; +} + +/** + * MSCAN Chip deregistration + * + * Called during @ref cleanup_module + * + * @param[in] dev Device ID of the controller to be registered + */ +int rtcan_mscan_unregister(struct rtcan_device *dev) +{ + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; + + printk("Unregistering %s device %s\n", RTCAN_DRV_NAME, dev->name); + + rtcan_mscan_mode_stop(dev, NULL); + rtdm_irq_free(&dev->irq_handle); + rtcan_mscan_remove_proc(dev); + rtcan_dev_unregister(dev); + + /* Disable MSCAN module. */ + clrbits8(®s->canctl1, MSCAN_CANE); + + return 0; +} diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.h relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.h --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009 Wolfgang Grandegger + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_MSCAN_H_ +#define __RTCAN_MSCAN_H_ + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "rtcan_mscan" + +/* MSCAN type variants */ +enum { + MSCAN_TYPE_MPC5200, + MSCAN_TYPE_MPC5121 +}; + +extern int rtcan_mscan_register(struct rtcan_device *dev, int irq, + int mscan_clksrc); +extern int rtcan_mscan_unregister(struct rtcan_device *dev); + +extern int rtcan_mscan_create_proc(struct rtcan_device* dev); +extern void rtcan_mscan_remove_proc(struct rtcan_device* dev); + +#endif /* __RTCAN_MSCAN_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc52xx.c relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc52xx.c --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc52xx.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc52xx.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2006-2010 Wolfgang Grandegger + * + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * Derived from the PCAN project file driver/src/pcan_mpc5200.c: + * + * Copyright (c) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (c) 2005 Felix Daners, Plugit AG, felix.daners@plugit.ch + * + * + * 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 +#include +#include + +#include + +/* CAN device profile */ +#include +#include "rtcan_dev.h" +#include "rtcan_raw.h" +#include "rtcan_internal.h" +#include "rtcan_mscan_regs.h" +#include "rtcan_mscan.h" + +#define RTCAN_MSCAN_DEVS 2 + +static char *mscan_ctlr_name = "MSCAN-MPC5200"; +static char *mscan_board_name = "unkown"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RT-Socket-CAN driver for MSCAN-MPC2500"); +MODULE_SUPPORTED_DEVICE("MSCAN-MPC5200 CAN controller"); +MODULE_LICENSE("GPL"); + +/** Module parameter for the CAN controllers' */ + +int port[RTCAN_MSCAN_DEVS] = { +#ifdef CONFIG_XENO_DRIVERS_CAN_MSCAN_1 +#ifdef CONFIG_XENO_DRIVERS_CAN_MSCAN_2 + 1, 1 /* Enable CAN 1 and 2 */ +#else + 1, 0 /* Enable CAN 1 only */ +#endif +#else +#ifdef CONFIG_XENO_DRIVERS_CAN_MSCAN_2 + 0, 1 /* Enable CAN 2 only */ +#else +#error "No CAN controller enabled, fix configuration!" +#endif +#endif +}; +compat_module_param_array(port, int, RTCAN_MSCAN_DEVS, 0444); +MODULE_PARM_DESC(port, "Enabled CAN ports (1,1 or 0,1 or 0,1)"); + +/* + * Note: on the MPC5200 the MSCAN clock source is the IP bus + * clock (IP_CLK) while on the MPC5200B it is the oscillator + * clock (SYS_XTAL_IN). + */ +unsigned int mscan_clock = CONFIG_XENO_DRIVERS_CAN_MSCAN_CLOCK; +module_param(mscan_clock, int, 0444); +MODULE_PARM_DESC(mscan_clock, "Clock frequency in Hz"); + +char *mscan_pins = NULL; +module_param(mscan_pins, charp, 0444); +MODULE_PARM_DESC(mscan_pins, "Routing to GPIO pins (PSC2 or I2C1/TMR01)"); + +static struct rtcan_device *rtcan_mscan_devs[RTCAN_MSCAN_DEVS]; +static int rtcan_mscan_count; + +static inline void __init mscan_gpio_config(void) +{ + struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5xxx_GPIO; + int can_to_psc2 = -1; + u32 port_config; + +#if defined(CONFIG_XENO_DRIVERS_CAN_MSCAN_ALT) + can_to_psc2 = 0; +#elif defined(CONFIG_XENO_DRIVERS_CAN_MSCAN_PSC2) + can_to_psc2 = 1; +#endif + + /* Configure CAN routing to GPIO pins. + */ + if (mscan_pins != NULL) { + if (strncmp(mscan_pins, "psc2", 4) == 0 || + !strncmp(mscan_pins, "PSC2", 4)) + can_to_psc2 = 1; + else if (strncmp(mscan_pins, "i2c1/tmr01", 10) == 0 || + strncmp(mscan_pins, "I2C1/TMR01", 10) == 0) + can_to_psc2 = 0; + else { + printk("Module parameter mscan_pins=%s is invalid. " + "Please use PSC2 or I2C1/TMR01.\n", mscan_pins); + } + } + + if (!gpio || can_to_psc2 < 0) { + printk("%s: use pre-configure CAN routing\n", RTCAN_DRV_NAME); + return; + } + + port_config = in_be32(&gpio->port_config); + if (can_to_psc2) { + port_config &= ~0x10000070; + port_config |= 0x00000010; + printk("%s: CAN 1 and 2 routed to PSC2 pins\n", RTCAN_DRV_NAME); + } else { + port_config |= 0x10000000; + printk("%s: CAN 1 routed to I2C1 pins and CAN2 to TMR01 pins\n", + RTCAN_DRV_NAME); + } + out_be32(&gpio->port_config, port_config); +} + +static inline int mscan_get_config(unsigned long *addr, unsigned int *irq) +{ +#if defined(CONFIG_PPC_MERGE) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27) + /* Use Open Firmware device tree */ + struct device_node *np = NULL; + unsigned int i; + int ret; + + for (i = 0; i < RTCAN_MSCAN_DEVS; i++) { + struct resource r[2] = {}; + + np = of_find_compatible_node(np, NULL, "fsl,mpc5200-mscan"); + if (np == NULL) + np = of_find_compatible_node(np, NULL, "mpc5200-mscan"); + if (np == NULL) + break; + ret = of_address_to_resource(np, 0, &r[0]); + if (ret) + return ret; + of_irq_to_resource(np, 0, &r[1]); + addr[i] = r[0].start; + irq[i] = r[1].start; + rtcan_mscan_count++; + } +#else + addr[0] = MSCAN_CAN1_ADDR; + irq[0] = MSCAN_CAN1_IRQ; + addr[1] = MSCAN_CAN2_ADDR; + irq[1] = MSCAN_CAN2_IRQ; + rtcan_mscan_count = 2; +#endif + return 0; +} + +static int __init rtcan_mscan_init_one(int idx, unsigned long addr, int irq) +{ + struct rtcan_device *dev; + int ret; + + dev = rtcan_dev_alloc(0, 0); + if (dev == NULL) + return -ENOMEM; + + dev->base_addr = (unsigned long)ioremap(addr, MSCAN_SIZE); + if (dev->base_addr == 0) { + ret = -ENOMEM; + printk("ERROR! ioremap of %#lx failed\n", addr); + goto out_dev_free; + } + + dev->ctrl_name = mscan_ctlr_name; + dev->board_name = mscan_board_name; + dev->can_sys_clock = mscan_clock; + + ret = rtcan_mscan_register(dev, irq, 1); + if (ret) + goto out_iounmap; + + /* Remember initialized devices */ + rtcan_mscan_devs[idx] = dev; + + printk("%s: %s driver: MSCAN port %d, base-addr 0x%lx, irq %d\n", + dev->name, RTCAN_DRV_NAME, idx + 1, addr, irq); + + return 0; + +out_iounmap: + iounmap((void *)dev->base_addr); + +out_dev_free: + rtcan_dev_free(dev); + + return ret; + +} + +static void rtcan_mscan_exit(void) +{ + int i; + struct rtcan_device *dev; + + for (i = 0; i < rtcan_mscan_count; i++) { + + if ((dev = rtcan_mscan_devs[i]) == NULL) + continue; + + printk("Unloading %s device %s\n", RTCAN_DRV_NAME, dev->name); + + rtcan_mscan_unregister(dev); + iounmap((void *)dev->base_addr); + rtcan_dev_free(dev); + } + +} + +static int __init rtcan_mscan_init(void) +{ + int i, err; + int unsigned long addr[RTCAN_MSCAN_DEVS]; + int irq[RTCAN_MSCAN_DEVS]; + + if ((err = mscan_get_config(addr, irq))) + return err; + mscan_gpio_config(); + + for (i = 0; i < rtcan_mscan_count; i++) { + if (!port[i]) + continue; + + err = rtcan_mscan_init_one(i, addr[i], irq[i]); + if (err) { + rtcan_mscan_exit(); + return err; + } + } + + return 0; +} + +module_init(rtcan_mscan_init); +module_exit(rtcan_mscan_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc5xxx.c relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc5xxx.c --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc5xxx.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_mpc5xxx.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,386 @@ +/* + * CAN bus driver for the Freescale MPC5xxx embedded CPU. + * + * Copyright (C) 2004-2005 Andrey Volkov , + * Varma Electronics Oy + * Copyright (C) 2008-2010 Wolfgang Grandegger + * Copyright (C) 2009 Wolfram Sang, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rtcan_dev.h" +#include "rtcan_mscan_regs.h" +#include "rtcan_mscan.h" + +static char mscan_ctrl_name_mpc5200[] = "MSCAN-MPC5200"; +static char mscan_ctrl_name_mpc512x[] = "MSCAN-MPC512x"; +static char mscan_board_name[] = "unkown"; + +struct mpc5xxx_can_data { + unsigned int type; + u32 (*get_clock)(struct of_device *ofdev, const char *clock_name, + int *mscan_clksrc); +}; + +#ifdef CONFIG_PPC_MPC52xx +static struct of_device_id __devinitdata mpc52xx_cdm_ids[] = { + { .compatible = "fsl,mpc5200-cdm", }, + {} +}; + +static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev, + const char *clock_name, + int *mscan_clksrc) +{ + unsigned int pvr; + struct mpc52xx_cdm __iomem *cdm; + struct device_node *np_cdm; + unsigned int freq; + u32 val; + + pvr = mfspr(SPRN_PVR); + + /* + * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock + * (IP_CLK) can be selected as MSCAN clock source. According to + * the MPC5200 user's manual, the oscillator clock is the better + * choice as it has less jitter. For this reason, it is selected + * by default. Unfortunately, it can not be selected for the old + * MPC5200 Rev. A chips due to a hardware bug (check errata). + */ + if (clock_name && strcmp(clock_name, "ip") == 0) + *mscan_clksrc = MSCAN_CLKSRC_BUS; + else + *mscan_clksrc = MSCAN_CLKSRC_XTAL; + + freq = mpc5xxx_get_bus_frequency(mpc5xxx_get_of_node(ofdev)); + if (!freq) + return 0; + + if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011) + return freq; + + /* Determine SYS_XTAL_IN frequency from the clock domain settings */ + np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids); + if (!np_cdm) { + dev_err(&ofdev->dev, "can't get clock node!\n"); + return 0; + } + cdm = of_iomap(np_cdm, 0); + + if (in_8(&cdm->ipb_clk_sel) & 0x1) + freq *= 2; + val = in_be32(&cdm->rstcfg); + + freq *= (val & (1 << 5)) ? 8 : 4; + freq /= (val & (1 << 6)) ? 12 : 16; + + of_node_put(np_cdm); + iounmap(cdm); + + return freq; +} +#else /* !CONFIG_PPC_MPC5200 */ +static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev, + const char *clock_name, + int *mscan_clksrc) +{ + return 0; +} +#endif /* CONFIG_PPC_MPC52xx */ + +#ifdef CONFIG_PPC_MPC512x +struct mpc512x_clockctl { + u32 spmr; /* System PLL Mode Reg */ + u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */ + u32 scfr1; /* System Clk Freq Reg 1 */ + u32 scfr2; /* System Clk Freq Reg 2 */ + u32 reserved; + u32 bcr; /* Bread Crumb Reg */ + u32 pccr[12]; /* PSC Clk Ctrl Reg 0-11 */ + u32 spccr; /* SPDIF Clk Ctrl Reg */ + u32 cccr; /* CFM Clk Ctrl Reg */ + u32 dccr; /* DIU Clk Cnfg Reg */ + u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */ +}; + +static struct of_device_id __devinitdata mpc512x_clock_ids[] = { + { .compatible = "fsl,mpc5121-clock", }, + {} +}; + +static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev, + const char *clock_name, + int *mscan_clksrc) +{ + struct mpc512x_clockctl __iomem *clockctl; + struct device_node *np_clock; + struct clk *sys_clk, *ref_clk; + int plen, clockidx, clocksrc = -1; + u32 sys_freq, val, clockdiv = 1, freq = 0; + const u32 *pval; + + np_clock = of_find_matching_node(NULL, mpc512x_clock_ids); + if (!np_clock) { + dev_err(&ofdev->dev, "couldn't find clock node\n"); + return -ENODEV; + } + clockctl = of_iomap(np_clock, 0); + if (!clockctl) { + dev_err(&ofdev->dev, "couldn't map clock registers\n"); + return 0; + } + + /* Determine the MSCAN device index from the physical address */ + pval = of_get_property(ofdev->node, "reg", &plen); + BUG_ON(!pval || plen < sizeof(*pval)); + clockidx = (*pval & 0x80) ? 1 : 0; + if (*pval & 0x2000) + clockidx += 2; + + /* + * Clock source and divider selection: 3 different clock sources + * can be selected: "ip", "ref" or "sys". For the latter two, a + * clock divider can be defined as well. If the clock source is + * not specified by the device tree, we first try to find an + * optimal CAN source clock based on the system clock. If that + * is not posslible, the reference clock will be used. + */ + if (clock_name && !strcmp(clock_name, "ip")) { + *mscan_clksrc = MSCAN_CLKSRC_IPS; + freq = mpc5xxx_get_bus_frequency(ofdev->node); + } else { + *mscan_clksrc = MSCAN_CLKSRC_BUS; + + pval = of_get_property(ofdev->node, + "fsl,mscan-clock-divider", &plen); + if (pval && plen == sizeof(*pval)) + clockdiv = *pval; + if (!clockdiv) + clockdiv = 1; + + if (!clock_name || !strcmp(clock_name, "sys")) { + sys_clk = clk_get(&ofdev->dev, "sys_clk"); + if (!sys_clk) { + dev_err(&ofdev->dev, "couldn't get sys_clk\n"); + goto exit_unmap; + } + /* Get and round up/down sys clock rate */ + sys_freq = 1000000 * + ((clk_get_rate(sys_clk) + 499999) / 1000000); + + if (!clock_name) { + /* A multiple of 16 MHz would be optimal */ + if ((sys_freq % 16000000) == 0) { + clocksrc = 0; + clockdiv = sys_freq / 16000000; + freq = sys_freq / clockdiv; + } + } else { + clocksrc = 0; + freq = sys_freq / clockdiv; + } + } + + if (clocksrc < 0) { + ref_clk = clk_get(&ofdev->dev, "ref_clk"); + if (!ref_clk) { + dev_err(&ofdev->dev, "couldn't get ref_clk\n"); + goto exit_unmap; + } + clocksrc = 1; + freq = clk_get_rate(ref_clk) / clockdiv; + } + } + + /* Disable clock */ + out_be32(&clockctl->mccr[clockidx], 0x0); + if (clocksrc >= 0) { + /* Set source and divider */ + val = (clocksrc << 14) | ((clockdiv - 1) << 17); + out_be32(&clockctl->mccr[clockidx], val); + /* Enable clock */ + out_be32(&clockctl->mccr[clockidx], val | 0x10000); + } + + /* Enable MSCAN clock domain */ + val = in_be32(&clockctl->sccr[1]); + if (!(val & (1 << 25))) + out_be32(&clockctl->sccr[1], val | (1 << 25)); + + dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n", + *mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" : + clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv); + +exit_unmap: + of_node_put(np_clock); + iounmap(clockctl); + + return freq; +} +#else /* !CONFIG_PPC_MPC512x */ +static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev, + const char *clock_name, + int *mscan_clksrc) +{ + return 0; +} +#endif /* CONFIG_PPC_MPC512x */ + +static int __devinit mpc5xxx_can_probe(struct of_device *ofdev, + const struct of_device_id *id) +{ + struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data; + struct device_node *np = mpc5xxx_get_of_node(ofdev); + struct rtcan_device *dev; + void __iomem *base; + const char *clock_name = NULL; + int irq, mscan_clksrc = 0; + int err = -ENOMEM; + + base = of_iomap(np, 0); + if (!base) { + dev_err(&ofdev->dev, "couldn't ioremap\n"); + return err; + } + + irq = irq_of_parse_and_map(np, 0); + if (!irq) { + dev_err(&ofdev->dev, "no irq found\n"); + err = -ENODEV; + goto exit_unmap_mem; + } + + dev = rtcan_dev_alloc(0, 0); + if (!dev) + goto exit_dispose_irq; + + clock_name = of_get_property(np, "fsl,mscan-clock-source", NULL); + + BUG_ON(!data); + dev->can_sys_clock = data->get_clock(ofdev, clock_name, + &mscan_clksrc); + if (!dev->can_sys_clock) { + dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n"); + goto exit_free_mscan; + } + + if (data->type == MSCAN_TYPE_MPC5121) + dev->ctrl_name = mscan_ctrl_name_mpc512x; + else + dev->ctrl_name = mscan_ctrl_name_mpc5200; + dev->board_name = mscan_board_name; + dev->base_addr = (unsigned long)base; + + err = rtcan_mscan_register(dev, irq, mscan_clksrc); + if (err) { + dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", + RTCAN_DRV_NAME, err); + goto exit_free_mscan; + } + + dev_set_drvdata(&ofdev->dev, dev); + + dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n", + base, irq, dev->can_sys_clock); + + return 0; + +exit_free_mscan: + rtcan_dev_free(dev); +exit_dispose_irq: + irq_dispose_mapping(irq); +exit_unmap_mem: + iounmap(base); + + return err; +} + +static int __devexit mpc5xxx_can_remove(struct of_device *ofdev) +{ + struct rtcan_device *dev = dev_get_drvdata(&ofdev->dev); + + dev_set_drvdata(&ofdev->dev, NULL); + + rtcan_mscan_unregister(dev); + iounmap((void *)dev->base_addr); + rtcan_dev_free(dev); + + return 0; +} + +static struct mpc5xxx_can_data __devinitdata mpc5200_can_data = { + .type = MSCAN_TYPE_MPC5200, + .get_clock = mpc52xx_can_get_clock, +}; + +static struct mpc5xxx_can_data __devinitdata mpc5121_can_data = { + .type = MSCAN_TYPE_MPC5121, + .get_clock = mpc512x_can_get_clock, +}; + +static struct of_device_id __devinitdata mpc5xxx_can_table[] = { + { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, }, + /* Note that only MPC5121 Rev. 2 (and later) is supported */ + { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, }, + {}, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) +static struct of_platform_driver mpc5xxx_can_driver = { + .driver = { + .owner = THIS_MODULE, + .name = RTCAN_DRV_NAME, + .of_match_table = mpc5xxx_can_table, + }, + .probe = mpc5xxx_can_probe, + .remove = __devexit_p(mpc5xxx_can_remove), +}; +#else +static struct of_platform_driver mpc5xxx_can_driver = { + .owner = THIS_MODULE, + .name = RTCAN_DRV_NAME, + .probe = mpc5xxx_can_probe, + .remove = __devexit_p(mpc5xxx_can_remove), + .match_table = mpc5xxx_can_table, +}; +#endif + +static int __init mpc5xxx_can_init(void) +{ + return of_register_platform_driver(&mpc5xxx_can_driver); +} +module_init(mpc5xxx_can_init); + +static void __exit mpc5xxx_can_exit(void) +{ + return of_unregister_platform_driver(&mpc5xxx_can_driver); +}; +module_exit(mpc5xxx_can_exit); + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RT-Socket-CAN driver for MPC5200 and MPC521x"); +MODULE_LICENSE("GPL v2"); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_proc.c relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_proc.c --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_proc.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * 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 +#include +#include + +#include + +/* CAN device profile */ +#include "rtcan_dev.h" +#include "rtcan_internal.h" +#include "rtcan_mscan_regs.h" + +#define MSCAN_REG_ARGS(reg) \ + "%-8s 0x%02x\n", #reg, (int)(in_8(®s->reg)) & 0xff + +#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG + +static int rtcan_mscan_proc_regs(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + struct rtcan_device *dev = (struct rtcan_device *)data; + struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr; +#ifdef MPC5xxx_GPIO + struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5xxx_GPIO; + u32 port_config; +#endif + u8 canctl0, canctl1; + RTCAN_PROC_PRINT_VARS(80); + + if (!RTCAN_PROC_PRINT("MSCAN registers at %p\n", regs)) + goto done; + canctl0 = in_8(®s->canctl0); + if (!RTCAN_PROC_PRINT("canctl0 0x%02x%s%s%s%s%s%s%s%s\n", + canctl0, + (canctl0 & MSCAN_RXFRM) ? " rxfrm" :"", + (canctl0 & MSCAN_RXACT) ? " rxact" :"", + (canctl0 & MSCAN_CSWAI) ? " cswai" :"", + (canctl0 & MSCAN_SYNCH) ? " synch" :"", + (canctl0 & MSCAN_TIME) ? " time" :"", + (canctl0 & MSCAN_WUPE) ? " wupe" :"", + (canctl0 & MSCAN_SLPRQ) ? " slprq" :"", + (canctl0 & MSCAN_INITRQ)? " initrq":"" )) + goto done; + canctl1 = in_8(®s->canctl1); + if (!RTCAN_PROC_PRINT("canctl1 0x%02x%s%s%s%s%s%s%s\n", + canctl1, + (canctl1 & MSCAN_CANE) ? " cane" :"", + (canctl1 & MSCAN_CLKSRC)? " clksrc":"", + (canctl1 & MSCAN_LOOPB) ? " loopb" :"", + (canctl1 & MSCAN_LISTEN)? " listen":"", + (canctl1 & MSCAN_WUPM) ? " wump" :"", + (canctl1 & MSCAN_SLPAK) ? " slpak" :"", + (canctl1 & MSCAN_INITAK)? " initak":"")) + goto done; + if (!RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canbtr0 )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canbtr1 )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canrflg )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canrier )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantflg )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantier )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantarq )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantaak )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantbsel)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidac )) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canrxerr)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(cantxerr)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar0)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar1)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar2)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar3)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr0)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr1)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr2)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr3)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar4)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar5)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar6)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidar7)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr4)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr5)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr6)) | + !RTCAN_PROC_PRINT(MSCAN_REG_ARGS(canidmr7))) + goto done; + +#ifdef MPC5xxx_GPIO + if (!RTCAN_PROC_PRINT("GPIO registers\n")) + goto done; + port_config = in_be32(&gpio->port_config); + if (!RTCAN_PROC_PRINT("port_config 0x%08x %s\n", port_config, + (port_config & 0x10000000 ? + "CAN1 on I2C1, CAN2 on TMR0/1 pins": + (port_config & 0x70) == 0x10 ? + "CAN1/2 on PSC2 pins": "MSCAN1/2 not routed"))) + goto done; +#endif + +done: + RTCAN_PROC_PRINT_DONE; +} + +int rtcan_mscan_create_proc(struct rtcan_device* dev) +{ + struct proc_dir_entry *proc_entry; + + if (!dev->proc_root) + return -EINVAL; + + proc_entry = create_proc_entry("registers", S_IFREG | S_IRUGO | S_IWUSR, + dev->proc_root); + if (!proc_entry) + goto error; + proc_entry->read_proc = rtcan_mscan_proc_regs; + proc_entry->data = dev; + + return 0; + +error: + printk("%s: unable to create /proc entries for MSCAN\n", dev->name); + return -1; +} + +void rtcan_mscan_remove_proc(struct rtcan_device* dev) +{ + if (!dev->proc_root) + return; + + remove_proc_entry("registers", dev->proc_root); +} + +#else /* !CONFIG_XENO_DRIVERS_CAN_DEBUG */ + +void rtcan_mscan_remove_proc(struct rtcan_device* dev) +{ +} + +int rtcan_mscan_create_proc(struct rtcan_device* dev) +{ + return 0; +} +#endif /* CONFIG_XENO_DRIVERS_CAN_DEBUG */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_regs.h relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_regs.h --- orig/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_regs.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/mscan/rtcan_mscan_regs.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Based on linux-2.4.25/include/asm-ppc/mpc5xxx.h + * Prototypes, etc. for the Motorola MPC5xxx embedded cpu chips + * + * Author: Dale Farnsworth + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_MSCAN_REGS_H_ +#define __RTCAN_MSCAN_REGS_H_ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || \ + defined(CONFIG_XENO_DRIVERS_CAN_MSCAN_OLD) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) +#include +#else +#include +#endif +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) +static inline void __iomem *mpc5xxx_gpio_find_and_map(void) +{ + struct device_node *ofn; + ofn = of_find_compatible_node(NULL, NULL, "mpc5200-gpio"); + if (!ofn) + ofn = of_find_compatible_node(NULL, NULL, "fsl,mpc5200-gpio"); + return ofn ? of_iomap(ofn, 0) : NULL; +} +#define MPC5xxx_GPIO mpc5xxx_gpio_find_and_map() +#else +#define MPC5xxx_GPIO mpc52xx_find_and_map("mpc5200-gpio") +#endif +#define mpc5xxx_gpio mpc52xx_gpio +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +#include +#define MSCAN_MBAR MPC5xxx_MBAR +#define MSCAN_CAN1_IRQ MPC5xxx_CAN1_IRQ +#define MSCAN_CAN2_IRQ MPC5xxx_CAN2_IRQ +#else +#include +#define MSCAN_MBAR MPC52xx_MBAR +#define MSCAN_CAN1_IRQ MPC52xx_MSCAN1_IRQ +#define MSCAN_CAN2_IRQ MPC52xx_MSCAN2_IRQ +#define MPC5xxx_GPIO MPC52xx_VA(MPC52xx_GPIO_OFFSET) +#define mpc5xxx_gpio mpc52xx_gpio +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) +#define mpc5xxx_get_of_node(ofdev) (ofdev)->dev.of_node +#else +#define mpc5xxx_get_of_node(ofdev) (ofdev)->node +#endif + +#define MSCAN_CAN1_ADDR (MSCAN_MBAR + 0x0900) /* MSCAN Module 1 */ +#define MSCAN_CAN2_ADDR (MSCAN_MBAR + 0x0980) /* MSCAN Module 2 */ +#define MSCAN_SIZE 0x80 + +/* MSCAN control register 0 (CANCTL0) bits */ +#define MSCAN_RXFRM 0x80 +#define MSCAN_RXACT 0x40 +#define MSCAN_CSWAI 0x20 +#define MSCAN_SYNCH 0x10 +#define MSCAN_TIME 0x08 +#define MSCAN_WUPE 0x04 +#define MSCAN_SLPRQ 0x02 +#define MSCAN_INITRQ 0x01 + +/* MSCAN control register 1 (CANCTL1) bits */ +#define MSCAN_CANE 0x80 +#define MSCAN_CLKSRC 0x40 +#define MSCAN_LOOPB 0x20 +#define MSCAN_LISTEN 0x10 +#define MSCAN_WUPM 0x04 +#define MSCAN_SLPAK 0x02 +#define MSCAN_INITAK 0x01 + +/* MSCAN receiver flag register (CANRFLG) bits */ +#define MSCAN_WUPIF 0x80 +#define MSCAN_CSCIF 0x40 +#define MSCAN_RSTAT1 0x20 +#define MSCAN_RSTAT0 0x10 +#define MSCAN_TSTAT1 0x08 +#define MSCAN_TSTAT0 0x04 +#define MSCAN_OVRIF 0x02 +#define MSCAN_RXF 0x01 + +/* MSCAN receiver interrupt enable register (CANRIER) bits */ +#define MSCAN_WUPIE 0x80 +#define MSCAN_CSCIE 0x40 +#define MSCAN_RSTATE1 0x20 +#define MSCAN_RSTATE0 0x10 +#define MSCAN_TSTATE1 0x08 +#define MSCAN_TSTATE0 0x04 +#define MSCAN_OVRIE 0x02 +#define MSCAN_RXFIE 0x01 + +/* MSCAN transmitter flag register (CANTFLG) bits */ +#define MSCAN_TXE2 0x04 +#define MSCAN_TXE1 0x02 +#define MSCAN_TXE0 0x01 +#define MSCAN_TXE (MSCAN_TXE2 | MSCAN_TXE1 | MSCAN_TXE0) + +/* MSCAN transmitter interrupt enable register (CANTIER) bits */ +#define MSCAN_TXIE2 0x04 +#define MSCAN_TXIE1 0x02 +#define MSCAN_TXIE0 0x01 +#define MSCAN_TXIE (MSCAN_TXIE2 | MSCAN_TXIE1 | MSCAN_TXIE0) + +/* MSCAN transmitter message abort request (CANTARQ) bits */ +#define MSCAN_ABTRQ2 0x04 +#define MSCAN_ABTRQ1 0x02 +#define MSCAN_ABTRQ0 0x01 + +/* MSCAN transmitter message abort ack (CANTAAK) bits */ +#define MSCAN_ABTAK2 0x04 +#define MSCAN_ABTAK1 0x02 +#define MSCAN_ABTAK0 0x01 + +/* MSCAN transmit buffer selection (CANTBSEL) bits */ +#define MSCAN_TX2 0x04 +#define MSCAN_TX1 0x02 +#define MSCAN_TX0 0x01 + +/* MSCAN ID acceptance control register (CANIDAC) bits */ +#define MSCAN_IDAM1 0x20 +#define MSCAN_IDAM0 0x10 +#define MSCAN_IDHIT2 0x04 +#define MSCAN_IDHIT1 0x02 +#define MSCAN_IDHIT0 0x01 + +struct mscan_msgbuf { + volatile u8 idr[0x8]; /* 0x00 */ + volatile u8 dsr[0x10]; /* 0x08 */ + volatile u8 dlr; /* 0x18 */ + volatile u8 tbpr; /* 0x19 */ /* This register is not applicable for receive buffers */ + volatile u16 rsrv1; /* 0x1A */ + volatile u8 tsrh; /* 0x1C */ + volatile u8 tsrl; /* 0x1D */ + volatile u16 rsrv2; /* 0x1E */ +}; + +struct mscan_regs { + volatile u8 canctl0; /* MSCAN + 0x00 */ + volatile u8 canctl1; /* MSCAN + 0x01 */ + volatile u16 rsrv1; /* MSCAN + 0x02 */ + volatile u8 canbtr0; /* MSCAN + 0x04 */ + volatile u8 canbtr1; /* MSCAN + 0x05 */ + volatile u16 rsrv2; /* MSCAN + 0x06 */ + volatile u8 canrflg; /* MSCAN + 0x08 */ + volatile u8 canrier; /* MSCAN + 0x09 */ + volatile u16 rsrv3; /* MSCAN + 0x0A */ + volatile u8 cantflg; /* MSCAN + 0x0C */ + volatile u8 cantier; /* MSCAN + 0x0D */ + volatile u16 rsrv4; /* MSCAN + 0x0E */ + volatile u8 cantarq; /* MSCAN + 0x10 */ + volatile u8 cantaak; /* MSCAN + 0x11 */ + volatile u16 rsrv5; /* MSCAN + 0x12 */ + volatile u8 cantbsel; /* MSCAN + 0x14 */ + volatile u8 canidac; /* MSCAN + 0x15 */ + volatile u16 rsrv6[3]; /* MSCAN + 0x16 */ + volatile u8 canrxerr; /* MSCAN + 0x1C */ + volatile u8 cantxerr; /* MSCAN + 0x1D */ + volatile u16 rsrv7; /* MSCAN + 0x1E */ + volatile u8 canidar0; /* MSCAN + 0x20 */ + volatile u8 canidar1; /* MSCAN + 0x21 */ + volatile u16 rsrv8; /* MSCAN + 0x22 */ + volatile u8 canidar2; /* MSCAN + 0x24 */ + volatile u8 canidar3; /* MSCAN + 0x25 */ + volatile u16 rsrv9; /* MSCAN + 0x26 */ + volatile u8 canidmr0; /* MSCAN + 0x28 */ + volatile u8 canidmr1; /* MSCAN + 0x29 */ + volatile u16 rsrv10; /* MSCAN + 0x2A */ + volatile u8 canidmr2; /* MSCAN + 0x2C */ + volatile u8 canidmr3; /* MSCAN + 0x2D */ + volatile u16 rsrv11; /* MSCAN + 0x2E */ + volatile u8 canidar4; /* MSCAN + 0x30 */ + volatile u8 canidar5; /* MSCAN + 0x31 */ + volatile u16 rsrv12; /* MSCAN + 0x32 */ + volatile u8 canidar6; /* MSCAN + 0x34 */ + volatile u8 canidar7; /* MSCAN + 0x35 */ + volatile u16 rsrv13; /* MSCAN + 0x36 */ + volatile u8 canidmr4; /* MSCAN + 0x38 */ + volatile u8 canidmr5; /* MSCAN + 0x39 */ + volatile u16 rsrv14; /* MSCAN + 0x3A */ + volatile u8 canidmr6; /* MSCAN + 0x3C */ + volatile u8 canidmr7; /* MSCAN + 0x3D */ + volatile u16 rsrv15; /* MSCAN + 0x3E */ + + struct mscan_msgbuf canrxfg; /* MSCAN + 0x40 */ /* Foreground receive buffer */ + struct mscan_msgbuf cantxfg; /* MSCAN + 0x60 */ /* Foreground transmit buffer */ +}; + +/* Clock source selection + */ +#define MSCAN_CLKSRC_BUS 0 +#define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC +#define MSCAN_CLKSRC_IPS MSCAN_CLKSRC + +/* Message type access macros. + */ +#define MSCAN_BUF_STD_RTR 0x10 +#define MSCAN_BUF_EXT_RTR 0x01 +#define MSCAN_BUF_EXTENDED 0x08 + +#define MSCAN_IDAM1 0x20 +/* Value for the interrupt enable register */ +#define MSCAN_RIER (MSCAN_OVRIE | \ + MSCAN_RXFIE | \ + MSCAN_WUPIF | \ + MSCAN_CSCIE | \ + MSCAN_RSTATE0 | \ + MSCAN_RSTATE1 | \ + MSCAN_TSTATE0 | \ + MSCAN_TSTATE1) + +#define BTR0_BRP_MASK 0x3f +#define BTR0_SJW_SHIFT 6 +#define BTR0_SJW_MASK (0x3 << BTR0_SJW_SHIFT) + +#define BTR1_TSEG1_MASK 0xf +#define BTR1_TSEG2_SHIFT 4 +#define BTR1_TSEG2_MASK (0x7 << BTR1_TSEG2_SHIFT) +#define BTR1_SAM_SHIFT 7 + +#define BTR0_SET_BRP(brp) (((brp) - 1) & BTR0_BRP_MASK) +#define BTR0_SET_SJW(sjw) ((((sjw) - 1) << BTR0_SJW_SHIFT) & \ + BTR0_SJW_MASK) + +#define BTR1_SET_TSEG1(tseg1) (((tseg1) - 1) & BTR1_TSEG1_MASK) +#define BTR1_SET_TSEG2(tseg2) ((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & \ + BTR1_TSEG2_MASK) +#define BTR1_SET_SAM(sam) (((sam) & 1) << BTR1_SAM_SHIFT) + +#endif /* __RTCAN_MSCAN_REGS_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from RTnet project file stack/rtdev.c: + * + * Copyright (C) 1999 Lineo, Inc + * 1999, 2002 David A. Schleef + * 2002 Ulrich Marx + * 2003-2005 Jan Kiszka + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include "rtcan_internal.h" +#include "rtcan_dev.h" + + +static struct rtcan_device *rtcan_devices[RTCAN_MAX_DEVICES]; +static rtdm_lock_t rtcan_devices_rt_lock = RTDM_LOCK_UNLOCKED; + +static int rtcan_global_init_done; + +DEFINE_SEMAPHORE(rtcan_devices_nrt_lock); + +/* Spinlock for all reception lists and also for some members in + * struct rtcan_socket */ +rtdm_lock_t rtcan_socket_lock; + +/* Spinlock for all reception lists and also for some members in + * struct rtcan_socket */ +rtdm_lock_t rtcan_recv_list_lock; + + + +static inline void rtcan_global_init(void) +{ + if (!rtcan_global_init_done) { + rtdm_lock_init(&rtcan_socket_lock); + rtdm_lock_init(&rtcan_recv_list_lock); + rtcan_global_init_done = 1; + } +} + + +static inline struct rtcan_device *__rtcan_dev_get_by_name(const char *name) +{ + int i; + struct rtcan_device *dev; + + + for (i = 0; i < RTCAN_MAX_DEVICES; i++) { + dev = rtcan_devices[i]; + if ((dev != NULL) && (strncmp(dev->name, name, IFNAMSIZ) == 0)) + return dev; + } + return NULL; +} + + +struct rtcan_device *rtcan_dev_get_by_name(const char *name) +{ + struct rtcan_device *dev; +#ifdef RTCAN_USE_REFCOUNT + rtdm_lockctx_t context; +#endif + + +#ifdef RTCAN_USE_REFCOUNT + rtdm_lock_get_irqsave(&rtcan_devices_rt_lock, context); +#endif + + dev = __rtcan_dev_get_by_name(name); + +#ifdef RTCAN_USE_REFCOUNT + if (dev != NULL) + atomic_inc(&dev->refcount); + rtdm_lock_put_irqrestore(&rtcan_devices_rt_lock, context); +#endif + + return dev; +} + + +static inline struct rtcan_device *__rtcan_dev_get_by_index(int ifindex) +{ + return rtcan_devices[ifindex - 1]; +} + + +struct rtcan_device *rtcan_dev_get_by_index(int ifindex) +{ + struct rtcan_device *dev; +#ifdef RTCAN_USE_REFCOUNT + rtdm_lockctx_t context; +#endif + + + if ((ifindex <= 0) || (ifindex > RTCAN_MAX_DEVICES)) + return NULL; + +#ifdef RTCAN_USE_REFCOUNT + rtdm_lock_get_irqsave(&rtcan_devices_rt_lock, context); +#endif + + dev = __rtcan_dev_get_by_index(ifindex); + +#ifdef RTCAN_USE_REFCOUNT + if (dev != NULL) + atomic_inc(&dev->refcount); + rtdm_lock_put_irqrestore(&rtcan_devices_rt_lock, context); +#endif + + return dev; +} + + +void rtcan_dev_alloc_name(struct rtcan_device *dev, const char *mask) +{ + char buf[IFNAMSIZ]; + struct rtcan_device *tmp; + int i; + + + for (i = 0; i < RTCAN_MAX_DEVICES; i++) { + snprintf(buf, IFNAMSIZ, mask, i); + if ((tmp = rtcan_dev_get_by_name(buf)) == NULL) { + strncpy(dev->name, buf, IFNAMSIZ); + break; + } +#ifdef RTCAN_USE_REFCOUNT + else + rtcan_dev_dereference(tmp); +#endif + } +} + + +struct rtcan_device *rtcan_dev_alloc(int sizeof_priv, int sizeof_board_priv) +{ + struct rtcan_device *dev; + struct rtcan_recv *recv_list_elem; + int alloc_size; + int j; + + + alloc_size = sizeof(*dev) + sizeof_priv + sizeof_board_priv; + + dev = (struct rtcan_device *)kmalloc(alloc_size, GFP_KERNEL); + if (dev == NULL) { + printk(KERN_ERR "rtcan: cannot allocate rtcan device\n"); + return NULL; + } + + memset(dev, 0, alloc_size); + + sema_init(&dev->nrt_lock, 1); + + rtdm_lock_init(&dev->device_lock); + + /* Init TX Semaphore, will be destroyed forthwith + * when setting stop mode */ + rtdm_sem_init(&dev->tx_sem, 0); +#ifdef RTCAN_USE_REFCOUNT + atomic_set(&dev->refcount, 0); +#endif + + /* Initialize receive list */ + dev->empty_list = recv_list_elem = dev->receivers; + for (j = 0; j < RTCAN_MAX_RECEIVERS - 1; j++, recv_list_elem++) + recv_list_elem->next = recv_list_elem + 1; + recv_list_elem->next = NULL; + dev->free_entries = RTCAN_MAX_RECEIVERS; + + if (sizeof_priv) + dev->priv = (void *)((unsigned long)dev + sizeof(*dev)); + if (sizeof_board_priv) + dev->board_priv = (void *)((unsigned long)dev + sizeof(*dev) + sizeof_priv); + + return dev; +} + +void rtcan_dev_free (struct rtcan_device *dev) +{ + if (dev != NULL) { + rtdm_sem_destroy(&dev->tx_sem); + kfree(dev); + } +} + + +static inline int __rtcan_dev_new_index(void) +{ + int i; + + + for (i = 0; i < RTCAN_MAX_DEVICES; i++) + if (rtcan_devices[i] == NULL) + return i+1; + + return -ENOMEM; +} + + +int rtcan_dev_register(struct rtcan_device *dev) +{ + rtdm_lockctx_t context; + int ret; + + down(&rtcan_devices_nrt_lock); + + rtcan_global_init(); + + if ((ret = __rtcan_dev_new_index()) < 0) { + up(&rtcan_devices_nrt_lock); + return ret; + } + dev->ifindex = ret; + + if (strchr(dev->name,'%') != NULL) + rtcan_dev_alloc_name(dev, dev->name); + + if (__rtcan_dev_get_by_name(dev->name) != NULL) { + up(&rtcan_devices_nrt_lock); + return -EEXIST; + } + + rtdm_lock_get_irqsave(&rtcan_devices_rt_lock, context); + + rtcan_devices[dev->ifindex - 1] = dev; + + rtdm_lock_put_irqrestore(&rtcan_devices_rt_lock, context); + rtcan_dev_create_proc(dev); + + up(&rtcan_devices_nrt_lock); + + printk("rtcan: registered %s\n", dev->name); + + return 0; +} + + +int rtcan_dev_unregister(struct rtcan_device *dev) +{ + rtdm_lockctx_t context; + + + RTCAN_ASSERT(dev->ifindex != 0, + printk("RTCAN: device %s/%p was not registered\n", + dev->name, dev); return -ENODEV;); + + /* If device is running, close it first. */ + if (CAN_STATE_OPERATING(dev->state)) + return -EBUSY; + + down(&rtcan_devices_nrt_lock); + + rtcan_dev_remove_proc(dev); + + rtdm_lock_get_irqsave(&rtcan_devices_rt_lock, context); + +#ifdef RTCAN_USE_REFCOUNT + while (atomic_read(&dev->refcount) > 0) { + rtdm_lock_put_irqrestore(&rtcan_devices_rt_lock, context); + up(&rtcan_devices_nrt_lock); + + RTCAN_DBG("RTCAN: unregistering %s deferred (refcount = %d)\n", + dev->name, atomic_read(&dev->refcount)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1*HZ); /* wait a second */ + + down(&rtcan_devices_nrt_lock); + rtdm_lock_get_irqsave(&rtcan_devices_rt_lock, context); + } +#endif + rtcan_devices[dev->ifindex - 1] = NULL; + + rtdm_lock_put_irqrestore(&rtcan_devices_rt_lock, context); + up(&rtcan_devices_nrt_lock); + +#ifdef RTCAN_USE_REFCOUNT + RTCAN_ASSERT(atomic_read(&dev->refcount) == 0, + printk("RTCAN: dev reference counter < 0!\n");); +#endif + + printk("RTCAN: unregistered %s\n", dev->name); + + return 0; +} + + +EXPORT_SYMBOL_GPL(rtcan_socket_lock); +EXPORT_SYMBOL_GPL(rtcan_recv_list_lock); + +EXPORT_SYMBOL_GPL(rtcan_dev_free); + +EXPORT_SYMBOL_GPL(rtcan_dev_alloc); +EXPORT_SYMBOL_GPL(rtcan_dev_alloc_name); + +EXPORT_SYMBOL_GPL(rtcan_dev_register); +EXPORT_SYMBOL_GPL(rtcan_dev_unregister); + +EXPORT_SYMBOL_GPL(rtcan_dev_get_by_name); +EXPORT_SYMBOL_GPL(rtcan_dev_get_by_index); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_dev.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from RTnet project file stack/include/rtdev.h: + * + * Copyright (C) 1999 Lineo, Inc + * 1999, 2002 David A. Schleef + * 2003-2005 Jan Kiszka + * + * + * 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. + */ + +#ifndef __RTCAN_DEV_H_ +#define __RTCAN_DEV_H_ + + +#ifdef __KERNEL__ + +#include +#include + +#include "rtcan_list.h" + + +/* Number of MSCAN devices the driver can handle */ +#define RTCAN_MAX_DEVICES CONFIG_XENO_DRIVERS_CAN_MAX_DEVICES + +/* Maximum number of single filters per controller which can be registered + * for reception at the same time using Bind */ +#define RTCAN_MAX_RECEIVERS CONFIG_XENO_DRIVERS_CAN_MAX_RECEIVERS + +/* Suppress handling of refcount if module support is not enabled + * or modules cannot be unloaded */ + +#if defined(CONFIG_MODULES) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || \ + defined(CONFIG_MODULE_UNLOAD)) +#define RTCAN_USE_REFCOUNT +#endif + + +struct rtcan_device { + unsigned int version; + + char name[IFNAMSIZ]; + + char *ctrl_name; /* Name of CAN controller */ + char *board_name;/* Name of CAN board */ + + unsigned long base_addr; /* device I/O address */ + rtdm_irq_t irq_handle; /* RTDM IRQ handle */ + + int ifindex; +#ifdef RTCAN_USE_REFCOUNT + atomic_t refcount; +#endif + + void *priv; /* pointer to chip private data */ + + void *board_priv;/* pointer to board private data*/ + + struct semaphore nrt_lock; /* non-real-time locking */ + + /* Spinlock for all devices (but not for all attributes) and also for HW + * access to all CAN controllers + */ + rtdm_lock_t device_lock; + + /* Acts as a mutex allowing only one sender to write to the MSCAN + * simultaneously. Created when the controller goes into operating mode, + * destroyed if it goes into reset mode. */ + rtdm_sem_t tx_sem; + + /* Baudrate of this device. Protected by device_lock in all device + * structures. */ + unsigned int can_sys_clock; + + + /* Baudrate of this device. Protected by device_lock in all device + * structures. */ + can_baudrate_t baudrate; + + struct can_bittime bit_time; + + /* State which the controller is in. Protected by device_lock in all + * device structures. */ + can_state_t state; + + /* State which the controller was before sleeping. Protected by + * device_lock in all device structures. */ + can_state_t state_before_sleep; + + /* Controller specific settings. Protected by device_lock in all + * device structures. */ + can_ctrlmode_t ctrl_mode; + + /* Device operations */ + int (*hard_start_xmit)(struct rtcan_device *dev, + struct can_frame *frame); + int (*do_set_mode)(struct rtcan_device *dev, + can_mode_t mode, + rtdm_lockctx_t *lock_ctx); + can_state_t (*do_get_state)(struct rtcan_device *dev); + int (*do_set_bit_time)(struct rtcan_device *dev, + struct can_bittime *bit_time, + rtdm_lockctx_t *lock_ctx); +#ifdef CONFIG_XENO_DRIVERS_CAN_BUS_ERR + void (*do_enable_bus_err)(struct rtcan_device *dev); +#endif + + /* Reception list head. This list contains all filters which have been + * registered via a bind call. */ + struct rtcan_recv *recv_list; + + /* Empty list head. This list contains all empty entries not needed + * by the reception list and therefore is disjunctive with it. */ + struct rtcan_recv *empty_list; + + /* Preallocated array for the list entries. To increase cache + * locality all list elements are kept in this array. */ + struct rtcan_recv receivers[RTCAN_MAX_RECEIVERS]; + + /* Indicates the length of the empty list */ + int free_entries; + + /* A few statistics counters */ + unsigned int tx_count; + unsigned int rx_count; + unsigned int err_count; + +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_root; +#endif +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK + struct rtcan_skb tx_skb; + struct rtcan_socket *tx_socket; +#endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */ +}; + + +extern struct semaphore rtcan_devices_nrt_lock; + + +void rtcan_dev_free(struct rtcan_device *dev); + +int rtcan_dev_register(struct rtcan_device *dev); +int rtcan_dev_unregister(struct rtcan_device *dev); + +struct rtcan_device *rtcan_dev_alloc(int sizeof_priv, int sizeof_board_priv); +void rtcan_dev_alloc_name (struct rtcan_device *dev, const char *name_mask); + +struct rtcan_device *rtcan_dev_get_by_name(const char *if_name); +struct rtcan_device *rtcan_dev_get_by_index(int ifindex); + +#ifdef RTCAN_USE_REFCOUNT +#define rtcan_dev_reference(dev) atomic_inc(&(dev)->refcount) +#define rtcan_dev_dereference(dev) atomic_dec(&(dev)->refcount) +#else +#define rtcan_dev_reference(dev) do {} while(0) +#define rtcan_dev_dereference(dev) do {} while(0) +#endif + +#ifdef CONFIG_PROC_FS +int rtcan_dev_create_proc(struct rtcan_device* dev); +void rtcan_dev_remove_proc(struct rtcan_device* dev); +#else /* !CONFIG_PROC_FS */ +static inline int rtcan_dev_create_proc(struct rtcan_device* dev) +{ + return 0; +} +static inline void rtcan_dev_remove_proc(struct rtcan_device* dev) { } +#endif /* !CONFIG_PROC_FS */ + +#endif /* __KERNEL__ */ + +#endif /* __RTCAN_DEV_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_internal.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_internal.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_internal.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_internal.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from RTnet project file stack/include/rtnet_internal.h: + * + * Copyright (C) 1999 Lineo, Inc + * 1999, 2002 David A. Schleef + * 2002 Ulrich Marx + * 2003-2005 Jan Kiszka + * + * 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. + */ + +#ifndef __RTCAN_INTERNAL_H_ +#define __RTCAN_INTERNAL_H_ + +#include +#include + +#ifndef LIST_POISON1 +/* 2.4 - 2.6 compatibility stuff */ +#define LIST_POISON1 ((void *) 0x0) +#endif + +#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG +#define RTCAN_ASSERT(expr, func) \ + if (!(expr)) { \ + rtdm_printk("Assertion failed! %s:%s:%d %s\n", \ + __FILE__, __FUNCTION__, __LINE__, (#expr)); \ + func \ + } +#else +#define RTCAN_ASSERT(expr, func) +#endif /* CONFIG_RTCAN_CHECKED */ + +#ifdef CONFIG_PROC_FS +#include + +/* Derived from Erwin Rol's rtai_proc_fs.h. + Standard version assumes that output fits into the provided buffer, + extended version also deals with potential fragmentation. */ + +#define RTCAN_PROC_PRINT_VARS(MAX_BLOCK_LEN) \ + const int max_block_len = MAX_BLOCK_LEN; \ + off_t __limit = count - MAX_BLOCK_LEN; \ + int __len = 0; \ + \ + *eof = 1; \ + if (count < MAX_BLOCK_LEN) \ + return 0 + +#define RTCAN_PROC_PRINT(fmt, args...) \ + ({ \ + __len += snprintf(buf + __len, max_block_len, fmt, ##args); \ + (__len <= __limit); \ + }) + +#define RTCAN_PROC_PRINT_DONE \ + return __len + + +#define RTCAN_PROC_PRINT_VARS_EX(MAX_BLOCK_LEN) \ + const int max_block_len = MAX_BLOCK_LEN; \ + off_t __limit = offset + count - MAX_BLOCK_LEN; \ + off_t __pos = 0; \ + off_t __begin = 0; \ + int __len = 0; \ + \ + *eof = 1; \ + if (count < MAX_BLOCK_LEN) \ + return 0 + +#define RTCAN_PROC_PRINT_EX(fmt, args...) \ + ({ \ + int len = snprintf(buf + __len, max_block_len, fmt, ##args); \ + __len += len; \ + __pos += len; \ + if (__pos < offset) { \ + __len = 0; \ + __begin = __pos; \ + } \ + if (__pos > __limit) \ + *eof = 0; \ + (__pos <= __limit); \ + }) + +#define RTCAN_PROC_PRINT_DONE_EX \ + *start = buf + (offset - __begin); \ + __len -= (offset - __begin); \ + if (__len > count) \ + __len = count; \ + if (__len < 0) \ + __len = 0; \ + return __len; + +#endif /* CONFIG_PROC_FS */ + +#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG +# define RTCAN_DBG(fmt,args...) do { printk(fmt ,##args); } while (0) +# define RTCAN_RTDM_DBG(fmt,args...) do { rtdm_printk(fmt ,##args); } while (0) +#else +# define RTCAN_DBG(fmt,args...) do {} while (0) +# define RTCAN_RTDM_DBG(fmt,args...) do {} while (0) +#endif + +#endif /* __RTCAN_INTERNAL_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_list.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_list.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_list.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_list.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,68 @@ +/* + * List management for the RTDM RTCAN device driver + * + * Copyright (C) 2005,2006 Sebastian Smolorz + * + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_LIST_H_ +#define __RTCAN_LIST_H_ + +#include "rtcan_socket.h" + + +/* + * List element in a single linked list used for registering reception sockets. + * Every single struct can_filter which was bound to a socket gets such a + * list entry. There is no member for the CAN interface because there is one + * reception list for every CAN controller. This is because when a CAN message + * is received it is clear from which interface and therefore minimizes + * searching time. + */ +struct rtcan_recv { + can_filter_t can_filter; /* filter used for deciding if + * a socket wants to get a CAN + * message */ + unsigned int match_count; /* count accepted messages */ + struct rtcan_socket *sock; /* pointer to registered socket + */ + struct rtcan_recv *next; /* pointer to next list element + */ +}; + + +/* + * Element in a TX wait queue. + * + * Every socket holds a TX wait queue where all RT tasks are queued when they + * are blocked while waiting to be able to transmit a message via this socket. + * + * Every sender holds its own element. + */ +struct tx_wait_queue { + struct list_head tx_wait_list; /* List pointers */ + rtdm_task_t *rt_task; /* Pointer to task handle */ +}; + + +/* Spinlock for all reception lists and also for some members in + * struct rtcan_socket */ +extern rtdm_lock_t rtcan_recv_list_lock; + + +#endif /* __RTCAN_LIST_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_module.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_module.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_module.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_module.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from RTnet project file stack/rtcan_module.c: + * + * Copyright (C) 2002 Ulrich Marx + * 2003-2006 Jan Kiszka + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + + +const char rtcan_rtdm_provider_name[] = + "(C) 2006 RT-Socket-CAN Development Team"; + + +#ifdef CONFIG_PROC_FS + +struct proc_dir_entry *rtcan_proc_root; + +static void rtcan_dev_get_ctrlmode_name(can_ctrlmode_t ctrlmode, + char* name, int max_len) +{ + *name = '\0'; + if (ctrlmode & CAN_CTRLMODE_LISTENONLY) + strncat(name, "listen-only ", max_len); + if (ctrlmode & CAN_CTRLMODE_LOOPBACK) + strncat(name, "loopback ", max_len); +} + +static char *rtcan_state_names[] = { + "active", "warning", "passive" , "bus-off", + "scanning", "stopped", "sleeping" +}; + +static void rtcan_dev_get_state_name(can_state_t state, + char* name, int max_len) +{ + if (state >= CAN_STATE_ACTIVE && + state <= CAN_STATE_SLEEPING) + strncpy(name, rtcan_state_names[state], max_len); + else + strncpy(name, "unknown", max_len); +} + +static void rtcan_dev_get_baudrate_name(can_baudrate_t baudrate, + char* name, int max_len) +{ + switch (baudrate) { + case CAN_BAUDRATE_UNCONFIGURED: + strncpy(name, "undefined", max_len); + break; + case CAN_BAUDRATE_UNKNOWN: + strncpy(name, "unknown", max_len); + break; + default: + snprintf(name, max_len, "%d", baudrate); + break; + } +} + +static void rtcan_dev_get_bittime_name(struct can_bittime *bit_time, + char* name, int max_len) +{ + switch (bit_time->type) { + case CAN_BITTIME_STD: + snprintf(name, max_len, + "brp=%d prop_seg=%d phase_seg1=%d " + "phase_seg2=%d sjw=%d sam=%d", + bit_time->std.brp, + bit_time->std.prop_seg, + bit_time->std.phase_seg1, + bit_time->std.phase_seg2, + bit_time->std.sjw, + bit_time->std.sam); + break; + case CAN_BITTIME_BTR: + snprintf(name, max_len, "btr0=0x%02x btr1=0x%02x", + bit_time->btr.btr0, bit_time->btr.btr1); + break; + default: + strncpy(name, "unknown", max_len); + break; + } +} + +static void rtcan_get_timeout_name(nanosecs_rel_t timeout, + char* name, int max_len) +{ + if (timeout == RTDM_TIMEOUT_INFINITE) + strncpy(name, "infinite", max_len); + else + sprintf(name, "%lld", (long long)timeout); +} + +static int rtcan_read_proc_devices(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int i, ret; + struct rtcan_device *dev; + char state_name[20], baudrate_name[20]; + RTCAN_PROC_PRINT_VARS(80); + + if (down_interruptible(&rtcan_devices_nrt_lock)) + return -ERESTARTSYS; + + /* Name___________ _Baudrate State___ _TX_Counts _TX_Counts ____Errors + * rtcan0 125000 stopped 1234567890 1234567890 1234567890 + * rtcan1 undefined warning 1234567890 1234567890 1234567890 + * rtcan2 undefined scanning 1234567890 1234567890 1234567890 + */ + if (!RTCAN_PROC_PRINT("Name___________ _Baudrate State___ " + "TX_Counter RX_Counter ____Errors\n")) + goto done; + + for (i = 1; i <= RTCAN_MAX_DEVICES; i++) { + if ((dev = rtcan_dev_get_by_index(i)) != NULL) { + rtcan_dev_get_state_name(dev->state, state_name, 20); + rtcan_dev_get_baudrate_name(dev->baudrate, baudrate_name, 20); + ret = RTCAN_PROC_PRINT("%-15s %9s %-8s %10d %10d %10d\n", + dev->name, baudrate_name, state_name, + dev->tx_count, dev->rx_count, dev->err_count); + rtcan_dev_dereference(dev); + if (!ret) + break; + } + } + + done: + up(&rtcan_devices_nrt_lock); + RTCAN_PROC_PRINT_DONE; +} + + +static int rtcan_read_proc_sockets(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + struct rtcan_socket *sock; + struct rtdm_dev_context *context; + struct rtcan_device *dev; + char name[IFNAMSIZ] = "not-bound"; + char rx_timeout[20], tx_timeout[16]; + rtdm_lockctx_t lock_ctx; + int ifindex; + RTCAN_PROC_PRINT_VARS(120); + + if (down_interruptible(&rtcan_devices_nrt_lock)) + return -ERESTARTSYS; + + /* fd Name___________ Filter ErrMask RX_Timeout TX_Timeout RX_BufFull TX_Lo + * 0 rtcan0 1 0x00010 1234567890 1234567890 1234567890 12345 + */ + if (!RTCAN_PROC_PRINT("fd Name___________ Filter ErrMask RX_Timeout_ns " + "TX_Timeout_ns RX_BufFull TX_Lo\n")) + goto done; + + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + + list_for_each_entry(sock, &rtcan_socket_list, socket_list) { + context = rtcan_socket_context(sock); + if (rtcan_sock_is_bound(sock)) { + ifindex = atomic_read(&sock->ifindex); + if (ifindex) { + dev = rtcan_dev_get_by_index(ifindex); + if (dev) { + strncpy(name, dev->name, IFNAMSIZ); + rtcan_dev_dereference(dev); + } + } else + sprintf(name, "%d", ifindex); + } + rtcan_get_timeout_name(sock->tx_timeout, tx_timeout, 20); + rtcan_get_timeout_name(sock->rx_timeout, rx_timeout, 20); + if (!RTCAN_PROC_PRINT("%2d %-15s %6d 0x%05x %13s %13s %10d %5d\n", + context->fd, name, sock->flistlen, + sock->err_mask, rx_timeout, tx_timeout, + sock->rx_buf_full, + rtcan_loopback_enabled(sock))) + break; + } + + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + done: + up(&rtcan_devices_nrt_lock); + RTCAN_PROC_PRINT_DONE; +} + + +static int rtcan_read_proc_info(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + struct rtcan_device *dev = (struct rtcan_device *)data; + char state_name[20], baudrate_name[20]; + char ctrlmode_name[80], bittime_name[80]; + RTCAN_PROC_PRINT_VARS(80); + + if (down_interruptible(&rtcan_devices_nrt_lock)) + return -ERESTARTSYS; + + rtcan_dev_get_state_name(dev->state, state_name, 20); + rtcan_dev_get_ctrlmode_name(dev->ctrl_mode, ctrlmode_name, 80); + rtcan_dev_get_baudrate_name(dev->baudrate, baudrate_name, 20); + rtcan_dev_get_bittime_name(&dev->bit_time, bittime_name, 80); + + if (!RTCAN_PROC_PRINT("%s %s\n", "Device ", dev->name) || + !RTCAN_PROC_PRINT("%s %s\n", "Controller", dev->ctrl_name) || + !RTCAN_PROC_PRINT("%s %s\n", "Board ", dev->board_name) || + !RTCAN_PROC_PRINT("%s %d\n", "Clock-Hz ", dev->can_sys_clock) || + !RTCAN_PROC_PRINT("%s %s\n", "Baudrate ", baudrate_name) || + !RTCAN_PROC_PRINT("%s %s\n", "Bit-time ", bittime_name) || + !RTCAN_PROC_PRINT("%s %s\n", "Ctrl-Mode ", ctrlmode_name) || + !RTCAN_PROC_PRINT("%s %s\n", "State ", state_name) || + !RTCAN_PROC_PRINT("%s %d\n", "TX-Counter", dev->tx_count) || + !RTCAN_PROC_PRINT("%s %d\n", "RX-Counter", dev->rx_count) || + !RTCAN_PROC_PRINT("%s %d\n", "Errors ", dev->err_count)) + goto done; + +#ifdef RTCAN_USE_REFCOUNT + if (!RTCAN_PROC_PRINT("%s %d\n", "Refcount ", atomic_read(&dev->refcount))) + goto done; +#endif + + done: + up(&rtcan_devices_nrt_lock); + RTCAN_PROC_PRINT_DONE; +} + + + +static int rtcan_read_proc_filter(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + struct rtcan_device *dev = (struct rtcan_device *)data; + struct rtcan_recv *recv_listener = dev->recv_list; + struct rtdm_dev_context *context; + rtdm_lockctx_t lock_ctx; + RTCAN_PROC_PRINT_VARS(80); + + /* fd __CAN_ID__ _CAN_Mask_ Inv MatchCount + * 3 0x12345678 0x12345678 no 1234567890 + */ + + if (!RTCAN_PROC_PRINT("fd __CAN_ID__ _CAN_Mask_ Inv MatchCount\n")) + goto done; + + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + + /* Loop over the reception list of the device */ + while (recv_listener != NULL) { + context = rtcan_socket_context(recv_listener->sock); + + if (!RTCAN_PROC_PRINT("%2d 0x%08x 0x%08x %s %10d\n", + context->fd, + recv_listener->can_filter.can_id, + recv_listener->can_filter.can_mask & + ~CAN_INV_FILTER, + (recv_listener->can_filter.can_mask & + CAN_INV_FILTER) ? "yes" : " no", + recv_listener->match_count)) + break; + recv_listener = recv_listener->next; + } + + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + done: + RTCAN_PROC_PRINT_DONE; +} + + + +static int rtcan_read_proc_version(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + RTCAN_PROC_PRINT_VARS(80); + + RTCAN_PROC_PRINT("RT-Socket-CAN %d.%d.%d - built on %s %s\n", + RTCAN_MAJOR_VER, RTCAN_MINOR_VER, RTCAN_BUGFIX_VER, + __DATE__, __TIME__); + + RTCAN_PROC_PRINT_DONE; +} + + +void rtcan_dev_remove_proc(struct rtcan_device* dev) +{ + if (!dev->proc_root) + return; + + remove_proc_entry("info", dev->proc_root); + remove_proc_entry("filters", dev->proc_root); + remove_proc_entry(dev->name, rtcan_proc_root); + + dev->proc_root = NULL; +} + +int rtcan_dev_create_proc(struct rtcan_device* dev) +{ + struct proc_dir_entry *proc_entry; + + if (!rtcan_proc_root) + return -EINVAL; + + dev->proc_root = create_proc_entry(dev->name, S_IFDIR, rtcan_proc_root); + if (!dev->proc_root) + goto error1; + + proc_entry = create_proc_entry("info", S_IFREG | S_IRUGO | S_IWUSR, + dev->proc_root); + if (!proc_entry) + goto error2; + proc_entry->read_proc = rtcan_read_proc_info; + proc_entry->data = dev; + + proc_entry = create_proc_entry("filters", S_IFREG | S_IRUGO | S_IWUSR, + dev->proc_root); + if (!proc_entry) + goto error3; + proc_entry->read_proc = rtcan_read_proc_filter; + proc_entry->data = dev; + + return 0; + + error3: + remove_proc_entry("info", dev->proc_root); + error2: + remove_proc_entry(dev->name, rtcan_proc_root); + error1: + printk("%s: unable to create /proc device entries\n", dev->name); + return -1; + +} + + +static int rtcan_proc_register(void) +{ + struct proc_dir_entry *proc_entry; + + rtcan_proc_root = create_proc_entry("rtcan", S_IFDIR, 0); + if (!rtcan_proc_root) + goto error1; + + proc_entry = create_proc_entry("devices", S_IFREG | S_IRUGO | S_IWUSR, + rtcan_proc_root); + if (!proc_entry) + goto error2; + proc_entry->read_proc = rtcan_read_proc_devices; + + proc_entry = create_proc_entry("version", S_IFREG | S_IRUGO | S_IWUSR, + rtcan_proc_root); + if (!proc_entry) + goto error3; + proc_entry->read_proc = rtcan_read_proc_version; + + proc_entry = create_proc_entry("sockets", S_IFREG | S_IRUGO | S_IWUSR, + rtcan_proc_root); + if (!proc_entry) + goto error4; + proc_entry->read_proc = rtcan_read_proc_sockets; + + return 0; + + error4: + remove_proc_entry("version", rtcan_proc_root); + + error3: + remove_proc_entry("devices", rtcan_proc_root); + + error2: + remove_proc_entry("rtcan", 0); + + error1: + printk("rtcan: unable to initialize /proc entries\n"); + return -1; +} + + + +static void rtcan_proc_unregister(void) +{ + remove_proc_entry("devices", rtcan_proc_root); + remove_proc_entry("version", rtcan_proc_root); + remove_proc_entry("sockets", rtcan_proc_root); + remove_proc_entry("rtcan", 0); +} +#endif /* CONFIG_PROC_FS */ + + + +int __init rtcan_init(void) +{ + int err = 0; + + + printk("RT-Socket-CAN %d.%d.%d - %s\n", + RTCAN_MAJOR_VER, RTCAN_MINOR_VER, RTCAN_BUGFIX_VER, + rtcan_rtdm_provider_name); + + if ((err = rtcan_raw_proto_register()) != 0) + goto out; + +#ifdef CONFIG_PROC_FS + if ((err = rtcan_proc_register()) != 0) + goto out; +#endif + + out: + return err; +} + + +void __exit rtcan_exit(void) +{ + + rtcan_raw_proto_unregister(); +#ifdef CONFIG_PROC_FS + rtcan_proc_unregister(); +#endif + + printk("rtcan: unloaded\n"); +} + + +module_init(rtcan_init); +module_exit(rtcan_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1050 @@ +/* + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * Parts of this software are based on the following: + * + * - RTAI CAN device driver for SJA1000 controllers by Jan Kiszka + * + * - linux-can.patch, a CAN socket framework for Linux, + * Copyright (C) 2004, 2005, Robert Schwebel, Benedikt Spranger, + * Marc Kleine-Budde, Sascha Hauer, Pengutronix + * + * - RTnet (www.rtnet.org) + * + * - serial device driver and profile included in Xenomai (RTDM), + * Copyright (C) 2005 Jan Kiszka . + * + * + * 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 +#include + +#include + +#include +#include "rtcan_version.h" +#include "rtcan_socket.h" +#include "rtcan_list.h" +#include "rtcan_dev.h" +#include "rtcan_raw.h" +#include "rtcan_internal.h" + + +/* + * Set if socket wants to receive a high precision timestamp together with + * CAN frames + */ +#define RTCAN_GET_TIMESTAMP RTDM_USER_CONTEXT_FLAG + + +MODULE_AUTHOR("RT-Socket-CAN Development Team"); +MODULE_DESCRIPTION("RTDM CAN raw socket device driver"); +MODULE_LICENSE("GPL"); + +void rtcan_tx_push(struct rtcan_device *dev, struct rtcan_socket *sock, + can_frame_t *frame); + +static struct rtdm_device rtcan_proto_raw_dev; + + +static inline int rtcan_accept_msg(uint32_t can_id, can_filter_t *filter) +{ + if ((filter->can_mask & CAN_INV_FILTER)) + return ((can_id & filter->can_mask) != filter->can_id); + else + return ((can_id & filter->can_mask) == filter->can_id); +} + + +static void rtcan_rcv_deliver(struct rtcan_recv *recv_listener, + struct rtcan_skb *skb) +{ + int size_free; + size_t cpy_size, first_part_size; + struct rtcan_rb_frame *frame = &skb->rb_frame; + struct rtcan_socket *sock = recv_listener->sock; + struct rtdm_dev_context *context = rtcan_socket_context(sock); + + cpy_size = skb->rb_frame_size; + /* Check if socket wants to receive a timestamp */ + if (test_bit(RTCAN_GET_TIMESTAMP, &context->context_flags)) { + cpy_size += RTCAN_TIMESTAMP_SIZE; + frame->can_dlc |= RTCAN_HAS_TIMESTAMP; + } else + frame->can_dlc &= RTCAN_HAS_NO_TIMESTAMP; + + /* Calculate free size in the ring buffer */ + size_free = sock->recv_head - sock->recv_tail; + if (size_free <= 0) + size_free += RTCAN_RXBUF_SIZE; + + /* Test if ring buffer has enough space. */ + if (size_free > cpy_size) { + /* Check if we must wrap around the end of buffer */ + if ((sock->recv_tail + cpy_size) > RTCAN_RXBUF_SIZE) { + /* Wrap around: Two memcpy operations */ + + first_part_size = RTCAN_RXBUF_SIZE - sock->recv_tail; + + memcpy(&sock->recv_buf[sock->recv_tail], (void *)frame, + first_part_size); + memcpy(&sock->recv_buf[0], (void *)frame + + first_part_size, cpy_size - first_part_size); + } else + memcpy(&sock->recv_buf[sock->recv_tail], (void *)frame, + cpy_size); + + /* Adjust tail */ + sock->recv_tail = (sock->recv_tail + cpy_size) & + (RTCAN_RXBUF_SIZE - 1); + + /*Notify the delivery of the message */ + rtdm_sem_up(&sock->recv_sem); + + } else { + /* Overflow of socket's ring buffer! */ + sock->rx_buf_full++; + RTCAN_RTDM_DBG("%s: socket buffer overflow (fd=%d), message discarded\n", + rtcan_proto_raw_dev.driver_name, context->fd); + } +} + + +void rtcan_rcv(struct rtcan_device *dev, struct rtcan_skb *skb) +{ + nanosecs_abs_t timestamp = rtdm_clock_read(); + /* Entry in reception list, begin with head */ + struct rtcan_recv *recv_listener = dev->recv_list; + struct rtcan_rb_frame *frame = &skb->rb_frame; + + /* Copy timestamp to skb */ + memcpy((void *)&skb->rb_frame + skb->rb_frame_size, + ×tamp, RTCAN_TIMESTAMP_SIZE); + + if ((frame->can_id & CAN_ERR_FLAG)) { + dev->err_count++; + while (recv_listener != NULL) { + if ((frame->can_id & recv_listener->sock->err_mask)) { + recv_listener->match_count++; + rtcan_rcv_deliver(recv_listener, skb); + } + recv_listener = recv_listener->next; + } + } else { + dev->rx_count++; + while (recv_listener != NULL) { + if (rtcan_accept_msg(frame->can_id, &recv_listener->can_filter)) { + recv_listener->match_count++; + rtcan_rcv_deliver(recv_listener, skb); + } + recv_listener = recv_listener->next; + } + } +} + +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK + +void rtcan_tx_push(struct rtcan_device *dev, struct rtcan_socket *sock, + can_frame_t *frame) +{ + struct rtcan_rb_frame *rb_frame = &dev->tx_skb.rb_frame; + + RTCAN_ASSERT(dev->tx_socket == 0, + rtdm_printk("(%d) TX skb still in use", dev->ifindex);); + + rb_frame->can_id = frame->can_id; + rb_frame->can_dlc = frame->can_dlc; + dev->tx_skb.rb_frame_size = EMPTY_RB_FRAME_SIZE; + if (frame->can_dlc && !(frame->can_id & CAN_RTR_FLAG)) { + memcpy(rb_frame->data, frame->data, frame->can_dlc); + dev->tx_skb.rb_frame_size += frame->can_dlc; + } + rb_frame->can_ifindex = dev->ifindex; + dev->tx_socket = sock; +} + +void rtcan_loopback(struct rtcan_device *dev) +{ + nanosecs_abs_t timestamp = rtdm_clock_read(); + /* Entry in reception list, begin with head */ + struct rtcan_recv *recv_listener = dev->recv_list; + struct rtcan_rb_frame *frame = &dev->tx_skb.rb_frame; + + memcpy((void *)&dev->tx_skb.rb_frame + dev->tx_skb.rb_frame_size, + ×tamp, RTCAN_TIMESTAMP_SIZE); + + while (recv_listener != NULL) { + dev->rx_count++; + if ((dev->tx_socket != recv_listener->sock) && + rtcan_accept_msg(frame->can_id, &recv_listener->can_filter)) { + recv_listener->match_count++; + rtcan_rcv_deliver(recv_listener, &dev->tx_skb); + } + recv_listener = recv_listener->next; + } + dev->tx_socket = NULL; +} + +EXPORT_SYMBOL_GPL(rtcan_loopback); + +#endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */ + + +int rtcan_raw_socket(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int protocol) +{ + /* Only protocol CAN_RAW is supported */ + if (protocol != CAN_RAW && protocol != 0) + return -EPROTONOSUPPORT; + + rtcan_socket_init(context); + + return 0; +} + + +static inline void rtcan_raw_unbind(struct rtcan_socket *sock) +{ + rtcan_raw_remove_filter(sock); + if (!rtcan_flist_no_filter(sock->flist) && sock->flist) + rtdm_free(sock->flist); + sock->flist = NULL; + sock->flistlen = RTCAN_SOCK_UNBOUND; + atomic_set(&sock->ifindex, 0); +} + + +static int rtcan_raw_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + struct rtcan_socket *sock = + (struct rtcan_socket *)&context->dev_private; + rtdm_lockctx_t lock_ctx; + + /* Get lock for reception lists */ + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + + /* Check if socket is bound */ + if (rtcan_sock_is_bound(sock)) + rtcan_raw_unbind(sock); + + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + + rtcan_socket_cleanup(context); + + return 0; +} + + +int rtcan_raw_bind(struct rtdm_dev_context *context, + struct sockaddr_can *scan) +{ + struct rtcan_socket *sock = + (struct rtcan_socket *)&context->dev_private; + rtdm_lockctx_t lock_ctx; + int ret = 0; + + /* Check address family and + check if given length of filter list is plausible */ + if (scan->can_family != AF_CAN) + return -EINVAL; + /* Check range of ifindex, must be between 0 and RTCAN_MAX_DEVICES */ + if (scan->can_ifindex < 0 || scan->can_ifindex > RTCAN_MAX_DEVICES) + return -ENODEV; + + /* Get lock for reception lists */ + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + + /* Test if socket is about to be closed */ + if (unlikely(test_bit(RTDM_CLOSING, &context->context_flags))) { + ret = -EBADF; + goto out; + } + + if ((ret = rtcan_raw_check_filter(sock, scan->can_ifindex, + sock->flist))) + goto out; + rtcan_raw_remove_filter(sock); + /* Add filter and mark socket as bound */ + sock->flistlen = rtcan_raw_add_filter(sock, scan->can_ifindex); + + /* Set new interface index the socket is now bound to */ + atomic_set(&sock->ifindex, scan->can_ifindex); + + out: + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + return ret; +} + + +static int rtcan_raw_setsockopt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + struct _rtdm_setsockopt_args *so) +{ + struct rtcan_socket *sock = (struct rtcan_socket *)&context->dev_private; + struct rtcan_filter_list *flist; + int ifindex = atomic_read(&sock->ifindex); + rtdm_lockctx_t lock_ctx; + can_err_mask_t err_mask; + int val, ret = 0; + + if (so->level != SOL_CAN_RAW) + return -ENOPROTOOPT; + + switch (so->optname) { + + case CAN_RAW_FILTER: + if (so->optlen == 0) { + flist = RTCAN_FLIST_NO_FILTER; + } else { + int flistlen; + flistlen = so->optlen / sizeof(struct can_filter); + if (flistlen < 1 || flistlen > RTCAN_MAX_RECEIVERS || + so->optlen % sizeof(struct can_filter) != 0) + return -EINVAL; + + flist = (struct rtcan_filter_list *)rtdm_malloc(so->optlen + sizeof(int)); + if (flist == NULL) + return -ENOMEM; + if (user_info) { + if (!rtdm_read_user_ok(user_info, so->optval, so->optlen) || + rtdm_copy_from_user(user_info, flist->flist, + so->optval, so->optlen)) { + rtdm_free(flist); + return -EFAULT; + } + } else + memcpy(flist->flist, so->optval, so->optlen); + flist->flistlen = flistlen; + } + + /* Get lock for reception lists */ + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + + /* Check if there is space for the filter list if already bound */ + if (rtcan_sock_is_bound(sock)) { + if (!rtcan_flist_no_filter(flist) && + (ret = rtcan_raw_check_filter(sock, ifindex, flist))) { + rtdm_free(flist); + goto out_filter; + } + rtcan_raw_remove_filter(sock); + } + + /* Remove previous list and attach the new one */ + if (!rtcan_flist_no_filter(flist) && sock->flist) + rtdm_free(sock->flist); + sock->flist = flist; + + if (rtcan_sock_is_bound(sock)) + sock->flistlen = rtcan_raw_add_filter(sock, ifindex); + + out_filter: + /* Release lock for reception lists */ + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + break; + + case CAN_RAW_ERR_FILTER: + + if (so->optlen != sizeof(can_err_mask_t)) + return -EINVAL; + + if (user_info) { + if (!rtdm_read_user_ok(user_info, so->optval, so->optlen) || + rtdm_copy_from_user(user_info, &err_mask, so->optval, so->optlen)) + return -EFAULT; + } else + memcpy(&err_mask, so->optval, so->optlen); + + /* Get lock for reception lists */ + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + sock->err_mask = err_mask; + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + break; + + case CAN_RAW_LOOPBACK: + + if (so->optlen != sizeof(int)) + return -EINVAL; + + if (user_info) { + if (!rtdm_read_user_ok(user_info, so->optval, so->optlen) || + rtdm_copy_from_user(user_info, &val, so->optval, so->optlen)) + return -EFAULT; + } else + memcpy(&val, so->optval, so->optlen); + +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK + sock->loopback = val; +#else + if (val) + return -EOPNOTSUPP; +#endif + break; + + default: + ret = -ENOPROTOOPT; + } + + return ret; +} + + +int rtcan_raw_ioctl(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + int ret = 0; + + switch (request) { + case _RTIOC_BIND: { + struct _rtdm_setsockaddr_args *setaddr, setaddr_buf; + struct sockaddr_can *sockaddr, sockaddr_buf; + + if (user_info) { + /* Copy argument structure from userspace */ + if (!rtdm_read_user_ok(user_info, arg, + sizeof(struct _rtdm_setsockaddr_args)) || + rtdm_copy_from_user(user_info, &setaddr_buf, arg, + sizeof(struct _rtdm_setsockaddr_args))) + return -EFAULT; + + setaddr = &setaddr_buf; + + /* Check size */ + if (setaddr->addrlen != sizeof(struct sockaddr_can)) + return -EINVAL; + + /* Copy argument structure from userspace */ + if (!rtdm_read_user_ok(user_info, arg, + sizeof(struct sockaddr_can)) || + rtdm_copy_from_user(user_info, &sockaddr_buf, setaddr->addr, + sizeof(struct sockaddr_can))) + return -EFAULT; + sockaddr = &sockaddr_buf; + } else { + setaddr = (struct _rtdm_setsockaddr_args *)arg; + sockaddr = (struct sockaddr_can *)setaddr->addr; + } + + /* Now, all required data are in kernel space */ + ret = rtcan_raw_bind(context, sockaddr); + + break; + } + + case _RTIOC_SETSOCKOPT: { + struct _rtdm_setsockopt_args *setopt; + struct _rtdm_setsockopt_args setopt_buf; + + if (user_info) { + if (!rtdm_read_user_ok(user_info, arg, + sizeof(struct _rtdm_setsockopt_args)) || + rtdm_copy_from_user(user_info, &setopt_buf, arg, + sizeof(struct _rtdm_setsockopt_args))) + return -EFAULT; + + setopt = &setopt_buf; + } else + setopt = (struct _rtdm_setsockopt_args *)arg; + + return rtcan_raw_setsockopt(context, user_info, setopt); + } + + case RTCAN_RTIOC_TAKE_TIMESTAMP: { + long timestamp_switch = (long)arg; + + if (timestamp_switch == RTCAN_TAKE_TIMESTAMPS) + set_bit(RTCAN_GET_TIMESTAMP, &context->context_flags); + else + clear_bit(RTCAN_GET_TIMESTAMP, &context->context_flags); + break; + } + + case RTCAN_RTIOC_RCV_TIMEOUT: + case RTCAN_RTIOC_SND_TIMEOUT: { + /* Do some work these requests have in common. */ + struct rtcan_socket *sock = + (struct rtcan_socket *)&context->dev_private; + + nanosecs_rel_t *timeout = (nanosecs_rel_t *)arg; + nanosecs_rel_t timeo_buf; + + if (user_info) { + /* Copy 64 bit timeout value from userspace */ + if (!rtdm_read_user_ok(user_info, arg, + sizeof(nanosecs_rel_t)) || + rtdm_copy_from_user(user_info, &timeo_buf, + arg, sizeof(nanosecs_rel_t))) + return -EFAULT; + + timeout = &timeo_buf; + } + + /* Now the differences begin between the requests. */ + if (request == RTCAN_RTIOC_RCV_TIMEOUT) + sock->rx_timeout = *timeout; + else + sock->tx_timeout = *timeout; + + break; + } + + default: + ret = rtcan_raw_ioctl_dev(context, user_info, request, arg); + break; + } + + return ret; +} + + +#define MEMCPY_FROM_RING_BUF(to, len) \ + \ + if (unlikely((recv_buf_index + len) > RTCAN_RXBUF_SIZE)) { \ + /* Wrap around end of buffer */ \ + \ + first_part_size = RTCAN_RXBUF_SIZE - recv_buf_index; \ + \ + memcpy(to, &recv_buf[recv_buf_index], first_part_size); \ + memcpy((void *)to + first_part_size, recv_buf, \ + len - first_part_size); \ + \ + } else \ + \ + memcpy(to, &recv_buf[recv_buf_index], len); \ + \ + \ + recv_buf_index = (recv_buf_index + len) & (RTCAN_RXBUF_SIZE - 1); + + +ssize_t rtcan_raw_recvmsg(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags) +{ + struct rtcan_socket *sock = + (struct rtcan_socket *)&context->dev_private; + struct sockaddr_can scan; + nanosecs_rel_t timeout; + struct iovec *iov = (struct iovec *)msg->msg_iov; + struct iovec iov_buf; + can_frame_t frame; + nanosecs_abs_t timestamp = 0; + unsigned char ifindex; + unsigned char can_dlc; + unsigned char *recv_buf; + int recv_buf_index; + size_t first_part_size; + size_t payload_size; + rtdm_lockctx_t lock_ctx; + int ret; + + /* Clear frame memory location */ + memset(&frame, 0, sizeof(can_frame_t)); + + /* Check flags */ + if (flags & ~(MSG_DONTWAIT | MSG_PEEK)) + return -EINVAL; + + + /* Check if msghdr entries are sane */ + + if (msg->msg_name != NULL) { + if (msg->msg_namelen < sizeof(struct sockaddr_can)) + return -EINVAL; + + if (user_info) { + if (!rtdm_rw_user_ok(user_info, msg->msg_name, msg->msg_namelen)) + return -EFAULT; + } + + } else { + if (msg->msg_namelen != 0) + return -EINVAL; + } + + /* Check msg_iovlen, only one buffer allowed */ + if (msg->msg_iovlen != 1) + return -EMSGSIZE; + + if (user_info) { + /* Copy IO vector from userspace */ + if (!rtdm_rw_user_ok(user_info, msg->msg_iov, + sizeof(struct iovec)) || + rtdm_copy_from_user(user_info, &iov_buf, msg->msg_iov, + sizeof(struct iovec))) + return -EFAULT; + + iov = &iov_buf; + } + + /* Check size of buffer */ + if (iov->iov_len < sizeof(can_frame_t)) + return -EMSGSIZE; + + /* Check buffer if in user space */ + if (user_info) { + if (!rtdm_rw_user_ok(user_info, iov->iov_base, iov->iov_len)) + return -EFAULT; + } + + if (msg->msg_control != NULL) { + if (msg->msg_controllen < sizeof(nanosecs_abs_t)) + return -EINVAL; + + if (user_info) { + if (!rtdm_rw_user_ok(user_info, msg->msg_control, + msg->msg_controllen)) + return -EFAULT; + } + + } else { + if (msg->msg_controllen != 0) + return -EINVAL; + } + + rtcan_raw_enable_bus_err(sock); + + /* Set RX timeout */ + timeout = (flags & MSG_DONTWAIT) ? RTDM_TIMEOUT_NONE : sock->rx_timeout; + + /* Fetch message (ok, try it ...) */ + ret = rtdm_sem_timeddown(&sock->recv_sem, timeout, NULL); + + /* Error code returned? */ + if (unlikely(ret)) { + /* Which error code? */ + + if (ret == -EIDRM) + /* Socket was closed */ + return -EBADF; + + else if (ret == -EWOULDBLOCK) + /* We would block but don't want to */ + return -EAGAIN; + + else + /* Return all other error codes unmodified. */ + return ret; + } + + + /* OK, we've got mail. */ + + rtdm_lock_get_irqsave(&rtcan_socket_lock, lock_ctx); + + + /* Construct a struct can_frame with data from socket's ring buffer */ + recv_buf_index = sock->recv_head; + recv_buf = sock->recv_buf; + + + /* Begin with CAN ID */ + MEMCPY_FROM_RING_BUF(&frame.can_id, sizeof(uint32_t)); + + + /* Fetch interface index */ + ifindex = recv_buf[recv_buf_index]; + recv_buf_index = (recv_buf_index + 1) & (RTCAN_RXBUF_SIZE - 1); + + + /* Fetch DLC (with indicator if a timestamp exists) */ + can_dlc = recv_buf[recv_buf_index]; + recv_buf_index = (recv_buf_index + 1) & (RTCAN_RXBUF_SIZE - 1); + + frame.can_dlc = can_dlc & RTCAN_HAS_NO_TIMESTAMP; + payload_size = (frame.can_dlc > 8) ? 8 : frame.can_dlc; + + + /* If frame is an RTR or one with no payload it's not necessary + * to copy the data bytes. */ + if (!(frame.can_id & CAN_RTR_FLAG) && payload_size) { + /* Copy data bytes */ + MEMCPY_FROM_RING_BUF(frame.data, payload_size); + } + + + /* Is a timestamp available and is the caller actually interested? */ + if (msg->msg_controllen && (can_dlc & RTCAN_HAS_TIMESTAMP)) { + /* Copy timestamp */ + MEMCPY_FROM_RING_BUF(×tamp, RTCAN_TIMESTAMP_SIZE); + } + + + + /* Message completely read from the socket's ring buffer. Now check if + * caller is just peeking. */ + if (flags & MSG_PEEK) + /* Next one, please! */ + rtdm_sem_up(&sock->recv_sem); + else + /* Adjust begin of first message in the ring buffer. */ + sock->recv_head = recv_buf_index; + + + /* Release lock */ + rtdm_lock_put_irqrestore(&rtcan_socket_lock, lock_ctx); + + + /* Create CAN socket address to give back */ + if (msg->msg_namelen) { + scan.can_family = AF_CAN; + scan.can_ifindex = ifindex; + } + + + /* Last duty: Copy all back to the caller's buffers. */ + + if (user_info) { + /* Copy to user space */ + + /* Copy socket address */ + if (msg->msg_namelen) { + if (rtdm_copy_to_user(user_info, msg->msg_name, &scan, + sizeof(struct sockaddr_can))) + return -EFAULT; + + msg->msg_namelen = sizeof(struct sockaddr_can); + } + + /* Copy CAN frame */ + if (rtdm_copy_to_user(user_info, iov->iov_base, &frame, + sizeof(can_frame_t))) + return -EFAULT; + /* Adjust iovec in the common way */ + iov->iov_base += sizeof(can_frame_t); + iov->iov_len -= sizeof(can_frame_t); + /* ... and copy it, too. */ + if (rtdm_copy_to_user(user_info, msg->msg_iov, iov, + sizeof(struct iovec))) + return -EFAULT; + + /* Copy timestamp if existent and wanted */ + if (msg->msg_controllen) { + if (can_dlc & RTCAN_HAS_TIMESTAMP) { + if (rtdm_copy_to_user(user_info, msg->msg_control, + ×tamp, RTCAN_TIMESTAMP_SIZE)) + return -EFAULT; + + msg->msg_controllen = RTCAN_TIMESTAMP_SIZE; + } else + msg->msg_controllen = 0; + } + + } else { + /* Kernel space */ + + /* Copy socket address */ + if (msg->msg_namelen) { + memcpy(msg->msg_name, &scan, sizeof(struct sockaddr_can)); + msg->msg_namelen = sizeof(struct sockaddr_can); + } + + /* Copy CAN frame */ + memcpy(iov->iov_base, &frame, sizeof(can_frame_t)); + /* Adjust iovec in the common way */ + iov->iov_base += sizeof(can_frame_t); + iov->iov_len -= sizeof(can_frame_t); + + /* Copy timestamp if existent and wanted */ + if (msg->msg_controllen) { + if (can_dlc & RTCAN_HAS_TIMESTAMP) { + memcpy(msg->msg_control, ×tamp, RTCAN_TIMESTAMP_SIZE); + msg->msg_controllen = RTCAN_TIMESTAMP_SIZE; + } else + msg->msg_controllen = 0; + } + } + + + return sizeof(can_frame_t); +} + + +ssize_t rtcan_raw_sendmsg(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags) +{ + struct rtcan_socket *sock = + (struct rtcan_socket *)&context->dev_private; + struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name; + struct sockaddr_can scan_buf; + struct iovec *iov = (struct iovec *)msg->msg_iov; + struct iovec iov_buf; + can_frame_t *frame; + can_frame_t frame_buf; + rtdm_lockctx_t lock_ctx; + nanosecs_rel_t timeout = 0; + struct tx_wait_queue tx_wait; + struct rtcan_device *dev; + int ifindex = 0; + int ret = 0; + + + if (flags & MSG_OOB) /* Mirror BSD error message compatibility */ + return -EOPNOTSUPP; + + /* Only MSG_DONTWAIT is a valid flag. */ + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + /* Check msg_iovlen, only one buffer allowed */ + if (msg->msg_iovlen != 1) + return -EMSGSIZE; + + if (scan == NULL) { + /* No socket address. Will use bound interface for sending */ + + if (msg->msg_namelen != 0) + return -EINVAL; + + + /* We only want a consistent value here, a spin lock would be + * overkill. Nevertheless, the binding could change till we have + * the chance to send. Blame the user, though. */ + ifindex = atomic_read(&sock->ifindex); + + if (!ifindex) + /* Socket isn't bound or bound to all interfaces. Go out. */ + return -ENXIO; + } else { + /* Socket address given */ + if (msg->msg_namelen < sizeof(struct sockaddr_can)) + return -EINVAL; + + if (user_info) { + /* Copy socket address from userspace */ + if (!rtdm_read_user_ok(user_info, msg->msg_name, + sizeof(struct sockaddr_can)) || + rtdm_copy_from_user(user_info, &scan_buf, msg->msg_name, + sizeof(struct sockaddr_can))) + return -EFAULT; + + scan = &scan_buf; + } + + /* Check address family */ + if (scan->can_family != AF_CAN) + return -EINVAL; + + ifindex = scan->can_ifindex; + } + + if (user_info) { + /* Copy IO vector from userspace */ + if (!rtdm_rw_user_ok(user_info, msg->msg_iov, + sizeof(struct iovec)) || + rtdm_copy_from_user(user_info, &iov_buf, msg->msg_iov, + sizeof(struct iovec))) + return -EFAULT; + + iov = &iov_buf; + } + + /* Check size of buffer */ + if (iov->iov_len != sizeof(can_frame_t)) + return -EMSGSIZE; + + frame = (can_frame_t *)iov->iov_base; + + if (user_info) { + /* Copy CAN frame from userspace */ + if (!rtdm_read_user_ok(user_info, iov->iov_base, + sizeof(can_frame_t)) || + rtdm_copy_from_user(user_info, &frame_buf, iov->iov_base, + sizeof(can_frame_t))) + return -EFAULT; + + frame = &frame_buf; + } + + /* Adjust iovec in the common way */ + iov->iov_base += sizeof(can_frame_t); + iov->iov_len -= sizeof(can_frame_t); + /* ... and copy it back to userspace if necessary */ + if (user_info) { + if (rtdm_copy_to_user(user_info, msg->msg_iov, iov, + sizeof(struct iovec))) + return -EFAULT; + } + + /* At last, we've got the frame ... */ + + /* Check if DLC between 0 and 15 */ + if (frame->can_dlc > 15) + return -EINVAL; + + /* Check if it is a standard frame and the ID between 0 and 2031 */ + if (!(frame->can_id & CAN_EFF_FLAG)) { + u32 id = frame->can_id & CAN_EFF_MASK; + if (id > (CAN_SFF_MASK - 16)) + return -EINVAL; + } + + if ((dev = rtcan_dev_get_by_index(ifindex)) == NULL) + return -ENXIO; + + timeout = (flags & MSG_DONTWAIT) ? RTDM_TIMEOUT_NONE : sock->tx_timeout; + + tx_wait.rt_task = rtdm_task_current(); + + /* If socket was not closed recently, register the task at the + * socket's TX wait queue and decrement the TX semaphore. This must be + * atomic. Finally, the task must be deregistered again (also atomic). */ + RTDM_EXECUTE_ATOMICALLY( + if (likely(!test_bit(RTDM_CLOSING, &context->context_flags))) { + + list_add(&tx_wait.tx_wait_list, &sock->tx_wait_head); + + /* Try to pass the guard in order to access the controller */ + ret = rtdm_sem_timeddown(&dev->tx_sem, timeout, NULL); + + /* Only dequeue task again if socket isn't being closed i.e. if + * this task was not unblocked within the close() function. */ + if (likely(tx_wait.tx_wait_list.next != LIST_POISON1)) + /* Dequeue this task from the TX wait queue */ + list_del(&tx_wait.tx_wait_list); + else + /* The socket was closed. */ + ret = -EBADF; + + } else + /* The socket was closed. */ + ret = -EBADF; + ); + + /* Error code returned? */ + if (ret != 0) { + /* Which error code? */ + switch (ret) { + case -EIDRM: + /* Controller is stopped or bus-off */ + ret = -ENETDOWN; + goto send_out1; + + case -EWOULDBLOCK: + /* We would block but don't want to */ + ret = -EAGAIN; + goto send_out1; + + default: + /* Return all other error codes unmodified. */ + goto send_out1; + } + } + + /* We got access */ + + + /* Push message onto stack for loopback when TX done */ + if (rtcan_loopback_enabled(sock)) + rtcan_tx_push(dev, sock, frame); + + rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx); + + /* Controller should be operating */ + if (!CAN_STATE_OPERATING(dev->state)) { + if (dev->state == CAN_STATE_SLEEPING) { + ret = -ECOMM; + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + rtdm_sem_up(&dev->tx_sem); + goto send_out1; + } + ret = -ENETDOWN; + goto send_out2; + } + + dev->tx_count++; + ret = dev->hard_start_xmit(dev, frame); + + /* Return number of bytes sent upon successful completion */ + if (ret == 0) + ret = sizeof(can_frame_t); + + send_out2: + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + send_out1: + rtcan_dev_dereference(dev); + return ret; +} + + +static struct rtdm_device rtcan_proto_raw_dev = { + struct_version: RTDM_DEVICE_STRUCT_VER, + + device_flags: RTDM_PROTOCOL_DEVICE, + context_size: sizeof(struct rtcan_socket), + + protocol_family: PF_CAN, + socket_type: SOCK_RAW, + + socket_nrt: rtcan_raw_socket, + + ops: { + close_nrt: rtcan_raw_close, + + ioctl_rt: rtcan_raw_ioctl, + ioctl_nrt: rtcan_raw_ioctl, + + read_rt: NULL, + read_nrt: NULL, + + write_rt: NULL, + write_nrt: NULL, + + recvmsg_rt: rtcan_raw_recvmsg, + recvmsg_nrt: NULL, + + sendmsg_rt: rtcan_raw_sendmsg, + sendmsg_nrt: NULL, + }, + + device_class: RTDM_CLASS_CAN, + device_sub_class: RTDM_SUBCLASS_GENERIC, + profile_version: RTCAN_PROFILE_VER, + + driver_name: "xeno_can", + driver_version: RTDM_DRIVER_VER(RTCAN_MAJOR_VER, + RTCAN_MINOR_VER, + RTCAN_BUGFIX_VER), + peripheral_name: "Real-Time CAN Raw Socket Interface", + provider_name: "RT-Socket-CAN development team", + + proc_name: "rtcan" +}; + + +int __init rtcan_raw_proto_register(void) +{ + return rtdm_dev_register(&rtcan_proto_raw_dev); +} + + +void __exit rtcan_raw_proto_unregister(void) +{ + rtdm_dev_unregister(&rtcan_proto_raw_dev, 1000); +} + + +EXPORT_SYMBOL(rtcan_rcv); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_dev.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_dev.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_dev.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_dev.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger, + * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix + * Copyright (C) 2006 Andrey Volkov, Varma Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include + +#include +#include "rtcan_dev.h" +#include "rtcan_raw.h" +#include "rtcan_internal.h" + +#define RTCAN_MAX_TSEG1 15 +#define RTCAN_MAX_TSEG2 7 + +/* + * Calculate standard bit-time values for odd bitrates. + * Most parts of this code is from Arnaud Westenberg + */ +static int rtcan_calc_bit_time(struct rtcan_device *dev, + can_baudrate_t rate, + struct can_bittime_std *bit_time) +{ + int best_error = 1000000000; + int error; + int best_tseg=0, best_brp=0, best_rate=0, brp=0; + int tseg=0, tseg1=0, tseg2=0; + int clock = dev->can_sys_clock; + int sjw = 0; + int sampl_pt = 90; + + /* some heuristic specials */ + if (rate > ((1000000 + 500000) / 2)) + sampl_pt = 75; + + if (rate < ((12500 + 10000) / 2)) + sampl_pt = 75; + + if (rate < ((100000 + 125000) / 2)) + sjw = 1; + + /* tseg even = round down, odd = round up */ + for (tseg = (0 + 0 + 2) * 2; + tseg <= (RTCAN_MAX_TSEG2 + RTCAN_MAX_TSEG1 + 2) * 2 + 1; + tseg++) { + brp = clock / ((1 + tseg / 2) * rate) + tseg % 2; + if ((brp == 0) || (brp > 64)) + continue; + + error = rate - clock / (brp * (1 + tseg / 2)); + if (error < 0) + error = -error; + + if (error <= best_error) { + best_error = error; + best_tseg = tseg/2; + best_brp = brp - 1; + best_rate = clock / (brp * (1 + tseg / 2)); + } + } + + if (best_error && (rate / best_error < 10)) { + RTCAN_RTDM_DBG("%s: bitrate %d is not possible with %d Hz clock\n", + dev->name, rate, clock); + return -EDOM; + } + + tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100; + + if (tseg2 < 0) + tseg2 = 0; + + if (tseg2 > RTCAN_MAX_TSEG2) + tseg2 = RTCAN_MAX_TSEG2; + + tseg1 = best_tseg - tseg2 - 2; + + if (tseg1 > RTCAN_MAX_TSEG1) { + tseg1 = RTCAN_MAX_TSEG1; + tseg2 = best_tseg-tseg1-2; + } + + bit_time->brp = best_brp + 1; + bit_time->prop_seg = 0; + bit_time->phase_seg1 = tseg1 + 1; + bit_time->phase_seg2 = tseg2 + 1; + bit_time->sjw = sjw + 1; + bit_time->sam = 0; + + return 0; +} + +static inline int rtcan_raw_ioctl_dev_get(struct rtcan_device *dev, + int request, struct ifreq *ifr) +{ + struct can_bittime *bittime; + can_baudrate_t *baudrate = NULL; + can_state_t *state; + can_ctrlmode_t *ctrlmode; + rtdm_lockctx_t lock_ctx; + int ret = 0; + + switch (request) { + + case SIOCGIFINDEX: { + ifr->ifr_ifindex = dev->ifindex; + break; + } + + case SIOCGCANSTATE: + state = (can_state_t *)&ifr->ifr_ifru; + rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx); + if (dev->do_get_state) + dev->state = dev->do_get_state(dev); + *state = dev->state; + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + break; + + case SIOCGCANCTRLMODE: + ctrlmode = (can_ctrlmode_t *)&ifr->ifr_ifru; + *ctrlmode = dev->ctrl_mode; + break; + + case SIOCGCANBAUDRATE: + baudrate = (can_baudrate_t *)&ifr->ifr_ifru; + *baudrate = dev->baudrate; + break; + + case SIOCGCANCUSTOMBITTIME: + bittime = (struct can_bittime *)&ifr->ifr_ifru; + *bittime = dev->bit_time; + break; + } + + return ret; +} + +static inline int rtcan_raw_ioctl_dev_set(struct rtcan_device *dev, + int request, struct ifreq *ifr) +{ + rtdm_lockctx_t lock_ctx; + can_ctrlmode_t *ctrl_mode; + can_mode_t *mode; + int ret = 0, started = 0; + struct can_bittime bit_time, *bt; + can_baudrate_t *baudrate = NULL; + + switch (request) { + case SIOCSCANBAUDRATE: + if (!dev->do_set_bit_time) + return 0; + baudrate = (can_baudrate_t *)&ifr->ifr_ifru; + if ((ret = rtcan_calc_bit_time(dev, *baudrate, &bit_time.std))) + break; + bit_time.type = CAN_BITTIME_STD; + break; + } + + rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx); + + if (dev->do_get_state) + dev->state = dev->do_get_state(dev); + + switch (request) { + case SIOCSCANCTRLMODE: + case SIOCSCANBAUDRATE: + case SIOCSCANCUSTOMBITTIME: + if ((started = CAN_STATE_OPERATING(dev->state))) { + if ((ret = dev->do_set_mode(dev, CAN_MODE_STOP, &lock_ctx))) + goto out; + } + break; + } + + switch (request) { + case SIOCSCANMODE: + mode = (can_mode_t *)&ifr->ifr_ifru; + if (dev->do_set_mode && + !(*mode == CAN_MODE_START && CAN_STATE_OPERATING(dev->state))) + ret = dev->do_set_mode(dev, *mode, &lock_ctx); + break; + + case SIOCSCANCTRLMODE: + ctrl_mode = (can_ctrlmode_t *)&ifr->ifr_ifru; + dev->ctrl_mode = *ctrl_mode; + break; + + case SIOCSCANBAUDRATE: + ret = dev->do_set_bit_time(dev, &bit_time, &lock_ctx); + if (!ret) { + dev->baudrate = *baudrate; + dev->bit_time = bit_time; + } + break; + + case SIOCSCANCUSTOMBITTIME: + bt = (struct can_bittime *)&ifr->ifr_ifru; + ret = dev->do_set_bit_time(dev, bt, &lock_ctx); + if (!ret) { + dev->bit_time = *bt; + if (bt->type == CAN_BITTIME_STD && bt->std.brp) + dev->baudrate = (dev->can_sys_clock / + (bt->std.brp * (1 + bt->std.prop_seg + + bt->std.phase_seg1 + + bt->std.phase_seg2))); + else + dev->baudrate = CAN_BAUDRATE_UNKNOWN; + } + break; + + default: + ret = -EOPNOTSUPP; + break; + + } + + out: + if (started) + dev->do_set_mode(dev, CAN_MODE_START, &lock_ctx); + + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + + return ret; +} + +int rtcan_raw_ioctl_dev(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int request, void *arg) +{ + int ret = 0; + struct ifreq *ifr; + struct ifreq ifr_buf; + struct rtcan_device *dev; + + switch (request) { + + case SIOCGIFINDEX: + case SIOCGCANSTATE: + case SIOCGCANBAUDRATE: + case SIOCGCANCUSTOMBITTIME: + + if (user_info) { + if (!rtdm_rw_user_ok(user_info, arg, sizeof(struct ifreq)) || + rtdm_copy_from_user(user_info, &ifr_buf, arg, + sizeof(struct ifreq))) + return -EFAULT; + + ifr = &ifr_buf; + } else + ifr = (struct ifreq *)arg; + + if ((dev = rtcan_dev_get_by_name(ifr->ifr_name)) == NULL) + return -ENODEV; + ret = rtcan_raw_ioctl_dev_get(dev, request, ifr); + rtcan_dev_dereference(dev); + + if (user_info && !ret) { + /* Since we yet tested if user memory is rw safe, + we can copy to user space directly */ + if (rtdm_copy_to_user(user_info, arg, ifr, + sizeof(struct ifreq))) + return -EFAULT; + } + break; + + case SIOCSCANMODE: + case SIOCSCANCTRLMODE: + case SIOCSCANBAUDRATE: + case SIOCSCANCUSTOMBITTIME: + + if (user_info) { + /* Copy struct ifreq from userspace */ + if (!rtdm_read_user_ok(user_info, arg, + sizeof(struct ifreq)) || + rtdm_copy_from_user(user_info, &ifr_buf, arg, + sizeof(struct ifreq))) + return -EFAULT; + + ifr = &ifr_buf; + } else + ifr = (struct ifreq *)arg; + + /* Get interface index and data */ + if ((dev = rtcan_dev_get_by_name(ifr->ifr_name)) == NULL) + return -ENODEV; + ret = rtcan_raw_ioctl_dev_set(dev, request, ifr); + rtcan_dev_dereference(dev); + break; + + default: + ret = -EOPNOTSUPP; + break; + + } + + return ret; +} + +#ifdef CONFIG_XENO_DRIVERS_CAN_BUS_ERR +void __rtcan_raw_enable_bus_err(struct rtcan_socket *sock) +{ + int i, begin, end; + struct rtcan_device *dev; + rtdm_lockctx_t lock_ctx; + int ifindex = atomic_read(&sock->ifindex); + + if (ifindex) { + begin = ifindex; + end = ifindex; + } else { + begin = 1; + end = RTCAN_MAX_DEVICES; + } + + for (i = begin; i <= end; i++) { + if ((dev = rtcan_dev_get_by_index(i)) == NULL) + continue; + + if (dev->do_enable_bus_err) { + rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx); + dev->do_enable_bus_err(dev); + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + } + rtcan_dev_dereference(dev); + } +} +#endif /* CONFIG_XENO_DRIVERS_CAN_BUS_ERR*/ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_filter.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_filter.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_filter.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw_filter.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * 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; eitherer 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 +#include + +#include + +#include +#include "rtcan_internal.h" +#include "rtcan_socket.h" +#include "rtcan_list.h" +#include "rtcan_dev.h" +#include "rtcan_raw.h" + + +#if 0 +void rtcan_raw_print_filter(struct rtcan_device *dev) +{ + int i; + struct rtcan_recv *r = dev->receivers; + + rtdm_printk("%s: recv_list=%p empty_list=%p free_entries=%d\n", + dev->name, dev->recv_list, dev->empty_list, dev->free_entries); + for (i = 0; i < RTCAN_MAX_RECEIVERS; i++, r++) { + rtdm_printk("%2d %p sock=%p next=%p id=%x mask=%x\n", + i, r, r->sock, r->next, + r->can_filter.can_id, r->can_filter.can_mask); + } +} +#else +#define rtcan_raw_print_filter(dev) +#endif + + +static inline void rtcan_raw_mount_filter(can_filter_t *recv_filter, + can_filter_t *filter) +{ + if (filter->can_id & CAN_INV_FILTER) { + recv_filter->can_id = filter->can_id & ~CAN_INV_FILTER; + recv_filter->can_mask = filter->can_mask | CAN_INV_FILTER; + } else { + recv_filter->can_id = filter->can_id; + recv_filter->can_mask = filter->can_mask & ~CAN_INV_FILTER; + } + + /* Apply mask for fast filter check */ + recv_filter->can_id &= recv_filter->can_mask; +} + + +int rtcan_raw_check_filter(struct rtcan_socket *sock, int ifindex, + struct rtcan_filter_list *flist) +{ + int old_ifindex = 0, old_flistlen_all = 0; + int free_entries, i, begin, end; + struct rtcan_device *dev; + int flistlen; + + if (rtcan_flist_no_filter(flist)) + return 0; + + /* Check if filter list has been defined by user */ + flistlen = (flist) ? flist->flistlen : 1; + + /* Now we check if a reception list would overflow. This takes some + * preparation, so let's go ... */ + + /* Check current bind status */ + if (rtcan_sock_has_filter(sock)) { + /* Socket is bound */ + i = atomic_read(&sock->ifindex); + + if (i == 0) + /* Socket was bound to ALL interfaces */ + old_flistlen_all = sock->flistlen; + else /* Socket was bound to only one interface */ + old_ifindex = i; + } + + if (ifindex) { + /* We bind the socket to only one interface. */ + begin = ifindex; + end = ifindex; + } else { + /* Socket must be bound to all interfaces. */ + begin = 1; + end = RTCAN_MAX_DEVICES; + } + + /* Check if there is space for the new binding */ + for (i = begin; i <= end; i++) { + if ((dev = rtcan_dev_get_by_index(i)) == NULL) + continue; + free_entries = dev->free_entries + old_flistlen_all; + rtcan_dev_dereference(dev); + if (i == old_ifindex) + free_entries += sock->flistlen; + /* Compare free list space to new filter list length */ + if (free_entries < flistlen) + return -ENOSPC; + } + + return 0; +} + + +int rtcan_raw_add_filter(struct rtcan_socket *sock, int ifindex) +{ + int i, j, begin, end; + struct rtcan_recv *first, *last; + struct rtcan_device *dev; + /* Check if filter list has been defined by user */ + int flistlen; + + if (rtcan_flist_no_filter(sock->flist)) { + return 0; + } + + flistlen = (sock->flist) ? sock->flist->flistlen : 0; + + if (ifindex) { + /* We bind the socket to only one interface. */ + begin = ifindex; + end = ifindex; + } else { + /* Socket must be bound to all interfaces. */ + begin = 1; + end = RTCAN_MAX_DEVICES; + } + + for (i = begin; i <= end; i++) { + if ((dev = rtcan_dev_get_by_index(i)) == NULL) + continue; + + /* Take first entry of empty list */ + first = last = dev->empty_list; + /* Check if filter list is empty */ + if (flistlen) { + /* Filter list is not empty */ + /* Register first filter */ + rtcan_raw_mount_filter(&last->can_filter, + &sock->flist->flist[0]); + last->match_count = 0; + last->sock = sock; + for (j = 1; j < flistlen; j++) { + /* Register remaining filters */ + last = last->next; + rtcan_raw_mount_filter(&last->can_filter, + &sock->flist->flist[j]); + last->sock = sock; + last->match_count = 0; + } + /* Decrease free entries counter by length of filter list */ + dev->free_entries -= flistlen; + + } else { + /* Filter list is empty. Socket must be bound to all CAN IDs. */ + /* Fill list entry members */ + last->can_filter.can_id = last->can_filter.can_mask = 0; + last->sock = sock; + last->match_count = 0; + /* Decrease free entries counter by 1 + * (one filter for all CAN frames) */ + dev->free_entries--; + } + + /* Set new empty list header */ + dev->empty_list = last->next; + /* Add new partial recv list to the head of reception list */ + last->next = dev->recv_list; + /* Adjust rececption list pointer */ + dev->recv_list = first; + + rtcan_raw_print_filter(dev); + rtcan_dev_dereference(dev); + } + + return (flistlen) ? flistlen : 1; +} + + +void rtcan_raw_remove_filter(struct rtcan_socket *sock) +{ + int i, j, begin, end; + struct rtcan_recv *first, *next, *last; + int ifindex = atomic_read(&sock->ifindex); + struct rtcan_device *dev; + + if (!rtcan_sock_has_filter(sock)) /* nothing to do */ + return; + + if (ifindex) { + /* Socket was bound to one interface only. */ + begin = ifindex; + end = ifindex; + } else { + /* Socket was bound to all interfaces */ + begin = 1; + end = RTCAN_MAX_DEVICES; + } + + for (i = begin; i <= end; i++) { + + if ((dev = rtcan_dev_get_by_index(i)) == NULL) + continue; + + /* Search for first list entry pointing to this socket */ + first = NULL; + next = dev->recv_list; + while (next->sock != sock) { + first = next; + next = first->next; + } + + /* Now go to the end of the old filter list */ + last = next; + for (j = 1; j < sock->flistlen; j++) + last = last->next; + + /* Detach found first list entry from reception list */ + if (first) + first->next = last->next; + else + dev->recv_list = last->next; + /* Add partial list to the head of empty list */ + last->next = dev->empty_list; + /* Adjust empty list pointer */ + dev->empty_list = next; + + /* Increase free entries counter by length of old filter list */ + dev->free_entries += sock->flistlen; + + rtcan_raw_print_filter(dev); + rtcan_dev_dereference(dev); + } +} diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_raw.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_RAW_H_ +#define __RTCAN_RAW_H_ + +#ifdef __KERNEL__ + +int rtcan_raw_ioctl_dev(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int request, void *arg); + +int rtcan_raw_check_filter(struct rtcan_socket *sock, + int ifindex, struct rtcan_filter_list *flist); +int rtcan_raw_add_filter(struct rtcan_socket *sock, int ifindex); +void rtcan_raw_remove_filter(struct rtcan_socket *sock); + +void rtcan_rcv(struct rtcan_device *rtcandev, struct rtcan_skb *skb); + +void rtcan_loopback(struct rtcan_device *rtcandev); +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK +#define rtcan_loopback_enabled(sock) (sock->loopback) +#define rtcan_loopback_pending(dev) (dev->tx_socket) +#else /* !CONFIG_XENO_DRIVERS_CAN_LOOPBACK */ +#define rtcan_loopback_enabled(sock) (0) +#define rtcan_loopback_pending(dev) (0) +#endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */ + +#ifdef CONFIG_XENO_DRIVERS_CAN_BUS_ERR +void __rtcan_raw_enable_bus_err(struct rtcan_socket *sock); +static inline void rtcan_raw_enable_bus_err(struct rtcan_socket *sock) +{ + if ((sock->err_mask & CAN_ERR_BUSERROR)) + __rtcan_raw_enable_bus_err(sock); +} +#else +#define rtcan_raw_enable_bus_err(sock) +#endif + +int __init rtcan_raw_proto_register(void); +void __exit rtcan_raw_proto_unregister(void); + +#endif /* __KERNEL__ */ + +#endif /* __RTCAN_RAW_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005,2006 Sebastian Smolorz + * + * + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * Based on stack/socket.c - sockets implementation for RTnet + * + * Copyright (C) 1999 Lineo, Inc + * 1999, 2002 David A. Schleef + * 2002 Ulrich Marx + * 2003-2005 Jan Kiszka + * + * + * 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 "rtcan_socket.h" +#include "rtcan_list.h" + + +LIST_HEAD(rtcan_socket_list); + +void rtcan_socket_init(struct rtdm_dev_context *context) +{ + struct rtcan_socket *sock = (struct rtcan_socket *)&context->dev_private; + rtdm_lockctx_t lock_ctx; + + + rtdm_sem_init(&sock->recv_sem, 0); + + sock->recv_head = 0; + sock->recv_tail = 0; + atomic_set(&sock->ifindex, 0); + sock->flistlen = RTCAN_SOCK_UNBOUND; + sock->flist = NULL; + sock->err_mask = 0; + sock->rx_buf_full = 0; +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK + sock->loopback = 1; +#endif + + sock->tx_timeout = RTDM_TIMEOUT_INFINITE; + sock->rx_timeout = RTDM_TIMEOUT_INFINITE; + + INIT_LIST_HEAD(&sock->tx_wait_head); + + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + list_add(&sock->socket_list, &rtcan_socket_list); + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); +} + + +void rtcan_socket_cleanup(struct rtdm_dev_context *context) +{ + struct rtcan_socket *sock = (struct rtcan_socket *)&context->dev_private; + struct tx_wait_queue *tx_waiting; + rtdm_lockctx_t lock_ctx; + int tx_list_empty; + + + /* Wake up sleeping senders. This is re-entrant-safe. */ + do { + RTDM_EXECUTE_ATOMICALLY( + /* Is someone there? */ + if (list_empty(&sock->tx_wait_head)) + tx_list_empty = 1; + + else { + tx_list_empty = 0; + + /* Get next entry pointing to a waiting task */ + tx_waiting = list_entry(sock->tx_wait_head.next, + struct tx_wait_queue, tx_wait_list); + + /* Remove it from list */ + list_del(&tx_waiting->tx_wait_list); + + /* Wake task up (atomic section is left implicitly) */ + rtdm_task_unblock(tx_waiting->rt_task); + } + ); + } while (!tx_list_empty); + + rtdm_sem_destroy(&sock->recv_sem); + + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + if (sock->socket_list.next) { + list_del(&sock->socket_list); + sock->socket_list.next = NULL; + } + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); +} diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_socket.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2005,2006 Sebastian Smolorz + * + * + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * Derived from RTnet project file include/stack/socket.h: + * + * Copyright (C) 1999 Lineo, Inc + * 1999, 2002 David A. Schleef + * 2002 Ulrich Marx + * 2003-2005 Jan Kiszka + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_SOCKET_H_ +#define __RTCAN_SOCKET_H_ + +#include + +#include + + + +/* This MUST BE 2^N */ +#define RTCAN_RXBUF_SIZE CONFIG_XENO_DRIVERS_CAN_RXBUF_SIZE + +/* Size of timestamp */ +#define RTCAN_TIMESTAMP_SIZE sizeof(nanosecs_abs_t) + +/* Bit in the can_dlc member of struct ring_buffer_frame used to indicate + * whether a frame has got a timestamp or not */ +#define RTCAN_HAS_TIMESTAMP 0x80 + +/* Mask for clearing bit RTCAN_HAS_TIMESTAMP */ +#define RTCAN_HAS_NO_TIMESTAMP 0x7F + +#define RTCAN_SOCK_UNBOUND -1 +#define RTCAN_FLIST_NO_FILTER (struct rtcan_filter_list *)-1 +#define rtcan_flist_no_filter(f) ((f) == RTCAN_FLIST_NO_FILTER) +#define rtcan_sock_has_filter(s) ((s)->flistlen > 0) +#define rtcan_sock_is_bound(s) ((s)->flistlen >= 0) + +/* + * Internal frame representation within the ring buffer of a + * struct rtcan_socket. + * + * The data array is of arbitrary size when the frame is actually + * stored in a socket's ring buffer. The timestamp member exists if the + * socket was set to take timestamps (then it follows direcly after the + * arbitrary-sized data array), otherwise it does not exist. + */ +struct rtcan_rb_frame { + + /* CAN ID representation equal to struct can_frame */ + uint32_t can_id; + + /* Interface index from which the frame originates */ + unsigned char can_ifindex; + + /* DLC (between 0 and 15) and mark if frame has got a timestamp. The + * existence of a timestamp is indicated by the RTCAN_HAS_TIMESTAMP + * bit. */ + unsigned char can_dlc; + + /* Data bytes */ + uint8_t data[8]; + + /* High precision timestamp indicating when the frame was received. + * Exists when RTCAN_HAS_TIMESTAMP bit in can_dlc is set. */ + nanosecs_abs_t timestamp; + +} __attribute__ ((packed)); + + +/* Size of struct rtcan_rb_frame without any data bytes and timestamp */ +#define EMPTY_RB_FRAME_SIZE \ + sizeof(struct rtcan_rb_frame) - 8 - RTCAN_TIMESTAMP_SIZE + + +/* + * Wrapper structure around a struct rtcan_rb_frame with actual size + * of the frame. + * + * This isn't really a socket buffer but only a sort of. It is constructed + * within the interrupt routine when a CAN frame is read from + * the controller. Then it's passed to the reception handler where only + * rb_frame finds its way to the sockets' ring buffers. + */ +struct rtcan_skb { + /* Actual size of following rb_frame (without timestamp) */ + size_t rb_frame_size; + /* Frame to be stored in the sockets' ring buffers (as is) */ + struct rtcan_rb_frame rb_frame; +}; + +struct rtcan_filter_list { + int flistlen; + struct can_filter flist[1]; +}; + +/* + * Internal CAN socket structure. + * + * Every socket has an internal ring buffer for incoming messages. A message + * is not stored as a struct can_frame (in order to save buffer space) + * but as struct rtcan_rb_frame of arbitrary length depending on the + * actual payload. + */ +struct rtcan_socket { + + struct list_head socket_list; + + /* Transmission timeout in ns. Protected by rtcan_socket_lock + * in all socket structures. */ + nanosecs_rel_t tx_timeout; + + /* Reception timeout in ns. Protected by rtcan_socket_lock + * in all socket structures. */ + nanosecs_rel_t rx_timeout; + + + /* Begin of first frame data in the ring buffer. Protected by + * rtcan_socket_lock in all socket structures. */ + int recv_head; + + /* End of last frame data in the ring buffer. I.e. position of first + * free byte in the ring buffer. Protected by + * rtcan_socket_lock in all socket structures. */ + int recv_tail; + + /* Ring buffer for incoming CAN frames. Protected by + * rtcan_socket_lock in all socket structures. */ + unsigned char recv_buf[RTCAN_RXBUF_SIZE]; + + /* Semaphore for receivers and incoming messages */ + rtdm_sem_t recv_sem; + + + /* All senders waiting to be able to send + * via this socket are queued here */ + struct list_head tx_wait_head; + + + /* Interface index the socket is bound to. Protected by + * rtcan_recv_list_lock in all socket structures. */ + atomic_t ifindex; + + /* Length of filter list. I.e. how many entries does this socket occupy in + * the reception list. 0 if unbound. Protected by + * rtcan_recv_list_lock in all socket structures. */ + int flistlen; + + uint32_t err_mask; + + uint32_t rx_buf_full; + + struct rtcan_filter_list *flist; + +#ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK + int loopback; +#endif +}; + + + +/* + * Get the RTDM context from a struct rtcan_socket + * + * @param[in] sock Pointer to socket structure + * + * @return Pointer to context of type struct rtdm_dev_context this socket + * belongs to + */ +/* FIXME: to be replaced with container_of */ +static inline struct rtdm_dev_context *rtcan_socket_context( + struct rtcan_socket *sock) +{ + return (struct rtdm_dev_context *)((void *)sock - + (void *)(&((struct rtdm_dev_context *)NULL)->dev_private)); +} + +/* Spinlock protecting the ring buffers and the timeouts of all + * rtcan_sockets */ +extern rtdm_lock_t rtcan_socket_lock; +extern struct list_head rtcan_socket_list; + +extern void rtcan_socket_init(struct rtdm_dev_context *context); +extern void rtcan_socket_cleanup(struct rtdm_dev_context *context); + + +#endif /* __RTCAN_SOCKET_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_version.h relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_version.h --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_version.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_version.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __RTCAN_VERSION_H_ +#define __RTCAN_VERSION_H_ + +#define RTCAN_MAJOR_VER 0 +#define RTCAN_MINOR_VER 90 +#define RTCAN_BUGFIX_VER 2 + +#endif /* __RTCAN_VERSION_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_virt.c relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_virt.c --- orig/linux-2.6.35.9//drivers/xenomai/can/rtcan_virt.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/rtcan_virt.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2006 Jan Kiszka + * + * + * 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 +#include +#include +#include "rtcan_dev.h" +#include "rtcan_raw.h" + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "VIRT" +#define RTCAN_MAX_VIRT_DEVS 8 + +#define VIRT_TX_BUFS 1 + +static char *virt_ctlr_name = ""; +static char *virt_board_name = ""; + +MODULE_AUTHOR("Jan Kiszka "); +MODULE_DESCRIPTION("Virtual RT-Socket-CAN driver"); +MODULE_LICENSE("GPL"); + +static unsigned int devices = 2; + +module_param(devices, uint, 0400); +MODULE_PARM_DESC(devices, "Number of devices on the virtual bus"); + +static struct rtcan_device *rtcan_virt_devs[RTCAN_MAX_VIRT_DEVS]; + + +static int rtcan_virt_start_xmit(struct rtcan_device *tx_dev, + can_frame_t *tx_frame) +{ + int i; + struct rtcan_device *rx_dev; + struct rtcan_skb skb; + struct rtcan_rb_frame *rx_frame = &skb.rb_frame; + rtdm_lockctx_t lock_ctx; + + /* we can transmit immediately again */ + rtdm_sem_up(&tx_dev->tx_sem); + + skb.rb_frame_size = EMPTY_RB_FRAME_SIZE; + + rx_frame->can_dlc = tx_frame->can_dlc; + rx_frame->can_id = tx_frame->can_id; + + if (!(tx_frame->can_id & CAN_RTR_FLAG)) { + memcpy(rx_frame->data, tx_frame->data, tx_frame->can_dlc); + skb.rb_frame_size += tx_frame->can_dlc; + } + + rtdm_lock_get_irqsave(&rtcan_recv_list_lock, lock_ctx); + rtdm_lock_get(&rtcan_socket_lock); + + + /* Deliver to all other devices on the virtual bus */ + for (i = 0; i < devices; i++) { + rx_dev = rtcan_virt_devs[i]; + if (rx_dev->state == CAN_STATE_ACTIVE) { + if (tx_dev != rx_dev) { + rx_frame->can_ifindex = rx_dev->ifindex; + rtcan_rcv(rx_dev, &skb); + } else if (rtcan_loopback_pending(tx_dev)) + rtcan_loopback(tx_dev); + } + } + rtdm_lock_put(&rtcan_socket_lock); + rtdm_lock_put_irqrestore(&rtcan_recv_list_lock, lock_ctx); + + return 0; +} + + +static int rtcan_virt_set_mode(struct rtcan_device *dev, can_mode_t mode, + rtdm_lockctx_t *lock_ctx) +{ + int err = 0; + + switch (mode) { + case CAN_MODE_STOP: + dev->state = CAN_STATE_STOPPED; + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + break; + + case CAN_MODE_START: + rtdm_sem_init(&dev->tx_sem, VIRT_TX_BUFS); + dev->state = CAN_STATE_ACTIVE; + break; + + default: + err = -EOPNOTSUPP; + } + + return err; +} + + +static int __init rtcan_virt_init_one(int idx) +{ + struct rtcan_device *dev; + int err; + + if ((dev = rtcan_dev_alloc(0, 0)) == NULL) + return -ENOMEM; + + dev->ctrl_name = virt_ctlr_name; + dev->board_name = virt_board_name; + + rtcan_virt_set_mode(dev, CAN_MODE_STOP, NULL); + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + dev->hard_start_xmit = rtcan_virt_start_xmit; + dev->do_set_mode = rtcan_virt_set_mode; + + /* Register RTDM device */ + err = rtcan_dev_register(dev); + if (err) { + printk(KERN_ERR "ERROR %d while trying to register RTCAN device!\n", err); + goto error_out; + } + + /* Remember initialized devices */ + rtcan_virt_devs[idx] = dev; + + printk("%s: %s driver loaded\n", dev->name, RTCAN_DRV_NAME); + + return 0; + + error_out: + rtcan_dev_free(dev); + return err; +} + + +/** Init module */ +static int __init rtcan_virt_init(void) +{ + int i, err = 0; + + for (i = 0; i < devices; i++) { + err = rtcan_virt_init_one(i); + if (err) { + while (--i >= 0) { + struct rtcan_device *dev = rtcan_virt_devs[i]; + + rtcan_dev_unregister(dev); + rtcan_dev_free(dev); + } + break; + } + } + + return err; +} + + +/** Cleanup module */ +static void __exit rtcan_virt_exit(void) +{ + int i; + struct rtcan_device *dev; + + for (i = 0; i < devices; i++) { + dev = rtcan_virt_devs[i]; + + printk("Unloading %s device %s\n", RTCAN_DRV_NAME, dev->name); + + rtcan_virt_set_mode(dev, CAN_MODE_STOP, NULL); + rtcan_dev_unregister(dev); + rtcan_dev_free(dev); + } +} + +module_init(rtcan_virt_init); +module_exit(rtcan_virt_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/Kconfig relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,91 @@ +config XENO_DRIVERS_CAN_SJA1000 + depends on XENO_DRIVERS_CAN + tristate "Philips SJA1000 CAN controller" + select XENO_DRIVERS_CAN_BUS_ERR + +config XENO_DRIVERS_CAN_SJA1000_ISA + depends on XENO_DRIVERS_CAN_SJA1000 + tristate "Standard ISA controllers" + help + + This driver is for CAN devices connected to the ISA bus of a PC + or a PC/104 system. The I/O port, interrupt number and a few other + hardware specific parameters can be defined via module parameters. + +config XENO_DRIVERS_CAN_SJA1000_MEM + depends on XENO_DRIVERS_CAN_SJA1000 + tristate "Memory mapped controllers" + help + + This driver is for memory mapped CAN devices. The memory address, + interrupt number and a few other hardware specific parameters can + be defined via module parameters. + +config XENO_DRIVERS_CAN_SJA1000_PEAK_PCI + depends on XENO_DRIVERS_CAN_SJA1000 && PCI + tristate "PEAK PCI Card" + help + + This driver is for the PCAN PCI, the PC-PCI CAN plug-in card (1 or + 2 channel) from PEAK Systems (http://www.peak-system.com). To get + the second channel working, Xenomai's shared interrupt support + must be enabled. + +config XENO_DRIVERS_CAN_SJA1000_IXXAT_PCI + depends on XENO_DRIVERS_CAN_SJA1000 && PCI + tristate "IXXAT PCI Card" + help + + This driver is for the IXXAT PC-I 04/PCI card (1 or 2 channel) + from the IXXAT Automation GmbH (http://www.ixxat.de). To get + the second channel working, Xenomai's shared interrupt support + must be enabled. + +config XENO_DRIVERS_CAN_SJA1000_PLX_PCI + depends on XENO_DRIVERS_CAN_SJA1000 && PCI + tristate "PLX90xx PCI-bridge based Cards" + help + + This driver is for CAN interface cards based on + the PLX90xx PCI bridge. + Driver supports now: + - Adlink PCI-7841/cPCI-7841 card (http://www.adlinktech.com/) + - Adlink PCI-7841/cPCI-7841 SE card + - esd CAN-PCI/CPCI/PCI104/200 (http://www.esd.eu/) + - esd CAN-PCI/PMC/266 + - esd CAN-PCIe/2000 + - Marathon CAN-bus-PCI card (http://www.marathon.ru/) + - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) + +config XENO_DRIVERS_CAN_SJA1000_EMS_PCI + depends on XENO_DRIVERS_CAN_SJA1000 && PCI + tristate "EMS CPC PCI Card" + help + + This driver is for the 2 channel CPC PCI card from EMS Dr. Thomas + Wünsche (http://www.ems-wuensche.de). To get the second channel + working, Xenomai's shared interrupt support must be enabled. + +config XENO_DRIVERS_CAN_SJA1000_ESD_PCI + depends on XENO_DRIVERS_CAN_SJA1000 && PCI + tristate "ESD PCI Cards (DEPRECATED)" + help + + This driver supports the esd PCI CAN cards CAN-PCI/200, + CAN-PCI/266, CAN-PMC/266 (PMC), CAN-CPCI/200 (CompactPCI), + CAN-PCIe2000 (PCI Express) and CAN-PCI104/200 (PCI104) + from the esd electronic system design gmbh (http://www.esd.eu). + + This driver is deprecated. It's functionality is now provided by + "PLX90xx PCI-bridge based Cards" driver. + +config XENO_DRIVERS_CAN_SJA1000_PEAK_DNG + depends on XENO_DRIVERS_CAN_SJA1000 && !PARPORT + tristate "PEAK Parallel Port Dongle" + help + + This driver is for the PCAN Dongle, the PC parallel port to CAN + converter from PEAK Systems (http://www.peak-system.com). You need + to disable parallel port support in the kernel (CONFIG_PARPORT) for + proper operation. The interface type (sp or epp), I/O port and + interrupt number should be defined via module parameters. diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/Makefile relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,87 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can -Idrivers/xenomai/can/sja1000 + +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000) += xeno_can_sja1000.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PEAK_PCI) += xeno_can_peak_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PEAK_DNG) += xeno_can_peak_dng.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PLX_PCI) += xeno_can_plx_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_IXXAT_PCI) += xeno_can_ixxat_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_EMS_PCI) += xeno_can_ems_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_ESD_PCI) += xeno_can_esd_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_ISA) += xeno_can_isa.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_MEM) += xeno_can_mem.o + +xeno_can_sja1000-y := rtcan_sja1000.o rtcan_sja1000_proc.o +xeno_can_peak_pci-y := rtcan_peak_pci.o +xeno_can_peak_dng-y := rtcan_peak_dng.o +xeno_can_plx_pci-y := rtcan_plx_pci.o +xeno_can_ixxat_pci-y := rtcan_ixxat_pci.o +xeno_can_ems_pci-y := rtcan_ems_pci.o +xeno_can_esd_pci-y := rtcan_esd_pci.o +xeno_can_isa-y := rtcan_isa.o +xeno_can_mem-y := rtcan_mem.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000) += xeno_can_sja1000.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PEAK_PCI) += xeno_can_peak_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PEAK_DNG) += xeno_can_peak_dng.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_PLX_PCI) += xeno_can_plx_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_IXXAT_PCI) += xeno_can_ixxat_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_EMS_PCI) += xeno_can_ems_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_ESD_PCI) += xeno_can_esd_pci.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_ISA) += xeno_can_isa.o +obj-$(CONFIG_XENO_DRIVERS_CAN_SJA1000_MEM) += xeno_can_mem.o + +list-multi := xeno_can_sja1000.o + +xeno_can_sja1000-objs := rtcan_sja1000.o rtcan_sja1000_proc.o +xeno_can_peak_pci-objs := rtcan_peak_pci.o +xeno_can_peak_dng-objs := rtcan_peak_dng.o +xeno_can_plx_pci-objs := rtcan_plx_pci.o +xeno_can_ixxat_pci-objs := rtcan_ixxat_pci.o +xeno_can_ems_pci-objs := rtcan_ems_pci.o +xeno_can_esd_pci-objs := rtcan_esd_pci.o +xeno_can_isa-objs := rtcan_isa.o +xeno_can_mem-objs := rtcan_mem.o + +export-objs := $(xeno_can_sja1000-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat -I.. -I. + +include $(TOPDIR)/Rules.make + +xeno_can_sja1000.o: $(xeno_can_sja1000-objs) + $(LD) -r -o $@ $(xeno_can_sja1000-objs) + +xeno_can_peak_pci.o: $(xeno_can_peak_pci-objs) + $(LD) -r -o $@ $(xeno_can_peak_pci-objs) + +xeno_can_peak_dng.o: $(xeno_can_peak_dng-objs) + $(LD) -r -o $@ $(xeno_can_peak_dng-objs) + +xeno_can_plx_pci.o: $(xeno_can_plx_pci-objs) + $(LD) -r -o $@ $(xeno_can_plx_pci-objs) + +xeno_can_ixxat_pci.o: $(xeno_can_ixxat_pci-objs) + $(LD) -r -o $@ $(xeno_can_ixxat_pci-objs) + +xeno_can_ems_pci.o: $(xeno_can_ems_pci-objs) + $(LD) -r -o $@ $(xeno_can_ems_pci-objs) + +xeno_can_esd_pci.o: $(xeno_can_esd_pci-objs) + $(LD) -r -o $@ $(xeno_can_esd_pci-objs) + +xeno_can_isa.o: $(xeno_can_isa-objs) + $(LD) -r -o $@ $(xeno_can_isa-objs) + +xeno_can_mem.o: $(xeno_can_mem-objs) + $(LD) -r -o $@ $(xeno_can_mem-objs) +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ems_pci.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ems_pci.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ems_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ems_pci.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2007 Wolfgang Grandegger + * + * Register definitions and descriptions are taken from LinCAN 0.3.3. + * + * 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 +#include +#include +#include +#include + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "EMS-CPC-PCI-CAN" + +static char *ems_pci_board_name = "EMS-CPC-PCI"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RTCAN board driver for EMS CPC-PCI cards"); +MODULE_SUPPORTED_DEVICE("EMS CPC-PCI card CAN controller"); +MODULE_LICENSE("GPL"); + +struct rtcan_ems_pci +{ + struct pci_dev *pci_dev; + struct rtcan_device *slave_dev; + int channel; + volatile void __iomem *base_addr; + volatile void __iomem *conf_addr; +}; + +#define EMS_PCI_MASTER 1 /* multi channel device, this device is master */ +#define EMS_PCI_SLAVE 2 /* multi channel device, this is slave */ + +/* + * PSB4610 PITA-2 bridge control registers + */ +#define PITA2_ICR 0x00 /* Interrupt Control Register */ +#define PITA2_ICR_INT0 0x00000002 /* [RC] INT0 Active/Clear */ +#define PITA2_ICR_INT0_EN 0x00020000 /* [RW] Enable INT0 */ + +#define PITA2_MISC 0x1c /* Miscellaneous Register */ +#define PITA2_MISC_CONFIG 0x04000000 /* Multiplexed Parallel_interface_model */ + +/* + * The board configuration is probably following: + * RX1 is connected to ground. + * TX1 is not connected. + * CLKO is not connected. + * Setting the OCR register to 0xDA is a good idea. + * This means normal output mode , push-pull and the correct polarity. + */ +#define EMS_PCI_OCR_STD 0xda /* Standard value: Pushpull */ + +/* + * In the CDR register, you should set CBP to 1. + * You will probably also want to set the clock divider value to 7 + * (meaning direct oscillator output) because the second SJA1000 chip + * is driven by the first one CLKOUT output. + */ +#define EMS_PCI_CDR_MASTER (SJA_CDR_CAN_MODE | SJA_CDR_CBP | 0x07) +#define EMS_PCI_CDR_SLAVE (SJA_CDR_CAN_MODE | SJA_CDR_CBP | 0x07 | \ + SJA_CDR_CLK_OFF) +#define EMS_PCI_CONF_SIZE 0x0100 /* Size of the config io-memory */ +#define EMS_PCI_PORT_START 0x0400 /* Start of the channel io-memory */ +#define EMS_PCI_PORT_SIZE 0x0200 /* Size of a channel io-memory */ + + +#define EMS_PCI_PORT_BYTES 0x4 /* Each register occupies 4 bytes */ + +#define EMS_PCI_VENDOR_ID 0x110a /* PCI device and vendor ID */ +#define EMS_PCI_DEVICE_ID 0x2104 + +static struct pci_device_id ems_pci_tbl[] = { + {EMS_PCI_VENDOR_ID, EMS_PCI_DEVICE_ID, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE (pci, ems_pci_tbl); + +#define EMS_PCI_CAN_SYS_CLOCK (16000000 / 2) + +static u8 rtcan_ems_pci_read_reg(struct rtcan_device *dev, int port) +{ + struct rtcan_ems_pci *board = (struct rtcan_ems_pci *)dev->board_priv; + return readb(board->base_addr + (port * EMS_PCI_PORT_BYTES)); +} + +static void rtcan_ems_pci_write_reg(struct rtcan_device *dev, int port, u8 data) +{ + struct rtcan_ems_pci *board = (struct rtcan_ems_pci *)dev->board_priv; + writeb(data, board->base_addr + (port * EMS_PCI_PORT_BYTES)); +} + +static void rtcan_ems_pci_irq_ack(struct rtcan_device *dev) +{ + struct rtcan_ems_pci *board = (struct rtcan_ems_pci *)dev->board_priv; + + writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, + board->conf_addr + PITA2_ICR); +} + +static void rtcan_ems_pci_del_chan(struct rtcan_device *dev, + int init_step) +{ + struct rtcan_ems_pci *board; + + if (!dev) + return; + + board = (struct rtcan_ems_pci *)dev->board_priv; + + switch (init_step) { + case 0: /* Full cleanup */ + RTCAN_DBG("Removing %s %s device %s\n", + ems_pci_board_name, dev->ctrl_name, dev->name); + rtcan_sja1000_unregister(dev); + case 5: + case 4: + iounmap((void *)board->base_addr); + case 3: + if (board->channel != EMS_PCI_SLAVE) + iounmap((void *)board->conf_addr); + case 2: + rtcan_dev_free(dev); + case 1: + break; + } +} + +static int rtcan_ems_pci_add_chan(struct pci_dev *pdev, int channel, + struct rtcan_device **master_dev) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_ems_pci *board; + unsigned long addr; + int err, init_step = 1; + + dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_ems_pci)); + if (dev == NULL) + return -ENOMEM; + init_step = 2; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_ems_pci *)dev->board_priv; + + board->pci_dev = pdev; + board->channel = channel; + + if (channel != EMS_PCI_SLAVE) { + + addr = pci_resource_start(pdev, 0); + board->conf_addr = ioremap(addr, EMS_PCI_CONF_SIZE); + if (board->conf_addr == 0) { + err = -ENODEV; + goto failure; + } + init_step = 3; + + /* Configure PITA-2 parallel interface */ + writel(PITA2_MISC_CONFIG, board->conf_addr + PITA2_MISC); + /* Enable interrupts from card */ + writel(PITA2_ICR_INT0_EN, board->conf_addr + PITA2_ICR); + } else { + struct rtcan_ems_pci *master_board = + (struct rtcan_ems_pci *)(*master_dev)->board_priv; + master_board->slave_dev = dev; + board->conf_addr = master_board->conf_addr; + } + + addr = pci_resource_start(pdev, 1) + EMS_PCI_PORT_START; + if (channel == EMS_PCI_SLAVE) + addr += EMS_PCI_PORT_SIZE; + + board->base_addr = ioremap(addr, EMS_PCI_PORT_SIZE); + if (board->base_addr == 0) { + err = -ENODEV; + goto failure; + } + init_step = 4; + + dev->board_name = ems_pci_board_name; + + chip->read_reg = rtcan_ems_pci_read_reg; + chip->write_reg = rtcan_ems_pci_write_reg; + chip->irq_ack = rtcan_ems_pci_irq_ack; + + /* Clock frequency in Hz */ + dev->can_sys_clock = EMS_PCI_CAN_SYS_CLOCK; + + /* Output control register */ + chip->ocr = EMS_PCI_OCR_STD; + + /* Clock divider register */ + if (channel == EMS_PCI_MASTER) + chip->cdr = EMS_PCI_CDR_MASTER; + else + chip->cdr = EMS_PCI_CDR_SLAVE; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + /* Register and setup interrupt handling */ + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->irq_num = pdev->irq; + init_step = 5; + + printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME, + board->base_addr, board->conf_addr, chip->irq_num); + + /* Register SJA1000 device */ + err = rtcan_sja1000_register(dev); + if (err) { + printk(KERN_ERR + "ERROR %d while trying to register SJA1000 device!\n", + err); + goto failure; + } + + if (channel != EMS_PCI_SLAVE) + *master_dev = dev; + + return 0; + +failure: + rtcan_ems_pci_del_chan(dev, init_step); + return err; +} + +static int __devinit ems_pci_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct rtcan_device *master_dev = NULL; + int err; + + RTCAN_DBG("%s: initializing device %04x:%04x\n", + RTCAN_DRV_NAME, pdev->vendor, pdev->device); + + if ((err = pci_enable_device (pdev))) + goto failure; + + if ((err = pci_request_regions(pdev, RTCAN_DRV_NAME))) + goto failure; + + if ((err = pci_write_config_word(pdev, 0x04, 2))) + goto failure_cleanup; + + if ((err = rtcan_ems_pci_add_chan(pdev, EMS_PCI_MASTER, + &master_dev))) + goto failure_cleanup; + if ((err = rtcan_ems_pci_add_chan(pdev, EMS_PCI_SLAVE, + &master_dev))) + goto failure_cleanup; + + pci_set_drvdata(pdev, master_dev); + return 0; + +failure_cleanup: + if (master_dev) + rtcan_ems_pci_del_chan(master_dev, 0); + + pci_release_regions(pdev); + +failure: + return err; + +} + +static void __devexit ems_pci_remove_one (struct pci_dev *pdev) +{ + struct rtcan_device *dev = pci_get_drvdata(pdev); + struct rtcan_ems_pci *board = (struct rtcan_ems_pci *)dev->board_priv; + + /* Disable interrupts from card */ + writel(0x0, board->conf_addr + PITA2_ICR); + + if (board->slave_dev) + rtcan_ems_pci_del_chan(board->slave_dev, 0); + rtcan_ems_pci_del_chan(dev, 0); + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver rtcan_ems_pci_driver = { + .name = RTCAN_DRV_NAME, + .id_table = ems_pci_tbl, + .probe = ems_pci_init_one, + .remove = __devexit_p(ems_pci_remove_one), +}; + +static int __init rtcan_ems_pci_init(void) +{ + return pci_register_driver(&rtcan_ems_pci_driver); +} + +static void __exit rtcan_ems_pci_exit(void) +{ + pci_unregister_driver(&rtcan_ems_pci_driver); +} + +module_init(rtcan_ems_pci_init); +module_exit(rtcan_ems_pci_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_esd_pci.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_esd_pci.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_esd_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_esd_pci.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2009 Sebastian Smolorz + * + * This driver is based on the Socket-CAN driver esd_pci.c, + * Copyright (C) 2007 Wolfgang Grandegger + * Copyright (C) 2008 Sascha Hauer , Pengutronix + * Copyright (C) 2009 Matthias Fuchs , esd gmbh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "ESD-PCI-CAN" + +static char *esd_pci_board_name = "ESD-PCI"; + +MODULE_AUTHOR("Sebastian Smolorz board_priv; + return readb(board->base_addr + port); +} + +static void rtcan_esd_pci_write_reg(struct rtcan_device *dev, int port, u8 val) +{ + struct rtcan_esd_pci *board = (struct rtcan_esd_pci *)dev->board_priv; + writeb(val, board->base_addr + port); +} + +static void rtcan_esd_pci_del_chan(struct rtcan_device *dev) +{ + struct rtcan_esd_pci *board; + + if (!dev) + return; + + board = (struct rtcan_esd_pci *)dev->board_priv; + + printk("Removing %s %s device %s\n", + esd_pci_board_name, dev->ctrl_name, dev->name); + + rtcan_sja1000_unregister(dev); + + rtcan_dev_free(dev); +} + +static int rtcan_esd_pci_add_chan(struct pci_dev *pdev, int channel, + struct rtcan_device **master_dev, + void __iomem *conf_addr, + void __iomem *base_addr) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_esd_pci *board; + int ret; + + dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_esd_pci)); + if (dev == NULL) + return -ENOMEM; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_esd_pci *)dev->board_priv; + + board->pci_dev = pdev; + board->conf_addr = conf_addr; + board->base_addr = base_addr; + + if (channel == CHANNEL_SLAVE) { + struct rtcan_esd_pci *master_board = + (struct rtcan_esd_pci *)(*master_dev)->board_priv; + master_board->slave_dev = dev; + } + + dev->board_name = esd_pci_board_name; + + chip->read_reg = rtcan_esd_pci_read_reg; + chip->write_reg = rtcan_esd_pci_write_reg; + + dev->can_sys_clock = ESD_PCI_CAN_CLOCK; + + chip->ocr = ESD_PCI_OCR; + chip->cdr = ESD_PCI_CDR; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->irq_num = pdev->irq; + + RTCAN_DBG("%s: base_addr=0x%p conf_addr=0x%p irq=%d ocr=%#x cdr=%#x\n", + RTCAN_DRV_NAME, board->base_addr, board->conf_addr, + chip->irq_num, chip->ocr, chip->cdr); + + /* Register SJA1000 device */ + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR "ERROR %d while trying to register SJA1000 " + "device!\n", ret); + goto failure; + } + + if (channel != CHANNEL_SLAVE) + *master_dev = dev; + + return 0; + + +failure: + rtcan_dev_free(dev); + return ret; +} + +static int __devinit esd_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret, channel; + void __iomem *base_addr; + void __iomem *conf_addr; + struct rtcan_device *master_dev = NULL; + + if ((ret = pci_enable_device (pdev))) + goto failure; + + if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME))) + goto failure; + + RTCAN_DBG("%s: Initializing device %04x:%04x %04x:%04x\n", + RTCAN_DRV_NAME, pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device); + + conf_addr = pci_iomap(pdev, 0, ESD_PCI_BASE_SIZE); + if (conf_addr == NULL) { + ret = -ENODEV; + goto failure_release_pci; + } + + base_addr = pci_iomap(pdev, 2, ESD_PCI_BASE_SIZE); + if (base_addr == NULL) { + ret = -ENODEV; + goto failure_iounmap_conf; + } + + /* Check if second channel is available */ + writeb(SJA_MOD_RM, base_addr + CHANNEL_OFFSET + SJA_MOD); + writeb(SJA_CDR_CBP, base_addr + CHANNEL_OFFSET + SJA_CDR); + writeb(SJA_MOD_RM, base_addr + CHANNEL_OFFSET + SJA_MOD); + if (readb(base_addr + CHANNEL_OFFSET + SJA_MOD) == 0x21) { + writeb(SJA_MOD_SM | SJA_MOD_AFM | SJA_MOD_STM | SJA_MOD_LOM | + SJA_MOD_RM, base_addr + CHANNEL_OFFSET + SJA_MOD); + if (readb(base_addr + CHANNEL_OFFSET + SJA_MOD) == 0x3f) + channel = CHANNEL_MASTER; + else { + writeb(SJA_MOD_RM, + base_addr + CHANNEL_OFFSET + SJA_MOD); + channel = CHANNEL_SINGLE; + } + } else { + writeb(SJA_MOD_RM, base_addr + CHANNEL_OFFSET + SJA_MOD); + channel = CHANNEL_SINGLE; + } + + if ((ret = rtcan_esd_pci_add_chan(pdev, channel, &master_dev, + conf_addr, base_addr))) + goto failure_iounmap_base; + + if (channel != CHANNEL_SINGLE) { + channel = CHANNEL_SLAVE; + if ((ret = rtcan_esd_pci_add_chan(pdev, channel, &master_dev, + conf_addr, base_addr + CHANNEL_OFFSET))) + goto failure_iounmap_base; + } + + if ((pdev->device == PCI_DEVICE_ID_PLX_9050) || + (pdev->device == PCI_DEVICE_ID_PLX_9030)) { + /* Enable interrupts in PLX9050 */ + writel(INTCSR_LINTI1 | INTCSR_PCI, conf_addr + INTCSR_OFFSET); + } else { + /* Enable interrupts in PLX9056*/ + writel(INTCSR9056_LINTI | INTCSR9056_PCI, + conf_addr + INTCSR9056_OFFSET); + } + + pci_set_drvdata(pdev, master_dev); + + return 0; + + +failure_iounmap_base: + if (master_dev) + rtcan_esd_pci_del_chan(master_dev); + pci_iounmap(pdev, base_addr); + +failure_iounmap_conf: + pci_iounmap(pdev, conf_addr); + +failure_release_pci: + pci_release_regions(pdev); + +failure: + return ret; +} + +static void __devexit esd_pci_remove_one(struct pci_dev *pdev) +{ + struct rtcan_device *dev = pci_get_drvdata(pdev); + struct rtcan_esd_pci *board = (struct rtcan_esd_pci *)dev->board_priv; + + if ((pdev->device == PCI_DEVICE_ID_PLX_9050) || + (pdev->device == PCI_DEVICE_ID_PLX_9030)) { + /* Disable interrupts in PLX9050*/ + writel(0, board->conf_addr + INTCSR_OFFSET); + } else { + /* Disable interrupts in PLX9056*/ + writel(0, board->conf_addr + INTCSR9056_OFFSET); + } + + if (board->slave_dev) + rtcan_esd_pci_del_chan(board->slave_dev); + rtcan_esd_pci_del_chan(dev); + + + pci_iounmap(pdev, board->base_addr); + pci_iounmap(pdev, board->conf_addr); + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver rtcan_esd_pci_driver = { + .name = RTCAN_DRV_NAME, + .id_table = esd_pci_tbl, + .probe = esd_pci_init_one, + .remove = __devexit_p(esd_pci_remove_one), +}; + +static int __init rtcan_esd_pci_init(void) +{ + return pci_register_driver(&rtcan_esd_pci_driver); +} + +static void __exit rtcan_esd_pci_exit(void) +{ + pci_unregister_driver(&rtcan_esd_pci_driver); +} + +module_init(rtcan_esd_pci_init); +module_exit(rtcan_esd_pci_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_isa.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_isa.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_isa.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_isa.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Copyright (C) 2005, 2006, 2009 Sebastian Smolorz + * + * + * + * 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; eitherer 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "sja1000-isa" + +#define RTCAN_ISA_MAX_DEV 4 + +static char *isa_board_name = "ISA-Board"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RTCAN board driver for standard ISA boards"); +MODULE_SUPPORTED_DEVICE("ISA board"); +MODULE_LICENSE("GPL"); + +static u16 io[RTCAN_ISA_MAX_DEV]; +static int irq[RTCAN_ISA_MAX_DEV]; +static u32 can_clock[RTCAN_ISA_MAX_DEV]; +static u8 ocr[RTCAN_ISA_MAX_DEV]; +static u8 cdr[RTCAN_ISA_MAX_DEV]; + +compat_module_param_array(io, ushort, RTCAN_ISA_MAX_DEV, 0444); +compat_module_param_array(irq, int, RTCAN_ISA_MAX_DEV, 0444); +compat_module_param_array(can_clock, uint, RTCAN_ISA_MAX_DEV, 0444); +compat_module_param_array(ocr, byte, RTCAN_ISA_MAX_DEV, 0444); +compat_module_param_array(cdr, byte, RTCAN_ISA_MAX_DEV, 0444); + +MODULE_PARM_DESC(io, "The io-port address"); +MODULE_PARM_DESC(irq, "The interrupt number"); +MODULE_PARM_DESC(can_clock, "External clock frequency (default 16 MHz)"); +MODULE_PARM_DESC(ocr, "Value of output control register (default 0x1a)"); +MODULE_PARM_DESC(cdr, "Value of clock divider register (default 0xc8"); + +#define RTCAN_ISA_PORT_SIZE 32 + +struct rtcan_isa +{ + u16 io; +}; + +static struct rtcan_device *rtcan_isa_devs[RTCAN_ISA_MAX_DEV]; + +static u8 rtcan_isa_readreg(struct rtcan_device *dev, int port) +{ + struct rtcan_isa *board = (struct rtcan_isa *)dev->board_priv; + return inb(board->io + port); +} + +static void rtcan_isa_writereg(struct rtcan_device *dev, int port, u8 val) +{ + struct rtcan_isa *board = (struct rtcan_isa *)dev->board_priv; + outb(val, board->io + port); +} + + +int __init rtcan_isa_init_one(int idx) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_isa *board; + int ret; + + if ((dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_isa))) == NULL) + return -ENOMEM; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_isa *)dev->board_priv; + + dev->board_name = isa_board_name; + + board->io = io[idx]; + + chip->irq_num = irq[idx]; + chip->irq_flags = RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE; + + chip->read_reg = rtcan_isa_readreg; + chip->write_reg = rtcan_isa_writereg; + + /* Check and request I/O ports */ + if (!request_region(board->io, RTCAN_ISA_PORT_SIZE, RTCAN_DRV_NAME)) { + ret = -EBUSY; + goto out_dev_free; + } + + /* Clock frequency in Hz */ + if (can_clock[idx]) + dev->can_sys_clock = can_clock[idx] / 2; + else + dev->can_sys_clock = 8000000; /* 16/2 MHz */ + + /* Output control register */ + if (ocr[idx]) + chip->ocr = ocr[idx]; + else + chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL; + + if (cdr[idx]) + chip->cdr = cdr[idx]; + else + chip->cdr = SJA_CDR_CAN_MODE | SJA_CDR_CLK_OFF | SJA_CDR_CBP; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR "ERROR %d while trying to register SJA1000 " + "device!\n", ret); + goto out_free_region; + } + + rtcan_isa_devs[idx] = dev; + return 0; + + out_free_region: + release_region(board->io, RTCAN_ISA_PORT_SIZE); + + out_dev_free: + rtcan_dev_free(dev); + + return ret; +} + +static void rtcan_isa_exit(void); + +/** Init module */ +static int __init rtcan_isa_init(void) +{ + int i, err; + int devices = 0; + + for (i = 0; i < RTCAN_ISA_MAX_DEV && io[i] != 0; i++) { + err = rtcan_isa_init_one(i); + if (err) { + rtcan_isa_exit(); + return err; + } + devices++; + } + if (devices) + return 0; + + printk(KERN_ERR "ERROR! No devices specified! " + "Use io=[,...] irq=[,...]\n"); + return -EINVAL; +} + + +/** Cleanup module */ +static void rtcan_isa_exit(void) +{ + int i; + struct rtcan_device *dev; + + for (i = 0; i < RTCAN_ISA_MAX_DEV; i++) { + dev = rtcan_isa_devs[i]; + if (!dev) + continue; + rtcan_sja1000_unregister(dev); + release_region(io[i], RTCAN_ISA_PORT_SIZE); + rtcan_dev_free(dev); + } +} + +module_init(rtcan_isa_init); +module_exit(rtcan_isa_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ixxat_pci.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ixxat_pci.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ixxat_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_ixxat_pci.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * 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 +#include +#include +#include +#include + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "IXXAT-PCI-CAN" + +static char *ixxat_pci_board_name = "IXXAT-PCI"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RTCAN board driver for IXXAT-PCI cards"); +MODULE_SUPPORTED_DEVICE("IXXAT-PCI card CAN controller"); +MODULE_LICENSE("GPL"); + +struct rtcan_ixxat_pci +{ + struct pci_dev *pci_dev; + struct rtcan_device *slave_dev; + int conf_addr; + void __iomem *base_addr; +}; + +#define IXXAT_PCI_CAN_SYS_CLOCK (16000000 / 2) + +#define CHANNEL_SINGLE 0 /* this is a single channel device */ +#define CHANNEL_MASTER 1 /* multi channel device, this device is master */ +#define CHANNEL_SLAVE 2 /* multi channel device, this is slave */ + +#define CHANNEL_OFFSET 0x200 +#define CHANNEL_MASTER_RESET 0x110 +#define CHANNEL_SLAVE_RESET (CHANNEL_MASTER_RESET + CHANNEL_OFFSET) + +#define IXXAT_INTCSR_OFFSET 0x4c /* Offset in PLX9050 conf registers */ +#define IXXAT_INTCSR_SLAVE 0x41 /* LINT1 and PCI interrupt enabled */ +#define IXXAT_INTCSR_MASTER 0x08 /* LINT2 enabled */ +#define IXXAT_SJA_MOD_MASK 0xa1 /* Mask for reading dual/single channel */ + +/* PCI vender, device and sub-device ID */ +#define IXXAT_PCI_VENDOR_ID 0x10b5 +#define IXXAT_PCI_DEVICE_ID 0x9050 +#define IXXAT_PCI_SUB_SYS_ID 0x2540 + +#define IXXAT_CONF_PORT_SIZE 0x0080 +#define IXXAT_BASE_PORT_SIZE 0x0400 + +static struct pci_device_id ixxat_pci_tbl[] = { + {IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID, + IXXAT_PCI_VENDOR_ID, IXXAT_PCI_SUB_SYS_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE (pci, ixxat_pci_tbl); + + +static u8 rtcan_ixxat_pci_read_reg(struct rtcan_device *dev, int port) +{ + struct rtcan_ixxat_pci *board = (struct rtcan_ixxat_pci *)dev->board_priv; + return readb(board->base_addr + port); +} + +static void rtcan_ixxat_pci_write_reg(struct rtcan_device *dev, int port, u8 data) +{ + struct rtcan_ixxat_pci *board = (struct rtcan_ixxat_pci *)dev->board_priv; + writeb(data, board->base_addr + port); +} + +static void rtcan_ixxat_pci_del_chan(struct rtcan_device *dev) +{ + struct rtcan_ixxat_pci *board; + u8 intcsr; + + if (!dev) + return; + + board = (struct rtcan_ixxat_pci *)dev->board_priv; + + printk("Removing %s %s device %s\n", + ixxat_pci_board_name, dev->ctrl_name, dev->name); + + rtcan_sja1000_unregister(dev); + + /* Disable PCI interrupts */ + intcsr = inb(board->conf_addr + IXXAT_INTCSR_OFFSET); + if (board->slave_dev) { + intcsr &= ~IXXAT_INTCSR_MASTER; + outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET); + writeb(0x1, board->base_addr + CHANNEL_MASTER_RESET); + iounmap(board->base_addr); + } else { + intcsr &= ~IXXAT_INTCSR_SLAVE; + outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET); + writeb(0x1, board->base_addr + CHANNEL_SLAVE_RESET ); + } + rtcan_dev_free(dev); +} + +static int rtcan_ixxat_pci_add_chan(struct pci_dev *pdev, + int channel, + struct rtcan_device **master_dev, + int conf_addr, + void __iomem *base_addr) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_ixxat_pci *board; + u8 intcsr; + int ret; + + dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_ixxat_pci)); + if (dev == NULL) + return -ENOMEM; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_ixxat_pci *)dev->board_priv; + + board->pci_dev = pdev; + board->conf_addr = conf_addr; + board->base_addr = base_addr; + + if (channel == CHANNEL_SLAVE) { + struct rtcan_ixxat_pci *master_board = + (struct rtcan_ixxat_pci *)(*master_dev)->board_priv; + master_board->slave_dev = dev; + } + + dev->board_name = ixxat_pci_board_name; + + chip->read_reg = rtcan_ixxat_pci_read_reg; + chip->write_reg = rtcan_ixxat_pci_write_reg; + + /* Clock frequency in Hz */ + dev->can_sys_clock = IXXAT_PCI_CAN_SYS_CLOCK; + + /* Output control register */ + chip->ocr = (SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_INVERT | + SJA_OCR_TX0_PUSHPULL | SJA_OCR_TX1_PUSHPULL); + + /* Clock divider register */ + chip->cdr = SJA_CDR_CAN_MODE; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + /* Enable PCI interrupts */ + intcsr = inb(board->conf_addr + IXXAT_INTCSR_OFFSET); + if (channel == CHANNEL_SLAVE) + intcsr |= IXXAT_INTCSR_SLAVE; + else + intcsr |= IXXAT_INTCSR_MASTER; + outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET); + + /* Register and setup interrupt handling */ + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->irq_num = pdev->irq; + + RTCAN_DBG("%s: base_addr=0x%p conf_addr=%#x irq=%d ocr=%#x cdr=%#x\n", + RTCAN_DRV_NAME, board->base_addr, board->conf_addr, + chip->irq_num, chip->ocr, chip->cdr); + + /* Register SJA1000 device */ + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR "ERROR %d while trying to register SJA1000 device!\n", + ret); + goto failure; + } + + if (channel != CHANNEL_SLAVE) + *master_dev = dev; + + return 0; + + failure: + rtcan_dev_free(dev); + return ret; +} + +static int __devinit ixxat_pci_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret, channel, conf_addr; + unsigned long addr; + void __iomem *base_addr; + struct rtcan_device *master_dev = NULL; + + if ((ret = pci_enable_device (pdev))) + goto failure; + + if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME))) + goto failure; + + RTCAN_DBG("%s: Initializing device %04x:%04x:%04x\n", + RTCAN_DRV_NAME, pdev->vendor, pdev->device, + pdev->subsystem_device); + + /* Enable memory and I/O space */ + if ((ret = pci_write_config_word(pdev, 0x04, 0x3))) + goto failure_release_pci; + + conf_addr = pci_resource_start(pdev, 1); + + addr = pci_resource_start(pdev, 2); + base_addr = ioremap(addr, IXXAT_BASE_PORT_SIZE); + if (base_addr == 0) { + ret = -ENODEV; + goto failure_release_pci; + } + + /* Check if second channel is available after reset */ + writeb(0x1, base_addr + CHANNEL_MASTER_RESET); + writeb(0x1, base_addr + CHANNEL_SLAVE_RESET); + udelay(100); + if ( (readb(base_addr + CHANNEL_OFFSET + SJA_MOD) & IXXAT_SJA_MOD_MASK ) != 0x21 || + readb(base_addr + CHANNEL_OFFSET + SJA_SR ) != 0x0c || + readb(base_addr + CHANNEL_OFFSET + SJA_IR ) != 0xe0) + channel = CHANNEL_SINGLE; + else + channel = CHANNEL_MASTER; + + if ((ret = rtcan_ixxat_pci_add_chan(pdev, channel, &master_dev, + conf_addr, base_addr))) + goto failure_iounmap; + + if (channel != CHANNEL_SINGLE) { + channel = CHANNEL_SLAVE; + if ((ret = rtcan_ixxat_pci_add_chan(pdev, channel, + &master_dev, conf_addr, + base_addr + CHANNEL_OFFSET))) + goto failure_iounmap; + } + + pci_set_drvdata(pdev, master_dev); + return 0; + +failure_iounmap: + if (master_dev) + rtcan_ixxat_pci_del_chan(master_dev); + iounmap(base_addr); + +failure_release_pci: + pci_release_regions(pdev); + +failure: + return ret; +} + +static void __devexit ixxat_pci_remove_one (struct pci_dev *pdev) +{ + struct rtcan_device *dev = pci_get_drvdata(pdev); + struct rtcan_ixxat_pci *board = (struct rtcan_ixxat_pci *)dev->board_priv; + + if (board->slave_dev) + rtcan_ixxat_pci_del_chan(board->slave_dev); + rtcan_ixxat_pci_del_chan(dev); + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver rtcan_ixxat_pci_driver = { + .name = RTCAN_DRV_NAME, + .id_table = ixxat_pci_tbl, + .probe = ixxat_pci_init_one, + .remove = __devexit_p(ixxat_pci_remove_one), +}; + +static int __init rtcan_ixxat_pci_init(void) +{ + return pci_register_driver(&rtcan_ixxat_pci_driver); +} + + +static void __exit rtcan_ixxat_pci_exit(void) +{ + pci_unregister_driver(&rtcan_ixxat_pci_driver); +} + +module_init(rtcan_ixxat_pci_init); +module_exit(rtcan_ixxat_pci_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_mem.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_mem.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_mem.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_mem.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2006 Matthias Fuchs , + * Jan Kiszka + * + * RTCAN driver for memory mapped SJA1000 CAN controller + * This code has been tested on esd's CPCI405/EPPC405 PPC405 systems. + * + * This driver is derived from the rtcan-isa driver by + * Wolfgang Grandegger and Sebastian Smolorz. + * + * Copyright (C) 2006 Wolfgang Grandegger + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * + * 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; eitherer 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "sja1000-mem" + +#define RTCAN_MEM_MAX_DEV 4 + +static char *mem_board_name = "mem mapped"; + +MODULE_AUTHOR("Matthias Fuchs "); +MODULE_DESCRIPTION("RTCAN driver for memory mapped SJA1000 controller"); +MODULE_SUPPORTED_DEVICE("mem mapped"); +MODULE_LICENSE("GPL"); + +static u32 mem[RTCAN_MEM_MAX_DEV]; +static int irq[RTCAN_MEM_MAX_DEV]; +static u32 can_clock[RTCAN_MEM_MAX_DEV]; +static u8 ocr[RTCAN_MEM_MAX_DEV]; +static u8 cdr[RTCAN_MEM_MAX_DEV]; + +compat_module_param_array(mem, uint, RTCAN_MEM_MAX_DEV, 0444); +compat_module_param_array(irq, int, RTCAN_MEM_MAX_DEV, 0444); +compat_module_param_array(can_clock, uint, RTCAN_MEM_MAX_DEV, 0444); +compat_module_param_array(ocr, byte, RTCAN_MEM_MAX_DEV, 0444); +compat_module_param_array(cdr, byte, RTCAN_MEM_MAX_DEV, 0444); + +MODULE_PARM_DESC(mem, "The io-memory address"); +MODULE_PARM_DESC(irq, "The interrupt number"); +MODULE_PARM_DESC(can_clock, "External clock frequency (default 16 MHz)"); +MODULE_PARM_DESC(ocr, "Value of output control register (default 0x1a)"); +MODULE_PARM_DESC(cdr, "Value of clock divider register (default 0xc8"); + +#define RTCAN_MEM_RANGE 0x80 + +struct rtcan_mem +{ + volatile void __iomem *vmem; +}; + +static struct rtcan_device *rtcan_mem_devs[RTCAN_MEM_MAX_DEV]; + +static u8 rtcan_mem_readreg(struct rtcan_device *dev, int reg) +{ + struct rtcan_mem *board = (struct rtcan_mem *)dev->board_priv; + return readb(board->vmem + reg); +} + +static void rtcan_mem_writereg(struct rtcan_device *dev, int reg, u8 val) +{ + struct rtcan_mem *board = (struct rtcan_mem *)dev->board_priv; + writeb(val, board->vmem + reg); +} + +int __init rtcan_mem_init_one(int idx) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_mem *board; + int ret; + + if ((dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_mem))) == NULL) + return -ENOMEM; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_mem *)dev->board_priv; + + dev->board_name = mem_board_name; + + chip->irq_num = irq[idx]; + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->read_reg = rtcan_mem_readreg; + chip->write_reg = rtcan_mem_writereg; + + if (!request_mem_region(mem[idx], RTCAN_MEM_RANGE, RTCAN_DRV_NAME)) { + ret = -EBUSY; + goto out_dev_free; + } + + /* ioremap io memory */ + if (!(board->vmem = ioremap(mem[idx], RTCAN_MEM_RANGE))) { + ret = -EBUSY; + goto out_release_mem; + } + + /* Clock frequency in Hz */ + if (can_clock[idx]) + dev->can_sys_clock = can_clock[idx] / 2; + else + dev->can_sys_clock = 8000000; /* 16/2 MHz */ + + /* Output control register */ + if (ocr[idx]) + chip->ocr = ocr[idx]; + else + chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL; + + if (cdr[idx]) + chip->cdr = cdr[idx]; + else + chip->cdr = SJA_CDR_CAN_MODE | SJA_CDR_CLK_OFF | SJA_CDR_CBP; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR "ERROR %d while trying to register SJA1000 " + "device!\n", ret); + goto out_iounmap; + } + + rtcan_mem_devs[idx] = dev; + return 0; + + out_iounmap: + iounmap((void *)board->vmem); + + out_release_mem: + release_mem_region(mem[idx], RTCAN_MEM_RANGE); + + out_dev_free: + rtcan_dev_free(dev); + + return ret; +} + +static void rtcan_mem_exit(void); + +/** Init module */ +static int __init rtcan_mem_init(void) +{ + int i, err; + int devices = 0; + + for (i = 0; i < RTCAN_MEM_MAX_DEV && mem[i] != 0; i++) { + err = rtcan_mem_init_one(i); + if (err) { + rtcan_mem_exit(); + return err; + } + devices++; + } + if (devices) + return 0; + + printk(KERN_ERR "ERROR! No devices specified! " + "Use mem=[,...] irq=[,...]\n"); + return -EINVAL; +} + + +/** Cleanup module */ +static void rtcan_mem_exit(void) +{ + int i; + struct rtcan_device *dev; + volatile void __iomem *vmem; + + for (i = 0; i < RTCAN_MEM_MAX_DEV; i++) { + dev = rtcan_mem_devs[i]; + if (!dev) + continue; + vmem = ((struct rtcan_mem *)dev->board_priv)->vmem; + rtcan_sja1000_unregister(dev); + iounmap((void *)vmem); + release_mem_region(mem[i], RTCAN_MEM_RANGE); + rtcan_dev_free(dev); + } +} + +module_init(rtcan_mem_init); +module_exit(rtcan_mem_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_dng.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_dng.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_dng.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_dng.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from the PCAN project file driver/src/pcan_dongle.c: + * + * Copyright (C) 2001-2006 PEAK System-Technik GmbH + * + * + * 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 +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include +#endif /* Linux >= 2.6.0 */ + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "PEAK-Dongle" + +#define RTCAN_PEAK_DNG_MAX_DEV 1 + +static char *dongle_board_name = "PEAK-Dongle"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RTCAN board driver for PEAK-Dongle"); +MODULE_SUPPORTED_DEVICE("PEAK-Dongle CAN controller"); +MODULE_LICENSE("GPL"); + +static char *type[RTCAN_PEAK_DNG_MAX_DEV]; +static ushort io[RTCAN_PEAK_DNG_MAX_DEV]; +static char irq[RTCAN_PEAK_DNG_MAX_DEV]; + +compat_module_param_array(type, charp, RTCAN_PEAK_DNG_MAX_DEV, 0444); +compat_module_param_array(io, ushort, RTCAN_PEAK_DNG_MAX_DEV, 0444); +compat_module_param_array(irq, byte, RTCAN_PEAK_DNG_MAX_DEV, 0444); + +MODULE_PARM_DESC(type, "The type of interface (sp, epp)"); +MODULE_PARM_DESC(io, "The io-port address"); +MODULE_PARM_DESC(irq, "The interrupt number"); + +#define DONGLE_TYPE_SP 0 +#define DONGLE_TYPE_EPP 1 + +#define DNG_PORT_SIZE 4 /* the address range of the dongle-port */ +#define ECR_PORT_SIZE 1 /* size of the associated ECR register */ + +struct rtcan_peak_dng +{ + u16 ioport; + u16 ecr; /* ECR register in case of EPP */ + u8 old_data; /* the overwritten contents of the port registers */ + u8 old_ctrl; + u8 old_ecr; + u8 type; +}; + +static struct rtcan_device *rtcan_peak_dng_devs[RTCAN_PEAK_DNG_MAX_DEV]; + +static u16 dng_ports[] = {0x378, 0x278, 0x3bc, 0x2bc}; +static u8 dng_irqs[] = {7, 5, 7, 5}; + +static unsigned char nibble_decode[32] = +{ + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 +}; + +/* Enable and disable irqs */ +static inline void rtcan_parport_disable_irq(u32 port) +{ + u32 pc = port + 2; + outb(inb(pc) & ~0x10, pc); +} + +static inline void rtcan_parport_enable_irq(u32 port) +{ + u32 pc = port + 2; + outb(inb(pc) | 0x10, pc); +} + +/* Functions for SP port */ +static u8 rtcan_peak_dng_sp_readreg(struct rtcan_device *dev, int port) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + u32 pa = dng->ioport; + u32 pb = pa + 1; + u32 pc = pb + 1; + u8 b0, b1 ; + u8 irq_enable = inb(pc) & 0x10; /* don't influence irq_enable */ + + outb((0x0B ^ 0x0D) | irq_enable, pc); + outb((port & 0x1F) | 0x80, pa); + outb((0x0B ^ 0x0C) | irq_enable, pc); + b1=nibble_decode[inb(pb)>>3]; + outb(0x40, pa); + b0=nibble_decode[inb(pb)>>3]; + outb((0x0B ^ 0x0D) | irq_enable, pc); + + return (b1 << 4) | b0 ; +} + +static void rtcan_peak_dng_writereg(struct rtcan_device *dev, int port, u8 data) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + u32 pa = dng->ioport; + u32 pc = pa + 2; + u8 irq_enable = inb(pc) & 0x10; /* don't influence irq_enable */ + + outb((0x0B ^ 0x0D) | irq_enable, pc); + outb(port & 0x1F, pa); + outb((0x0B ^ 0x0C) | irq_enable, pc); + outb(data, pa); + outb((0x0B ^ 0x0D) | irq_enable, pc); +} + +/* Functions for EPP port */ +static u8 rtcan_peak_dng_epp_readreg(struct rtcan_device *dev, int port) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + u32 pa = dng->ioport; + u32 pc = pa + 2; + u8 val; + u8 irq_enable = inb(pc) & 0x10; /* don't influence irq_enable */ + + outb((0x0B ^ 0x0F) | irq_enable, pc); + outb((port & 0x1F) | 0x80, pa); + outb((0x0B ^ 0x2E) | irq_enable, pc); + val = inb(pa); + outb((0x0B ^ 0x0F) | irq_enable, pc); + + return val; +} + + +/* to switch epp on or restore register */ +static void dongle_set_ecr(u16 port, struct rtcan_peak_dng *dng) +{ + u32 ecr = dng->ecr; + + dng->old_ecr = inb(ecr); + outb((dng->old_ecr & 0x1F) | 0x20, ecr); + + if (dng->old_ecr == 0xff) + printk(KERN_DEBUG "%s: realy ECP mode configured?\n", RTCAN_DRV_NAME); +} + +static void dongle_restore_ecr(u16 port, struct rtcan_peak_dng *dng) +{ + u32 ecr = dng->ecr; + + outb(dng->old_ecr, ecr); + + printk(KERN_DEBUG "%s: restore ECR\n", RTCAN_DRV_NAME); +} + +static inline void rtcan_peak_dng_enable(struct rtcan_device *dev) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + u32 port = dng->ioport; + + /* save old port contents */ + dng->old_data = inb(port); + dng->old_ctrl = inb(port + 2); + + /* switch to epp mode if possible */ + if (dng->type == DONGLE_TYPE_EPP) + dongle_set_ecr(port, dng); + + rtcan_parport_enable_irq(port); +} + +static inline void rtcan_peak_dng_disable(struct rtcan_device *dev) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + u32 port = dng->ioport; + + rtcan_parport_disable_irq(port); + + if (dng->type == DONGLE_TYPE_EPP) + dongle_restore_ecr(port, dng); + + /* restore port state */ + outb(dng->old_data, port); + outb(dng->old_ctrl, port + 2); +} + +/** Init module */ +int __init rtcan_peak_dng_init_one(int idx) +{ + int ret, dtype; + struct rtcan_device *dev; + struct rtcan_sja1000 *sja; + struct rtcan_peak_dng *dng; + + if (strncmp(type[idx], "sp", 2) == 0) + dtype = DONGLE_TYPE_SP; + else if (strncmp(type[idx], "epp", 3) == 0) + dtype = DONGLE_TYPE_EPP; + else { + printk("%s: type %s is invalid, use \"sp\" or \"epp\".", + RTCAN_DRV_NAME, type[idx]); + return -EINVAL; + } + + if ((dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_peak_dng))) == NULL) + return -ENOMEM; + + sja = (struct rtcan_sja1000 *)dev->priv; + dng = (struct rtcan_peak_dng *)dev->board_priv; + + dev->board_name = dongle_board_name; + + if (io[idx]) + dng->ioport = io[idx]; + else + dng->ioport = dng_ports[idx]; + + if (irq[idx]) + sja->irq_num = irq[idx]; + else + sja->irq_num = dng_irqs[idx]; + sja->irq_flags = 0; + + if (dtype == DONGLE_TYPE_SP) { + sja->read_reg = rtcan_peak_dng_sp_readreg; + sja->write_reg = rtcan_peak_dng_writereg; + dng->ecr = 0; /* set to anything */ + } else { + sja->read_reg = rtcan_peak_dng_epp_readreg; + sja->write_reg = rtcan_peak_dng_writereg; + dng->ecr = dng->ioport + 0x402; + } + + /* Check and request I/O ports */ + if (!request_region(dng->ioport, DNG_PORT_SIZE, RTCAN_DRV_NAME)) { + ret = -EBUSY; + goto out_dev_free; + } + + if (dng->type == DONGLE_TYPE_EPP) { + if (!request_region(dng->ecr, ECR_PORT_SIZE, RTCAN_DRV_NAME)) { + ret = -EBUSY; + goto out_free_region; + } + } + + /* Clock frequency in Hz */ + dev->can_sys_clock = 8000000; /* 16/2 MHz */ + + /* Output control register */ + sja->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL; + + sja->cdr = SJA_CDR_CAN_MODE; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + rtcan_peak_dng_enable(dev); + + /* Register RTDM device */ + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR "ERROR while trying to register SJA1000 device %d!\n", + ret); + goto out_free_region2; + } + + rtcan_peak_dng_devs[idx] = dev; + return 0; + + out_free_region2: + if (dng->type == DONGLE_TYPE_EPP) + release_region(dng->ecr, ECR_PORT_SIZE); + + out_free_region: + release_region(dng->ioport, DNG_PORT_SIZE); + + out_dev_free: + rtcan_dev_free(dev); + + return ret; +} + +void rtcan_peak_dng_exit_one(struct rtcan_device *dev) +{ + struct rtcan_peak_dng *dng = (struct rtcan_peak_dng *)dev->board_priv; + + rtcan_sja1000_unregister(dev); + rtcan_peak_dng_disable(dev); + if (dng->type == DONGLE_TYPE_EPP) + release_region(dng->ecr, ECR_PORT_SIZE); + release_region(dng->ioport, DNG_PORT_SIZE); + rtcan_dev_free(dev); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static const struct pnp_device_id rtcan_peak_dng_pnp_tbl[] = { + /* Standard LPT Printer Port */ + {.id = "PNP0400", .driver_data = 0}, + /* ECP Printer Port */ + {.id = "PNP0401", .driver_data = 0}, + { } +}; + +static int rtcan_peak_dng_pnp_probe(struct pnp_dev *dev, + const struct pnp_device_id *id) +{ + return 0; +} + +static struct pnp_driver rtcan_peak_dng_pnp_driver = { + .name = RTCAN_DRV_NAME, + .id_table = rtcan_peak_dng_pnp_tbl, + .probe = rtcan_peak_dng_pnp_probe, +}; + +static int pnp_registered; +#endif /* Linux >= 2.6.0 */ + +/** Cleanup module */ +static void rtcan_peak_dng_exit(void) +{ + int i; + struct rtcan_device *dev; + + for (i = 0, dev = rtcan_peak_dng_devs[i]; + i < RTCAN_PEAK_DNG_MAX_DEV && dev != NULL; + i++) + rtcan_peak_dng_exit_one(dev); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (pnp_registered) + pnp_unregister_driver(&rtcan_peak_dng_pnp_driver); +#endif /* Linux >= 2.6.0 */ +} + +/** Init module */ +static int __init rtcan_peak_dng_init(void) +{ + int i, ret = -EINVAL, done = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (pnp_register_driver(&rtcan_peak_dng_pnp_driver) == 0) + pnp_registered = 1; +#endif /* Linux >= 2.6.0 */ + + for (i = 0; + i < RTCAN_PEAK_DNG_MAX_DEV && type[i] != 0; + i++) { + + if ((ret = rtcan_peak_dng_init_one(i)) != 0) { + printk(KERN_ERR "%s: Init failed with %d\n", RTCAN_DRV_NAME, ret); + goto cleanup; + } + done++; + } + if (done) + return 0; + + printk(KERN_ERR "%s: Please specify type=epp or type=sp\n", + RTCAN_DRV_NAME); + +cleanup: + rtcan_peak_dng_exit(); + return ret; +} + +module_init(rtcan_peak_dng_init); +module_exit(rtcan_peak_dng_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_pci.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_pci.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_peak_pci.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * Derived from the PCAN project file driver/src/pcan_pci.c: + * + * Copyright (C) 2001-2006 PEAK System-Technik GmbH + * + * + * 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 +#include +#include +#include +#include + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include + +#define RTCAN_DEV_NAME "rtcan%d" +#define RTCAN_DRV_NAME "PEAK-PCI-CAN" + +static char *peak_pci_board_name = "PEAK-PCI"; + +MODULE_AUTHOR("Wolfgang Grandegger "); +MODULE_DESCRIPTION("RTCAN board driver for PEAK-PCI cards"); +MODULE_SUPPORTED_DEVICE("PEAK-PCI card CAN controller"); +MODULE_LICENSE("GPL"); + +struct rtcan_peak_pci +{ + struct pci_dev *pci_dev; + struct rtcan_device *slave_dev; + int channel; + volatile void __iomem *base_addr; + volatile void __iomem *conf_addr; +}; + +#define PEAK_PCI_CAN_SYS_CLOCK (16000000 / 2) + +#define PELICAN_SINGLE (SJA_CDR_CAN_MODE | SJA_CDR_CBP | 0x07 | SJA_CDR_CLK_OFF) +#define PELICAN_MASTER (SJA_CDR_CAN_MODE | SJA_CDR_CBP | 0x07 ) +#define PELICAN_DEFAULT (SJA_CDR_CAN_MODE ) + +#define CHANNEL_SINGLE 0 /* this is a single channel device */ +#define CHANNEL_MASTER 1 /* multi channel device, this device is master */ +#define CHANNEL_SLAVE 2 /* multi channel device, this is slave */ + +// important PITA registers +#define PITA_ICR 0x00 // interrupt control register +#define PITA_GPIOICR 0x18 // general purpose IO interface control register +#define PITA_MISC 0x1C // miscellanoes register + +#define PEAK_PCI_VENDOR_ID 0x001C // the PCI device and vendor IDs +#define PEAK_PCI_DEVICE_ID 0x0001 + +#define PCI_CONFIG_PORT_SIZE 0x1000 // size of the config io-memory +#define PCI_PORT_SIZE 0x0400 // size of a channel io-memory + +static struct pci_device_id peak_pci_tbl[] = { + {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE (pci, peak_pci_tbl); + + +static u8 rtcan_peak_pci_read_reg(struct rtcan_device *dev, int port) +{ + struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv; + return readb(board->base_addr + ((unsigned long)port << 2)); +} + +static void rtcan_peak_pci_write_reg(struct rtcan_device *dev, int port, u8 data) +{ + struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv; + writeb(data, board->base_addr + ((unsigned long)port << 2)); +} + +static void rtcan_peak_pci_irq_ack(struct rtcan_device *dev) +{ + struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv; + u16 pita_icr_low; + + /* Select and clear in Pita stored interrupt */ + pita_icr_low = readw(board->conf_addr + PITA_ICR); + if (board->channel == CHANNEL_SLAVE) { + if (pita_icr_low & 0x0001) + writew(0x0001, board->conf_addr + PITA_ICR); + } + else { + if (pita_icr_low & 0x0002) + writew(0x0002, board->conf_addr + PITA_ICR); + } +} + +static void rtcan_peak_pci_del_chan(struct rtcan_device *dev, + int init_step) +{ + struct rtcan_peak_pci *board; + u16 pita_icr_high; + + if (!dev) + return; + + board = (struct rtcan_peak_pci *)dev->board_priv; + + switch (init_step) { + case 0: /* Full cleanup */ + printk("Removing %s %s device %s\n", + peak_pci_board_name, dev->ctrl_name, dev->name); + rtcan_sja1000_unregister(dev); + case 5: + pita_icr_high = readw(board->conf_addr + PITA_ICR + 2); + if (board->channel == CHANNEL_SLAVE) { + pita_icr_high &= ~0x0001; + } else { + pita_icr_high &= ~0x0002; + } + writew(pita_icr_high, board->conf_addr + PITA_ICR + 2); + case 4: + iounmap((void *)board->base_addr); + case 3: + if (board->channel != CHANNEL_SLAVE) + iounmap((void *)board->conf_addr); + case 2: + rtcan_dev_free(dev); + case 1: + break; + } + +} + +static int rtcan_peak_pci_add_chan(struct pci_dev *pdev, int channel, + struct rtcan_device **master_dev) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_peak_pci *board; + u16 pita_icr_high; + unsigned long addr; + int ret, init_step = 1; + + dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct rtcan_peak_pci)); + if (dev == NULL) + return -ENOMEM; + init_step = 2; + + chip = (struct rtcan_sja1000 *)dev->priv; + board = (struct rtcan_peak_pci *)dev->board_priv; + + board->pci_dev = pdev; + board->channel = channel; + + if (channel != CHANNEL_SLAVE) { + + addr = pci_resource_start(pdev, 0); + board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE); + if (board->conf_addr == 0) { + ret = -ENODEV; + goto failure; + } + init_step = 3; + + /* Set GPIO control register */ + writew(0x0005, board->conf_addr + PITA_GPIOICR + 2); + + if (channel == CHANNEL_MASTER) + writeb(0x00, board->conf_addr + PITA_GPIOICR); /* enable both */ + else + writeb(0x04, board->conf_addr + PITA_GPIOICR); /* enable single */ + + writeb(0x05, board->conf_addr + PITA_MISC + 3); /* toggle reset */ + mdelay(5); + writeb(0x04, board->conf_addr + PITA_MISC + 3); /* leave parport mux mode */ + } else { + struct rtcan_peak_pci *master_board = + (struct rtcan_peak_pci *)(*master_dev)->board_priv; + master_board->slave_dev = dev; + board->conf_addr = master_board->conf_addr; + } + + addr = pci_resource_start(pdev, 1); + if (channel == CHANNEL_SLAVE) + addr += 0x400; + + board->base_addr = ioremap(addr, PCI_PORT_SIZE); + if (board->base_addr == 0) { + ret = -ENODEV; + goto failure; + } + init_step = 4; + + dev->board_name = peak_pci_board_name; + + chip->read_reg = rtcan_peak_pci_read_reg; + chip->write_reg = rtcan_peak_pci_write_reg; + chip->irq_ack = rtcan_peak_pci_irq_ack; + + /* Clock frequency in Hz */ + dev->can_sys_clock = PEAK_PCI_CAN_SYS_CLOCK; + + /* Output control register */ + chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL; + + /* Clock divider register */ + if (channel == CHANNEL_MASTER) + chip->cdr = PELICAN_MASTER; + else + chip->cdr = PELICAN_SINGLE; + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + + /* Register and setup interrupt handling */ + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->irq_num = pdev->irq; + pita_icr_high = readw(board->conf_addr + PITA_ICR + 2); + if (channel == CHANNEL_SLAVE) { + pita_icr_high |= 0x0001; + } else { + pita_icr_high |= 0x0002; + } + writew(pita_icr_high, board->conf_addr + PITA_ICR + 2); + init_step = 5; + + printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME, + board->base_addr, board->conf_addr, chip->irq_num); + + /* Register SJA1000 device */ + ret = rtcan_sja1000_register(dev); + if (ret) { + printk(KERN_ERR + "ERROR %d while trying to register SJA1000 device!\n", ret); + goto failure; + } + + if (channel != CHANNEL_SLAVE) + *master_dev = dev; + + return 0; + + failure: + rtcan_peak_pci_del_chan(dev, init_step); + return ret; +} + +static int __devinit peak_pci_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret; + u16 sub_sys_id; + struct rtcan_device *master_dev = NULL; + + printk("%s: initializing device %04x:%04x\n", + RTCAN_DRV_NAME, pdev->vendor, pdev->device); + + if ((ret = pci_enable_device (pdev))) + goto failure; + + if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME))) + goto failure; + + if ((ret = pci_read_config_word(pdev, 0x2e, &sub_sys_id))) + goto failure_cleanup; + + /* Enable memory space */ + if ((ret = pci_write_config_word(pdev, 0x04, 2))) + goto failure_cleanup; + + if ((ret = pci_write_config_word(pdev, 0x44, 0))) + goto failure_cleanup; + + if (sub_sys_id > 3) { + if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_MASTER, + &master_dev))) + goto failure_cleanup; + if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SLAVE, + &master_dev))) + goto failure_cleanup; + } else { + if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SINGLE, + &master_dev))) + goto failure_cleanup; + } + + pci_set_drvdata(pdev, master_dev); + return 0; + + failure_cleanup: + if (master_dev) + rtcan_peak_pci_del_chan(master_dev, 0); + + pci_release_regions(pdev); + + failure: + return ret; + +} + +static void __devexit peak_pci_remove_one (struct pci_dev *pdev) +{ + struct rtcan_device *dev = pci_get_drvdata(pdev); + struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv; + + if (board->slave_dev) + rtcan_peak_pci_del_chan(board->slave_dev, 0); + rtcan_peak_pci_del_chan(dev, 0); + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver rtcan_peak_pci_driver = { + .name = RTCAN_DRV_NAME, + .id_table = peak_pci_tbl, + .probe = peak_pci_init_one, + .remove = __devexit_p(peak_pci_remove_one), +}; + +static int __init rtcan_peak_pci_init(void) +{ + return pci_register_driver(&rtcan_peak_pci_driver); +} + + +static void __exit rtcan_peak_pci_exit(void) +{ + pci_unregister_driver(&rtcan_peak_pci_driver); +} + +module_init(rtcan_peak_pci_init); +module_exit(rtcan_peak_pci_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_plx_pci.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_plx_pci.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_plx_pci.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_plx_pci.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,608 @@ +/* + * Copyright (C) 2008-2010 Pavel Cheblakov + * + * Derived from the ems_pci.c driver: + * Copyright (C) 2007 Wolfgang Grandegger + * Copyright (C) 2008 Markus Plessing + * Copyright (C) 2008 Sebastian Haas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the version 2 of the GNU General Public License + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include + +/* CAN device profile */ +#include +#include +#include +#include +#include +#include + +#define RTCAN_DRV_NAME "rt_sja1000_plx_pci" +#define RTCAN_DEV_NAME "rtcan%d" + +MODULE_AUTHOR("Pavel Cheblakov "); +MODULE_DESCRIPTION("RTCAN driver for PLX90xx PCI-bridge cards with " + "the SJA1000 chips"); +MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " + "Adlink PCI-7841/cPCI-7841 SE, " + "Marathon CAN-bus-PCI, " + "TEWS TECHNOLOGIES TPMC810, " + "esd CAN-PCI/CPCI/PCI104/200, " + "esd CAN-PCI/PMC/266, " + "esd CAN-PCIe/2000") +MODULE_LICENSE("GPL v2"); + +#define PLX_PCI_MAX_CHAN 2 + +struct plx_pci_card { + int channels; /* detected channels count */ + struct rtcan_device *rtcan_dev[PLX_PCI_MAX_CHAN]; + void __iomem *conf_addr; + + /* Pointer to device-dependent reset function */ + void (*reset_func)(struct pci_dev *pdev); +}; + +#define PLX_PCI_CAN_CLOCK (16000000 / 2) + +/* PLX9030/9050/9052 registers */ +#define PLX_INTCSR 0x4c /* Interrupt Control/Status */ +#define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response, + * Serial EEPROM, and Initialization + * Control register + */ + +#define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */ +#define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */ +#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ +#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ + +/* PLX9056 registers */ +#define PLX9056_INTCSR 0x68 /* Interrupt Control/Status */ +#define PLX9056_CNTRL 0x6c /* Control / Software Reset */ + +#define PLX9056_LINTI (1 << 11) +#define PLX9056_PCI_INT_EN (1 << 8) +#define PLX9056_PCI_RCR (1 << 29) /* Read Configuration Registers */ + +/* + * The board configuration is probably following: + * RX1 is connected to ground. + * TX1 is not connected. + * CLKO is not connected. + * Setting the OCR register to 0xDA is a good idea. + * This means normal output mode, push-pull and the correct polarity. + */ +#define PLX_PCI_OCR (SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL | SJA_OCR_TX1_PUSHPULL) + +/* + * In the CDR register, you should set CBP to 1. + * You will probably also want to set the clock divider value to 7 + * (meaning direct oscillator output) because the second SJA1000 chip + * is driven by the first one CLKOUT output. + */ +#define PLX_PCI_CDR (SJA_CDR_CBP | SJA_CDR_CAN_MODE) + +/* SJA1000 Control Register in the BasicCAN Mode */ +#define SJA_CR 0x00 + +/* States of some SJA1000 registers after hardware reset in the BasicCAN mode*/ +#define REG_CR_BASICCAN_INITIAL 0x21 +#define REG_CR_BASICCAN_INITIAL_MASK 0xa1 +#define REG_SR_BASICCAN_INITIAL 0x0c +#define REG_IR_BASICCAN_INITIAL 0xe0 + +/* States of some SJA1000 registers after hardware reset in the PeliCAN mode*/ +#define REG_MOD_PELICAN_INITIAL 0x01 +#define REG_SR_PELICAN_INITIAL 0x3c +#define REG_IR_PELICAN_INITIAL 0x00 + +#define ADLINK_PCI_VENDOR_ID 0x144A +#define ADLINK_PCI_DEVICE_ID 0x7841 + +#define ESD_PCI_SUB_SYS_ID_PCI200 0x0004 +#define ESD_PCI_SUB_SYS_ID_PCI266 0x0009 +#define ESD_PCI_SUB_SYS_ID_PMC266 0x000e +#define ESD_PCI_SUB_SYS_ID_CPCI200 0x010b +#define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200 +#define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501 + +#define MARATHON_PCI_DEVICE_ID 0x2715 + +#define TEWS_PCI_VENDOR_ID 0x1498 +#define TEWS_PCI_DEVICE_ID_TMPC810 0x032A + +static void plx_pci_reset_common(struct pci_dev *pdev); +static void plx_pci_reset_marathon(struct pci_dev *pdev); +static void plx9056_pci_reset_common(struct pci_dev *pdev); + +struct plx_pci_channel_map { + u32 bar; + u32 offset; + u32 size; /* 0x00 - auto, e.g. length of entire bar */ +}; + +struct plx_pci_card_info { + const char *name; + int channel_count; + u32 can_clock; + u8 ocr; /* output control register */ + u8 cdr; /* clock divider register */ + + /* Parameters for mapping local configuration space */ + struct plx_pci_channel_map conf_map; + + /* Parameters for mapping the SJA1000 chips */ + struct plx_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CHAN]; + + /* Pointer to device-dependent reset function */ + void (*reset_func)(struct pci_dev *pdev); +}; + +static struct plx_pci_card_info plx_pci_card_info_adlink __devinitdata = { + "Adlink PCI-7841/cPCI-7841", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {1, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} }, + &plx_pci_reset_common + /* based on PLX9052 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_adlink_se __devinitdata = { + "Adlink PCI-7841/cPCI-7841 SE", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} }, + &plx_pci_reset_common + /* based on PLX9052 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_esd200 __devinitdata = { + "esd CAN-PCI/CPCI/PCI104/200", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, + &plx_pci_reset_common + /* based on PLX9030/9050 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_esd266 __devinitdata = { + "esd CAN-PCI/PMC/266", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, + &plx9056_pci_reset_common + /* based on PLX9056 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = { + "esd CAN-PCIe/2000", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, + &plx9056_pci_reset_common + /* based on PEX8311 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { + "Marathon CAN-bus-PCI", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} }, + &plx_pci_reset_marathon + /* based on PLX9052 */ +}; + +static struct plx_pci_card_info plx_pci_card_info_tews __devinitdata = { + "TEWS TECHNOLOGIES TPMC810", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x000, 0x80}, {2, 0x100, 0x80} }, + &plx_pci_reset_common + /* based on PLX9030 */ +}; + +static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = { + { + /* Adlink PCI-7841/cPCI-7841 */ + ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_NETWORK_OTHER << 8, ~0, + (kernel_ulong_t)&plx_pci_card_info_adlink + }, + { + /* Adlink PCI-7841/cPCI-7841 SE */ + ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID, + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_OTHER << 8, ~0, + (kernel_ulong_t)&plx_pci_card_info_adlink_se + }, + { + /* esd CAN-PCI/200 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI200, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd200 + }, + { + /* esd CAN-CPCI/200 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_CPCI200, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd200 + }, + { + /* esd CAN-PCI104/200 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI104200, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd200 + }, + { + /* esd CAN-PCI/266 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI266, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd266 + }, + { + /* esd CAN-PMC/266 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PMC266, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd266 + }, + { + /* esd CAN-PCIE/2000 */ + PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, + PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCIE2000, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_esd2000 + }, + { + /* Marathon CAN-bus-PCI card */ + PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_marathon + }, + { + /* TEWS TECHNOLOGIES TPMC810 card */ + TEWS_PCI_VENDOR_ID, TEWS_PCI_DEVICE_ID_TMPC810, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_tews + }, + { 0,} +}; +MODULE_DEVICE_TABLE(pci, plx_pci_tbl); + +static u8 plx_pci_read_reg(struct rtcan_device *dev, int port) +{ + return ioread8((void* __iomem)dev->base_addr + port); +} + +static void plx_pci_write_reg(struct rtcan_device *dev, int port, u8 val) +{ + iowrite8(val, (void* __iomem)dev->base_addr + port); +} + +/* + * Check if a CAN controller is present at the specified location + * by trying to switch 'em from the Basic mode into the PeliCAN mode. + * Also check states of some registers in reset mode. + */ +static inline int plx_pci_check_sja1000(struct rtcan_device *dev) +{ + int flag = 0; + + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + /* + * Check registers after hardware reset (the Basic mode) + * See states on p. 10 of the Datasheet. + */ + if ((chip->read_reg(dev, SJA_CR) & REG_CR_BASICCAN_INITIAL_MASK) == + REG_CR_BASICCAN_INITIAL && + (chip->read_reg(dev, SJA_SR) == REG_SR_BASICCAN_INITIAL) && + (chip->read_reg(dev, SJA_IR) == REG_IR_BASICCAN_INITIAL)) + flag = 1; + + /* Bring the SJA1000 into the PeliCAN mode*/ + chip->write_reg(dev, SJA_CDR, SJA_CDR_CAN_MODE); + + /* + * Check registers after reset in the PeliCAN mode. + * See states on p. 23 of the Datasheet. + */ + if (chip->read_reg(dev, SJA_MOD) == REG_MOD_PELICAN_INITIAL && + chip->read_reg(dev, SJA_SR) == REG_SR_PELICAN_INITIAL && + chip->read_reg(dev, SJA_IR) == REG_IR_PELICAN_INITIAL) + return flag; + + return 0; +} + +/* + * PLX9030/50/52 software reset + * Also LRESET# asserts and brings to reset device on the Local Bus (if wired). + * For most cards it's enough for reset the SJA1000 chips. + */ +static void plx_pci_reset_common(struct pci_dev *pdev) +{ + struct plx_pci_card *card = pci_get_drvdata(pdev); + u32 cntrl; + + cntrl = ioread32(card->conf_addr + PLX_CNTRL); + cntrl |= PLX_PCI_RESET; + iowrite32(cntrl, card->conf_addr + PLX_CNTRL); + udelay(100); + cntrl ^= PLX_PCI_RESET; + iowrite32(cntrl, card->conf_addr + PLX_CNTRL); +}; + +/* + * PLX9056 software reset + * Assert LRESET# and reset device(s) on the Local Bus (if wired). + */ +static void plx9056_pci_reset_common(struct pci_dev *pdev) +{ + struct plx_pci_card *card = pci_get_drvdata(pdev); + u32 cntrl; + + /* issue a local bus reset */ + cntrl = ioread32(card->conf_addr + PLX9056_CNTRL); + cntrl |= PLX_PCI_RESET; + iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); + udelay(100); + cntrl ^= PLX_PCI_RESET; + iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); + + /* reload local configuration from EEPROM */ + cntrl |= PLX9056_PCI_RCR; + iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); + + /* + * There is no safe way to poll for the end + * of reconfiguration process. Waiting for 10ms + * is safe. + */ + mdelay(10); + + cntrl ^= PLX9056_PCI_RCR; + iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); +}; + +/* Special reset function for Marathon card */ +static void plx_pci_reset_marathon(struct pci_dev *pdev) +{ + void __iomem *reset_addr; + int i; + int reset_bar[2] = {3, 5}; + + plx_pci_reset_common(pdev); + + for (i = 0; i < 2; i++) { + reset_addr = pci_iomap(pdev, reset_bar[i], 0); + if (!reset_addr) { + dev_err(&pdev->dev, "Failed to remap reset " + "space %d (BAR%d)\n", i, reset_bar[i]); + } else { + /* reset the SJA1000 chip */ + iowrite8(0x1, reset_addr); + udelay(100); + pci_iounmap(pdev, reset_addr); + } + } +} + +static void plx_pci_del_card(struct pci_dev *pdev) +{ + struct plx_pci_card *card = pci_get_drvdata(pdev); + struct rtcan_device *dev; + int i = 0; + + for (i = 0; i < card->channels; i++) { + dev = card->rtcan_dev[i]; + if (!dev) + continue; + + dev_info(&pdev->dev, "Removing %s\n", dev->name); + rtcan_sja1000_unregister(dev); + if (dev->base_addr) + pci_iounmap(pdev, (void* __iomem)dev->base_addr); + rtcan_dev_free(dev); + } + + card->reset_func(pdev); + + /* + * Disable interrupts from PCI-card and disable local + * interrupts + */ + if (pdev->device != PCI_DEVICE_ID_PLX_9056) + iowrite32(0x0, card->conf_addr + PLX_INTCSR); + else + iowrite32(0x0, card->conf_addr + PLX9056_INTCSR); + + if (card->conf_addr) + pci_iounmap(pdev, card->conf_addr); + + kfree(card); + + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +/* + * Probe PLX90xx based device for the SJA1000 chips and register each + * available CAN channel to SJA1000 Socket-CAN subsystem. + */ +static int __devinit plx_pci_add_card(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct rtcan_sja1000 *chip; + struct rtcan_device *dev; + struct plx_pci_card *card; + struct plx_pci_card_info *ci; + int err, i; + u32 val; + void __iomem *addr; + + ci = (struct plx_pci_card_info *)ent->driver_data; + + if (pci_enable_device(pdev) < 0) { + dev_err(&pdev->dev, "Failed to enable PCI device\n"); + return -ENODEV; + } + + dev_info(&pdev->dev, "Detected \"%s\" card at slot #%i\n", + ci->name, PCI_SLOT(pdev->devfn)); + + /* Allocate card structures to hold addresses, ... */ + card = kzalloc(sizeof(*card), GFP_KERNEL); + if (!card) { + dev_err(&pdev->dev, "Unable to allocate memory\n"); + pci_disable_device(pdev); + return -ENOMEM; + } + + pci_set_drvdata(pdev, card); + + card->channels = 0; + + /* Remap PLX90xx configuration space */ + addr = pci_iomap(pdev, ci->conf_map.bar, ci->conf_map.size); + if (!addr) { + err = -ENOMEM; + dev_err(&pdev->dev, "Failed to remap configuration space " + "(BAR%d)\n", ci->conf_map.bar); + goto failure_cleanup; + } + card->conf_addr = addr + ci->conf_map.offset; + + ci->reset_func(pdev); + card->reset_func = ci->reset_func; + + /* Detect available channels */ + for (i = 0; i < ci->channel_count; i++) { + struct plx_pci_channel_map *cm = &ci->chan_map_tbl[i]; + + dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000), + sizeof(struct plx_pci_card)); + if (!dev) { + err = -ENOMEM; + goto failure_cleanup; + } + + strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ); + dev->board_name = (char *)ci->name; + + card->rtcan_dev[i] = dev; + chip = card->rtcan_dev[i]->priv; + chip->irq_flags = RTDM_IRQTYPE_SHARED; + chip->irq_num = pdev->irq; + + /* + * Remap IO space of the SJA1000 chips + * This is device-dependent mapping + */ + addr = pci_iomap(pdev, cm->bar, cm->size); + if (!addr) { + err = -ENOMEM; + dev_err(&pdev->dev, "Failed to remap BAR%d\n", cm->bar); + goto failure_cleanup; + } + + dev->base_addr = (unsigned long)(addr + cm->offset); + chip->read_reg = plx_pci_read_reg; + chip->write_reg = plx_pci_write_reg; + + /* Check if channel is present */ + if (plx_pci_check_sja1000(dev)) { + dev->can_sys_clock = ci->can_clock; + chip->ocr = ci->ocr; + chip->cdr = ci->cdr; + + /* Register SJA1000 device */ + err = rtcan_sja1000_register(dev); + if (err) { + dev_err(&pdev->dev, "Registering device failed " + "(err=%d)\n", err); + rtcan_dev_free(dev); + goto failure_cleanup; + } + + card->channels++; + + dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d " + "registered as %s\n", i + 1, + (void* __iomem)dev->base_addr, chip->irq_num, + dev->name); + } else { + dev_err(&pdev->dev, "Channel #%d not detected\n", + i + 1); + rtcan_dev_free(dev); + } + } + + if (!card->channels) { + err = -ENODEV; + goto failure_cleanup; + } + + /* + * Enable interrupts from PCI-card (PLX90xx) and enable Local_1, + * Local_2 interrupts from the SJA1000 chips + */ + if (pdev->device != PCI_DEVICE_ID_PLX_9056) { + val = ioread32(card->conf_addr + PLX_INTCSR); + if (pdev->subsystem_vendor == PCI_VENDOR_ID_ESDGMBH) + val |= PLX_LINT1_EN | PLX_PCI_INT_EN; + else + val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN; + iowrite32(val, card->conf_addr + PLX_INTCSR); + } else { + iowrite32(PLX9056_LINTI | PLX9056_PCI_INT_EN, + card->conf_addr + PLX9056_INTCSR); + } + return 0; + +failure_cleanup: + dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err); + + plx_pci_del_card(pdev); + + return err; +} + +static struct pci_driver plx_pci_driver = { + .name = RTCAN_DRV_NAME, + .id_table = plx_pci_tbl, + .probe = plx_pci_add_card, + .remove = plx_pci_del_card, +}; + +static int __init plx_pci_init(void) +{ + return pci_register_driver(&plx_pci_driver); +} + +static void __exit plx_pci_exit(void) +{ + pci_unregister_driver(&plx_pci_driver); +} + +module_init(plx_pci_init); +module_exit(plx_pci_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,821 @@ +/* + * Copyright (C) 2005, 2006 Sebastian Smolorz + * + * + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * Parts of this software are based on the following: + * + * - RTAI CAN device driver for SJA1000 controllers by Jan Kiszka + * + * - linux-can.patch, a CAN socket framework for Linux, + * Copyright (C) 2004, 2005, Robert Schwebel, Benedikt Spranger, + * Marc Kleine-Budde, Sascha Hauer, Pengutronix + * + * - RTnet (www.rtnet.org) + * + * - serial device driver and profile included in Xenomai (RTDM), + * Copyright (C) 2005 Jan Kiszka . + * + * + * 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 + +#include +#include + +#include +#include +#include +#include +#include +#include + + +#define BTR0_BRP_MASK 0x3f +#define BTR0_SJW_SHIFT 6 +#define BTR0_SJW_MASK (0x3 << BTR0_SJW_SHIFT) + +#define BTR1_TSEG1_MASK 0xf +#define BTR1_TSEG2_SHIFT 4 +#define BTR1_TSEG2_MASK (0x7 << BTR1_TSEG2_SHIFT) +#define BTR1_SAM_SHIFT 7 + +#define BTR0_SET_BRP(brp) (((brp) - 1) & BTR0_BRP_MASK) +#define BTR0_SET_SJW(sjw) ((((sjw) - 1) << BTR0_SJW_SHIFT) & BTR0_SJW_MASK) + +#define BTR1_SET_TSEG1(tseg1) (((tseg1) - 1) & BTR1_TSEG1_MASK) +#define BTR1_SET_TSEG2(tseg2) ((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & BTR1_TSEG2_MASK) +#define BTR1_SET_SAM(sam) (((sam) & 1) << BTR1_SAM_SHIFT) + +/* Value for the interrupt enable register */ +#define SJA1000_IER SJA_IER_RIE | SJA_IER_TIE | \ + SJA_IER_EIE | SJA_IER_WUIE | \ + SJA_IER_EPIE | SJA_IER_BEIE | \ + SJA_IER_ALIE | SJA_IER_DOIE + +static char *sja_ctrl_name = "SJA1000"; + +#define STATE_OPERATING(state) \ + ((state) != CAN_STATE_STOPPED && (state) != CAN_STATE_BUS_OFF) + +#define STATE_RESET(state) \ + ((state) == CAN_STATE_STOPPED || (state) == CAN_STATE_BUS_OFF) + + +MODULE_AUTHOR("Sebastian.Smolorz@stud.uni-hannover.de"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RT-Socket-CAN driver for SJA1000"); +MODULE_SUPPORTED_DEVICE("SJA1000 CAN controller"); + + +static inline void rtcan_sja_rx_interrupt(struct rtcan_device *dev, + struct rtcan_skb *skb) +{ + int i; + /* "Real" size of the payload */ + u8 size; + /* Content of frame information register */ + u8 fir; + /* Ring buffer frame within skb */ + struct rtcan_rb_frame *frame = &skb->rb_frame; + struct rtcan_sja1000 *chip = dev->priv; + + /* Read out frame information register */ + fir = chip->read_reg(dev, SJA_FIR); + + /* Extract data length code */ + frame->can_dlc = fir & SJA_FIR_DLC_MASK; + + /* If DLC exceeds 8 bytes adjust it to 8 (for the payload size) */ + size = (frame->can_dlc > 8) ? 8 : frame->can_dlc; + + + if (fir & SJA_FIR_EFF) { + /* Extended frame */ + frame->can_id = CAN_EFF_FLAG; + + /* Read ID */ + frame->can_id |= chip->read_reg(dev, SJA_ID1) << 21; + frame->can_id |= chip->read_reg(dev, SJA_ID2) << 13; + frame->can_id |= chip->read_reg(dev, SJA_ID3) << 5; + frame->can_id |= chip->read_reg(dev, SJA_ID4) >> 3; + + if (!(fir & SJA_FIR_RTR)) { + /* No RTR, read data bytes */ + for (i = 0; i < size; i++) + frame->data[i] = chip->read_reg(dev, + SJA_DATA_EFF(i)); + } + + } else { + /* Standard frame */ + + /* Read ID */ + frame->can_id = chip->read_reg(dev, SJA_ID1) << 3; + frame->can_id |= chip->read_reg(dev, SJA_ID2) >> 5; + + if (!(fir & SJA_FIR_RTR)) { + /* No RTR, read data bytes */ + for (i = 0; i < size; i++) + frame->data[i] = chip->read_reg(dev, SJA_DATA_SFF(i)); + } + } + + /* Release Receive Buffer */ + chip->write_reg(dev, SJA_CMR, SJA_CMR_RRB); + + + /* RTR? */ + if (fir & SJA_FIR_RTR) { + frame->can_id |= CAN_RTR_FLAG; + skb->rb_frame_size = EMPTY_RB_FRAME_SIZE; + } else + skb->rb_frame_size = EMPTY_RB_FRAME_SIZE + size; + + /* Store the interface index */ + frame->can_ifindex = dev->ifindex; +} + + +static inline void rtcan_sja_err_interrupt(struct rtcan_device *dev, + struct rtcan_sja1000 *chip, + struct rtcan_skb *skb, + u8 irq_source) +{ + struct rtcan_rb_frame *frame = &skb->rb_frame; + can_state_t state = dev->state; + u8 status, txerr, rxerr; + + status = chip->read_reg(dev, SJA_SR); + txerr = chip->read_reg(dev, SJA_TXERR); + rxerr = chip->read_reg(dev, SJA_RXERR); + + skb->rb_frame_size = EMPTY_RB_FRAME_SIZE + CAN_ERR_DLC; + + frame->can_id = CAN_ERR_FLAG; + frame->can_dlc = CAN_ERR_DLC; + + memset(&frame->data[0], 0, frame->can_dlc); + + /* Data overrun interrupt? */ + if (irq_source & SJA_IR_DOI) { + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + } + + /* Arbitratio lost interrupt? */ + if (irq_source & SJA_IR_ALI) { + frame->can_id |= CAN_ERR_LOSTARB; + frame->data[0] = chip->read_reg(dev, SJA_ALC) & 0x1f; + } + + /* Bus error interrupt? */ + if (irq_source & SJA_IR_BEI) { + u8 ecc = chip->read_reg(dev, SJA_ECC); + + frame->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + + switch (ecc & SJA_ECC_ERR_MASK) { + case SJA_ECC_ERR_BIT: + frame->data[2] |= CAN_ERR_PROT_BIT; + break; + case SJA_ECC_ERR_FORM: + frame->data[2] |= CAN_ERR_PROT_FORM; + break; + case SJA_ECC_ERR_STUFF: + frame->data[2] |= CAN_ERR_PROT_STUFF; + break; + default: + frame->data[2] |= CAN_ERR_PROT_UNSPEC; + frame->data[3] = ecc & SJA_ECC_SEG_MASK; + break; + } + /* Error occured during transmission? */ + if ((ecc & SJA_ECC_DIR) == 0) + frame->data[2] |= CAN_ERR_PROT_TX; + } + + /* Error passive interrupt? */ + if (unlikely(irq_source & SJA_IR_EPI)) { + if (state == CAN_STATE_BUS_WARNING) { + state = CAN_STATE_BUS_PASSIVE; + } else { + state = CAN_STATE_BUS_WARNING; + } + } + + /* Error warning interrupt? */ + if (irq_source & SJA_IR_EI) { + + /* Test bus status (bus-off condition) */ + if (status & SJA_SR_BS) { + /* Bus-off */ + state = CAN_STATE_BUS_OFF; + frame->can_id |= CAN_ERR_BUSOFF; + /* Only allow error warning interrupts + (otherwise an EPI would arise during bus-off + recovery) */ + chip->write_reg(dev, SJA_IER, SJA_IER_EIE); + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + } + + /* Test error status (error warning limit) */ + else if (status & SJA_SR_ES) + /* error warning limit reached */ + state = CAN_STATE_BUS_WARNING; + + /* Re-entrance into error active state from bus-warn? */ + else if (state == CAN_STATE_BUS_WARNING) + state = CAN_STATE_ACTIVE; + + else + /* Bus-off recovery complete, enable all interrupts again */ + chip->write_reg(dev, SJA_IER, SJA1000_IER); + } + + if (state != dev->state && + (state == CAN_STATE_BUS_WARNING || state == CAN_STATE_BUS_PASSIVE)) { + frame->can_id |= CAN_ERR_PROT; + if (txerr > rxerr) + frame->data[1] = CAN_ERR_CRTL_TX_WARNING; + else + frame->data[1] = CAN_ERR_CRTL_RX_WARNING; + } + + dev->state = state; + frame->can_ifindex = dev->ifindex; +} + +static int rtcan_sja_interrupt(rtdm_irq_t *irq_handle) +{ + struct rtcan_device *dev; + struct rtcan_sja1000 *chip; + struct rtcan_skb skb; + int recv_lock_free = 1; + int irq_count = 0; + int ret = RTDM_IRQ_NONE; + u8 irq_source; + + + /* Get the ID of the device which registered this IRQ. */ + dev = (struct rtcan_device *)rtdm_irq_get_arg(irq_handle, void); + chip = (struct rtcan_sja1000 *)dev->priv; + + /* Take spinlock protecting HW register access and device structures. */ + rtdm_lock_get(&dev->device_lock); + + /* Loop as long as the device reports an event */ + while ((irq_source = chip->read_reg(dev, SJA_IR))) { + ret = RTDM_IRQ_HANDLED; + irq_count++; + + /* Now look up which interrupts appeared */ + + /* Wake-up interrupt? */ + if (irq_source & SJA_IR_WUI) + dev->state = dev->state_before_sleep; + + /* Error Interrupt? */ + if (irq_source & (SJA_IR_EI | SJA_IR_DOI | SJA_IR_EPI | + SJA_IR_ALI | SJA_IR_BEI)) { + + /* Check error condition and fill error frame */ + if (!((irq_source & SJA_IR_BEI) && (chip->bus_err_on-- < 2))) { + rtcan_sja_err_interrupt(dev, chip, &skb, irq_source); + + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + /* Pass error frame out to the sockets */ + rtcan_rcv(dev, &skb); + } + } + + /* Transmit Interrupt? */ + if (irq_source & SJA_IR_TI) { + /* Wake up a sender */ + rtdm_sem_up(&dev->tx_sem); + + if (rtcan_loopback_pending(dev)) { + + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + + rtcan_loopback(dev); + } + } + + /* Receive Interrupt? */ + if (irq_source & SJA_IR_RI) { + + /* Read out HW registers */ + rtcan_sja_rx_interrupt(dev, &skb); + + /* Take more locks. Ensure that they are taken and + * released only once in the IRQ handler. */ + /* WARNING: Nested locks are dangerous! But they are + * nested only in this routine so a deadlock should + * not be possible. */ + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + + /* Pass received frame out to the sockets */ + rtcan_rcv(dev, &skb); + } + } + + if (chip->irq_ack) + chip->irq_ack(dev); + + /* Release spinlocks */ + if (!recv_lock_free) { + rtdm_lock_put(&rtcan_socket_lock); + rtdm_lock_put(&rtcan_recv_list_lock); + } + rtdm_lock_put(&dev->device_lock); + + return ret; +} + + + +/* + * Inline function to decide if controller is operating + * + * Catch the very unlikely case that setting stop mode + * returned without success before this call but in the + * meantime the controller went into reset mode. + */ +static inline int rtcan_sja_is_operating(struct rtcan_device *dev, + can_state_t *state) +{ + int is_operating = STATE_OPERATING(*state); + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + if (unlikely(is_operating && chip->read_reg(dev, SJA_MOD) & SJA_MOD_RM)) { + *state = CAN_STATE_STOPPED; + is_operating = 0; + /* Disable the controller's interrupts */ + chip->write_reg(dev, SJA_IER, 0x00); + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + } + + return is_operating; +} + + +/* + * Set controller into reset mode. + * + * According to the SJA1000 specification, it is necessary to check the + * reset mode bit in PeliCAN mode after having set it. So we do. But if + * using a ISA card like the PHYTEC eNET card this should not be necessary + * because the CAN controller clock of this card (16 MHz) is twice as high + * as the ISA bus clock. + */ +static int rtcan_sja_mode_stop(struct rtcan_device *dev, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0; + /* Max. 50 loops busy sleep. If the controller is stopped while in + * sleep mode 20-40 loops are needed (tested on PHYTEC eNET). */ + int wait_loop = 50; + can_state_t state; + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + state = dev->state; + /* If controller is not operating anyway, go out */ + if (STATE_RESET(state)) + goto out; + + /* Disable the controller's interrupts */ + chip->write_reg(dev, SJA_IER, 0x00); + + /* Set reset mode bit */ + chip->write_reg(dev, SJA_MOD, SJA_MOD_RM); + + /* Read reset mode bit, multiple tests */ + do { + if (chip->read_reg(dev, SJA_MOD) & SJA_MOD_RM) + break; + + if (lock_ctx) + rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx); + /* Busy sleep 1 microsecond */ + rtdm_task_busy_sleep(1000); + if (lock_ctx) + rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx); + } while(--wait_loop); + + + if (wait_loop) { + /* Volatile state could have changed while we slept busy. */ + dev->state = CAN_STATE_STOPPED; + /* Wake up waiting senders */ + rtdm_sem_destroy(&dev->tx_sem); + } else { + ret = -EAGAIN; + /* Enable interrupts again as we did not succeed */ + chip->write_reg(dev, SJA_IER, SJA1000_IER); + } + + out: + return ret; +} + + + +/* + * Set controller into operating mode. + * + * If coming from CAN_STATE_SLEEPING, the controller must wait + * some time to avoid bus errors. Measured on an PHYTEC eNET card, + * this time was 110 microseconds. + */ +static int rtcan_sja_mode_start(struct rtcan_device *dev, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0; + u8 mod_reg; + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + /* We won't forget that state in the device structure is volatile and + * access to it will not be optimized by the compiler. So ... */ + + mod_reg = 0; + if (dev->ctrl_mode & CAN_CTRLMODE_LISTENONLY) + mod_reg |= SJA_MOD_LOM; + if (dev->ctrl_mode & CAN_CTRLMODE_LOOPBACK) + mod_reg |= SJA_MOD_STM; + + switch (dev->state) { + + case CAN_STATE_ACTIVE: + case CAN_STATE_BUS_WARNING: + case CAN_STATE_BUS_PASSIVE: + break; + + case CAN_STATE_STOPPED: + /* Clear error counters */ + chip->write_reg(dev, SJA_RXERR , 0); + chip->write_reg(dev, SJA_TXERR , 0); + /* Clear error code capture (i.e. read it) */ + chip->read_reg(dev, SJA_ECC); + /* Set error active state */ + dev->state = CAN_STATE_ACTIVE; + /* Set up sender "mutex" */ + rtdm_sem_init(&dev->tx_sem, 1); + /* Enable interrupts */ + chip->write_reg(dev, SJA_IER, SJA1000_IER); + + /* Clear reset mode bit in SJA1000 */ + chip->write_reg(dev, SJA_MOD, mod_reg); + + break; + + case CAN_STATE_SLEEPING: + /* Trigger Wake-up interrupt */ + chip->write_reg(dev, SJA_MOD, mod_reg); + + /* Ok, coming from sleep mode is problematic. We have to wait + * for the SJA1000 to get on both feet again. */ + rtdm_lock_put_irqrestore(&dev->device_lock, *lock_ctx); + rtdm_task_busy_sleep(110000); + rtdm_lock_get_irqsave(&dev->device_lock, *lock_ctx); + + /* Meanwhile, the Wake-up interrupt was serviced and has set the + * right state. As we don't want to set it back jump out. */ + goto out; + + break; + + case CAN_STATE_BUS_OFF: + /* Trigger bus-off recovery */ + chip->write_reg(dev, SJA_MOD, mod_reg); + /* Set up sender "mutex" */ + rtdm_sem_init(&dev->tx_sem, 1); + /* Set error active state */ + dev->state = CAN_STATE_ACTIVE; + + break; + + default: + /* Never reached, but we don't want nasty compiler warnings ... */ + break; + } + + out: + return ret; +} + +can_state_t rtcan_sja_get_state(struct rtcan_device *dev) +{ + can_state_t state = dev->state; + rtcan_sja_is_operating(dev, &state); + return state; +} + +int rtcan_sja_set_mode(struct rtcan_device *dev, + can_mode_t mode, + rtdm_lockctx_t *lock_ctx) +{ + int ret = 0; + can_state_t state; + struct rtcan_sja1000 *chip = (struct rtcan_sja1000*)dev->priv; + + switch (mode) { + + case CAN_MODE_STOP: + ret = rtcan_sja_mode_stop(dev, lock_ctx); + break; + + case CAN_MODE_START: + ret = rtcan_sja_mode_start(dev, lock_ctx); + break; + + case CAN_MODE_SLEEP: + + state = dev->state; + + /* Controller must operate, otherwise go out */ + if (!rtcan_sja_is_operating(dev, &state)) { + ret = -ENETDOWN; + goto mode_sleep_out; + } + + /* Is controller sleeping yet? If yes, go out */ + if (state == CAN_STATE_SLEEPING) + goto mode_sleep_out; + + /* Remember into which state to return when we + * wake up */ + dev->state_before_sleep = state; + + /* Let's take a nap. (Now I REALLY understand + * the meaning of interrupts ...) */ + state = CAN_STATE_SLEEPING; + chip->write_reg(dev, SJA_MOD, + chip->read_reg(dev, SJA_MOD) | SJA_MOD_SM); + + mode_sleep_out: + dev->state = state; + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +int rtcan_sja_set_bit_time(struct rtcan_device *dev, + struct can_bittime *bit_time, + rtdm_lockctx_t *lock_ctx) +{ + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + u8 btr0, btr1; + + switch (bit_time->type) { + case CAN_BITTIME_BTR: + btr0 = bit_time->btr.btr0; + btr1 = bit_time->btr.btr1; + break; + + case CAN_BITTIME_STD: + btr0 = (BTR0_SET_BRP(bit_time->std.brp) | + BTR0_SET_SJW(bit_time->std.sjw)); + btr1 = (BTR1_SET_TSEG1(bit_time->std.prop_seg + + bit_time->std.phase_seg1) | + BTR1_SET_TSEG2(bit_time->std.phase_seg2) | + BTR1_SET_SAM(bit_time->std.sam)); + + break; + + default: + return -EINVAL; + } + + chip->write_reg(dev, SJA_BTR0, btr0); + chip->write_reg(dev, SJA_BTR1, btr1); + + return 0; +} + +void rtcan_sja_enable_bus_err(struct rtcan_device *dev) +{ + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + if (chip->bus_err_on < 2) { + if (chip->bus_err_on < 1) + chip->read_reg(dev, SJA_ECC); + chip->bus_err_on = 2; + } +} + +/* + * Start a transmission to a SJA1000 device + */ +static int rtcan_sja_start_xmit(struct rtcan_device *dev, + can_frame_t *frame) +{ + int i; + /* "Real" size of the payload */ + u8 size; + /* Content of frame information register */ + u8 fir; + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + + /* Get DLC */ + fir = frame->can_dlc; + + /* If DLC exceeds 8 bytes adjust it to 8 (for the payload) */ + size = (fir > 8) ? 8 : fir; + + + if (frame->can_id & CAN_EFF_FLAG) { + /* Send extended frame */ + fir |= SJA_FIR_EFF; + + /* Write ID */ + chip->write_reg(dev, SJA_ID1, frame->can_id >> 21); + chip->write_reg(dev, SJA_ID2, frame->can_id >> 13); + chip->write_reg(dev, SJA_ID3, frame->can_id >> 5); + chip->write_reg(dev, SJA_ID4, frame->can_id << 3); + + /* RTR? */ + if (frame->can_id & CAN_RTR_FLAG) + fir |= SJA_FIR_RTR; + + else { + /* No RTR, write data bytes */ + for (i = 0; i < size; i++) + chip->write_reg(dev, SJA_DATA_EFF(i), + frame->data[i]); + } + + } else { + /* Send standard frame */ + + /* Write ID */ + chip->write_reg(dev, SJA_ID1, frame->can_id >> 3); + chip->write_reg(dev, SJA_ID2, frame->can_id << 5); + + /* RTR? */ + if (frame->can_id & CAN_RTR_FLAG) + fir |= SJA_FIR_RTR; + + else { + /* No RTR, write data bytes */ + for (i = 0; i < size; i++) + chip->write_reg(dev, SJA_DATA_SFF(i), + frame->data[i]); + } + } + + + /* Write frame information register */ + chip->write_reg(dev, SJA_FIR, fir); + + /* Push the 'send' button */ + if (dev->ctrl_mode & CAN_CTRLMODE_LOOPBACK) + chip->write_reg(dev, SJA_CMR, SJA_CMR_SRR); + else + chip->write_reg(dev, SJA_CMR, SJA_CMR_TR); + + return 0; +} + + + +/* + * SJA1000 chip configuration + */ +static void sja1000_chip_config(struct rtcan_device *dev) +{ + struct rtcan_sja1000 *chip = (struct rtcan_sja1000* )dev->priv; + + chip->write_reg(dev, SJA_CDR, chip->cdr); + chip->write_reg(dev, SJA_OCR, chip->ocr); + + chip->write_reg(dev, SJA_AMR0, 0xFF); + chip->write_reg(dev, SJA_AMR1, 0xFF); + chip->write_reg(dev, SJA_AMR2, 0xFF); + chip->write_reg(dev, SJA_AMR3, 0xFF); +} + + +int rtcan_sja1000_register(struct rtcan_device *dev) +{ + int ret; + struct rtcan_sja1000 *chip = dev->priv; + + if (chip == NULL) + return -EINVAL; + + /* Set dummy state for following call */ + dev->state = CAN_STATE_ACTIVE; + /* Enter reset mode */ + rtcan_sja_mode_stop(dev, NULL); + + if ((chip->read_reg(dev, SJA_SR) & + (SJA_SR_RBS | SJA_SR_DOS | SJA_SR_TBS)) != SJA_SR_TBS) { + printk("ERROR! No SJA1000 device found!\n"); + return -ENODEV; + } + + dev->ctrl_name = sja_ctrl_name; + + dev->hard_start_xmit = rtcan_sja_start_xmit; + dev->do_set_mode = rtcan_sja_set_mode; + dev->do_get_state = rtcan_sja_get_state; + dev->do_set_bit_time = rtcan_sja_set_bit_time; + dev->do_enable_bus_err = rtcan_sja_enable_bus_err; + chip->bus_err_on = 1; + + ret = rtdm_irq_request(&dev->irq_handle, + chip->irq_num, rtcan_sja_interrupt, + chip->irq_flags, sja_ctrl_name, dev); + if (ret) { + printk(KERN_ERR "ERROR %d: IRQ %d is %s!\n", + ret, chip->irq_num, ret == -EBUSY ? + "busy, check shared interrupt support" : "invalid"); + return ret; + } + + sja1000_chip_config(dev); + + /* Register RTDM device */ + ret = rtcan_dev_register(dev); + if (ret) { + printk(KERN_ERR + "ERROR %d while trying to register RTCAN device!\n", ret); + goto out_irq_free; + } + + rtcan_sja_create_proc(dev); + + return 0; + + out_irq_free: + rtdm_irq_free(&dev->irq_handle); + + return ret; +} + + +/* Cleanup module */ +void rtcan_sja1000_unregister(struct rtcan_device *dev) +{ + printk("Unregistering SJA1000 device %s\n", dev->name); + + rtdm_irq_disable(&dev->irq_handle); + rtcan_sja_mode_stop(dev, NULL); + rtdm_irq_free(&dev->irq_handle); + rtcan_sja_remove_proc(dev); + rtcan_dev_unregister(dev); +} + +int __init rtcan_sja_init(void) +{ + printk("RTCAN SJA1000 driver initialized\n"); + return 0; +} + + +void __exit rtcan_sja_exit(void) +{ + printk("%s removed\n", sja_ctrl_name); +} + +module_init(rtcan_sja_init); +module_exit(rtcan_sja_exit); + +EXPORT_SYMBOL_GPL(rtcan_sja1000_register); +EXPORT_SYMBOL_GPL(rtcan_sja1000_unregister); diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.h relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.h --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, Wolfgang Grandegger + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SJA1000_H_ +#define __SJA1000_H_ + +#include + +struct rtcan_sja1000 { + unsigned char (*read_reg)(struct rtcan_device *dev, int off); + void (*write_reg)(struct rtcan_device *dev, int off, unsigned char val); + void (*irq_ack)(struct rtcan_device *dev); + unsigned short irq_num; + unsigned short irq_flags; + unsigned char ocr; + unsigned char cdr; + char bus_err_on; +}; + +int rtcan_sja_create_proc(struct rtcan_device* dev); +void rtcan_sja_remove_proc(struct rtcan_device* dev); +int rtcan_sja1000_register(struct rtcan_device *dev); +void rtcan_sja1000_unregister(struct rtcan_device *dev); + + +#endif /* __SJA1000_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_proc.c relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_proc.c --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_proc.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2006 Wolfgang Grandegger + * + * + * 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 +#include +#include + +#include + +#include +#include +#include + +#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG + +static int rtcan_sja_proc_regs(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + struct rtcan_device *dev = (struct rtcan_device *)data; + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; + int i; + RTCAN_PROC_PRINT_VARS(80); + + if (!RTCAN_PROC_PRINT("SJA1000 registers")) + goto done; + for (i = 0; i < 0x20; i++) { + if ((i % 0x10) == 0) { + if (!RTCAN_PROC_PRINT("\n%02x:", i)) + goto done; + } + if (!RTCAN_PROC_PRINT(" %02x", chip->read_reg(dev, i))) + goto done; + } + if (!RTCAN_PROC_PRINT("\n")) + goto done; + + done: + RTCAN_PROC_PRINT_DONE; +} + +int rtcan_sja_create_proc(struct rtcan_device* dev) +{ + struct proc_dir_entry *proc_entry; + + if (!dev->proc_root) + return -EINVAL; + + proc_entry = create_proc_entry("registers", S_IFREG | S_IRUGO | S_IWUSR, + dev->proc_root); + if (!proc_entry) + goto error; + proc_entry->read_proc = rtcan_sja_proc_regs; + proc_entry->data = dev; + + return 0; + + error: + printk("%s: unable to create /proc entries for SJA\n", dev->name); + return -1; +} + +void rtcan_sja_remove_proc(struct rtcan_device* dev) +{ + if (!dev->proc_root) + return; + + remove_proc_entry("registers", dev->proc_root); +} + +#else /* !CONFIG_XENO_DRIVERS_CAN_DEBUG */ + +void rtcan_sja_remove_proc(struct rtcan_device* dev) +{ +} + +int rtcan_sja_create_proc(struct rtcan_device* dev) +{ + return 0; +} +#endif /* CONFIG_XENO_DRIVERS_CAN_DEBUG */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_regs.h relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_regs.h --- orig/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_regs.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/can/sja1000/rtcan_sja1000_regs.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2005,2006 Sebastian Smolorz + * + * + * Based on drivers/can/sja1000.h in linux-can.patch, a CAN socket + * framework for Linux: + * + * Copyright (C) 2005, Sascha Hauer, Pengutronix + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SJA1000_REGS_H_ +#define __SJA1000_REGS_H_ + + +/* PeliCAN mode address map */ + +/* reset and operating mode */ +#define SJA_MOD 0 /* Mode register */ +#define SJA_CMR 1 /* Command register */ +#define SJA_SR 2 /* Status register */ +#define SJA_IR 3 /* Interrupt register */ +#define SJA_IER 4 /* Interrupt enable register */ +#define SJA_BTR0 6 /* Bus timing register 0 */ +#define SJA_BTR1 7 /* Bus timing register 1 */ +#define SJA_OCR 8 /* Output control register */ +#define SJA_ALC 11 /* Arbitration lost capture */ +#define SJA_ECC 12 /* Error code capture register */ +#define SJA_RXERR 14 /* Receive error counter */ +#define SJA_TXERR 15 /* Transmit error counter */ +#define SJA_CDR 31 /* Clock divider register */ + +/* reset mode */ +#define SJA_ACR0 16 /* Acceptance code register 0 */ +#define SJA_ACR1 17 /* Acceptance code register 1 */ +#define SJA_ACR2 18 /* Acceptance code register 2 */ +#define SJA_ACR3 19 /* Acceptance code register 3 */ +#define SJA_AMR0 20 /* Acceptance mask register 0 */ +#define SJA_AMR1 21 /* Acceptance mask register 1 */ +#define SJA_AMR2 22 /* Acceptance mask register 2 */ +#define SJA_AMR3 23 /* Acceptance mask register 3 */ + +/* operating mode */ +#define SJA_FIR 16 /* Frame information register */ +#define SJA_ID1 17 /* Identifier 1 */ +#define SJA_ID2 18 /* Identifier 2 */ +#define SJA_ID3 19 /* Identifier 3 (EFF only) */ +#define SJA_ID4 20 /* Identifier 4 (EFF only) */ + +#define SJA_DATA_SFF(x) (19 + (x)) /* Data registers in case of standard + * frame format; 0 <= x <= 7 */ +#define SJA_DATA_EFF(x) (21 + (x)) /* Data registers in case of extended + * frame format; 0 <= x <= 7 */ + +/* Mode register */ +enum SJA1000_PELI_MOD { + SJA_MOD_RM = 1, /* Reset Mode */ + SJA_MOD_LOM = 1<<1, /* Listen Only Mode */ + SJA_MOD_STM = 1<<2, /* Self Test Mode */ + SJA_MOD_AFM = 1<<3, /* Acceptance Filter Mode */ + SJA_MOD_SM = 1<<4 /* Sleep Mode */ +}; + +/* Command register */ +enum SJA1000_PELI_CMR { + SJA_CMR_TR = 1, /* Transmission request */ + SJA_CMR_AT = 1<<1, /* Abort Transmission */ + SJA_CMR_RRB = 1<<2, /* Release Receive Buffer */ + SJA_CMR_CDO = 1<<3, /* Clear Data Overrun */ + SJA_CMR_SRR = 1<<4 /* Self reception request */ +}; + +/* Status register */ +enum SJA1000_PELI_SR { + SJA_SR_RBS = 1, /* Receive Buffer Status */ + SJA_SR_DOS = 1<<1, /* Data Overrun Status */ + SJA_SR_TBS = 1<<2, /* Transmit Buffer Status */ + SJA_SR_ES = 1<<6, /* Error Status */ + SJA_SR_BS = 1<<7 /* Bus Status */ +}; + +/* Interrupt register */ +enum SJA1000_PELI_IR { + SJA_IR_RI = 1, /* Receive Interrupt */ + SJA_IR_TI = 1<<1, /* Transmit Interrupt */ + SJA_IR_EI = 1<<2, /* Error Warning Interrupt */ + SJA_IR_DOI = 1<<3, /* Data Overrun Interrupt */ + SJA_IR_WUI = 1<<4, /* Wake-Up Interrupt */ + SJA_IR_EPI = 1<<5, /* Error Passive Interrupt */ + SJA_IR_ALI = 1<<6, /* Arbitration Lost Interrupt */ + SJA_IR_BEI = 1<<7, /* Bus Error Interrupt */ +}; + +/* Interrupt enable register */ +enum SJA1000_PELI_IER { + SJA_IER_RIE = 1, /* Receive Interrupt Enable */ + SJA_IER_TIE = 1<<1, /* Transmit Interrupt Enable */ + SJA_IER_EIE = 1<<2, /* Error Warning Interrupt Enable */ + SJA_IER_DOIE = 1<<3, /* Data Overrun Interrupt Enable */ + SJA_IER_WUIE = 1<<4, /* Wake-Up Interrupt Enable */ + SJA_IER_EPIE = 1<<5, /* Error Passive Interrupt Enable */ + SJA_IER_ALIE = 1<<6, /* Arbitration Lost Interrupt Enable */ + SJA_IER_BEIE = 1<<7, /* Bus Error Interrupt Enable */ +}; + +/* Bus timing register 0 */ +enum SJA1000_PELI_BTR0 { + /* Period of the CAN system clock t_SCl + * (t_CLK = time period of XTAL frequency) */ + SJA_BTR0_T_SCL_2_T_CLK = 0, /* t_SCl = 2 x t_CLK */ + SJA_BTR0_T_SCL_4_T_CLK = 1, /* t_SCl = 4 x t_CLK */ + SJA_BTR0_T_SCL_6_T_CLK = 2, /* t_SCl = 6 x t_CLK */ + SJA_BTR0_T_SCL_8_T_CLK = 3, /* t_SCl = 8 x t_CLK */ + SJA_BTR0_T_SCL_10_T_CLK = 4, /* t_SCl = 10 x t_CLK */ + SJA_BTR0_T_SCL_12_T_CLK = 5, /* t_SCl = 12 x t_CLK */ + SJA_BTR0_T_SCL_14_T_CLK = 6, /* t_SCl = 14 x t_CLK */ + SJA_BTR0_T_SCL_16_T_CLK = 7, /* t_SCl = 16 x t_CLK */ + SJA_BTR0_T_SCL_20_T_CLK = 9, /* t_SCl = 20 x t_CLK */ + SJA_BTR0_T_SCL_40_T_CLK = 19, /* t_SCl = 40 x t_CLK */ + SJA_BTR0_T_SCL_100_T_CLK = 49, /* t_SCl = 100 x t_CLK */ + +}; + +/* Bus timing register 1 */ +enum SJA1000_PELI_BTR1 { + /* Time segment 1 */ + SJA_BTR1_T_SEG1_1_T_SCL = 0, /* t_SEG1 = 1 x t_SCl */ + SJA_BTR1_T_SEG1_2_T_SCL = 1, /* t_SEG1 = 2 x t_SCl */ + SJA_BTR1_T_SEG1_3_T_SCL = 2, /* t_SEG1 = 3 x t_SCl */ + SJA_BTR1_T_SEG1_4_T_SCL = 3, /* t_SEG1 = 4 x t_SCl */ + SJA_BTR1_T_SEG1_5_T_SCL = 4, /* t_SEG1 = 5 x t_SCl */ + SJA_BTR1_T_SEG1_6_T_SCL = 5, /* t_SEG1 = 6 x t_SCl */ + SJA_BTR1_T_SEG1_7_T_SCL = 6, /* t_SEG1 = 7 x t_SCl */ + SJA_BTR1_T_SEG1_8_T_SCL = 7, /* t_SEG1 = 8 x t_SCl */ + /* Time segment 2 */ + SJA_BTR1_T_SEG2_1_T_SCL = 0<<4, /* t_SEG2 = 1 x t_SCl */ + SJA_BTR1_T_SEG2_2_T_SCL = 1<<4, /* t_SEG2 = 2 x t_SCl */ + SJA_BTR1_T_SEG2_3_T_SCL = 2<<4, /* t_SEG2 = 3 x t_SCl */ + SJA_BTR1_T_SEG2_4_T_SCL = 3<<4, /* t_SEG2 = 4 x t_SCl */ + SJA_BTR1_T_SEG2_5_T_SCL = 4<<4, /* t_SEG2 = 5 x t_SCl */ + SJA_BTR1_T_SEG2_6_T_SCL = 5<<4, /* t_SEG2 = 6 x t_SCl */ + SJA_BTR1_T_SEG2_7_T_SCL = 6<<4, /* t_SEG2 = 7 x t_SCl */ + SJA_BTR1_T_SEG2_8_T_SCL = 7<<4, /* t_SEG2 = 8 x t_SCl */ +}; + +/* One bit time = t_SCl + t_SEG1 + t_SEG2 */ + + +/* Output control register */ +enum SJA1000_PELI_OCR { + SJA_OCR_MODE_BIPHASE = 0, + SJA_OCR_MODE_TEST = 1, + SJA_OCR_MODE_NORMAL = 2, + SJA_OCR_MODE_CLOCK = 3, + SJA_OCR_TX0_INVERT = 1<<2, + SJA_OCR_TX0_PULLDOWN = 1<<3, + SJA_OCR_TX0_PULLUP = 2<<3, + SJA_OCR_TX0_PUSHPULL = 3<<3, + SJA_OCR_TX1_INVERT = 1<<5, + SJA_OCR_TX1_PULLDOWN = 1<<6, + SJA_OCR_TX1_PULLUP = 2<<6, + SJA_OCR_TX1_PUSHPULL = 3<<6 +}; + +/* Error code capture register */ +enum SJA1000_PELI_ECC { + /* The segmentation field gives information about the location of + * errors on the bus */ + SJA_ECC_SEG_MASK = 31, /* Segmentation field mask */ + SJA_ECC_DIR = 1<<5, /* Transfer direction */ + SJA_ECC_ERR_BIT = 0<<6, + SJA_ECC_ERR_FORM = 1<<6, + SJA_ECC_ERR_STUFF = 2<<6, + SJA_ECC_ERR_MASK = 3<<6 /* Error code mask */ +}; + +/* Frame information register */ +enum SJA1000_PELI_FIR { + SJA_FIR_DLC_MASK = 15, /* Data length code mask */ + SJA_FIR_RTR = 1<<6, /* Remote transmission request */ + SJA_FIR_EFF = 1<<7 /* Extended frame format */ +}; + +/* Clock divider register */ +enum SJA1000_PELI_CDR { + SJA_CDR_CLK_OFF = 1<<3, /* Clock off (CLKOUT pin) */ + SJA_CDR_CBP = 1<<6, /* CAN input comparator bypass */ + SJA_CDR_CAN_MODE = 1<<7 /* CAN mode: 1 = PeliCAN */ +}; + +#endif /* __SJA1000_REGS_H_ */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/bufp.c relase/linux-2.6.35.9//drivers/xenomai/ipc/bufp.c --- orig/linux-2.6.35.9//drivers/xenomai/ipc/bufp.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/bufp.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1070 @@ +/** + * This file is part of the Xenomai project. + * + * @note Copyright (C) 2009 Philippe Gerum + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +#define trace(m,a...) printk(KERN_WARNING "%s: " m "\n", __FUNCTION__, ##a) + +#define BUFP_SOCKET_MAGIC 0xa61a61a6 + +struct bufp_socket { + int magic; + struct sockaddr_ipc name; + struct sockaddr_ipc peer; + + void *bufmem; + size_t bufsz; + u_long status; + xnhandle_t handle; + char label[BUFP_LABEL_LEN]; + + off_t rdoff; + off_t wroff; + size_t fillsz; + u_long wrtoken; + u_long rdtoken; + rtdm_event_t i_event; + rtdm_event_t o_event; + + nanosecs_rel_t rx_timeout; + nanosecs_rel_t tx_timeout; + + struct rtipc_private *priv; +}; + +struct bufp_wait_context { + struct rtipc_wait_context wc; + size_t len; + struct bufp_socket *sk; + rtdm_lockctx_t lockctx; +}; + +static struct sockaddr_ipc nullsa = { + .sipc_family = AF_RTIPC, + .sipc_port = -1 +}; + +static struct xnmap *portmap; + +#define _BUFP_BINDING 0 +#define _BUFP_BOUND 1 + +#ifdef CONFIG_PROC_FS + +static ssize_t __bufp_link_proc(char *buf, int count, void *data) +{ + struct bufp_socket *sk = data; + return snprintf(buf, count, "%d", sk->name.sipc_port); +} + +static struct xnpnode __bufp_pnode = { + + .dir = NULL, + .type = "bufp", + .entries = 0, + .link_proc = &__bufp_link_proc, + .root = &rtipc_ptree, +}; + +#else /* !CONFIG_PROC_FS */ + +static struct xnpnode __bufp_pnode = { + + .type = "bufp" +}; + +#endif /* !CONFIG_PROC_FS */ + +static void __bufp_cleanup_handler(struct rtipc_wait_context *wc) +{ + struct bufp_wait_context *bufwc; + /* + * Cancellation request is pending - release the lock we hold, + * we'll be vanishing away soon. Granted, we could avoid doing + * that, since we know that this particular lock is Xenomai's + * nklock, which may be held across rescheduling calls. + * Anyway, this illustrates how to use the cleanup handler of + * a wait context. + */ + bufwc = container_of(wc, struct bufp_wait_context, wc); + rtipc_leave_atomic(bufwc->lockctx); +} + +static int bufp_socket(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct bufp_socket *sk = priv->state; + + sk->magic = BUFP_SOCKET_MAGIC; + sk->name = nullsa; /* Unbound */ + sk->peer = nullsa; + sk->bufmem = NULL; + sk->bufsz = 0; + sk->rdoff = 0; + sk->wroff = 0; + sk->fillsz = 0; + sk->rdtoken = 0; + sk->wrtoken = 0; + sk->status = 0; + sk->handle = 0; + sk->rx_timeout = RTDM_TIMEOUT_INFINITE; + sk->tx_timeout = RTDM_TIMEOUT_INFINITE; + *sk->label = 0; + rtdm_event_init(&sk->i_event, 0); + rtdm_event_init(&sk->o_event, 0); + sk->priv = priv; + + return 0; +} + +static int bufp_close(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct bufp_socket *sk = priv->state; + + rtdm_event_destroy(&sk->i_event); + rtdm_event_destroy(&sk->o_event); + + if (sk->name.sipc_port > -1) + xnmap_remove(portmap, sk->name.sipc_port); + + if (sk->handle) + xnregistry_remove(sk->handle); + + if (sk->bufmem) + xnarch_free_host_mem(sk->bufmem, sk->bufsz); + + return 0; +} + +static ssize_t __bufp_readbuf(struct bufp_socket *sk, + struct xnbufd *bufd, + int flags) +{ + struct bufp_wait_context wait, *bufwc; + struct rtipc_wait_context *wc; + rtdm_task_t *waiter; + rtdm_toseq_t toseq; + ssize_t len, ret; + size_t rbytes, n; + u_long rdtoken; + off_t rdoff; + + len = bufd->b_len; + + rtdm_toseq_init(&toseq, sk->rx_timeout); + + rtipc_enter_atomic(wait.lockctx); + +redo: + for (;;) { + /* + * We should be able to read a complete message of the + * requested length, or block. + */ + if (sk->fillsz < len) + goto wait; + + /* + * Draw the next read token so that we can later + * detect preemption. + */ + rdtoken = ++sk->rdtoken; + + /* Read from the buffer in a circular way. */ + rdoff = sk->rdoff; + rbytes = len; + + do { + if (rdoff + rbytes > sk->bufsz) + n = sk->bufsz - rdoff; + else + n = rbytes; + /* + * Release the lock while retrieving the data + * to keep latency low. + */ + rtipc_leave_atomic(wait.lockctx); + ret = xnbufd_copy_from_kmem(bufd, sk->bufmem + rdoff, n); + if (ret < 0) + return ret; + + rtipc_enter_atomic(wait.lockctx); + /* + * In case we were preempted while retrieving + * the message, we have to re-read the whole + * thing. + */ + if (sk->rdtoken != rdtoken) { + xnbufd_reset(bufd); + goto redo; + } + + rdoff = (rdoff + n) % sk->bufsz; + rbytes -= n; + } while (rbytes > 0); + + sk->fillsz -= len; + sk->rdoff = rdoff; + ret = len; + + /* + * Wake up all threads pending on the output wait + * queue, if we freed enough room for the leading one + * to post its message. + */ + waiter = rtipc_peek_wait_head(&sk->o_event); + if (waiter == NULL) + goto out; + + wc = rtipc_get_wait_context(waiter); + XENO_BUGON(NUCLEUS, wc == NULL); + bufwc = container_of(wc, struct bufp_wait_context, wc); + if (bufwc->len + sk->fillsz <= sk->bufsz) + rtdm_event_pulse(&sk->o_event); + /* + * We cannot fail anymore once some data has been + * copied via the buffer descriptor, so no need to + * check for any reason to invalidate the latter. + */ + goto out; + + wait: + if (flags & MSG_DONTWAIT) { + ret = -EWOULDBLOCK; + break; + } + + /* + * Check whether writers are already waiting for + * sending data, while we are about to wait for + * receiving some. In such a case, we have a + * pathological use of the buffer. We must allow for a + * short read to prevent a deadlock. + */ + if (sk->fillsz > 0 && rtipc_peek_wait_head(&sk->o_event)) { + len = sk->fillsz; + goto redo; + } + + wait.len = len; + wait.sk = sk; + rtipc_prepare_wait(&wait.wc); + /* + * Keep the nucleus lock across the wait call, so that + * we don't miss a pulse. + */ + ret = rtdm_event_timedwait(&sk->i_event, + sk->rx_timeout, &toseq); + rtipc_finish_wait(&wait.wc, __bufp_cleanup_handler); + + if (unlikely(ret)) + break; + } + +out: + rtipc_leave_atomic(wait.lockctx); + + return ret; +} + +static ssize_t __bufp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + struct sockaddr_ipc *saddr) +{ + struct bufp_socket *sk = priv->state; + ssize_t len, wrlen, vlen, ret; + struct xnbufd bufd; + int nvec; + + if (!test_bit(_BUFP_BOUND, &sk->status)) + return -EAGAIN; + + len = rtipc_get_iov_flatlen(iov, iovlen); + if (len == 0) + return 0; + /* + * We may only return complete messages to readers, so there + * is no point in waiting for messages which are larger than + * what the buffer can hold. + */ + if (len > sk->bufsz) + return -EINVAL; + + /* + * Write "len" bytes from the buffer to the vector cells. Each + * cell is handled as a separate message. + */ + for (nvec = 0, wrlen = len; nvec < iovlen && wrlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = __bufp_readbuf(sk, &bufd, flags); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = __bufp_readbuf(sk, &bufd, flags); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + return ret; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + wrlen -= vlen; + if (ret < vlen) + /* Short reads may happen in rare cases. */ + break; + } + + /* + * There is no way to determine who the sender was since we + * process data in byte-oriented mode, so we just copy our own + * sockaddr to send back a valid address. + */ + if (saddr) + *saddr = sk->name; + + return len - wrlen; +} + +static ssize_t bufp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags) +{ + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc saddr; + ssize_t ret; + + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen < sizeof(struct sockaddr_ipc)) + return -EINVAL; + } else if (msg->msg_namelen != 0) + return -EINVAL; + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __bufp_recvmsg(priv, user_info, + iov, msg->msg_iovlen, flags, &saddr); + if (ret <= 0) + return ret; + + /* Copy the updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + /* Copy the source address if required. */ + if (msg->msg_name) { + if (rtipc_put_arg(user_info, msg->msg_name, + &saddr, sizeof(saddr))) + return -EFAULT; + msg->msg_namelen = sizeof(struct sockaddr_ipc); + } + + return ret; +} + +static ssize_t bufp_read(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + void *buf, size_t len) +{ + struct iovec iov = { .iov_base = buf, .iov_len = len }; + return __bufp_recvmsg(priv, user_info, &iov, 1, 0, NULL); +} + +static ssize_t __bufp_writebuf(struct bufp_socket *rsk, + struct bufp_socket *sk, + struct xnbufd *bufd, + int flags) +{ + struct bufp_wait_context wait, *bufwc; + struct rtipc_wait_context *wc; + rtdm_task_t *waiter; + rtdm_toseq_t toseq; + ssize_t len, ret; + size_t wbytes, n; + u_long wrtoken; + off_t wroff; + + len = bufd->b_len; + + rtdm_toseq_init(&toseq, sk->rx_timeout); + + rtipc_enter_atomic(wait.lockctx); + +redo: + for (;;) { + /* + * We should be able to write the entire message at + * once or block. + */ + if (rsk->fillsz + len > rsk->bufsz) + goto wait; + + /* + * Draw the next write token so that we can later + * detect preemption. + */ + wrtoken = ++rsk->wrtoken; + + /* Write to the buffer in a circular way. */ + wroff = rsk->wroff; + wbytes = len; + + do { + if (wroff + wbytes > rsk->bufsz) + n = rsk->bufsz - wroff; + else + n = wbytes; + /* + * Release the lock while copying the data to + * keep latency low. + */ + rtipc_leave_atomic(wait.lockctx); + ret = xnbufd_copy_to_kmem(rsk->bufmem + wroff, bufd, n); + if (ret < 0) + return ret; + rtipc_enter_atomic(wait.lockctx); + /* + * In case we were preempted while copying the + * message, we have to write the whole thing + * again. + */ + if (rsk->wrtoken != wrtoken) { + xnbufd_reset(bufd); + goto redo; + } + + wroff = (wroff + n) % rsk->bufsz; + wbytes -= n; + } while (wbytes > 0); + + rsk->fillsz += len; + rsk->wroff = wroff; + ret = len; + + /* + * Wake up all threads pending on the input wait + * queue, if we accumulated enough data to feed the + * leading one. + */ + waiter = rtipc_peek_wait_head(&rsk->i_event); + if (waiter == NULL) + goto out; + + wc = rtipc_get_wait_context(waiter); + XENO_BUGON(NUCLEUS, wc == NULL); + bufwc = container_of(wc, struct bufp_wait_context, wc); + if (bufwc->len <= rsk->fillsz) + rtdm_event_pulse(&rsk->i_event); + /* + * We cannot fail anymore once some data has been + * copied via the buffer descriptor, so no need to + * check for any reason to invalidate the latter. + */ + goto out; + + wait: + if (flags & MSG_DONTWAIT) { + ret = -EWOULDBLOCK; + break; + } + + wait.len = len; + wait.sk = rsk; + rtipc_prepare_wait(&wait.wc); + /* + * Keep the nucleus lock across the wait call, so that + * we don't miss a pulse. + */ + ret = rtdm_event_timedwait(&rsk->o_event, + sk->tx_timeout, &toseq); + rtipc_finish_wait(&wait.wc, __bufp_cleanup_handler); + if (unlikely(ret)) + break; + } + +out: + rtipc_leave_atomic(wait.lockctx); + + return ret; +} + +static ssize_t __bufp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + const struct sockaddr_ipc *daddr) +{ + struct bufp_socket *sk = priv->state, *rsk; + struct rtdm_dev_context *rcontext; + ssize_t len, rdlen, vlen, ret = 0; + struct xnbufd bufd; + int nvec; + void *p; + + len = rtipc_get_iov_flatlen(iov, iovlen); + if (len == 0) + return 0; + + p = xnmap_fetch_nocheck(portmap, daddr->sipc_port); + if (p == NULL) + return -ECONNRESET; + + rcontext = rtdm_context_get(rtipc_map2fd(p)); + if (rcontext == NULL) + return -ECONNRESET; + + rsk = rtipc_context_to_state(rcontext); + if (!test_bit(_BUFP_BOUND, &rsk->status)) { + rtdm_context_unlock(rcontext); + return -ECONNREFUSED; + } + + /* + * We may only send complete messages, so there is no point in + * accepting messages which are larger than what the buffer + * can hold. + */ + if (len > rsk->bufsz) { + ret = -EINVAL; + goto fail; + } + + /* + * Read "len" bytes to the buffer from the vector cells. Each + * cell is handled as a separate message. + */ + for (nvec = 0, rdlen = len; nvec < iovlen && rdlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = __bufp_writebuf(rsk, sk, &bufd, flags); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = __bufp_writebuf(rsk, sk, &bufd, flags); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + goto fail; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + rdlen -= vlen; + } + + rtdm_context_unlock(rcontext); + + return len - rdlen; + +fail: + rtdm_context_unlock(rcontext); + + return ret; +} + +static ssize_t bufp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags) +{ + struct bufp_socket *sk = priv->state; + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc daddr; + ssize_t ret; + + if (flags & ~(MSG_OOB | MSG_DONTWAIT)) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen != sizeof(struct sockaddr_ipc)) + return -EINVAL; + + /* Fetch the destination address to send to. */ + if (rtipc_get_arg(user_info, &daddr, + msg->msg_name, sizeof(daddr))) + return -EFAULT; + + if (daddr.sipc_port < 0 || + daddr.sipc_port >= CONFIG_XENO_OPT_BUFP_NRPORT) + return -EINVAL; + } else { + if (msg->msg_namelen != 0) + return -EINVAL; + daddr = sk->peer; + if (daddr.sipc_port < 0) + return -ENOTCONN; + } + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __bufp_sendmsg(priv, user_info, iov, + msg->msg_iovlen, flags, &daddr); + if (ret <= 0) + return ret; + + /* Copy updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + return ret; +} + +static ssize_t bufp_write(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const void *buf, size_t len) +{ + struct iovec iov = { .iov_base = (void *)buf, .iov_len = len }; + struct bufp_socket *sk = priv->state; + + if (sk->peer.sipc_port < 0) + return -EDESTADDRREQ; + + return __bufp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer); +} + +static int __bufp_bind_socket(struct rtipc_private *priv, + struct sockaddr_ipc *sa) +{ + struct bufp_socket *sk = priv->state; + int ret = 0, port, fd; + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_BUFP_NRPORT) + return -EINVAL; + + RTDM_EXECUTE_ATOMICALLY( + if (test_bit(_BUFP_BOUND, &sk->status) || + __test_and_set_bit(_BUFP_BINDING, &sk->status)) + ret = -EADDRINUSE; + ); + if (ret) + return ret; + + /* Will auto-select a free port number if unspec (-1). */ + port = sa->sipc_port; + fd = rtdm_private_to_context(priv)->fd; + port = xnmap_enter(portmap, port, rtipc_fd2map(fd)); + if (port < 0) + return port == -EEXIST ? -EADDRINUSE : -ENOMEM; + + sa->sipc_port = port; + + /* + * The caller must have told us how much memory is needed for + * buffer space via setsockopt(), before we got there. + */ + if (sk->bufsz == 0) + return -EINVAL; + + sk->bufmem = xnarch_alloc_host_mem(sk->bufsz); + if (sk->bufmem == NULL) { + ret = -ENOMEM; + goto fail; + } + + sk->name = *sa; + /* Set default destination if unset at binding time. */ + if (sk->peer.sipc_port < 0) + sk->peer = *sa; + + if (*sk->label) { + ret = xnregistry_enter(sk->label, sk, + &sk->handle, &__bufp_pnode); + if (ret) { + xnarch_free_host_mem(sk->bufmem, sk->bufsz); + goto fail; + } + } + + RTDM_EXECUTE_ATOMICALLY( + __clear_bit(_BUFP_BINDING, &sk->status); + __set_bit(_BUFP_BOUND, &sk->status); + ); + + return 0; +fail: + xnmap_remove(portmap, port); + clear_bit(_BUFP_BINDING, &sk->status); + + return ret; +} + +static int __bufp_connect_socket(struct bufp_socket *sk, + struct sockaddr_ipc *sa) +{ + struct bufp_socket *rsk; + xnhandle_t h; + int ret; + + if (sa == NULL) { + sa = &nullsa; + goto set_assoc; + } + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_BUFP_NRPORT) + return -EINVAL; + /* + * - If a valid sipc_port is passed in the [0..NRPORT-1] range, + * it is used verbatim and the connection succeeds + * immediately, regardless of whether the destination is + * bound at the time of the call. + * + * - If sipc_port is -1 and a label was set via BUFP_SETLABEL, + * connect() blocks for the requested amount of time until a + * socket is bound to the same label, unless the internal + * timeout (see SO_RCVTIMEO) specifies a non-blocking + * operation (RTDM_TIMEOUT_NONE). + * + * - If sipc_port is -1 and no label is given, the default + * destination address is cleared, meaning that any subsequent + * write() to the socket will return -EDESTADDRREQ, until a + * valid destination address is set via connect() or bind(). + * + * - In all other cases, -EINVAL is returned. + */ + if (sa->sipc_port < 0 && *sk->label) { + ret = xnregistry_bind(sk->label, + sk->rx_timeout, XN_RELATIVE, &h); + if (ret) + return ret; + + RTDM_EXECUTE_ATOMICALLY( + rsk = xnregistry_fetch(h); + if (rsk == NULL || rsk->magic != BUFP_SOCKET_MAGIC) + ret = -EINVAL; + else + /* Fetch labeled port number. */ + sa->sipc_port = rsk->name.sipc_port; + ); + if (ret) + return ret; + } + +set_assoc: + RTDM_EXECUTE_ATOMICALLY( + if (!test_bit(_BUFP_BOUND, &sk->status)) + /* Set default name. */ + sk->name = *sa; + /* Set default destination. */ + sk->peer = *sa; + ); + + return 0; +} + +static int __bufp_setsockopt(struct bufp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + struct _rtdm_setsockopt_args sopt; + char label[BUFP_LABEL_LEN]; + struct timeval tv; + int ret = 0; + size_t len; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (sopt.optlen != sizeof(tv)) + return -EINVAL; + if (rtipc_get_arg(user_info, &tv, + sopt.optval, sizeof(tv))) + return -EFAULT; + sk->rx_timeout = rtipc_timeval_to_ns(&tv); + break; + + case SO_SNDTIMEO: + if (sopt.optlen != sizeof(tv)) + return -EINVAL; + if (rtipc_get_arg(user_info, &tv, + sopt.optval, sizeof(tv))) + return -EFAULT; + sk->tx_timeout = rtipc_timeval_to_ns(&tv); + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case BUFP_SETBUFFER: + if (sopt.optlen != sizeof(len)) + return -EINVAL; + if (rtipc_get_arg(user_info, &len, + sopt.optval, sizeof(len))) + return -EFAULT; + if (len == 0) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + /* + * We may not do this more than once, and we + * have to do this before the first binding. + */ + if (test_bit(_BUFP_BOUND, &sk->status) || + test_bit(_BUFP_BINDING, &sk->status)) + ret = -EALREADY; + else + sk->bufsz = len; + ); + break; + + case BUFP_SETLABEL: + if (sopt.optlen < sizeof(label)) + return -EINVAL; + if (rtipc_get_arg(user_info, label, + sopt.optval, sizeof(label) - 1)) + return -EFAULT; + RTDM_EXECUTE_ATOMICALLY( + /* + * We may attach a label to a client socket + * which was previously bound in BUFP. + */ + if (test_bit(_BUFP_BINDING, &sk->status)) + ret = -EALREADY; + else { + strcpy(sk->label, label); + sk->label[BUFP_LABEL_LEN-1] = 0; + } + ); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __bufp_getsockopt(struct bufp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + struct _rtdm_getsockopt_args sopt; + char label[BUFP_LABEL_LEN]; + struct timeval tv; + socklen_t len; + int ret = 0; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (len != sizeof(tv)) + return -EINVAL; + rtipc_ns_to_timeval(&tv, sk->rx_timeout); + if (rtipc_put_arg(user_info, sopt.optval, + &tv, sizeof(tv))) + return -EFAULT; + break; + + case SO_SNDTIMEO: + if (len != sizeof(tv)) + return -EINVAL; + rtipc_ns_to_timeval(&tv, sk->tx_timeout); + if (rtipc_put_arg(user_info, sopt.optval, + &tv, sizeof(tv))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case BUFP_GETLABEL: + if (len < sizeof(label)) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + strcpy(label, sk->label); + ); + if (rtipc_put_arg(user_info, sopt.optval, + label, sizeof(label))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __bufp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + struct sockaddr_ipc saddr, *saddrp = &saddr; + struct bufp_socket *sk = priv->state; + int ret = 0; + + switch (request) { + + case _RTIOC_CONNECT: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret) + return ret; + ret = __bufp_connect_socket(sk, saddrp); + break; + + case _RTIOC_BIND: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret) + return ret; + if (saddrp == NULL) + return -EFAULT; + ret = __bufp_bind_socket(priv, saddrp); + break; + + case _RTIOC_GETSOCKNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->name); + break; + + case _RTIOC_GETPEERNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->peer); + break; + + case _RTIOC_SETSOCKOPT: + ret = __bufp_setsockopt(sk, user_info, arg); + break; + + case _RTIOC_GETSOCKOPT: + ret = __bufp_getsockopt(sk, user_info, arg); + break; + + case _RTIOC_LISTEN: + case _RTIOC_ACCEPT: + ret = -EOPNOTSUPP; + break; + + case _RTIOC_SHUTDOWN: + ret = -ENOTCONN; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int bufp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + if (rtdm_in_rt_context() && request == _RTIOC_BIND) + return -ENOSYS; /* Try downgrading to NRT */ + + return __bufp_ioctl(priv, user_info, request, arg); +} + +static int __init bufp_init(void) +{ + portmap = xnmap_create(CONFIG_XENO_OPT_BUFP_NRPORT, 0, 0); + if (portmap == NULL) + return -ENOMEM; + + return 0; +} + +static void bufp_exit(void) +{ + xnmap_delete(portmap); +} + +struct rtipc_protocol bufp_proto_driver = { + .proto_name = "bufp", + .proto_statesz = sizeof(struct bufp_socket), + .proto_init = bufp_init, + .proto_exit = bufp_exit, + .proto_ops = { + .socket = bufp_socket, + .close = bufp_close, + .recvmsg = bufp_recvmsg, + .sendmsg = bufp_sendmsg, + .read = bufp_read, + .write = bufp_write, + .ioctl = bufp_ioctl, + } +}; diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/iddp.c relase/linux-2.6.35.9//drivers/xenomai/ipc/iddp.c --- orig/linux-2.6.35.9//drivers/xenomai/ipc/iddp.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/iddp.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,950 @@ +/** + * This file is part of the Xenomai project. + * + * @note Copyright (C) 2009 Philippe Gerum + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +#define trace(m,a...) printk(KERN_WARNING "%s: " m "\n", __FUNCTION__, ##a) + +#define IDDP_SOCKET_MAGIC 0xa37a37a8 + +struct iddp_message { + struct list_head next; + int from; + size_t rdoff; + size_t len; + char data[]; +}; + +struct iddp_socket { + int magic; + struct sockaddr_ipc name; + struct sockaddr_ipc peer; + + struct xnheap *bufpool; + struct xnheap privpool; + rtdm_event_t *poolevt; + rtdm_event_t privevt; + int *poolwait; + int privwait; + size_t poolsz; + rtdm_sem_t insem; + struct list_head inq; + u_long status; + xnhandle_t handle; + char label[IDDP_LABEL_LEN]; + + nanosecs_rel_t rx_timeout; + nanosecs_rel_t tx_timeout; + unsigned long stalls; /* Buffer stall counter. */ + + struct rtipc_private *priv; +}; + +static struct sockaddr_ipc nullsa = { + .sipc_family = AF_RTIPC, + .sipc_port = -1 +}; + +static struct xnmap *portmap; + +static rtdm_event_t poolevt; + +static int poolwait; + +#define _IDDP_BINDING 0 +#define _IDDP_BOUND 1 + +#ifdef CONFIG_PROC_FS + +static ssize_t __iddp_link_proc(char *buf, int count, void *data) +{ + struct iddp_socket *sk = data; + return snprintf(buf, count, "%d", sk->name.sipc_port); +} + +static struct xnpnode __iddp_pnode = { + + .dir = NULL, + .type = "iddp", + .entries = 0, + .link_proc = &__iddp_link_proc, + .root = &rtipc_ptree, +}; + +#else /* !CONFIG_PROC_FS */ + +static struct xnpnode __iddp_pnode = { + + .type = "iddp" +}; + +#endif /* !CONFIG_PROC_FS */ + +static inline void __iddp_init_mbuf(struct iddp_message *mbuf, size_t len) +{ + mbuf->rdoff = 0; + mbuf->len = len; + INIT_LIST_HEAD(&mbuf->next); +} + +static struct iddp_message * +__iddp_alloc_mbuf(struct iddp_socket *sk, size_t len, + nanosecs_rel_t timeout, int flags, int *pret) +{ + struct iddp_message *mbuf = NULL; + rtdm_toseq_t timeout_seq; + int ret = 0; + + rtdm_toseq_init(&timeout_seq, timeout); + + for (;;) { + mbuf = xnheap_alloc(sk->bufpool, len + sizeof(*mbuf)); + if (mbuf) { + __iddp_init_mbuf(mbuf, len); + break; + } + if (flags & MSG_DONTWAIT) { + ret = -EAGAIN; + break; + } + /* + * No luck, no buffer free. Wait for a buffer to be + * released and retry. Admittedly, we might create a + * thundering herd effect if many waiters put a lot of + * memory pressure on the pool, but in this case, the + * pool size should be adjusted. + */ + RTDM_EXECUTE_ATOMICALLY( + /* + * membars are implicitly issued when required + * by this construct. + */ + ++sk->stalls; + (*sk->poolwait)++; + ret = rtdm_event_timedwait(sk->poolevt, + timeout, + &timeout_seq); + (*sk->poolwait)--; + if (unlikely(ret == -EIDRM)) + ret = -ECONNRESET; + ); + if (ret) + break; + } + + *pret = ret; + + return mbuf; +} + +static void __iddp_free_mbuf(struct iddp_socket *sk, + struct iddp_message *mbuf) +{ + xnheap_free(sk->bufpool, mbuf); + RTDM_EXECUTE_ATOMICALLY( + /* Wake up sleepers if any. */ + if (*sk->poolwait > 0) + rtdm_event_pulse(sk->poolevt); + ); +} + +static void __iddp_flush_pool(struct xnheap *heap, + void *poolmem, u_long poolsz, void *cookie) +{ + xnarch_free_host_mem(poolmem, poolsz); +} + +static int iddp_socket(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct iddp_socket *sk = priv->state; + + sk->magic = IDDP_SOCKET_MAGIC; + sk->name = nullsa; /* Unbound */ + sk->peer = nullsa; + sk->bufpool = &kheap; + sk->poolevt = &poolevt; + sk->poolwait = &poolwait; + sk->poolsz = 0; + sk->status = 0; + sk->handle = 0; + sk->rx_timeout = RTDM_TIMEOUT_INFINITE; + sk->tx_timeout = RTDM_TIMEOUT_INFINITE; + sk->stalls = 0; + *sk->label = 0; + INIT_LIST_HEAD(&sk->inq); + rtdm_sem_init(&sk->insem, 0); + rtdm_event_init(&sk->privevt, 0); + sk->priv = priv; + + return 0; +} + +static int iddp_close(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct iddp_socket *sk = priv->state; + struct iddp_message *mbuf; + + if (sk->name.sipc_port > -1) + xnmap_remove(portmap, sk->name.sipc_port); + + rtdm_sem_destroy(&sk->insem); + rtdm_event_destroy(&sk->privevt); + + if (sk->handle) + xnregistry_remove(sk->handle); + + if (sk->bufpool != &kheap) { + xnheap_destroy(&sk->privpool, __iddp_flush_pool, NULL); + return 0; + } + + /* Send unread datagrams back to the system heap. */ + while (!list_empty(&sk->inq)) { + mbuf = list_entry(sk->inq.next, struct iddp_message, next); + list_del(&mbuf->next); + xnheap_free(&kheap, mbuf); + } + + return 0; +} + +static ssize_t __iddp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + struct sockaddr_ipc *saddr) +{ + struct iddp_socket *sk = priv->state; + ssize_t maxlen, len, wrlen, vlen; + int nvec, rdoff, ret, dofree; + struct iddp_message *mbuf; + nanosecs_rel_t timeout; + struct xnbufd bufd; + + if (!test_bit(_IDDP_BOUND, &sk->status)) + return -EAGAIN; + + maxlen = rtipc_get_iov_flatlen(iov, iovlen); + if (maxlen == 0) + return 0; + + /* We want to pick one buffer from the queue. */ + timeout = (flags & MSG_DONTWAIT) ? RTDM_TIMEOUT_NONE : sk->rx_timeout; + ret = rtdm_sem_timeddown(&sk->insem, timeout, NULL); + if (unlikely(ret)) { + if (ret == -EIDRM) + return -ECONNRESET; + return ret; + } + + RTDM_EXECUTE_ATOMICALLY( + /* Pull heading message from input queue. */ + mbuf = list_entry(sk->inq.next, struct iddp_message, next); + rdoff = mbuf->rdoff; + len = mbuf->len - rdoff; + if (saddr) { + saddr->sipc_family = AF_RTIPC; + saddr->sipc_port = mbuf->from; + } + if (maxlen >= len) { + list_del(&mbuf->next); + dofree = 1; + } else { + /* Buffer is only partially read: repost. */ + mbuf->rdoff += maxlen; + len = maxlen; + dofree = 0; + rtdm_sem_up(&sk->insem); + } + ); + + /* Now, write "len" bytes from mbuf->data to the vector cells */ + for (nvec = 0, wrlen = len; nvec < iovlen && wrlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + break; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + wrlen -= vlen; + rdoff += vlen; + } + + if (dofree) + __iddp_free_mbuf(sk, mbuf); + + return ret ?: len; +} + +static ssize_t iddp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags) +{ + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc saddr; + ssize_t ret; + + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen < sizeof(struct sockaddr_ipc)) + return -EINVAL; + } else if (msg->msg_namelen != 0) + return -EINVAL; + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __iddp_recvmsg(priv, user_info, + iov, msg->msg_iovlen, flags, &saddr); + if (ret <= 0) + return ret; + + /* Copy the updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + /* Copy the source address if required. */ + if (msg->msg_name) { + if (rtipc_put_arg(user_info, msg->msg_name, + &saddr, sizeof(saddr))) + return -EFAULT; + msg->msg_namelen = sizeof(struct sockaddr_ipc); + } + + return ret; +} + +static ssize_t iddp_read(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + void *buf, size_t len) +{ + struct iovec iov = { .iov_base = buf, .iov_len = len }; + return __iddp_recvmsg(priv, user_info, &iov, 1, 0, NULL); +} + +static ssize_t __iddp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + const struct sockaddr_ipc *daddr) +{ + struct iddp_socket *sk = priv->state, *rsk; + struct rtdm_dev_context *rcontext; + struct iddp_message *mbuf; + ssize_t len, rdlen, vlen; + int nvec, wroff, ret; + struct xnbufd bufd; + void *p; + + len = rtipc_get_iov_flatlen(iov, iovlen); + if (len == 0) + return 0; + + p = xnmap_fetch_nocheck(portmap, daddr->sipc_port); + if (p == NULL) + return -ECONNRESET; + + rcontext = rtdm_context_get(rtipc_map2fd(p)); + if (rcontext == NULL) + return -ECONNRESET; + + rsk = rtipc_context_to_state(rcontext); + if (!test_bit(_IDDP_BOUND, &rsk->status)) { + rtdm_context_unlock(rcontext); + return -ECONNREFUSED; + } + + mbuf = __iddp_alloc_mbuf(rsk, len, flags, sk->tx_timeout, &ret); + if (unlikely(ret)) { + rtdm_context_unlock(rcontext); + return ret; + } + + /* Now, move "len" bytes to mbuf->data from the vector cells */ + for (nvec = 0, rdlen = len, wroff = 0; + nvec < iovlen && rdlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_to_kmem(mbuf->data + wroff, &bufd, vlen); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_to_kmem(mbuf->data + wroff, &bufd, vlen); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + goto fail; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + rdlen -= vlen; + wroff += vlen; + } + + RTDM_EXECUTE_ATOMICALLY( + mbuf->from = sk->name.sipc_port; + if (flags & MSG_OOB) + list_add(&mbuf->next, &rsk->inq); + else + list_add_tail(&mbuf->next, &rsk->inq); + rtdm_sem_up(&rsk->insem); + ); + + rtdm_context_unlock(rcontext); + + return len; + +fail: + __iddp_free_mbuf(rsk, mbuf); + + rtdm_context_unlock(rcontext); + + return ret; +} + +static ssize_t iddp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags) +{ + struct iddp_socket *sk = priv->state; + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc daddr; + ssize_t ret; + + if (flags & ~(MSG_OOB | MSG_DONTWAIT)) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen != sizeof(struct sockaddr_ipc)) + return -EINVAL; + + /* Fetch the destination address to send to. */ + if (rtipc_get_arg(user_info, &daddr, + msg->msg_name, sizeof(daddr))) + return -EFAULT; + + if (daddr.sipc_port < 0 || + daddr.sipc_port >= CONFIG_XENO_OPT_IDDP_NRPORT) + return -EINVAL; + } else { + if (msg->msg_namelen != 0) + return -EINVAL; + daddr = sk->peer; + if (daddr.sipc_port < 0) + return -ENOTCONN; + } + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __iddp_sendmsg(priv, user_info, iov, + msg->msg_iovlen, flags, &daddr); + if (ret <= 0) + return ret; + + /* Copy updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + return ret; +} + +static ssize_t iddp_write(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const void *buf, size_t len) +{ + struct iovec iov = { .iov_base = (void *)buf, .iov_len = len }; + struct iddp_socket *sk = priv->state; + + if (sk->peer.sipc_port < 0) + return -EDESTADDRREQ; + + return __iddp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer); +} + +static int __iddp_bind_socket(struct rtipc_private *priv, + struct sockaddr_ipc *sa) +{ + struct iddp_socket *sk = priv->state; + int ret = 0, port, fd; + void *poolmem; + size_t poolsz; + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_IDDP_NRPORT) + return -EINVAL; + + RTDM_EXECUTE_ATOMICALLY( + if (test_bit(_IDDP_BOUND, &sk->status) || + __test_and_set_bit(_IDDP_BINDING, &sk->status)) + ret = -EADDRINUSE; + ); + if (ret) + return ret; + + /* Will auto-select a free port number if unspec (-1). */ + port = sa->sipc_port; + fd = rtdm_private_to_context(priv)->fd; + port = xnmap_enter(portmap, port, rtipc_fd2map(fd)); + if (port < 0) + return port == -EEXIST ? -EADDRINUSE : -ENOMEM; + + sa->sipc_port = port; + + /* + * Allocate a local buffer pool if we were told to do so via + * setsockopt() before we got there. + */ + poolsz = sk->poolsz; + if (poolsz > 0) { + poolsz = xnheap_rounded_size(poolsz, XNHEAP_PAGE_SIZE); + poolmem = xnarch_alloc_host_mem(poolsz); + if (poolmem == NULL) { + ret = -ENOMEM; + goto fail; + } + + ret = xnheap_init(&sk->privpool, + poolmem, poolsz, XNHEAP_PAGE_SIZE); + if (ret) { + xnarch_free_host_mem(poolmem, poolsz); + goto fail; + } + xnheap_set_label(&sk->privpool, "ippd: %d", port); + + sk->poolevt = &sk->privevt; + sk->poolwait = &sk->privwait; + sk->bufpool = &sk->privpool; + } + + sk->name = *sa; + /* Set default destination if unset at binding time. */ + if (sk->peer.sipc_port < 0) + sk->peer = *sa; + + if (*sk->label) { + ret = xnregistry_enter(sk->label, sk, + &sk->handle, &__iddp_pnode); + if (ret) { + if (poolsz > 0) + xnheap_destroy(&sk->privpool, + __iddp_flush_pool, NULL); + goto fail; + } + } + + RTDM_EXECUTE_ATOMICALLY( + __clear_bit(_IDDP_BINDING, &sk->status); + __set_bit(_IDDP_BOUND, &sk->status); + ); + + return 0; +fail: + xnmap_remove(portmap, port); + clear_bit(_IDDP_BINDING, &sk->status); + + return ret; +} + +static int __iddp_connect_socket(struct iddp_socket *sk, + struct sockaddr_ipc *sa) +{ + struct iddp_socket *rsk; + xnhandle_t h; + int ret; + + if (sa == NULL) { + sa = &nullsa; + goto set_assoc; + } + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_IDDP_NRPORT) + return -EINVAL; + /* + * - If a valid sipc_port is passed in the [0..NRPORT-1] range, + * it is used verbatim and the connection succeeds + * immediately, regardless of whether the destination is + * bound at the time of the call. + * + * - If sipc_port is -1 and a label was set via IDDP_SETLABEL, + * connect() blocks for the requested amount of time until a + * socket is bound to the same label, unless the internal + * timeout (see SO_RCVTIMEO) specifies a non-blocking + * operation (RTDM_TIMEOUT_NONE). + * + * - If sipc_port is -1 and no label is given, the default + * destination address is cleared, meaning that any subsequent + * write() to the socket will return -EDESTADDRREQ, until a + * valid destination address is set via connect() or bind(). + * + * - In all other cases, -EINVAL is returned. + */ + if (sa->sipc_port < 0 && *sk->label) { + ret = xnregistry_bind(sk->label, + sk->rx_timeout, XN_RELATIVE, &h); + if (ret) + return ret; + + RTDM_EXECUTE_ATOMICALLY( + rsk = xnregistry_fetch(h); + if (rsk == NULL || rsk->magic != IDDP_SOCKET_MAGIC) + ret = -EINVAL; + else + /* Fetch labeled port number. */ + sa->sipc_port = rsk->name.sipc_port; + ); + if (ret) + return ret; + } + +set_assoc: + RTDM_EXECUTE_ATOMICALLY( + if (!test_bit(_IDDP_BOUND, &sk->status)) + /* Set default name. */ + sk->name = *sa; + /* Set default destination. */ + sk->peer = *sa; + ); + + return 0; +} + +static int __iddp_setsockopt(struct iddp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + struct _rtdm_setsockopt_args sopt; + char label[IDDP_LABEL_LEN]; + struct timeval tv; + int ret = 0; + size_t len; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (sopt.optlen != sizeof(tv)) + return -EINVAL; + if (rtipc_get_arg(user_info, &tv, + sopt.optval, sizeof(tv))) + return -EFAULT; + sk->rx_timeout = rtipc_timeval_to_ns(&tv); + break; + + case SO_SNDTIMEO: + if (sopt.optlen != sizeof(tv)) + return -EINVAL; + if (rtipc_get_arg(user_info, &tv, + sopt.optval, sizeof(tv))) + return -EFAULT; + sk->tx_timeout = rtipc_timeval_to_ns(&tv); + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case IDDP_SETLOCALPOOL: + if (sopt.optlen != sizeof(len)) + return -EINVAL; + if (rtipc_get_arg(user_info, &len, + sopt.optval, sizeof(len))) + return -EFAULT; + if (len == 0) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + /* + * We may not do this more than once, and we + * have to do this before the first binding. + */ + if (test_bit(_IDDP_BOUND, &sk->status) || + test_bit(_IDDP_BINDING, &sk->status)) + ret = -EALREADY; + else + sk->poolsz = len; + ); + break; + + case IDDP_GETSTALLCOUNT: + if (rtipc_put_arg(user_info, arg, + &sk->stalls, sizeof(sk->stalls))) + return -EFAULT; + break; + + case IDDP_SETLABEL: + if (sopt.optlen < sizeof(label)) + return -EINVAL; + if (rtipc_get_arg(user_info, label, + sopt.optval, sizeof(label) - 1)) + return -EFAULT; + RTDM_EXECUTE_ATOMICALLY( + /* + * We may attach a label to a client socket + * which was previously bound in IDDP. + */ + if (test_bit(_IDDP_BINDING, &sk->status)) + ret = -EALREADY; + else { + strcpy(sk->label, label); + sk->label[IDDP_LABEL_LEN-1] = 0; + } + ); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __iddp_getsockopt(struct iddp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + struct _rtdm_getsockopt_args sopt; + char label[IDDP_LABEL_LEN]; + struct timeval tv; + socklen_t len; + int ret = 0; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (len != sizeof(tv)) + return -EINVAL; + rtipc_ns_to_timeval(&tv, sk->rx_timeout); + if (rtipc_put_arg(user_info, sopt.optval, + &tv, sizeof(tv))) + return -EFAULT; + break; + + case SO_SNDTIMEO: + if (len != sizeof(tv)) + return -EINVAL; + rtipc_ns_to_timeval(&tv, sk->tx_timeout); + if (rtipc_put_arg(user_info, sopt.optval, + &tv, sizeof(tv))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case IDDP_GETSTALLCOUNT: + if (len < sizeof(sk->stalls)) + return -EINVAL; + if (rtipc_put_arg(user_info, sopt.optval, + &sk->stalls, sizeof(sk->stalls))) + return -EFAULT; + break; + + case IDDP_GETLABEL: + if (len < sizeof(label)) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + strcpy(label, sk->label); + ); + if (rtipc_put_arg(user_info, sopt.optval, + label, sizeof(label))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __iddp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + struct sockaddr_ipc saddr, *saddrp = &saddr; + struct iddp_socket *sk = priv->state; + int ret = 0; + + switch (request) { + + case _RTIOC_CONNECT: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret) + return ret; + ret = __iddp_connect_socket(sk, saddrp); + break; + + case _RTIOC_BIND: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret) + return ret; + if (saddrp == NULL) + return -EFAULT; + ret = __iddp_bind_socket(priv, saddrp); + break; + + case _RTIOC_GETSOCKNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->name); + break; + + case _RTIOC_GETPEERNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->peer); + break; + + case _RTIOC_SETSOCKOPT: + ret = __iddp_setsockopt(sk, user_info, arg); + break; + + case _RTIOC_GETSOCKOPT: + ret = __iddp_getsockopt(sk, user_info, arg); + break; + + case _RTIOC_LISTEN: + case _RTIOC_ACCEPT: + ret = -EOPNOTSUPP; + break; + + case _RTIOC_SHUTDOWN: + ret = -ENOTCONN; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int iddp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + if (rtdm_in_rt_context() && request == _RTIOC_BIND) + return -ENOSYS; /* Try downgrading to NRT */ + + return __iddp_ioctl(priv, user_info, request, arg); +} + +static int __init iddp_init(void) +{ + portmap = xnmap_create(CONFIG_XENO_OPT_IDDP_NRPORT, 0, 0); + if (portmap == NULL) + return -ENOMEM; + + rtdm_event_init(&poolevt, 0); + + return 0; +} + +static void iddp_exit(void) +{ + rtdm_event_destroy(&poolevt); + xnmap_delete(portmap); +} + +struct rtipc_protocol iddp_proto_driver = { + .proto_name = "iddp", + .proto_statesz = sizeof(struct iddp_socket), + .proto_init = iddp_init, + .proto_exit = iddp_exit, + .proto_ops = { + .socket = iddp_socket, + .close = iddp_close, + .recvmsg = iddp_recvmsg, + .sendmsg = iddp_sendmsg, + .read = iddp_read, + .write = iddp_write, + .ioctl = iddp_ioctl, + } +}; diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/internal.h relase/linux-2.6.35.9//drivers/xenomai/ipc/internal.h --- orig/linux-2.6.35.9//drivers/xenomai/ipc/internal.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/internal.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,130 @@ +/** + * This file is part of the Xenomai project. + * + * @note Copyright (C) 2009 Philippe Gerum + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _RTIPC_INTERNAL_H +#define _RTIPC_INTERNAL_H + +#include +#include +#include + +#define RTIPC_IOV_MAX 64 + +struct rtipc_protocol; + +struct rtipc_private { + struct rtipc_protocol *proto; + void *state; +}; + +struct rtipc_protocol { + const char *proto_name; + int proto_statesz; + int (*proto_init)(void); + void (*proto_exit)(void); + struct { + int (*socket)(struct rtipc_private *priv, + rtdm_user_info_t *user_info); + int (*close)(struct rtipc_private *priv, + rtdm_user_info_t *user_info); + ssize_t (*recvmsg)(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags); + ssize_t (*sendmsg)(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags); + ssize_t (*read)(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + void *buf, size_t len); + ssize_t (*write)(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const void *buf, size_t len); + int (*ioctl)(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg); + } proto_ops; +}; + +static inline void *rtipc_context_to_state(struct rtdm_dev_context *context) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->state; +} + +static inline void *rtipc_fd2map(int fd) +{ + return (void *)(long)(fd + 1); +} + +static inline int rtipc_map2fd(void *p) +{ + return (long)p - 1; +} + +static inline nanosecs_rel_t rtipc_timeval_to_ns(const struct timeval *tv) +{ + nanosecs_rel_t ns = tv->tv_usec * 1000; + + if (tv->tv_sec) + ns += (nanosecs_rel_t)tv->tv_sec * 1000000000UL; + + return ns; +} + +static inline void rtipc_ns_to_timeval(struct timeval *tv, nanosecs_rel_t ns) +{ + unsigned long nsecs; + + tv->tv_sec = xnarch_divrem_billion(ns, &nsecs); + tv->tv_usec = nsecs / 1000; +} + +int rtipc_get_arg(rtdm_user_info_t *user_info, + void *dst, const void *src, size_t len); + +int rtipc_put_arg(rtdm_user_info_t *user_info, + void *dst, const void *src, size_t len); + +int rtipc_get_sockaddr(rtdm_user_info_t *user_info, + const void *arg, struct sockaddr_ipc **saddrp); + +int rtipc_put_sockaddr(rtdm_user_info_t *user_info, void *arg, + const struct sockaddr_ipc *saddr); + +ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen); + +extern struct rtipc_protocol xddp_proto_driver; + +extern struct rtipc_protocol iddp_proto_driver; + +extern struct rtipc_protocol bufp_proto_driver; + +extern struct xnptree rtipc_ptree; + +#define rtipc_wait_context xnthread_wait_context +#define rtipc_prepare_wait xnthread_prepare_wait +#define rtipc_finish_wait xnthread_finish_wait +#define rtipc_get_wait_context xnthread_get_wait_context + +#define rtipc_peek_wait_head(obj) xnsynch_peek_pendq(&(obj)->synch_base) +#define rtipc_enter_atomic(lockctx) xnlock_get_irqsave(&nklock, (lockctx)) +#define rtipc_leave_atomic(lockctx) xnlock_put_irqrestore(&nklock, (lockctx)) + +#endif /* !_RTIPC_INTERNAL_H */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/Kconfig relase/linux-2.6.35.9//drivers/xenomai/ipc/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/ipc/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,89 @@ +menu "Real-time IPC drivers" + +config XENO_DRIVERS_RTIPC + depends on XENO_SKIN_RTDM + tristate "RTIPC protocol family" + help + + This driver provides the real-time IPC protocol family + (PF_RTIPC) over RTDM. + +config XENO_DRIVERS_RTIPC_XDDP + depends on XENO_DRIVERS_RTIPC + select XENO_OPT_PIPE + default y + bool "XDDP cross-domain datagram protocol" + help + + Xenomai's XDDP protocol enables threads to exchange datagrams + across the Xenomai/Linux domain boundary, using "message + pipes". + + Message pipes are bi-directional FIFO communication channels + allowing data exchange between real-time Xenomai threads and + regular (i.e. non real-time) user-space processes. Message + pipes are datagram-based and thus natively preserve message + boundaries, but they can also be used in byte stream mode when + sending from the real-time to the non real-time domain. + + The maximum number of communication ports available in the + system can be configured using the XENO_OPT_PIPE_NRDEV option + from the Nucleus menu. + + NOTE: this protocol is a replacement for the legacy RT_PIPE + interface still available from the native skin, but which is + scheduled for removal in Xenomai 3. + +config XENO_DRIVERS_RTIPC_IDDP + depends on XENO_DRIVERS_RTIPC + select XENO_OPT_MAP + default y + bool "IDDP intra-domain datagram protocol" + help + + Xenomai's IDDP protocol enables real-time threads to exchange + datagrams within the Xenomai domain. + +config XENO_OPT_IDDP_NRPORT + depends on XENO_DRIVERS_RTIPC_IDDP + int "Number of IDDP communication ports" + default 32 + help + + This parameter defines the number of IDDP ports available in + the system for creating receiver endpoints. Port numbers range + from 0 to CONFIG_XENO_OPT_IDDP_NRPORT - 1. + +config XENO_DRIVERS_RTIPC_BUFP + depends on XENO_DRIVERS_RTIPC + select XENO_OPT_MAP + default y + bool "Buffer protocol" + help + + The buffer protocol implements a byte-oriented, one-way + Producer-Consumer data path, which makes it a bit faster than + datagram-oriented protocols. All messages written are buffered + into a single memory area in strict FIFO order, until read by + the consumer. + + This protocol prevents short writes, and only allows short + reads when a potential deadlock situation arises (i.e. readers + and writers waiting for each other indefinitely), which + usually means that the buffer size does not fit the use peer + threads are making from the protocol. + + NOTE: this protocol is strictly identical to the RT_BUFFER + interface available from the native skin. + +config XENO_OPT_BUFP_NRPORT + depends on XENO_DRIVERS_RTIPC_BUFP + int "Number of BUFP communication ports" + default 32 + help + + This parameter defines the number of BUFP ports available in + the system for creating receiver endpoints. Port numbers range + from 0 to CONFIG_XENO_OPT_BUFP_NRPORT - 1. + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/Makefile relase/linux-2.6.35.9//drivers/xenomai/ipc/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/ipc/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,41 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/ipc + +obj-$(CONFIG_XENO_DRIVERS_RTIPC) += xeno_rtipc.o + +xeno_rtipc-y := rtipc.o + +xeno_rtipc-$(CONFIG_XENO_DRIVERS_RTIPC_XDDP) += xddp.o +xeno_rtipc-$(CONFIG_XENO_DRIVERS_RTIPC_IDDP) += iddp.o +xeno_rtipc-$(CONFIG_XENO_DRIVERS_RTIPC_BUFP) += bufp.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_RTIPC) += xeno_rtipc.o + +xeno_rtipc-objs := rtipc.o + +opt_objs-y := +opt_objs-$(CONFIG_XENO_DRIVERS_RTIPC_XDDP) += xddp.o +opt_objs-$(CONFIG_XENO_DRIVERS_RTIPC_IDDP) += iddp.o +opt_objs-$(CONFIG_XENO_DRIVERS_RTIPC_BUFP) += bufp.o + +xeno_rtipc-objs += $(opt_objs-y) + +export-objs := $(xeno_rtipc-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat -I. + +include $(TOPDIR)/Rules.make + +xeno_rtipc.o: $(xeno_rtipc-objs) + $(LD) -r -o $@ $(xeno_rtipc-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/rtipc.c relase/linux-2.6.35.9//drivers/xenomai/ipc/rtipc.c --- orig/linux-2.6.35.9//drivers/xenomai/ipc/rtipc.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/rtipc.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,289 @@ +/** + * This file is part of the Xenomai project. + * + * @note Copyright (C) 2009 Philippe Gerum + * + * 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 +#include +#include +#include "internal.h" + +static struct rtipc_protocol *protocols[IPCPROTO_MAX] = { +#ifdef CONFIG_XENO_DRIVERS_RTIPC_XDDP + [IPCPROTO_XDDP - 1] = &xddp_proto_driver, +#endif +#ifdef CONFIG_XENO_DRIVERS_RTIPC_IDDP + [IPCPROTO_IDDP - 1] = &iddp_proto_driver, +#endif +#ifdef CONFIG_XENO_DRIVERS_RTIPC_BUFP + [IPCPROTO_BUFP - 1] = &bufp_proto_driver, +#endif +}; + +#ifdef CONFIG_PROC_FS +struct xnptree rtipc_ptree = { + + .dir = NULL, + .name = "rtipc", + .entries = 0, +}; +#endif /* CONFIG_PROC_FS */ + +int rtipc_get_arg(rtdm_user_info_t *user_info, + void *dst, const void *src, size_t len) +{ + if (user_info) { + if (rtdm_safe_copy_from_user(user_info, dst, src, len)) + return -EFAULT; + } else + memcpy(dst, src, len); + + return 0; +} + +int rtipc_put_arg(rtdm_user_info_t *user_info, + void *dst, const void *src, size_t len) +{ + if (user_info) { + if (rtdm_safe_copy_to_user(user_info, dst, src, len)) + return -EFAULT; + } else + memcpy(dst, src, len); + + return 0; +} + +int rtipc_get_sockaddr(rtdm_user_info_t *user_info, + const void *arg, struct sockaddr_ipc **saddrp) +{ + struct _rtdm_setsockaddr_args setaddr; + + if (rtipc_get_arg(user_info, + &setaddr, arg, sizeof(setaddr))) + return -EFAULT; + + if (setaddr.addrlen > 0) { + if (setaddr.addrlen != sizeof(**saddrp)) + return -EINVAL; + + if (rtipc_get_arg(user_info, *saddrp, + setaddr.addr, sizeof(**saddrp))) + return -EFAULT; + } else { + if (setaddr.addr) + return -EINVAL; + *saddrp = NULL; + } + + return 0; +} + +int rtipc_put_sockaddr(rtdm_user_info_t *user_info, void *arg, + const struct sockaddr_ipc *saddr) +{ + struct _rtdm_getsockaddr_args getaddr; + socklen_t len; + + if (rtipc_get_arg(user_info, + &getaddr, arg, sizeof(getaddr))) + return -EFAULT; + + if (rtipc_get_arg(user_info, + &len, getaddr.addrlen, sizeof(len))) + return -EFAULT; + + if (len < sizeof(*saddr)) + return -EINVAL; + + if (rtipc_put_arg(user_info, + getaddr.addr, saddr, sizeof(*saddr))) + return -EFAULT; + + len = sizeof(*saddr); + if (rtipc_put_arg(user_info, + getaddr.addrlen, &len, sizeof(len))) + return -EFAULT; + + return 0; +} + +ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen) +{ + ssize_t len; + int nvec; + + /* Return the flattened vector length. */ + for (len = 0, nvec = 0; nvec < iovlen; nvec++) { + ssize_t l = iov[nvec].iov_len; + if (l < 0 || len + l < len) /* SuS wants this. */ + return -EINVAL; + len += l; + } + + return len; +} + +static int rtipc_socket(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int protocol) +{ + struct rtipc_protocol *proto; + struct rtipc_private *p; + int ret; + + if (protocol < 0 || protocol >= IPCPROTO_MAX) + return -EPROTONOSUPPORT; + + if (protocol == IPCPROTO_IPC) + /* Default protocol is IDDP */ + protocol = IPCPROTO_IDDP; + + proto = protocols[protocol - 1]; + if (proto == NULL) /* Not compiled in? */ + return -ENOPROTOOPT; + + p = rtdm_context_to_private(context); + p->proto = proto; + p->state = kmalloc(proto->proto_statesz, GFP_KERNEL); + if (p->state == NULL) + return -ENOMEM; + + ret = proto->proto_ops.socket(p, user_info); + if (ret) + kfree(p->state); + + return ret; +} + +static int rtipc_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + struct rtipc_private *p; + int ret; + + p = rtdm_context_to_private(context); + ret = p->proto->proto_ops.close(p, user_info); + if (ret) + return ret; + + kfree(p->state); + + return 0; +} + +static ssize_t rtipc_recvmsg(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->proto->proto_ops.recvmsg(p, user_info, msg, flags); +} + +static ssize_t rtipc_sendmsg(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->proto->proto_ops.sendmsg(p, user_info, msg, flags); +} + +static ssize_t rtipc_read(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + void *buf, size_t len) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->proto->proto_ops.read(p, user_info, buf, len); +} + +static ssize_t rtipc_write(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + const void *buf, size_t len) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->proto->proto_ops.write(p, user_info, buf, len); +} + +static int rtipc_ioctl(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + struct rtipc_private *p = rtdm_context_to_private(context); + return p->proto->proto_ops.ioctl(p, user_info, request, arg); +} + +static struct rtdm_device device = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + .device_flags = RTDM_PROTOCOL_DEVICE, + .context_size = sizeof(struct rtipc_private), + .device_name = "rtipc", + .protocol_family= PF_RTIPC, + .socket_type = SOCK_DGRAM, + .socket_nrt = rtipc_socket, + .ops = { + .close_nrt = rtipc_close, + .recvmsg_rt = rtipc_recvmsg, + .recvmsg_nrt = NULL, + .sendmsg_rt = rtipc_sendmsg, + .sendmsg_nrt = NULL, + .ioctl_rt = rtipc_ioctl, + .ioctl_nrt = rtipc_ioctl, + .read_rt = rtipc_read, + .read_nrt = NULL, + .write_rt = rtipc_write, + .write_nrt = NULL, + }, + .device_class = RTDM_CLASS_RTIPC, + .device_sub_class = RTDM_SUBCLASS_GENERIC, + .profile_version = 1, + .driver_name = "rtipc", + .driver_version = RTDM_DRIVER_VER(1, 0, 0), + .peripheral_name = "Real-time IPC interface", + .proc_name = device.device_name, + .provider_name = "Philippe Gerum (xenomai.org)", +}; + +int __init __rtipc_init(void) +{ + int ret, n; + + for (n = 0; n < IPCPROTO_MAX; n++) { + if (protocols[n] && protocols[n]->proto_init) { + ret = protocols[n]->proto_init(); + if (ret) + return ret; + } + } + + return rtdm_dev_register(&device); +} + +void __exit __rtipc_exit(void) +{ + int n; + + rtdm_dev_unregister(&device, 1000); + + for (n = 0; n < IPCPROTO_MAX; n++) { + if (protocols[n] && protocols[n]->proto_exit) + protocols[n]->proto_exit(); + } +} + +module_init(__rtipc_init); +module_exit(__rtipc_exit); + +MODULE_LICENSE("GPL"); diff -urN orig/linux-2.6.35.9//drivers/xenomai/ipc/xddp.c relase/linux-2.6.35.9//drivers/xenomai/ipc/xddp.c --- orig/linux-2.6.35.9//drivers/xenomai/ipc/xddp.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/ipc/xddp.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1102 @@ +/** + * This file is part of the Xenomai project. + * + * @note Copyright (C) 2009 Philippe Gerum + * + * 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 +#include +#include +#include +#include +#include +#include "internal.h" + +#define XDDP_SOCKET_MAGIC 0xa21a21a2 + +struct xddp_message { + struct xnpipe_mh mh; + char data[]; +}; + +struct xddp_socket { + int magic; + struct sockaddr_ipc name; + struct sockaddr_ipc peer; + + int minor; + size_t poolsz; + xnhandle_t handle; + char label[XDDP_LABEL_LEN]; + + struct xddp_message *buffer; + int buffer_port; + xnheap_t *bufpool; + xnheap_t privpool; + size_t fillsz; + size_t curbufsz; /* Current streaming buffer size */ + u_long status; + rtdm_lock_t lock; + + nanosecs_rel_t timeout; /* connect()/recvmsg() timeout */ + size_t reqbufsz; /* Requested streaming buffer size */ + + int (*monitor)(int s, int event, long arg); + struct rtipc_private *priv; +}; + +static struct sockaddr_ipc nullsa = { + .sipc_family = AF_RTIPC, + .sipc_port = -1 +}; + +static int portmap[CONFIG_XENO_OPT_PIPE_NRDEV]; /* indexes RTDM fildes */ + +#define _XDDP_SYNCWAIT 0 +#define _XDDP_ATOMIC 1 +#define _XDDP_BINDING 2 +#define _XDDP_BOUND 3 + +#ifdef CONFIG_PROC_FS + +static ssize_t __xddp_link_proc(char *buf, int count, void *data) +{ + struct xddp_socket *sk = data; + return snprintf(buf, count, "/dev/rtp%d", sk->minor); +} + +static struct xnpnode __xddp_pnode = { + + .dir = NULL, + .type = "xddp", + .entries = 0, + .link_proc = &__xddp_link_proc, + .root = &rtipc_ptree, +}; + +#else /* !CONFIG_PROC_FS */ + +static struct xnpnode __xddp_pnode = { + + .type = "xddp" +}; + +#endif /* !CONFIG_PROC_FS */ + +static void __xddp_flush_pool(xnheap_t *heap, + void *poolmem, u_long poolsz, void *cookie) +{ + xnarch_free_host_mem(poolmem, poolsz); +} + +static void *__xddp_alloc_handler(size_t size, void *xstate) /* nklock free */ +{ + struct rtdm_dev_context *context = xstate; + struct rtipc_private *priv; + struct xddp_socket *sk; + void *buf; + + priv = rtdm_context_to_private(context); + sk = priv->state; + + /* Try to allocate memory for the incoming message. */ + buf = xnheap_alloc(sk->bufpool, size); + if (unlikely(buf == NULL)) { + if (sk->monitor) + sk->monitor(context->fd, XDDP_EVTNOBUF, size); + if (size > xnheap_max_contiguous(sk->bufpool)) + buf = (void *)-1; /* Will never succeed. */ + } + + return buf; +} + +static int __xddp_resize_streambuf(struct xddp_socket *sk) /* sk->lock held */ +{ + if (sk->buffer) + xnheap_free(sk->bufpool, sk->buffer); + + if (sk->reqbufsz == 0) { + sk->buffer = NULL; + sk->curbufsz = 0; + return 0; + } + + sk->buffer = xnheap_alloc(sk->bufpool, sk->reqbufsz); + if (sk->buffer == NULL) { + sk->curbufsz = 0; + return -ENOMEM; + } + + sk->curbufsz = sk->reqbufsz; + + return 0; +} + +static void __xddp_free_handler(void *buf, void *xstate) /* nklock free */ +{ + struct rtdm_dev_context *context = xstate; + struct rtipc_private *priv; + rtdm_lockctx_t lockctx; + struct xddp_socket *sk; + + priv = rtdm_context_to_private(context); + sk = priv->state; + + if (buf != sk->buffer) { + xnheap_free(sk->bufpool, buf); + return; + } + + /* Reset the streaming buffer. */ + + rtdm_lock_get_irqsave(&sk->lock, lockctx); + + sk->fillsz = 0; + sk->buffer_port = -1; + __clear_bit(_XDDP_SYNCWAIT, &sk->status); + __clear_bit(_XDDP_ATOMIC, &sk->status); + + /* + * If a XDDP_SETSTREAMBUF request is pending, resize the + * streaming buffer on-the-fly. + */ + if (unlikely(sk->curbufsz != sk->reqbufsz)) + __xddp_resize_streambuf(sk); + + rtdm_lock_put_irqrestore(&sk->lock, lockctx); +} + +static void __xddp_output_handler(xnpipe_mh_t *mh, void *xstate) /* nklock held */ +{ + struct rtdm_dev_context *context = xstate; + struct rtipc_private *priv; + struct xddp_socket *sk; + + priv = rtdm_context_to_private(context); + sk = priv->state; + + if (sk->monitor) + sk->monitor(context->fd, XDDP_EVTOUT, xnpipe_m_size(mh)); +} + +static int __xddp_input_handler(xnpipe_mh_t *mh, int retval, void *xstate) /* nklock held */ +{ + struct rtdm_dev_context *context = xstate; + struct rtipc_private *priv; + struct xddp_socket *sk; + + priv = rtdm_context_to_private(context); + sk = priv->state; + + if (sk->monitor == NULL) + return retval; + + if (retval == 0) + /* Callee may alter the return value passed to userland. */ + retval = sk->monitor(context->fd, XDDP_EVTIN, + xnpipe_m_size(mh)); + else if (retval == -EPIPE && mh == NULL) + sk->monitor(context->fd, XDDP_EVTDOWN, 0); + + return retval; +} + +static void __xddp_release_handler(void *xstate) /* nklock free */ +{ + struct rtdm_dev_context *context = xstate; + struct rtipc_private *priv; + struct xddp_socket *sk; + + priv = rtdm_context_to_private(context); + sk = priv->state; + + if (sk->bufpool == &sk->privpool) + xnheap_destroy(&sk->privpool, __xddp_flush_pool, NULL); +} + +static int xddp_socket(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct xddp_socket *sk = priv->state; + + sk->magic = XDDP_SOCKET_MAGIC; + sk->name = nullsa; /* Unbound */ + sk->peer = nullsa; + sk->minor = -1; + sk->handle = 0; + *sk->label = 0; + sk->poolsz = 0; + sk->buffer = NULL; + sk->buffer_port = -1; + sk->bufpool = NULL; + sk->fillsz = 0; + sk->status = 0; + sk->timeout = RTDM_TIMEOUT_INFINITE; + sk->curbufsz = 0; + sk->reqbufsz = 0; + sk->monitor = NULL; + rtdm_lock_init(&sk->lock); + sk->priv = priv; + + return 0; +} + +static int xddp_close(struct rtipc_private *priv, + rtdm_user_info_t *user_info) +{ + struct xddp_socket *sk = priv->state; + + sk->monitor = NULL; + + if (!test_bit(_XDDP_BOUND, &sk->status)) + return 0; + + portmap[sk->name.sipc_port] = -1; + + if (sk->handle) + xnregistry_remove(sk->handle); + + return xnpipe_disconnect(sk->minor); +} + +static ssize_t __xddp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + struct sockaddr_ipc *saddr) +{ + struct xddp_message *mbuf = NULL; /* Fake GCC */ + struct xddp_socket *sk = priv->state; + ssize_t maxlen, len, wrlen, vlen; + nanosecs_rel_t timeout; + struct xnpipe_mh *mh; + int nvec, rdoff, ret; + struct xnbufd bufd; + + if (!test_bit(_XDDP_BOUND, &sk->status)) + return -EAGAIN; + + maxlen = rtipc_get_iov_flatlen(iov, iovlen); + if (maxlen == 0) + return 0; + + timeout = (flags & MSG_DONTWAIT) ? RTDM_TIMEOUT_NONE : sk->timeout; + /* Pull heading message from the input queue. */ + len = xnpipe_recv(sk->minor, &mh, timeout); + if (len < 0) + return len == -EIDRM ? 0 : len; + if (len > maxlen) { + ret = -ENOBUFS; + goto out; + } + + mbuf = container_of(mh, struct xddp_message, mh); + + if (saddr) + *saddr = sk->name; + + /* Write "len" bytes from mbuf->data to the vector cells */ + for (ret = 0, nvec = 0, rdoff = 0, wrlen = len; + nvec < iovlen && wrlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = wrlen >= iov[nvec].iov_len ? iov[nvec].iov_len : wrlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_from_kmem(&bufd, mbuf->data + rdoff, vlen); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + goto out; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + wrlen -= vlen; + rdoff += vlen; + } + +out: + xnheap_free(sk->bufpool, mbuf); + + return ret ?: len; +} + +static ssize_t xddp_recvmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct msghdr *msg, int flags) +{ + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc saddr; + ssize_t ret; + + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen < sizeof(struct sockaddr_ipc)) + return -EINVAL; + } else if (msg->msg_namelen != 0) + return -EINVAL; + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __xddp_recvmsg(priv, user_info, + iov, msg->msg_iovlen, flags, &saddr); + if (ret <= 0) + return ret; + + /* Copy the updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + /* Copy the source address if required. */ + if (msg->msg_name) { + if (rtipc_put_arg(user_info, msg->msg_name, + &saddr, sizeof(saddr))) + return -EFAULT; + msg->msg_namelen = sizeof(struct sockaddr_ipc); + } + + return ret; +} + +static ssize_t xddp_read(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + void *buf, size_t len) +{ + struct iovec iov = { .iov_base = buf, .iov_len = len }; + return __xddp_recvmsg(priv, user_info, &iov, 1, 0, NULL); +} + +static ssize_t __xddp_stream(struct xddp_socket *sk, + int from, struct xnbufd *bufd) +{ + struct xddp_message *mbuf; + size_t fillptr, rembytes; + rtdm_lockctx_t lockctx; + ssize_t outbytes; + int ret; + + /* + * xnpipe_msend() and xnpipe_mfixup() routines will only grab + * the nklock directly or indirectly, so holding our socket + * lock across those calls is fine. + */ + rtdm_lock_get_irqsave(&sk->lock, lockctx); + + /* + * There are two cases in which we must remove the cork + * unconditionally and send the incoming data as a standalone + * datagram: the destination port does not support streaming, + * or its streaming buffer is already filled with data issued + * from another port. + */ + if (sk->curbufsz == 0 || + (sk->buffer_port >= 0 && sk->buffer_port != from)) { + /* This will end up into a standalone datagram. */ + outbytes = 0; + goto out; + } + + mbuf = sk->buffer; + rembytes = sk->curbufsz - sizeof(*mbuf) - sk->fillsz; + outbytes = bufd->b_len > rembytes ? rembytes : bufd->b_len; + if (likely(outbytes > 0)) { + repeat: + /* Mark the beginning of a should-be-atomic section. */ + __set_bit(_XDDP_ATOMIC, &sk->status); + fillptr = sk->fillsz; + sk->fillsz += outbytes; + + rtdm_lock_put_irqrestore(&sk->lock, lockctx); + ret = xnbufd_copy_to_kmem(mbuf->data + fillptr, + bufd, outbytes); + rtdm_lock_get_irqsave(&sk->lock, lockctx); + + if (ret < 0) { + outbytes = ret; + __clear_bit(_XDDP_ATOMIC, &sk->status); + goto out; + } + + /* We haven't been atomic, let's try again. */ + if (!__test_and_clear_bit(_XDDP_ATOMIC, &sk->status)) + goto repeat; + + if (__test_and_set_bit(_XDDP_SYNCWAIT, &sk->status)) + outbytes = xnpipe_mfixup(sk->minor, + &mbuf->mh, outbytes); + else { + sk->buffer_port = from; + outbytes = xnpipe_send(sk->minor, &mbuf->mh, + outbytes + sizeof(*mbuf), + XNPIPE_NORMAL); + if (outbytes > 0) + outbytes -= sizeof(*mbuf); + } + } + +out: + rtdm_lock_put_irqrestore(&sk->lock, lockctx); + + return outbytes; +} + +static ssize_t __xddp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + struct iovec *iov, int iovlen, int flags, + const struct sockaddr_ipc *daddr) +{ + ssize_t len, rdlen, wrlen, vlen, ret, sublen; + struct xddp_socket *sk = priv->state; + struct rtdm_dev_context *rcontext; + struct xddp_message *mbuf; + struct xddp_socket *rsk; + int nvec, to, from; + struct xnbufd bufd; + + len = rtipc_get_iov_flatlen(iov, iovlen); + if (len == 0) + return 0; + + from = sk->name.sipc_port; + to = daddr->sipc_port; + + rcontext = rtdm_context_get(portmap[to]); + if (rcontext == NULL) + return -ECONNRESET; + + rsk = rtipc_context_to_state(rcontext); + if (!test_bit(_XDDP_BOUND, &rsk->status)) { + rtdm_context_unlock(rcontext); + return -ECONNREFUSED; + } + + sublen = len; + nvec = 0; + + /* + * If active, the streaming buffer is already pending on the + * output queue, so we basically have nothing to do during a + * MSG_MORE -> MSG_NONE transition. Therefore, we only have to + * take care of filling that buffer when MSG_MORE is + * given. Yummie. + */ + if (flags & MSG_MORE) { + for (rdlen = sublen, wrlen = 0; + nvec < iovlen && rdlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = __xddp_stream(rsk, from, &bufd); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = __xddp_stream(rsk, from, &bufd); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + goto fail_unlock; + wrlen += ret; + rdlen -= ret; + iov[nvec].iov_base += ret; + iov[nvec].iov_len -= ret; + /* + * In case of a short write to the streaming + * buffer, send the unsent part as a + * standalone datagram. + */ + if (ret < vlen) { + sublen = rdlen; + goto nostream; + } + } + rtdm_context_unlock(rcontext); + return wrlen; + } + +nostream: + mbuf = xnheap_alloc(rsk->bufpool, sublen + sizeof(*mbuf)); + if (unlikely(mbuf == NULL)) { + ret = -ENOMEM; + goto fail_unlock; + } + + /* + * Move "sublen" bytes to mbuf->data from the vector cells + */ + for (rdlen = sublen, wrlen = 0; nvec < iovlen && rdlen > 0; nvec++) { + if (iov[nvec].iov_len == 0) + continue; + vlen = rdlen >= iov[nvec].iov_len ? iov[nvec].iov_len : rdlen; +#ifdef CONFIG_XENO_OPT_PERVASIVE + if (user_info) { + xnbufd_map_uread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_to_kmem(mbuf->data + wrlen, &bufd, vlen); + xnbufd_unmap_uread(&bufd); + } else +#endif + { + xnbufd_map_kread(&bufd, iov[nvec].iov_base, vlen); + ret = xnbufd_copy_to_kmem(mbuf->data + wrlen, &bufd, vlen); + xnbufd_unmap_kread(&bufd); + } + if (ret < 0) + goto fail_freebuf; + iov[nvec].iov_base += vlen; + iov[nvec].iov_len -= vlen; + rdlen -= vlen; + wrlen += vlen; + } + + ret = xnpipe_send(rsk->minor, &mbuf->mh, + sublen + sizeof(*mbuf), + (flags & MSG_OOB) ? + XNPIPE_URGENT : XNPIPE_NORMAL); + + if (unlikely(ret < 0)) { + fail_freebuf: + xnheap_free(rsk->bufpool, mbuf); + fail_unlock: + rtdm_context_unlock(rcontext); + return ret; + } + + rtdm_context_unlock(rcontext); + + return len; +} + +static ssize_t xddp_sendmsg(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const struct msghdr *msg, int flags) +{ + struct xddp_socket *sk = priv->state; + struct iovec iov[RTIPC_IOV_MAX]; + struct sockaddr_ipc daddr; + ssize_t ret; + + /* + * We accept MSG_DONTWAIT, but do not care about it, since + * writing to the real-time endpoint of a message pipe must be + * a non-blocking operation. + */ + if (flags & ~(MSG_MORE | MSG_OOB | MSG_DONTWAIT)) + return -EINVAL; + + /* + * MSG_MORE and MSG_OOB are mutually exclusive in our + * implementation. + */ + if ((flags & (MSG_MORE | MSG_OOB)) == (MSG_MORE | MSG_OOB)) + return -EINVAL; + + if (msg->msg_name) { + if (msg->msg_namelen != sizeof(struct sockaddr_ipc)) + return -EINVAL; + + /* Fetch the destination address to send to. */ + if (rtipc_get_arg(user_info, &daddr, + msg->msg_name, sizeof(daddr))) + return -EFAULT; + + if (daddr.sipc_port < 0 || + daddr.sipc_port >= CONFIG_XENO_OPT_PIPE_NRDEV) + return -EINVAL; + } else { + if (msg->msg_namelen != 0) + return -EINVAL; + daddr = sk->peer; + if (daddr.sipc_port < 0) + return -ENOTCONN; + } + + if (msg->msg_iovlen >= RTIPC_IOV_MAX) + return -EINVAL; + + /* Copy I/O vector in */ + if (rtipc_get_arg(user_info, iov, msg->msg_iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + ret = __xddp_sendmsg(priv, user_info, iov, + msg->msg_iovlen, flags, &daddr); + if (ret <= 0) + return ret; + + /* Copy updated I/O vector back */ + if (rtipc_put_arg(user_info, msg->msg_iov, iov, + sizeof(iov[0]) * msg->msg_iovlen)) + return -EFAULT; + + return ret; +} + +static ssize_t xddp_write(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + const void *buf, size_t len) +{ + struct iovec iov = { .iov_base = (void *)buf, .iov_len = len }; + struct xddp_socket *sk = priv->state; + + if (sk->peer.sipc_port < 0) + return -EDESTADDRREQ; + + return __xddp_sendmsg(priv, user_info, &iov, 1, 0, &sk->peer); +} + +static int __xddp_bind_socket(struct rtipc_private *priv, + struct sockaddr_ipc *sa) +{ + struct xddp_socket *sk = priv->state; + struct xnpipe_operations ops; + size_t poolsz; + void *poolmem; + int ret = 0; + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + /* Allow special port -1 for auto-selection. */ + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_PIPE_NRDEV) + return -EINVAL; + + RTDM_EXECUTE_ATOMICALLY( + if (test_bit(_XDDP_BOUND, &sk->status) || + __test_and_set_bit(_XDDP_BINDING, &sk->status)) + ret = -EADDRINUSE; + ); + if (ret) + return ret; + + poolsz = sk->poolsz; + if (poolsz > 0) { + poolsz = xnheap_rounded_size(poolsz + sk->reqbufsz, XNHEAP_PAGE_SIZE); + poolmem = xnarch_alloc_host_mem(poolsz); + if (poolmem == NULL) { + ret = -ENOMEM; + goto fail; + } + + ret = xnheap_init(&sk->privpool, + poolmem, poolsz, XNHEAP_PAGE_SIZE); + if (ret) { + xnarch_free_host_mem(poolmem, poolsz); + goto fail; + } + + sk->bufpool = &sk->privpool; + } else + sk->bufpool = &kheap; + + if (sk->reqbufsz > 0) { + sk->buffer = xnheap_alloc(sk->bufpool, sk->reqbufsz); + if (sk->buffer == NULL) { + ret = -ENOMEM; + goto fail_freeheap; + } + sk->curbufsz = sk->reqbufsz; + } + + ops.output = &__xddp_output_handler; + ops.input = &__xddp_input_handler; + ops.alloc_ibuf = &__xddp_alloc_handler; + ops.free_ibuf = &__xddp_free_handler; + ops.free_obuf = &__xddp_free_handler; + ops.release = &__xddp_release_handler; + + ret = xnpipe_connect(sa->sipc_port, &ops, + rtdm_private_to_context(priv)); + if (ret < 0) { + if (ret == -EBUSY) + ret = -EADDRINUSE; + fail_freeheap: + if (sk->bufpool == &sk->privpool) + xnheap_destroy(&sk->privpool, + __xddp_flush_pool, NULL); + fail: + clear_bit(_XDDP_BINDING, &sk->status); + return ret; + } + + sk->minor = ret; + sa->sipc_port = ret; + sk->name = *sa; + /* Set default destination if unset at binding time. */ + if (sk->peer.sipc_port < 0) + sk->peer = *sa; + + if (poolsz > 0) + xnheap_set_label(sk->bufpool, "xddp: %d", sa->sipc_port); + + if (*sk->label) { + ret = xnregistry_enter(sk->label, sk, &sk->handle, + &__xddp_pnode); + if (ret) { + /* The release handler will cleanup the pool for us. */ + xnpipe_disconnect(sk->minor); + return ret; + } + } + + RTDM_EXECUTE_ATOMICALLY( + portmap[sk->minor] = rtdm_private_to_context(priv)->fd; + __clear_bit(_XDDP_BINDING, &sk->status); + __set_bit(_XDDP_BOUND, &sk->status); + ); + + return 0; +} + +static int __xddp_connect_socket(struct xddp_socket *sk, + struct sockaddr_ipc *sa) +{ + struct xddp_socket *rsk; + xnhandle_t h; + int ret; + + if (sa == NULL) { + sa = &nullsa; + goto set_assoc; + } + + if (sa->sipc_family != AF_RTIPC) + return -EINVAL; + + if (sa->sipc_port < -1 || + sa->sipc_port >= CONFIG_XENO_OPT_PIPE_NRDEV) + return -EINVAL; + /* + * - If a valid sipc_port is passed in the [0..NRDEV-1] range, + * it is used verbatim and the connection succeeds + * immediately, regardless of whether the destination is + * bound at the time of the call. + * + * - If sipc_port is -1 and a label was set via XDDP_SETLABEL, + * connect() blocks for the requested amount of time until a + * socket is bound to the same label, unless the internal + * timeout (see SO_RCVTIMEO) specifies a non-blocking + * operation (RTDM_TIMEOUT_NONE). + * + * - If sipc_port is -1 and no label is given, the default + * destination address is cleared, meaning that any subsequent + * write() to the socket will return -EDESTADDRREQ, until a + * valid destination address is set via connect() or bind(). + * + * - In all other cases, -EINVAL is returned. + */ + if (sa->sipc_port < 0 && *sk->label) { + ret = xnregistry_bind(sk->label, + sk->timeout, XN_RELATIVE, &h); + if (ret) + return ret; + + RTDM_EXECUTE_ATOMICALLY( + rsk = xnregistry_fetch(h); + if (rsk == NULL || rsk->magic != XDDP_SOCKET_MAGIC) + ret = -EINVAL; + else + /* Fetch labeled port number. */ + sa->sipc_port = rsk->minor; + ); + if (ret) + return ret; + } + +set_assoc: + RTDM_EXECUTE_ATOMICALLY( + if (!test_bit(_XDDP_BOUND, &sk->status)) + /* Set default name. */ + sk->name = *sa; + /* Set default destination. */ + sk->peer = *sa; + ); + + return 0; +} + +static int __xddp_setsockopt(struct xddp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + int (*monitor)(int s, int event, long arg); + struct _rtdm_setsockopt_args sopt; + char label[XDDP_LABEL_LEN]; + rtdm_lockctx_t lockctx; + struct timeval tv; + int ret = 0; + size_t len; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (sopt.optlen != sizeof(tv)) + return -EINVAL; + if (rtipc_get_arg(user_info, &tv, + sopt.optval, sizeof(tv))) + return -EFAULT; + sk->timeout = rtipc_timeval_to_ns(&tv); + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case XDDP_SETSTREAMBUF: + if (sopt.optlen != sizeof(len)) + return -EINVAL; + if (rtipc_get_arg(user_info, &len, + sopt.optval, sizeof(len))) + return -EFAULT; + if (len > 0) { + len += sizeof(struct xddp_message); + if (sk->bufpool && + len > xnheap_max_contiguous(sk->bufpool)) { + return -EINVAL; + } + } + rtdm_lock_get_irqsave(&sk->lock, lockctx); + sk->reqbufsz = len; + if (len != sk->curbufsz && + !test_bit(_XDDP_SYNCWAIT, &sk->status) && + test_bit(_XDDP_BOUND, &sk->status)) + ret = __xddp_resize_streambuf(sk); + rtdm_lock_put_irqrestore(&sk->lock, lockctx); + break; + + case XDDP_SETLOCALPOOL: + if (sopt.optlen != sizeof(len)) + return -EINVAL; + if (rtipc_get_arg(user_info, &len, + sopt.optval, sizeof(len))) + return -EFAULT; + if (len == 0) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + if (test_bit(_XDDP_BOUND, &sk->status) || + test_bit(_XDDP_BINDING, &sk->status)) + ret = -EALREADY; + else + sk->poolsz = len; + ); + break; + + case XDDP_SETMONITOR: + /* Monitoring is available from kernel-space only. */ + if (user_info) + return -EPERM; + if (sopt.optlen != sizeof(monitor)) + return -EINVAL; + if (rtipc_get_arg(NULL, &monitor, + sopt.optval, sizeof(monitor))) + return -EFAULT; + sk->monitor = monitor; + break; + + case XDDP_SETLABEL: + if (sopt.optlen < sizeof(label)) + return -EINVAL; + if (rtipc_get_arg(user_info, label, + sopt.optval, sizeof(label) - 1)) + return -EFAULT; + RTDM_EXECUTE_ATOMICALLY( + if (test_bit(_XDDP_BOUND, &sk->status) || + test_bit(_XDDP_BINDING, &sk->status)) + ret = -EALREADY; + else { + strcpy(sk->label, label); + sk->label[XDDP_LABEL_LEN-1] = 0; + } + ); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __xddp_getsockopt(struct xddp_socket *sk, + rtdm_user_info_t *user_info, + void *arg) +{ + struct _rtdm_getsockopt_args sopt; + char label[XDDP_LABEL_LEN]; + struct timeval tv; + socklen_t len; + int ret = 0; + + if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt))) + return -EFAULT; + + if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len))) + return -EFAULT; + + if (sopt.level == SOL_SOCKET) { + switch (sopt.optname) { + + case SO_RCVTIMEO: + if (len != sizeof(tv)) + return -EINVAL; + rtipc_ns_to_timeval(&tv, sk->timeout); + if (rtipc_put_arg(user_info, sopt.optval, + &tv, sizeof(tv))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; + } + + if (sopt.level != SOL_RTIPC) + return -ENOPROTOOPT; + + switch (sopt.optname) { + + case XDDP_GETLABEL: + if (len < sizeof(label)) + return -EINVAL; + RTDM_EXECUTE_ATOMICALLY( + strcpy(label, sk->label); + ); + if (rtipc_put_arg(user_info, sopt.optval, + label, sizeof(label))) + return -EFAULT; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int __xddp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + struct sockaddr_ipc saddr, *saddrp = &saddr; + struct xddp_socket *sk = priv->state; + int ret = 0; + + switch (request) { + + case _RTIOC_CONNECT: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret == 0) + ret = __xddp_connect_socket(sk, saddrp); + break; + + case _RTIOC_BIND: + ret = rtipc_get_sockaddr(user_info, arg, &saddrp); + if (ret) + return ret; + if (saddrp == NULL) + return -EFAULT; + ret = __xddp_bind_socket(priv, saddrp); + break; + + case _RTIOC_GETSOCKNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->name); + break; + + case _RTIOC_GETPEERNAME: + ret = rtipc_put_sockaddr(user_info, arg, &sk->peer); + break; + + case _RTIOC_SETSOCKOPT: + ret = __xddp_setsockopt(sk, user_info, arg); + break; + + case _RTIOC_GETSOCKOPT: + ret = __xddp_getsockopt(sk, user_info, arg); + break; + + case _RTIOC_LISTEN: + case _RTIOC_ACCEPT: + ret = -EOPNOTSUPP; + break; + + case _RTIOC_SHUTDOWN: + ret = -ENOTCONN; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int xddp_ioctl(struct rtipc_private *priv, + rtdm_user_info_t *user_info, + unsigned int request, void *arg) +{ + if (rtdm_in_rt_context() && request == _RTIOC_BIND) + return -ENOSYS; /* Try downgrading to NRT */ + + return __xddp_ioctl(priv, user_info, request, arg); +} + +struct rtipc_protocol xddp_proto_driver = { + .proto_name = "xddp", + .proto_statesz = sizeof(struct xddp_socket), + .proto_ops = { + .socket = xddp_socket, + .close = xddp_close, + .recvmsg = xddp_recvmsg, + .sendmsg = xddp_sendmsg, + .read = xddp_read, + .write = xddp_write, + .ioctl = xddp_ioctl, + } +}; diff -urN orig/linux-2.6.35.9//drivers/xenomai/Kconfig relase/linux-2.6.35.9//drivers/xenomai/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,11 @@ +menu "Drivers" + +depends on XENO_OPT_NUCLEUS + +source "drivers/xenomai/serial/Kconfig" +source "drivers/xenomai/testing/Kconfig" +source "drivers/xenomai/can/Kconfig" +source "drivers/xenomai/analogy/Kconfig" +source "drivers/xenomai/ipc/Kconfig" + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/Makefile relase/linux-2.6.35.9//drivers/xenomai/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,25 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +obj-$(CONFIG_XENOMAI) += serial/ testing/ can/ analogy/ ipc/ + +else + +# Makefile frag for Linux v2.4 + +mod-subdirs := serial testing can analogy ipc + +subdir-$(CONFIG_XENO_DRIVERS_16550A) += serial + +subdir-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += testing +subdir-$(CONFIG_XENO_DRIVERS_IRQBENCH) += testing +subdir-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += testing + +subdir-$(CONFIG_XENO_DRIVERS_CAN) += can +subdir-$(CONFIG_XENO_DRIVERS_ANALOGY) += analogy +subdir-$(CONFIG_XENO_DRIVERS_MPIPE) += ipc + +include $(TOPDIR)/Rules.make + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/16550A.c relase/linux-2.6.35.9//drivers/xenomai/serial/16550A.c --- orig/linux-2.6.35.9//drivers/xenomai/serial/16550A.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/16550A.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,1204 @@ +/* + * Copyright (C) 2005-2007 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include +#include + +#define RT_16550_DRIVER_NAME "xeno_16550A" + +#define MAX_DEVICES 8 + +#define IN_BUFFER_SIZE 4096 +#define OUT_BUFFER_SIZE 4096 + +#define DEFAULT_BAUD_BASE 115200 +#define DEFAULT_TX_FIFO 16 + +#define PARITY_MASK 0x03 +#define DATA_BITS_MASK 0x03 +#define STOP_BITS_MASK 0x01 +#define FIFO_MASK 0xC0 +#define EVENT_MASK 0x0F + +#define LCR_DLAB 0x80 + +#define FCR_FIFO 0x01 +#define FCR_RESET_RX 0x02 +#define FCR_RESET_TX 0x04 + +#define IER_RX 0x01 +#define IER_TX 0x02 +#define IER_STAT 0x04 +#define IER_MODEM 0x08 + +#define IIR_MODEM 0x00 +#define IIR_PIRQ 0x01 +#define IIR_TX 0x02 +#define IIR_RX 0x04 +#define IIR_STAT 0x06 +#define IIR_MASK 0x07 + +#define RHR 0 /* Receive Holding Buffer */ +#define THR 0 /* Transmit Holding Buffer */ +#define DLL 0 /* Divisor Latch LSB */ +#define IER 1 /* Interrupt Enable Register */ +#define DLM 1 /* Divisor Latch MSB */ +#define IIR 2 /* Interrupt Id Register */ +#define FCR 2 /* Fifo Control Register */ +#define LCR 3 /* Line Control Register */ +#define MCR 4 /* Modem Control Register */ +#define LSR 5 /* Line Status Register */ +#define MSR 6 /* Modem Status Register */ + +struct rt_16550_context { + struct rtser_config config; /* current device configuration */ + + rtdm_irq_t irq_handle; /* device IRQ handle */ + rtdm_lock_t lock; /* lock to protect context struct */ + + unsigned long base_addr; /* hardware IO base address */ +#ifdef CONFIG_XENO_DRIVERS_16550A_ANY + int io_mode; /* hardware IO-access mode */ +#endif + int tx_fifo; /* cached global tx_fifo[] */ + + int in_head; /* RX ring buffer, head pointer */ + int in_tail; /* RX ring buffer, tail pointer */ + size_t in_npend; /* pending bytes in RX ring */ + int in_nwait; /* bytes the user waits for */ + rtdm_event_t in_event; /* raised to unblock reader */ + char in_buf[IN_BUFFER_SIZE]; /* RX ring buffer */ + volatile unsigned long in_lock; /* single-reader lock */ + uint64_t *in_history; /* RX timestamp buffer */ + + int out_head; /* TX ring buffer, head pointer */ + int out_tail; /* TX ring buffer, tail pointer */ + size_t out_npend; /* pending bytes in TX ring */ + rtdm_event_t out_event; /* raised to unblock writer */ + char out_buf[OUT_BUFFER_SIZE]; /* TX ring buffer */ + rtdm_mutex_t out_lock; /* single-writer mutex */ + + uint64_t last_timestamp; /* timestamp of last event */ + int ioc_events; /* recorded events */ + rtdm_event_t ioc_event; /* raised to unblock event waiter */ + volatile unsigned long ioc_event_lock; /* single-waiter lock */ + + int ier_status; /* IER cache */ + int mcr_status; /* MCR cache */ + int status; /* cache for LSR + soft-states */ + int saved_errors; /* error cache for RTIOC_GET_STATUS */ +}; + +static const struct rtser_config default_config = { + 0xFFFF, RTSER_DEF_BAUD, RTSER_DEF_PARITY, RTSER_DEF_BITS, + RTSER_DEF_STOPB, RTSER_DEF_HAND, RTSER_DEF_FIFO_DEPTH, + RTSER_DEF_TIMEOUT, RTSER_DEF_TIMEOUT, RTSER_DEF_TIMEOUT, + RTSER_DEF_TIMESTAMP_HISTORY, RTSER_DEF_EVENT_MASK +}; + +static struct rtdm_device *device[MAX_DEVICES]; + +static unsigned int irq[MAX_DEVICES]; +static unsigned long irqtype[MAX_DEVICES] = { + [0 ... MAX_DEVICES-1] = RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE +}; +static unsigned int baud_base[MAX_DEVICES]; +static int tx_fifo[MAX_DEVICES]; +static unsigned int start_index; + +compat_module_param_array(irq, uint, MAX_DEVICES, 0400); +compat_module_param_array(baud_base, uint, MAX_DEVICES, 0400); +compat_module_param_array(tx_fifo, int, MAX_DEVICES, 0400); + +MODULE_PARM_DESC(irq, "IRQ numbers of the serial devices"); +MODULE_PARM_DESC(baud_base, "Maximum baud rate of the serial device " + "(internal clock rate / 16)"); +MODULE_PARM_DESC(tx_fifo, "Transmitter FIFO size"); + +module_param(start_index, uint, 0400); +MODULE_PARM_DESC(start_index, "First device instance number to be used"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jan.kiszka@web.de"); + +#include "16550A_io.h" +#include "16550A_pnp.h" +#include "16550A_pci.h" + +static inline int rt_16550_rx_interrupt(struct rt_16550_context *ctx, + uint64_t * timestamp) +{ + unsigned long base = ctx->base_addr; + int mode = rt_16550_io_mode_from_ctx(ctx); + int rbytes = 0; + int lsr = 0; + int c; + + do { + c = rt_16550_reg_in(mode, base, RHR); /* read input char */ + + ctx->in_buf[ctx->in_tail] = c; + if (ctx->in_history) + ctx->in_history[ctx->in_tail] = *timestamp; + ctx->in_tail = (ctx->in_tail + 1) & (IN_BUFFER_SIZE - 1); + + if (++ctx->in_npend > IN_BUFFER_SIZE) { + lsr |= RTSER_SOFT_OVERRUN_ERR; + ctx->in_npend--; + } + + rbytes++; + lsr &= ~RTSER_LSR_DATA; + lsr |= (rt_16550_reg_in(mode, base, LSR) & + (RTSER_LSR_DATA | RTSER_LSR_OVERRUN_ERR | + RTSER_LSR_PARITY_ERR | RTSER_LSR_FRAMING_ERR | + RTSER_LSR_BREAK_IND)); + } while (testbits(lsr, RTSER_LSR_DATA)); + + /* save new errors */ + ctx->status |= lsr; + + /* If we are enforcing the RTSCTS control flow and the input + buffer is busy above the specified high watermark, clear + RTS. */ +/* if (uart->i_count >= uart->config.rts_hiwm && + (uart->config.handshake & RT_UART_RTSCTS) != 0 && + (uart->modem & MCR_RTS) != 0) { + uart->modem &= ~MCR_RTS; + rt_16550_reg_out(mode, base, MCR, uart->modem); + }*/ + + return rbytes; +} + +static inline void rt_16550_tx_interrupt(struct rt_16550_context *ctx) +{ + int c; + int count; + unsigned long base = ctx->base_addr; + int mode = rt_16550_io_mode_from_ctx(ctx); + +/* if (uart->modem & MSR_CTS)*/ + { + for (count = ctx->tx_fifo; + (count > 0) && (ctx->out_npend > 0); + count--, ctx->out_npend--) { + c = ctx->out_buf[ctx->out_head++]; + rt_16550_reg_out(mode, base, THR, c); + ctx->out_head &= (OUT_BUFFER_SIZE - 1); + } + } +} + +static inline void rt_16550_stat_interrupt(struct rt_16550_context *ctx) +{ + unsigned long base = ctx->base_addr; + int mode = rt_16550_io_mode_from_ctx(ctx); + + ctx->status |= (rt_16550_reg_in(mode, base, LSR) & + (RTSER_LSR_OVERRUN_ERR | RTSER_LSR_PARITY_ERR | + RTSER_LSR_FRAMING_ERR | RTSER_LSR_BREAK_IND)); +} + +static int rt_16550_interrupt(rtdm_irq_t * irq_context) +{ + struct rt_16550_context *ctx; + unsigned long base; + int mode; + int iir; + uint64_t timestamp = rtdm_clock_read(); + int rbytes = 0; + int events = 0; + int modem; + int ret = RTDM_IRQ_NONE; + + ctx = rtdm_irq_get_arg(irq_context, struct rt_16550_context); + base = ctx->base_addr; + mode = rt_16550_io_mode_from_ctx(ctx); + + rtdm_lock_get(&ctx->lock); + + while (1) { + iir = rt_16550_reg_in(mode, base, IIR) & IIR_MASK; + if (testbits(iir, IIR_PIRQ)) + break; + + if (iir == IIR_RX) { + rbytes += rt_16550_rx_interrupt(ctx, ×tamp); + events |= RTSER_EVENT_RXPEND; + } else if (iir == IIR_STAT) + rt_16550_stat_interrupt(ctx); + else if (iir == IIR_TX) + rt_16550_tx_interrupt(ctx); + else if (iir == IIR_MODEM) { + modem = rt_16550_reg_in(mode, base, MSR); + if (modem & (modem << 4)) + events |= RTSER_EVENT_MODEMHI; + if ((modem ^ 0xF0) & (modem << 4)) + events |= RTSER_EVENT_MODEMLO; + } + + ret = RTDM_IRQ_HANDLED; + } + + if (ctx->in_nwait > 0) { + if ((ctx->in_nwait <= rbytes) || ctx->status) { + ctx->in_nwait = 0; + rtdm_event_signal(&ctx->in_event); + } else + ctx->in_nwait -= rbytes; + } + + if (ctx->status) { + events |= RTSER_EVENT_ERRPEND; + ctx->ier_status &= ~IER_STAT; + } + + if (testbits(events, ctx->config.event_mask)) { + int old_events = ctx->ioc_events; + + ctx->last_timestamp = timestamp; + ctx->ioc_events = events; + + if (!old_events) + rtdm_event_signal(&ctx->ioc_event); + } + + if (testbits(ctx->ier_status, IER_TX) && (ctx->out_npend == 0)) { + /* mask transmitter empty interrupt */ + ctx->ier_status &= ~IER_TX; + + rtdm_event_signal(&ctx->out_event); + } + + /* update interrupt mask */ + rt_16550_reg_out(mode, base, IER, ctx->ier_status); + + rtdm_lock_put(&ctx->lock); + + return ret; +} + +static int rt_16550_set_config(struct rt_16550_context *ctx, + const struct rtser_config *config, + uint64_t **in_history_ptr) +{ + rtdm_lockctx_t lock_ctx; + unsigned long base = ctx->base_addr; + int mode = rt_16550_io_mode_from_ctx(ctx); + int err = 0; + + /* make line configuration atomic and IRQ-safe */ + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + if (testbits(config->config_mask, RTSER_SET_BAUD)) { + int dev_id = container_of(((void *)ctx), + struct rtdm_dev_context, + dev_private)->device->device_id; + int baud_div; + + ctx->config.baud_rate = config->baud_rate; + baud_div = (baud_base[dev_id] + (ctx->config.baud_rate>>1)) / + ctx->config.baud_rate; + rt_16550_reg_out(mode, base, LCR, LCR_DLAB); + rt_16550_reg_out(mode, base, DLL, baud_div & 0xff); + rt_16550_reg_out(mode, base, DLM, baud_div >> 8); + } + + if (testbits(config->config_mask, RTSER_SET_PARITY)) + ctx->config.parity = config->parity & PARITY_MASK; + if (testbits(config->config_mask, RTSER_SET_DATA_BITS)) + ctx->config.data_bits = config->data_bits & DATA_BITS_MASK; + if (testbits(config->config_mask, RTSER_SET_STOP_BITS)) + ctx->config.stop_bits = config->stop_bits & STOP_BITS_MASK; + + if (testbits(config->config_mask, RTSER_SET_PARITY | + RTSER_SET_DATA_BITS | + RTSER_SET_STOP_BITS | + RTSER_SET_BAUD)) { + rt_16550_reg_out(mode, base, LCR, + (ctx->config.parity << 3) | + (ctx->config.stop_bits << 2) | + ctx->config.data_bits); + ctx->status = 0; + ctx->ioc_events &= ~RTSER_EVENT_ERRPEND; + } + + if (testbits(config->config_mask, RTSER_SET_FIFO_DEPTH)) { + ctx->config.fifo_depth = config->fifo_depth & FIFO_MASK; + rt_16550_reg_out(mode, base, FCR, + FCR_FIFO | FCR_RESET_RX | FCR_RESET_TX); + rt_16550_reg_out(mode, base, FCR, + FCR_FIFO | ctx->config.fifo_depth); + } + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + /* Timeout manipulation is not atomic. The user is supposed to take + care not to use and change timeouts at the same time. */ + if (testbits(config->config_mask, RTSER_SET_TIMEOUT_RX)) + ctx->config.rx_timeout = config->rx_timeout; + if (testbits(config->config_mask, RTSER_SET_TIMEOUT_TX)) + ctx->config.tx_timeout = config->tx_timeout; + if (testbits(config->config_mask, RTSER_SET_TIMEOUT_EVENT)) + ctx->config.event_timeout = config->event_timeout; + + if (testbits(config->config_mask, RTSER_SET_TIMESTAMP_HISTORY)) { + /* change timestamp history atomically */ + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + if (testbits + (config->timestamp_history, RTSER_RX_TIMESTAMP_HISTORY)) { + if (!ctx->in_history) { + ctx->in_history = *in_history_ptr; + *in_history_ptr = NULL; + if (!ctx->in_history) + err = -ENOMEM; + } + } else { + *in_history_ptr = ctx->in_history; + ctx->in_history = NULL; + } + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + } + + if (testbits(config->config_mask, RTSER_SET_EVENT_MASK)) { + /* change event mask atomically */ + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + ctx->config.event_mask = config->event_mask & EVENT_MASK; + ctx->ioc_events = 0; + + if (testbits(config->event_mask, RTSER_EVENT_RXPEND) && + (ctx->in_npend > 0)) + ctx->ioc_events |= RTSER_EVENT_RXPEND; + + if (testbits(config->event_mask, RTSER_EVENT_ERRPEND) + && ctx->status) + ctx->ioc_events |= RTSER_EVENT_ERRPEND; + + if (testbits(config->event_mask, + RTSER_EVENT_MODEMHI | RTSER_EVENT_MODEMLO)) + /* enable modem status interrupt */ + ctx->ier_status |= IER_MODEM; + else + /* disable modem status interrupt */ + ctx->ier_status &= ~IER_MODEM; + rt_16550_reg_out(mode, base, IER, ctx->ier_status); + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + } + + if (testbits(config->config_mask, RTSER_SET_HANDSHAKE)) { + /* change handshake atomically */ + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + ctx->config.handshake = config->handshake; + + switch (ctx->config.handshake) { + case RTSER_RTSCTS_HAND: + // ...? + + default: /* RTSER_NO_HAND */ + ctx->mcr_status = + RTSER_MCR_DTR | RTSER_MCR_RTS | RTSER_MCR_OUT2; + break; + } + rt_16550_reg_out(mode, base, MCR, ctx->mcr_status); + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + } + + return err; +} + +void rt_16550_cleanup_ctx(struct rt_16550_context *ctx) +{ + rtdm_event_destroy(&ctx->in_event); + rtdm_event_destroy(&ctx->out_event); + rtdm_event_destroy(&ctx->ioc_event); + rtdm_mutex_destroy(&ctx->out_lock); +} + +int rt_16550_open(struct rtdm_dev_context *context, + rtdm_user_info_t * user_info, int oflags) +{ + struct rt_16550_context *ctx; + int dev_id = context->device->device_id; + int err; + uint64_t *dummy; + rtdm_lockctx_t lock_ctx; + + ctx = (struct rt_16550_context *)context->dev_private; + + /* IPC initialisation - cannot fail with used parameters */ + rtdm_lock_init(&ctx->lock); + rtdm_event_init(&ctx->in_event, 0); + rtdm_event_init(&ctx->out_event, 0); + rtdm_event_init(&ctx->ioc_event, 0); + rtdm_mutex_init(&ctx->out_lock); + + rt_16550_init_io_ctx(dev_id, ctx); + + ctx->tx_fifo = tx_fifo[dev_id]; + + ctx->in_head = 0; + ctx->in_tail = 0; + ctx->in_npend = 0; + ctx->in_nwait = 0; + ctx->in_lock = 0; + ctx->in_history = NULL; + + ctx->out_head = 0; + ctx->out_tail = 0; + ctx->out_npend = 0; + + ctx->ioc_events = 0; + ctx->ioc_event_lock = 0; + ctx->status = 0; + ctx->saved_errors = 0; + + rt_16550_set_config(ctx, &default_config, &dummy); + + err = rtdm_irq_request(&ctx->irq_handle, irq[dev_id], + rt_16550_interrupt, irqtype[dev_id], + context->device->proc_name, ctx); + if (err) { + /* reset DTR and RTS */ + rt_16550_reg_out(rt_16550_io_mode_from_ctx(ctx), ctx->base_addr, + MCR, 0); + + rt_16550_cleanup_ctx(ctx); + + return err; + } + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + /* enable interrupts */ + ctx->ier_status = IER_RX; + rt_16550_reg_out(rt_16550_io_mode_from_ctx(ctx), ctx->base_addr, IER, + IER_RX); + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + return 0; +} + +int rt_16550_close(struct rtdm_dev_context *context, + rtdm_user_info_t * user_info) +{ + struct rt_16550_context *ctx; + unsigned long base; + int mode; + uint64_t *in_history; + rtdm_lockctx_t lock_ctx; + + ctx = (struct rt_16550_context *)context->dev_private; + base = ctx->base_addr; + mode = rt_16550_io_mode_from_ctx(ctx); + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + /* reset DTR and RTS */ + rt_16550_reg_out(mode, base, MCR, 0); + + /* mask all UART interrupts and clear pending ones. */ + rt_16550_reg_out(mode, base, IER, 0); + rt_16550_reg_in(mode, base, IIR); + rt_16550_reg_in(mode, base, LSR); + rt_16550_reg_in(mode, base, RHR); + rt_16550_reg_in(mode, base, MSR); + + in_history = ctx->in_history; + ctx->in_history = NULL; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + rtdm_irq_free(&ctx->irq_handle); + + rt_16550_cleanup_ctx(ctx); + + kfree(in_history); + + return 0; +} + +int rt_16550_ioctl(struct rtdm_dev_context *context, + rtdm_user_info_t * user_info, + unsigned int request, void *arg) +{ + rtdm_lockctx_t lock_ctx; + struct rt_16550_context *ctx; + int err = 0; + unsigned long base; + int mode; + + ctx = (struct rt_16550_context *)context->dev_private; + base = ctx->base_addr; + mode = rt_16550_io_mode_from_ctx(ctx); + + switch (request) { + case RTSER_RTIOC_GET_CONFIG: + if (user_info) + err = + rtdm_safe_copy_to_user(user_info, arg, + &ctx->config, + sizeof(struct + rtser_config)); + else + memcpy(arg, &ctx->config, + sizeof(struct rtser_config)); + break; + + case RTSER_RTIOC_SET_CONFIG: { + struct rtser_config *config; + struct rtser_config config_buf; + uint64_t *hist_buf = NULL; + + config = (struct rtser_config *)arg; + + if (user_info) { + err = + rtdm_safe_copy_from_user(user_info, &config_buf, + arg, + sizeof(struct + rtser_config)); + if (err) + return err; + + config = &config_buf; + } + + if (testbits(config->config_mask, RTSER_SET_BAUD) && + (config->baud_rate > + baud_base[context->device->device_id] || + config->baud_rate <= 0)) + /* invalid baudrate for this port */ + return -EINVAL; + + if (testbits(config->config_mask, + RTSER_SET_TIMESTAMP_HISTORY)) { + /* + * Reflect the call to non-RT as we will likely + * allocate or free the buffer. + */ + if (rtdm_in_rt_context()) + return -ENOSYS; + + if (testbits(config->timestamp_history, + RTSER_RX_TIMESTAMP_HISTORY)) + hist_buf = kmalloc(IN_BUFFER_SIZE * + sizeof(nanosecs_abs_t), + GFP_KERNEL); + } + + rt_16550_set_config(ctx, config, &hist_buf); + + if (hist_buf) + kfree(hist_buf); + + break; + } + + case RTSER_RTIOC_GET_STATUS: { + int status; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + status = ctx->saved_errors | ctx->status; + ctx->status = 0; + ctx->saved_errors = 0; + ctx->ioc_events &= ~RTSER_EVENT_ERRPEND; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + if (user_info) { + struct rtser_status status_buf; + + status_buf.line_status = + rt_16550_reg_in(mode, base, LSR) | status; + status_buf.modem_status = + rt_16550_reg_in(mode, base, MSR); + + err = + rtdm_safe_copy_to_user(user_info, arg, + &status_buf, + sizeof(struct + rtser_status)); + } else { + ((struct rtser_status *)arg)->line_status = + rt_16550_reg_in(mode, base, LSR) | status; + ((struct rtser_status *)arg)->modem_status = + rt_16550_reg_in(mode, base, MSR); + } + break; + } + + case RTSER_RTIOC_GET_CONTROL: + if (user_info) + err = + rtdm_safe_copy_to_user(user_info, arg, + &ctx->mcr_status, + sizeof(int)); + else + *(int *)arg = ctx->mcr_status; + + break; + + case RTSER_RTIOC_SET_CONTROL: { + int new_mcr = (long)arg; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + ctx->mcr_status = new_mcr; + rt_16550_reg_out(mode, base, MCR, new_mcr); + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + break; + } + + case RTSER_RTIOC_WAIT_EVENT: { + struct rtser_event ev = { .rxpend_timestamp = 0 }; + rtdm_toseq_t timeout_seq; + + if (!rtdm_in_rt_context()) + return -ENOSYS; + + /* Only one waiter allowed, stop any further attempts here. */ + if (test_and_set_bit(0, &ctx->ioc_event_lock)) + return -EBUSY; + + rtdm_toseq_init(&timeout_seq, ctx->config.event_timeout); + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + while (!ctx->ioc_events) { + /* Only enable error interrupt + when the user waits for it. */ + if (testbits(ctx->config.event_mask, + RTSER_EVENT_ERRPEND)) { + ctx->ier_status |= IER_STAT; + rt_16550_reg_out(mode, base, IER, + ctx->ier_status); + } + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + err = rtdm_event_timedwait(&ctx->ioc_event, + ctx->config.event_timeout, + &timeout_seq); + if (err) { + /* Device has been closed? */ + if (err == -EIDRM) + err = -EBADF; + goto wait_unlock_out; + } + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + } + + ev.events = ctx->ioc_events; + ctx->ioc_events &= + ~(RTSER_EVENT_MODEMHI | RTSER_EVENT_MODEMLO); + + ev.last_timestamp = ctx->last_timestamp; + ev.rx_pending = ctx->in_npend; + + if (ctx->in_history) + ev.rxpend_timestamp = ctx->in_history[ctx->in_head]; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + if (user_info) + err = + rtdm_safe_copy_to_user(user_info, arg, &ev, + sizeof(struct + rtser_event)); + else + memcpy(arg, &ev, sizeof(struct rtser_event)); + + wait_unlock_out: + /* release the simple event waiter lock */ + clear_bit(0, &ctx->ioc_event_lock); + break; + } + + case RTSER_RTIOC_BREAK_CTL: { + int lcr = ((long)arg & RTSER_BREAK_SET) << 6; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + lcr |= + (ctx->config.parity << 3) | (ctx->config.stop_bits << 2) | + ctx->config.data_bits; + + rt_16550_reg_out(mode, base, LCR, lcr); + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + break; + } + + case RTIOC_PURGE: { + int fcr = 0; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + if ((long)arg & RTDM_PURGE_RX_BUFFER) { + ctx->in_head = 0; + ctx->in_tail = 0; + ctx->in_npend = 0; + ctx->status = 0; + fcr |= FCR_FIFO | FCR_RESET_RX; + rt_16550_reg_in(mode, base, RHR); + } + if ((long)arg & RTDM_PURGE_TX_BUFFER) { + ctx->out_head = 0; + ctx->out_tail = 0; + ctx->out_npend = 0; + fcr |= FCR_FIFO | FCR_RESET_TX; + } + if (fcr) { + rt_16550_reg_out(mode, base, FCR, fcr); + rt_16550_reg_out(mode, base, FCR, + FCR_FIFO | ctx->config.fifo_depth); + } + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + break; + } + + default: + err = -ENOTTY; + } + + return err; +} + +ssize_t rt_16550_read(struct rtdm_dev_context * context, + rtdm_user_info_t * user_info, void *buf, size_t nbyte) +{ + struct rt_16550_context *ctx; + rtdm_lockctx_t lock_ctx; + size_t read = 0; + int pending; + int block; + int subblock; + int in_pos; + char *out_pos = (char *)buf; + rtdm_toseq_t timeout_seq; + ssize_t ret = -EAGAIN; /* for non-blocking read */ + int nonblocking; + + if (nbyte == 0) + return 0; + + if (user_info && !rtdm_rw_user_ok(user_info, buf, nbyte)) + return -EFAULT; + + ctx = (struct rt_16550_context *)context->dev_private; + + rtdm_toseq_init(&timeout_seq, ctx->config.rx_timeout); + + /* non-blocking is handled separately here */ + nonblocking = (ctx->config.rx_timeout < 0); + + /* only one reader allowed, stop any further attempts here */ + if (test_and_set_bit(0, &ctx->in_lock)) + return -EBUSY; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + while (1) { + /* switch on error interrupt - the user is ready to listen */ + if (!testbits(ctx->ier_status, IER_STAT)) { + ctx->ier_status |= IER_STAT; + rt_16550_reg_out(rt_16550_io_mode_from_ctx(ctx), + ctx->base_addr, IER, + ctx->ier_status); + } + + if (ctx->status) { + if (testbits(ctx->status, RTSER_LSR_BREAK_IND)) + ret = -EPIPE; + else + ret = -EIO; + ctx->saved_errors = ctx->status & + (RTSER_LSR_OVERRUN_ERR | RTSER_LSR_PARITY_ERR | + RTSER_LSR_FRAMING_ERR | RTSER_SOFT_OVERRUN_ERR); + ctx->status = 0; + break; + } + + pending = ctx->in_npend; + + if (pending > 0) { + block = subblock = (pending <= nbyte) ? pending : nbyte; + in_pos = ctx->in_head; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + /* Do we have to wrap around the buffer end? */ + if (in_pos + subblock > IN_BUFFER_SIZE) { + /* Treat the block between head and buffer end + separately. */ + subblock = IN_BUFFER_SIZE - in_pos; + + if (user_info) { + if (rtdm_copy_to_user + (user_info, out_pos, + &ctx->in_buf[in_pos], + subblock) != 0) { + ret = -EFAULT; + goto break_unlocked; + } + } else + memcpy(out_pos, &ctx->in_buf[in_pos], + subblock); + + read += subblock; + out_pos += subblock; + + subblock = block - subblock; + in_pos = 0; + } + + if (user_info) { + if (rtdm_copy_to_user(user_info, out_pos, + &ctx->in_buf[in_pos], + subblock) != 0) { + ret = -EFAULT; + goto break_unlocked; + } + } else + memcpy(out_pos, &ctx->in_buf[in_pos], subblock); + + read += subblock; + out_pos += subblock; + nbyte -= block; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + ctx->in_head = + (ctx->in_head + block) & (IN_BUFFER_SIZE - 1); + if ((ctx->in_npend -= block) == 0) + ctx->ioc_events &= ~RTSER_EVENT_RXPEND; + + if (nbyte == 0) + break; /* All requested bytes read. */ + + continue; + } + + if (nonblocking) + /* ret was set to EAGAIN in case of a real + non-blocking call or contains the error + returned by rtdm_event_wait[_until] */ + break; + + ctx->in_nwait = nbyte; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + ret = rtdm_event_timedwait(&ctx->in_event, + ctx->config.rx_timeout, + &timeout_seq); + if (ret < 0) { + if (ret == -EIDRM) { + /* Device has been closed - + return immediately. */ + return -EBADF; + } + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + nonblocking = 1; + if (ctx->in_npend > 0) { + /* Final turn: collect pending bytes + before exit. */ + continue; + } + + ctx->in_nwait = 0; + break; + } + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + } + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + +break_unlocked: + /* Release the simple reader lock, */ + clear_bit(0, &ctx->in_lock); + + if ((read > 0) && ((ret == 0) || (ret == -EAGAIN) || + (ret == -ETIMEDOUT) || (ret == -EINTR))) + ret = read; + + return ret; +} + +ssize_t rt_16550_write(struct rtdm_dev_context * context, + rtdm_user_info_t * user_info, const void *buf, + size_t nbyte) +{ + struct rt_16550_context *ctx; + rtdm_lockctx_t lock_ctx; + size_t written = 0; + int free; + int block; + int subblock; + int out_pos; + char *in_pos = (char *)buf; + rtdm_toseq_t timeout_seq; + ssize_t ret; + + if (nbyte == 0) + return 0; + + if (user_info && !rtdm_read_user_ok(user_info, buf, nbyte)) + return -EFAULT; + + ctx = (struct rt_16550_context *)context->dev_private; + + rtdm_toseq_init(&timeout_seq, ctx->config.rx_timeout); + + /* Make write operation atomic. */ + ret = rtdm_mutex_timedlock(&ctx->out_lock, ctx->config.rx_timeout, + &timeout_seq); + if (ret) + return ret; + + while (nbyte > 0) { + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + free = OUT_BUFFER_SIZE - ctx->out_npend; + + if (free > 0) { + block = subblock = (nbyte <= free) ? nbyte : free; + out_pos = ctx->out_tail; + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + /* Do we have to wrap around the buffer end? */ + if (out_pos + subblock > OUT_BUFFER_SIZE) { + /* Treat the block between head and buffer + end separately. */ + subblock = OUT_BUFFER_SIZE - out_pos; + + if (user_info) { + if (rtdm_copy_from_user + (user_info, + &ctx->out_buf[out_pos], + in_pos, subblock) != 0) { + ret = -EFAULT; + break; + } + } else + memcpy(&ctx->out_buf[out_pos], in_pos, + subblock); + + written += subblock; + in_pos += subblock; + + subblock = block - subblock; + out_pos = 0; + } + + if (user_info) { + if (rtdm_copy_from_user + (user_info, &ctx->out_buf[out_pos], + in_pos, subblock) != 0) { + ret = -EFAULT; + break; + } + } else + memcpy(&ctx->out_buf[out_pos], in_pos, block); + + written += subblock; + in_pos += subblock; + nbyte -= block; + + rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); + + ctx->out_tail = + (ctx->out_tail + block) & (OUT_BUFFER_SIZE - 1); + ctx->out_npend += block; + + /* unmask tx interrupt */ + ctx->ier_status |= IER_TX; + rt_16550_reg_out(rt_16550_io_mode_from_ctx(ctx), + ctx->base_addr, IER, + ctx->ier_status); + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + continue; + } + + rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); + + ret = + rtdm_event_timedwait(&ctx->out_event, + ctx->config.tx_timeout, + &timeout_seq); + if (ret < 0) { + if (ret == -EIDRM) { + /* Device has been closed - + return immediately. */ + return -EBADF; + } + if (ret == -EWOULDBLOCK) { + /* Fix error code for non-blocking mode. */ + ret = -EAGAIN; + } + break; + } + } + + rtdm_mutex_unlock(&ctx->out_lock); + + if ((written > 0) && ((ret == 0) || (ret == -EAGAIN) || + (ret == -ETIMEDOUT) || (ret == -EINTR))) + ret = written; + + return ret; +} + +static const struct rtdm_device __initdata device_tmpl = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + + .device_flags = RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE, + .context_size = sizeof(struct rt_16550_context), + .device_name = "", + + .open_nrt = rt_16550_open, + + .ops = { + .close_nrt = rt_16550_close, + + .ioctl_rt = rt_16550_ioctl, + .ioctl_nrt = rt_16550_ioctl, + + .read_rt = rt_16550_read, + + .write_rt = rt_16550_write, + }, + + .device_class = RTDM_CLASS_SERIAL, + .device_sub_class = RTDM_SUBCLASS_16550A, + .profile_version = RTSER_PROFILE_VER, + .driver_name = RT_16550_DRIVER_NAME, + .driver_version = RTDM_DRIVER_VER(1, 5, 2), + .peripheral_name = "UART 16550A", + .provider_name = "Jan Kiszka", +}; + +void rt_16550_exit(void); + +int __init rt_16550_init(void) +{ + struct rtdm_device *dev; + unsigned long base; + int mode; + int err; + int i; + + rt_16550_pnp_init(); + rt_16550_pci_init(); + + for (i = 0; i < MAX_DEVICES; i++) { + if (!rt_16550_addr_param(i)) + continue; + + err = -EINVAL; + if (!irq[i] || !rt_16550_addr_param_valid(i)) + goto cleanup_out; + + dev = kmalloc(sizeof(struct rtdm_device), GFP_KERNEL); + err = -ENOMEM; + if (!dev) + goto cleanup_out; + + memcpy(dev, &device_tmpl, sizeof(struct rtdm_device)); + snprintf(dev->device_name, RTDM_MAX_DEVNAME_LEN, "rtser%d", + start_index + i); + dev->device_id = i; + + dev->proc_name = dev->device_name; + + err = rt_16550_init_io(i, dev->device_name); + if (err) + goto kfree_out; + + if (baud_base[i] == 0) + baud_base[i] = DEFAULT_BAUD_BASE; + + if (tx_fifo[i] == 0) + tx_fifo[i] = DEFAULT_TX_FIFO; + + /* Mask all UART interrupts and clear pending ones. */ + base = rt_16550_base_addr(i); + mode = rt_16550_io_mode(i); + rt_16550_reg_out(mode, base, IER, 0); + rt_16550_reg_in(mode, base, IIR); + rt_16550_reg_in(mode, base, LSR); + rt_16550_reg_in(mode, base, RHR); + rt_16550_reg_in(mode, base, MSR); + + err = rtdm_dev_register(dev); + + if (err) + goto release_io_out; + + device[i] = dev; + } + + return 0; + + release_io_out: + rt_16550_release_io(i); + + kfree_out: + kfree(dev); + + cleanup_out: + rt_16550_exit(); + + return err; +} + +void rt_16550_exit(void) +{ + int i; + + for (i = 0; i < MAX_DEVICES; i++) + if (device[i]) { + rtdm_dev_unregister(device[i], 1000); + rt_16550_release_io(i); + kfree(device[i]); + } + + rt_16550_pci_cleanup(); + rt_16550_pnp_cleanup(); +} + +module_init(rt_16550_init); +module_exit(rt_16550_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_io.h relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_io.h --- orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_io.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_io.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2007 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Manages the I/O access method of the driver. */ + +typedef enum { MODE_PIO, MODE_MMIO } io_mode_t; + +#if defined(CONFIG_XENO_DRIVERS_16550A_PIO) || \ + defined(CONFIG_XENO_DRIVERS_16550A_ANY) +static unsigned long io[MAX_DEVICES]; +compat_module_param_array(io, ulong, MAX_DEVICES, 0400); +MODULE_PARM_DESC(io, "I/O port addresses of the serial devices"); +#endif /* CONFIG_XENO_DRIVERS_16550A_PIO || CONFIG_XENO_DRIVERS_16550A_ANY */ + +#if defined(CONFIG_XENO_DRIVERS_16550A_MMIO) || \ + defined(CONFIG_XENO_DRIVERS_16550A_ANY) +static unsigned long mem[MAX_DEVICES]; +static void *mapped_io[MAX_DEVICES]; +compat_module_param_array(mem, ulong, MAX_DEVICES, 0400); +MODULE_PARM_DESC(mem, "I/O memory addresses of the serial devices"); +#endif /* CONFIG_XENO_DRIVERS_16550A_MMIO || CONFIG_XENO_DRIVERS_16550A_ANY */ + +#ifdef CONFIG_XENO_DRIVERS_16550A_PIO + +#define RT_16550_IO_INLINE inline + +extern void *mapped_io[]; /* dummy */ + +static inline unsigned long rt_16550_addr_param(int dev_id) +{ + return io[dev_id]; +} + +static inline int rt_16550_addr_param_valid(int dev_id) +{ + return 1; +} + +static inline unsigned long rt_16550_base_addr(int dev_id) +{ + return io[dev_id]; +} + +static inline io_mode_t rt_16550_io_mode(int dev_id) +{ + return MODE_PIO; +} + +static inline io_mode_t +rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx) +{ + return MODE_PIO; +} + +static inline void +rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx) +{ + ctx->base_addr = io[dev_id]; +} + +#elif defined(CONFIG_XENO_DRIVERS_16550A_MMIO) + +#define RT_16550_IO_INLINE inline + +extern unsigned long io[]; /* dummy */ + +static inline unsigned long rt_16550_addr_param(int dev_id) +{ + return mem[dev_id]; +} + +static inline int rt_16550_addr_param_valid(int dev_id) +{ + return 1; +} + +static inline unsigned long rt_16550_base_addr(int dev_id) +{ + return (unsigned long)mapped_io[dev_id]; +} + +static inline io_mode_t rt_16550_io_mode(int dev_id) +{ + return MODE_MMIO; +} + +static inline io_mode_t +rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx) +{ + return MODE_MMIO; +} + +static inline void +rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx) +{ + ctx->base_addr = (unsigned long)mapped_io[dev_id]; +} + +#elif defined(CONFIG_XENO_DRIVERS_16550A_ANY) + +#define RT_16550_IO_INLINE /* uninline */ + +static inline unsigned long rt_16550_addr_param(int dev_id) +{ + return (io[dev_id]) ? io[dev_id] : mem[dev_id]; +} + +static inline int rt_16550_addr_param_valid(int dev_id) +{ + return !(io[dev_id] && mem[dev_id]); +} + +static inline unsigned long rt_16550_base_addr(int dev_id) +{ + return (io[dev_id]) ? io[dev_id] : (unsigned long)mapped_io[dev_id]; +} + +static inline io_mode_t rt_16550_io_mode(int dev_id) +{ + return (io[dev_id]) ? MODE_PIO : MODE_MMIO; +} + +static inline io_mode_t +rt_16550_io_mode_from_ctx(struct rt_16550_context *ctx) +{ + return ctx->io_mode; +} + +static inline void +rt_16550_init_io_ctx(int dev_id, struct rt_16550_context *ctx) +{ + if (io[dev_id]) { + ctx->base_addr = io[dev_id]; + ctx->io_mode = MODE_PIO; + } else { + ctx->base_addr = (unsigned long)mapped_io[dev_id]; + ctx->io_mode = MODE_MMIO; + } +} + +#else +# error Unsupported I/O access method +#endif + +static RT_16550_IO_INLINE u8 +rt_16550_reg_in(io_mode_t io_mode, unsigned long base, int off) +{ + switch (io_mode) { + case MODE_PIO: + return inb(base + off); + default: /* MODE_MMIO */ + return readb((void *)base + off); + } +} + +static RT_16550_IO_INLINE void +rt_16550_reg_out(io_mode_t io_mode, unsigned long base, int off, u8 val) +{ + switch (io_mode) { + case MODE_PIO: + outb(val, base + off); + break; + case MODE_MMIO: + writeb(val, (void *)base + off); + break; + } +} + +static int rt_16550_init_io(int dev_id, char* name) +{ + switch (rt_16550_io_mode(dev_id)) { + case MODE_PIO: + if (!request_region(rt_16550_addr_param(dev_id), 8, name)) + return -EBUSY; + break; + case MODE_MMIO: + mapped_io[dev_id] = ioremap(rt_16550_addr_param(dev_id), 8); + if (!mapped_io[dev_id]) + return -EBUSY; + break; + } + return 0; +} + +static void rt_16550_release_io(int dev_id) +{ + switch (rt_16550_io_mode(dev_id)) { + case MODE_PIO: + release_region(io[dev_id], 8); + break; + case MODE_MMIO: + iounmap(mapped_io[dev_id]); + break; + } +} diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_pci.h relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_pci.h --- orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_pci.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_pci.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2006-2007 Jan Kiszka . + * Copyright (C) 2011 Stefan Kisdaroczi . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if defined(CONFIG_XENO_DRIVERS_16550A_PCI) + +#include + +struct rt_16550_pci_board { + char *name; + resource_size_t resource_base_addr; + unsigned int nports; + unsigned int port_ofs; + unsigned long irqtype; + unsigned int baud_base; + int tx_fifo; +}; + +#if defined(CONFIG_XENO_DRIVERS_16550A_PCI_MOXA) + +#define PCI_DEVICE_ID_CP112UL 0x1120 +#define PCI_DEVICE_ID_CP114UL 0x1143 +#define PCI_DEVICE_ID_CP138U 0x1380 + +static const struct rt_16550_pci_board rt_16550_moxa_c104 = { + .name = "Moxa C104H/PCI", + .resource_base_addr = 2, + .nports = 4, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_c168 = { + .name = "Moxa C168H/PCI", + .resource_base_addr = 2, + .nports = 8, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp114 = { + .name = "Moxa CP-114", + .resource_base_addr = 2, + .nports = 4, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp132 = { + .name = "Moxa CP-132", + .resource_base_addr = 2, + .nports = 2, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp102u = { + .name = "Moxa CP-102U", + .resource_base_addr = 2, + .nports = 2, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp102ul = { + .name = "Moxa CP-102UL", + .resource_base_addr = 2, + .nports = 2, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp104u = { + .name = "Moxa CP-104U", + .resource_base_addr = 2, + .nports = 4, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp112ul = { + .name = "Moxa CP-112UL", + .resource_base_addr = 2, + .nports = 2, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp114ul = { + .name = "Moxa CP-114UL", + .resource_base_addr = 2, + .nports = 4, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp118u = { + .name = "Moxa CP-118U", + .resource_base_addr = 2, + .nports = 8, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp132u = { + .name = "Moxa CP-132U", + .resource_base_addr = 2, + .nports = 2, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp134u = { + .name = "Moxa CP-134U", + .resource_base_addr = 2, + .nports = 4, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp138u = { + .name = "Moxa CP-138U", + .resource_base_addr = 2, + .nports = 8, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; + +static const struct rt_16550_pci_board rt_16550_moxa_cp168u = { + .name = "Moxa CP-168U", + .resource_base_addr = 2, + .nports = 8, + .port_ofs = 8, + .baud_base = 921600, + .tx_fifo = 16, + .irqtype = RTDM_IRQTYPE_SHARED, +}; +#endif + +DEFINE_PCI_DEVICE_TABLE( rt_16550_pci_table ) = { +#if defined(CONFIG_XENO_DRIVERS_16550A_PCI_MOXA) + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), + .driver_data = (unsigned long)&rt_16550_moxa_c104}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), + .driver_data = (unsigned long)&rt_16550_moxa_c168}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), + .driver_data = (unsigned long)&rt_16550_moxa_cp114}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), + .driver_data = (unsigned long)&rt_16550_moxa_cp132}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), + .driver_data = (unsigned long)&rt_16550_moxa_cp102u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL), + .driver_data = (unsigned long)&rt_16550_moxa_cp102ul}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), + .driver_data = (unsigned long)&rt_16550_moxa_cp104u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), + .driver_data = (unsigned long)&rt_16550_moxa_cp112ul}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), + .driver_data = (unsigned long)&rt_16550_moxa_cp114ul}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), + .driver_data = (unsigned long)&rt_16550_moxa_cp118u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), + .driver_data = (unsigned long)&rt_16550_moxa_cp132u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), + .driver_data = (unsigned long)&rt_16550_moxa_cp134u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), + .driver_data = (unsigned long)&rt_16550_moxa_cp138u}, + {PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), + .driver_data = (unsigned long)&rt_16550_moxa_cp168u}, +#endif + { } +}; + +static int __devinit rt_16550_pci_probe( struct pci_dev *pdev, + const struct pci_device_id *ent ) +{ + struct rt_16550_pci_board *board; + int err; + int i; + int port = 0; + int base_addr; + int max_devices = 0; + + if (!ent->driver_data) + return -ENODEV; + + board = (struct rt_16550_pci_board *)ent->driver_data; + + for (i = 0; i < MAX_DEVICES; i++) + if (!rt_16550_addr_param(i)) + max_devices++; + + if (board->nports > max_devices) + return -ENODEV; + + if ((err = pci_enable_device(pdev))) + return err; + + base_addr = pci_resource_start(pdev, board->resource_base_addr); + + for (i = 0; i < MAX_DEVICES; i++) { + if ((port < board->nports) && (!rt_16550_addr_param(i))) { + io[i] = base_addr + port * board->port_ofs; + irq[i] = pdev->irq; + irqtype[i] = board->irqtype; + baud_base[i] = board->baud_base; + tx_fifo[i] = board->tx_fifo; + port++; + } + } + + return 0; +} + +static void __devexit rt_16550_pci_remove( struct pci_dev *pdev ) { + pci_disable_device( pdev ); +}; + +static struct pci_driver rt_16550_pci_driver = { + .name = RT_16550_DRIVER_NAME, + .id_table = rt_16550_pci_table, + .probe = rt_16550_pci_probe, + .remove = __devexit_p(rt_16550_pci_remove) +}; + +static int pci_registered; + +static inline void rt_16550_pci_init(void) +{ + if (pci_register_driver(&rt_16550_pci_driver) == 0) + pci_registered = 1; +} + +static inline void rt_16550_pci_cleanup(void) +{ + if (pci_registered) + pci_unregister_driver(&rt_16550_pci_driver); +} + +#else /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */ + +#define rt_16550_pci_init() do { } while (0) +#define rt_16550_pci_cleanup() do { } while (0) + +#endif /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_pnp.h relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_pnp.h --- orig/linux-2.6.35.9//drivers/xenomai/serial/16550A_pnp.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/16550A_pnp.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2006-2007 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && defined(CONFIG_PNP) && \ + (defined(CONFIG_XENO_DRIVERS_16550A_PIO) || \ + defined(CONFIG_XENO_DRIVERS_16550A_ANY)) + +#include + +#define UNKNOWN_DEV 0x3000 + +/* Bluntly cloned from drivers/serial/8250_pnp.c */ +static const struct pnp_device_id rt_16550_pnp_tbl[] = { + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { "AAC000F", 0 }, + /* Anchor Datacomm BV */ + /* SXPro 144 External Data Fax Modem Plug & Play */ + { "ADC0001", 0 }, + /* SXPro 288 External Data Fax Modem Plug & Play */ + { "ADC0002", 0 }, + /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */ + { "AEI0250", 0 }, + /* Actiontec ISA PNP 56K X2 Fax Modem */ + { "AEI1240", 0 }, + /* Rockwell 56K ACF II Fax+Data+Voice Modem */ + { "AKY1021", 0 /*SPCI_FL_NO_SHIRQ*/ }, + /* AZT3005 PnP SOUND DEVICE */ + { "AZT4001", 0 }, + /* Best Data Products Inc. Smart One 336F PnP Modem */ + { "BDP3336", 0 }, + /* Boca Research */ + /* Boca Complete Ofc Communicator 14.4 Data-FAX */ + { "BRI0A49", 0 }, + /* Boca Research 33,600 ACF Modem */ + { "BRI1400", 0 }, + /* Boca 33.6 Kbps Internal FD34FSVD */ + { "BRI3400", 0 }, + /* Boca 33.6 Kbps Internal FD34FSVD */ + { "BRI0A49", 0 }, + /* Best Data Products Inc. Smart One 336F PnP Modem */ + { "BDP3336", 0 }, + /* Computer Peripherals Inc */ + /* EuroViVa CommCenter-33.6 SP PnP */ + { "CPI4050", 0 }, + /* Creative Labs */ + /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */ + { "CTL3001", 0 }, + /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ + { "CTL3011", 0 }, + /* Creative */ + /* Creative Modem Blaster Flash56 DI5601-1 */ + { "DMB1032", 0 }, + /* Creative Modem Blaster V.90 DI5660 */ + { "DMB2001", 0 }, + /* E-Tech */ + /* E-Tech CyberBULLET PC56RVP */ + { "ETT0002", 0 }, + /* FUJITSU */ + /* Fujitsu 33600 PnP-I2 R Plug & Play */ + { "FUJ0202", 0 }, + /* Fujitsu FMV-FX431 Plug & Play */ + { "FUJ0205", 0 }, + /* Fujitsu 33600 PnP-I4 R Plug & Play */ + { "FUJ0206", 0 }, + /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */ + { "FUJ0209", 0 }, + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { "GVC000F", 0 }, + /* Hayes */ + /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ + { "HAY0001", 0 }, + /* Hayes Optima 336 V.34 + FAX + Voice PnP */ + { "HAY000C", 0 }, + /* Hayes Optima 336B V.34 + FAX + Voice PnP */ + { "HAY000D", 0 }, + /* Hayes Accura 56K Ext Fax Modem PnP */ + { "HAY5670", 0 }, + /* Hayes Accura 56K Ext Fax Modem PnP */ + { "HAY5674", 0 }, + /* Hayes Accura 56K Fax Modem PnP */ + { "HAY5675", 0 }, + /* Hayes 288, V.34 + FAX */ + { "HAYF000", 0 }, + /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */ + { "HAYF001", 0 }, + /* IBM */ + /* IBM Thinkpad 701 Internal Modem Voice */ + { "IBM0033", 0 }, + /* Intertex */ + /* Intertex 28k8 33k6 Voice EXT PnP */ + { "IXDC801", 0 }, + /* Intertex 33k6 56k Voice EXT PnP */ + { "IXDC901", 0 }, + /* Intertex 28k8 33k6 Voice SP EXT PnP */ + { "IXDD801", 0 }, + /* Intertex 33k6 56k Voice SP EXT PnP */ + { "IXDD901", 0 }, + /* Intertex 28k8 33k6 Voice SP INT PnP */ + { "IXDF401", 0 }, + /* Intertex 28k8 33k6 Voice SP EXT PnP */ + { "IXDF801", 0 }, + /* Intertex 33k6 56k Voice SP EXT PnP */ + { "IXDF901", 0 }, + /* Kortex International */ + /* KORTEX 28800 Externe PnP */ + { "KOR4522", 0 }, + /* KXPro 33.6 Vocal ASVD PnP */ + { "KORF661", 0 }, + /* Lasat */ + /* LASAT Internet 33600 PnP */ + { "LAS4040", 0 }, + /* Lasat Safire 560 PnP */ + { "LAS4540", 0 }, + /* Lasat Safire 336 PnP */ + { "LAS5440", 0 }, + /* Microcom, Inc. */ + /* Microcom TravelPorte FAST V.34 Plug & Play */ + { "MNP0281", 0 }, + /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */ + { "MNP0336", 0 }, + /* Microcom DeskPorte FAST EP 28.8 Plug & Play */ + { "MNP0339", 0 }, + /* Microcom DeskPorte 28.8P Plug & Play */ + { "MNP0342", 0 }, + /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ + { "MNP0500", 0 }, + /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ + { "MNP0501", 0 }, + /* Microcom DeskPorte 28.8S Internal Plug & Play */ + { "MNP0502", 0 }, + /* Motorola */ + /* Motorola BitSURFR Plug & Play */ + { "MOT1105", 0 }, + /* Motorola TA210 Plug & Play */ + { "MOT1111", 0 }, + /* Motorola HMTA 200 (ISDN) Plug & Play */ + { "MOT1114", 0 }, + /* Motorola BitSURFR Plug & Play */ + { "MOT1115", 0 }, + /* Motorola Lifestyle 28.8 Internal */ + { "MOT1190", 0 }, + /* Motorola V.3400 Plug & Play */ + { "MOT1501", 0 }, + /* Motorola Lifestyle 28.8 V.34 Plug & Play */ + { "MOT1502", 0 }, + /* Motorola Power 28.8 V.34 Plug & Play */ + { "MOT1505", 0 }, + /* Motorola ModemSURFR External 28.8 Plug & Play */ + { "MOT1509", 0 }, + /* Motorola Premier 33.6 Desktop Plug & Play */ + { "MOT150A", 0 }, + /* Motorola VoiceSURFR 56K External PnP */ + { "MOT150F", 0 }, + /* Motorola ModemSURFR 56K External PnP */ + { "MOT1510", 0 }, + /* Motorola ModemSURFR 56K Internal PnP */ + { "MOT1550", 0 }, + /* Motorola ModemSURFR Internal 28.8 Plug & Play */ + { "MOT1560", 0 }, + /* Motorola Premier 33.6 Internal Plug & Play */ + { "MOT1580", 0 }, + /* Motorola OnlineSURFR 28.8 Internal Plug & Play */ + { "MOT15B0", 0 }, + /* Motorola VoiceSURFR 56K Internal PnP */ + { "MOT15F0", 0 }, + /* Com 1 */ + /* Deskline K56 Phone System PnP */ + { "MVX00A1", 0 }, + /* PC Rider K56 Phone System PnP */ + { "MVX00F2", 0 }, + /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */ + { "nEC8241", 0 }, + /* Pace 56 Voice Internal Plug & Play Modem */ + { "PMC2430", 0 }, + /* Generic */ + /* Generic standard PC COM port */ + { "PNP0500", 0 }, + /* Generic 16550A-compatible COM port */ + { "PNP0501", 0 }, + /* Compaq 14400 Modem */ + { "PNPC000", 0 }, + /* Compaq 2400/9600 Modem */ + { "PNPC001", 0 }, + /* Dial-Up Networking Serial Cable between 2 PCs */ + { "PNPC031", 0 }, + /* Dial-Up Networking Parallel Cable between 2 PCs */ + { "PNPC032", 0 }, + /* Standard 9600 bps Modem */ + { "PNPC100", 0 }, + /* Standard 14400 bps Modem */ + { "PNPC101", 0 }, + /* Standard 28800 bps Modem*/ + { "PNPC102", 0 }, + /* Standard Modem*/ + { "PNPC103", 0 }, + /* Standard 9600 bps Modem*/ + { "PNPC104", 0 }, + /* Standard 14400 bps Modem*/ + { "PNPC105", 0 }, + /* Standard 28800 bps Modem*/ + { "PNPC106", 0 }, + /* Standard Modem */ + { "PNPC107", 0 }, + /* Standard 9600 bps Modem */ + { "PNPC108", 0 }, + /* Standard 14400 bps Modem */ + { "PNPC109", 0 }, + /* Standard 28800 bps Modem */ + { "PNPC10A", 0 }, + /* Standard Modem */ + { "PNPC10B", 0 }, + /* Standard 9600 bps Modem */ + { "PNPC10C", 0 }, + /* Standard 14400 bps Modem */ + { "PNPC10D", 0 }, + /* Standard 28800 bps Modem */ + { "PNPC10E", 0 }, + /* Standard Modem */ + { "PNPC10F", 0 }, + /* Standard PCMCIA Card Modem */ + { "PNP2000", 0 }, + /* Rockwell */ + /* Modular Technology */ + /* Rockwell 33.6 DPF Internal PnP */ + /* Modular Technology 33.6 Internal PnP */ + { "ROK0030", 0 }, + /* Kortex International */ + /* KORTEX 14400 Externe PnP */ + { "ROK0100", 0 }, + /* Rockwell 28.8 */ + { "ROK4120", 0 }, + /* Viking Components, Inc */ + /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */ + { "ROK4920", 0 }, + /* Rockwell */ + /* British Telecom */ + /* Modular Technology */ + /* Rockwell 33.6 DPF External PnP */ + /* BT Prologue 33.6 External PnP */ + /* Modular Technology 33.6 External PnP */ + { "RSS00A0", 0 }, + /* Viking 56K FAX INT */ + { "RSS0262", 0 }, + /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */ + { "RSS0250", 0 }, + /* SupraExpress 28.8 Data/Fax PnP modem */ + { "SUP1310", 0 }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { "SUP1421", 0 }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { "SUP1590", 0 }, + /* SupraExpress 336i Sp ASVD */ + { "SUP1620", 0 }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { "SUP1760", 0 }, + /* SupraExpress 56i Sp Intl */ + { "SUP2171", 0 }, + /* Phoebe Micro */ + /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */ + { "TEX0011", 0 }, + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { "UAC000F", 0 }, + /* 3Com Corp. */ + /* Gateway Telepath IIvi 33.6 */ + { "USR0000", 0 }, + /* U.S. Robotics Sporster 33.6K Fax INT PnP */ + { "USR0002", 0 }, + /* Sportster Vi 14.4 PnP FAX Voicemail */ + { "USR0004", 0 }, + /* U.S. Robotics 33.6K Voice INT PnP */ + { "USR0006", 0 }, + /* U.S. Robotics 33.6K Voice EXT PnP */ + { "USR0007", 0 }, + /* U.S. Robotics Courier V.Everything INT PnP */ + { "USR0009", 0 }, + /* U.S. Robotics 33.6K Voice INT PnP */ + { "USR2002", 0 }, + /* U.S. Robotics 56K Voice INT PnP */ + { "USR2070", 0 }, + /* U.S. Robotics 56K Voice EXT PnP */ + { "USR2080", 0 }, + /* U.S. Robotics 56K FAX INT */ + { "USR3031", 0 }, + /* U.S. Robotics 56K FAX INT */ + { "USR3050", 0 }, + /* U.S. Robotics 56K Voice INT PnP */ + { "USR3070", 0 }, + /* U.S. Robotics 56K Voice EXT PnP */ + { "USR3080", 0 }, + /* U.S. Robotics 56K Voice INT PnP */ + { "USR3090", 0 }, + /* U.S. Robotics 56K Message */ + { "USR9100", 0 }, + /* U.S. Robotics 56K FAX EXT PnP*/ + { "USR9160", 0 }, + /* U.S. Robotics 56K FAX INT PnP*/ + { "USR9170", 0 }, + /* U.S. Robotics 56K Voice EXT PnP*/ + { "USR9180", 0 }, + /* U.S. Robotics 56K Voice INT PnP*/ + { "USR9190", 0 }, + /* Wacom tablets */ + { "WACF004", 0 }, + { "WACF005", 0 }, + { "WACF006", 0 }, + /* Compaq touchscreen */ + { "FPI2002", 0 }, + /* Fujitsu Stylistic touchscreens */ + { "FUJ02B2", 0 }, + { "FUJ02B3", 0 }, + /* Fujitsu Stylistic LT touchscreens */ + { "FUJ02B4", 0 }, + /* Passive Fujitsu Stylistic touchscreens */ + { "FUJ02B6", 0 }, + { "FUJ02B7", 0 }, + { "FUJ02B8", 0 }, + { "FUJ02B9", 0 }, + { "FUJ02BC", 0 }, + /* Rockwell's (PORALiNK) 33600 INT PNP */ + { "WCI0003", 0 }, + /* Unkown PnP modems */ + { "PNPCXXX", UNKNOWN_DEV }, + /* More unkown PnP modems */ + { "PNPDXXX", UNKNOWN_DEV }, + { "", 0 } +}; + +static int rt_16550_pnp_probe(struct pnp_dev *dev, + const struct pnp_device_id *dev_id) +{ + int i; + + for (i = 0; i < MAX_DEVICES; i++) + if (pnp_port_valid(dev, 0) && + pnp_port_start(dev, 0) == io[i]) { + if (!irq[i]) + irq[i] = pnp_irq(dev, 0); + return 0; + } + + return -ENODEV; +} + +static struct pnp_driver rt_16550_pnp_driver = { + .name = RT_16550_DRIVER_NAME, + .id_table = rt_16550_pnp_tbl, + .probe = rt_16550_pnp_probe, +}; + +static int pnp_registered; + +static inline void rt_16550_pnp_init(void) +{ + if (pnp_register_driver(&rt_16550_pnp_driver) == 0) + pnp_registered = 1; +} + +static inline void rt_16550_pnp_cleanup(void) +{ + if (pnp_registered) + pnp_unregister_driver(&rt_16550_pnp_driver); +} + +#else /* Linux < 2.6.0 || !CONFIG_PNP || !(..._16550A_IO || ..._16550A_ANY) */ + +#define rt_16550_pnp_init() do { } while (0) +#define rt_16550_pnp_cleanup() do { } while (0) + +#endif /* Linux < 2.6.0 || !CONFIG_PNP || !(..._16550A_IO || ..._16550A_ANY) */ diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/Kconfig relase/linux-2.6.35.9//drivers/xenomai/serial/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/serial/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,66 @@ +menu "Serial drivers" + +config XENO_DRIVERS_16550A + depends on XENO_SKIN_RTDM + tristate "16550A UART driver" + help + Real-time UART driver for 16550A compatible controllers. See + doc/txt/16550A-driver.txt for more details. + +choice + prompt "Hardware access mode" + depends on XENO_DRIVERS_16550A + default XENO_DRIVERS_16550A_PIO + +config XENO_DRIVERS_16550A_PIO + bool "Port-based I/O" + help + Hardware access only via I/O ports. Use module parameter + "io=[,[,...]]" to specify the base port of a device. + +config XENO_DRIVERS_16550A_MMIO + bool "Memory-mapped I/O" + help + Hardware access only via memory mapping. Use module paramter + "mem=[,[,...]]" to specify the physical base address of + a device. + +config XENO_DRIVERS_16550A_ANY + bool "Any access mode" + help + Decide at module load-time (or via kernel parameter) which access + mode to use for which device. This mode is useful when devices of + both types can be present in a system, also at the same time. + + Both "io" and "mem" module parameters are available, but always only + one of them can be applied on a particular device. Use, e.g., + "io=0x3f8,0 mem=0,0xe0000000" to address device 1 via IO base port + 0x3f8 and device 2 via physical base address 0xe0000000. + +endchoice + +config XENO_DRIVERS_16550A_PCI + depends on PCI && (XENO_DRIVERS_16550A_PIO || XENO_DRIVERS_16550A_ANY) + bool "PCI board support" + default n + help + + This option activates support for PCI serial boards. + +config XENO_DRIVERS_16550A_PCI_MOXA + depends on XENO_DRIVERS_16550A_PCI + bool "Moxa PCI boards" + default n + help + + This option activates support for the following Moxa boards: + PCI Serial Boards: + C104H/PCI, C168H/PCI + CP-114, CP-132 + Universal PCI Serial Boards: + CP-102U, CP-102UL, CP-104U + CP-112UL, CP-114UL, CP-118U + CP-132U, CP-134U, CP-138U + CP-168U + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/serial/Makefile relase/linux-2.6.35.9//drivers/xenomai/serial/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/serial/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/serial/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,30 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_16550A) += xeno_16550A.o + +xeno_16550A-y := 16550A.o + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_16550A) := xeno_16550A.o + +xeno_16550A-objs := 16550A.o + +export-objs := $(xeno_16550A-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +xeno_16550A.o: $(xeno_16550A-objs) + $(LD) -r -o $@ $(xeno_16550A-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/irqbench.c relase/linux-2.6.35.9//drivers/xenomai/testing/irqbench.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/irqbench.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/irqbench.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,549 @@ +/* + * Copyright (C) 2006 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include +#endif /* Linux >= 2.6.0 */ + +#include +#include +#include + +/* --- Serial port --- */ + +#define MSR_DCTS 0x01 +#define MSR_DDSR 0x02 +#define MSR_DDCD 0x08 + +#define MCR_RTS 0x02 +#define MCR_OUT2 0x08 + +#define IER_MODEM 0x08 + +#define RHR(ctx) (ctx->port_ioaddr + 0) /* Receive Holding Buffer */ +#define IER(ctx) (ctx->port_ioaddr + 1) /* Interrupt Enable Register*/ +#define IIR(ctx) (ctx->port_ioaddr + 2) /* Interrupt Id Register */ +#define LCR(ctx) (ctx->port_ioaddr + 3) /* Line Control Register */ +#define MCR(ctx) (ctx->port_ioaddr + 4) /* Modem Control Register */ +#define LSR(ctx) (ctx->port_ioaddr + 5) /* Line Status Register */ +#define MSR(ctx) (ctx->port_ioaddr + 6) /* Modem Status Register */ + +/* --- Parallel port --- */ + +#define STAT_BUSY 0x80 + +#define CTRL_INIT 0x04 +#define CTRL_STROBE 0x10 + +#define DATA(ctx) (ctx->port_ioaddr + 0) /* Data register */ +#define STAT(ctx) (ctx->port_ioaddr + 1) /* Status register */ +#define CTRL(ctx) (ctx->port_ioaddr + 2) /* Control register */ + +struct rt_irqbench_context { + int mode; + int port_type; + unsigned long port_ioaddr; + unsigned int port_irq; + unsigned int toggle; + struct rttst_irqbench_stats stats; + rtdm_irq_t irq_handle; + rtdm_event_t irq_event; + rtdm_task_t irq_task; + rthal_pipeline_stage_t domain; + struct semaphore nrt_mutex; +}; + +static unsigned int start_index; + +module_param(start_index, uint, 0400); +MODULE_PARM_DESC(start_index, "First device instance number to be used"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jan.kiszka@web.de"); + +static inline int rt_irqbench_check_irq(struct rt_irqbench_context *ctx) +{ + int status; + + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + status = inb(MSR(ctx)); + /* Any change on DSR or DCD triggers trace freeze */ + if (status & (MSR_DDSR | MSR_DDCD)) + xntrace_user_freeze(0, 0); + if (!(status & MSR_DCTS)) + return 0; + break; + + case RTTST_IRQBENCH_PARPORT: + /* A set BUSY line on /ACK IRW triggers trace freeze */ + if (!(inb(STAT(ctx)) & STAT_BUSY)) { + xntrace_user_freeze(0, 0); + return 0; + } + break; + } + ctx->stats.irqs_received++; + return 1; +} + +static inline void rt_irqbench_hwreply(struct rt_irqbench_context *ctx) +{ + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + /* Toggle RTS */ + ctx->toggle ^= MCR_RTS; + outb(ctx->toggle, MCR(ctx)); + break; + + case RTTST_IRQBENCH_PARPORT: + ctx->toggle ^= 0x08; + outb(ctx->toggle, DATA(ctx)); + break; + } + xntrace_special(0xBE, 0); + ctx->stats.irqs_acknowledged++; +} + +static void rt_irqbench_task(void *arg) +{ + struct rt_irqbench_context *ctx = arg; + + while (1) { + if (rtdm_event_wait(&ctx->irq_event) < 0) + return; + rt_irqbench_hwreply(ctx); + } +} + +static int rt_irqbench_task_irq(rtdm_irq_t *irq_handle) +{ + struct rt_irqbench_context *ctx; + + ctx = rtdm_irq_get_arg(irq_handle, struct rt_irqbench_context); + + if (rt_irqbench_check_irq(ctx)) + rtdm_event_signal(&ctx->irq_event); + + return RTDM_IRQ_HANDLED; +} + +static int rt_irqbench_direct_irq(rtdm_irq_t *irq_handle) +{ + struct rt_irqbench_context *ctx; + + ctx = rtdm_irq_get_arg(irq_handle, struct rt_irqbench_context); + + if (rt_irqbench_check_irq(ctx)) + rt_irqbench_hwreply(ctx); + + return RTDM_IRQ_HANDLED; +} + +static void rt_irqbench_domain_irq(unsigned irq, void *arg) +{ + struct rt_irqbench_context *ctx = arg; + + if (rt_irqbench_check_irq(ctx)) + rt_irqbench_hwreply(ctx); + + rthal_irq_end(ctx->port_irq); +} + +static inline void do_rt_irqbench_domain_entry(void) +{ +} + +static RTHAL_DECLARE_DOMAIN(rt_irqbench_domain_entry); + +static int rt_irqbench_stop(struct rt_irqbench_context *ctx) +{ + if (ctx->mode < 0) + return -EINVAL; + + /* Disable hardware */ + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + outb(0, IER(ctx)); + release_region(ctx->port_ioaddr, 8); + break; + + case RTTST_IRQBENCH_PARPORT: + outb(0, CTRL(ctx)); + release_region(ctx->port_ioaddr, 3); + break; + } + + if (ctx->mode == RTTST_IRQBENCH_HARD_IRQ) { + rthal_virtualize_irq(&ctx->domain, ctx->port_irq, NULL, NULL, + NULL, IPIPE_PASS_MASK); + rthal_unregister_domain(&ctx->domain); + } else + rtdm_irq_free(&ctx->irq_handle); + + if (ctx->mode == RTTST_IRQBENCH_KERNEL_TASK) + rtdm_task_destroy(&ctx->irq_task); + + ctx->mode = -1; + + return 0; +} + +static int rt_irqbench_open(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int oflags) +{ + struct rt_irqbench_context *ctx; + + ctx = (struct rt_irqbench_context *)context->dev_private; + ctx->mode = -1; + rtdm_event_init(&ctx->irq_event, 0); + sema_init(&ctx->nrt_mutex, 1); + + return 0; +} + +static int rt_irqbench_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + struct rt_irqbench_context *ctx; + + ctx = (struct rt_irqbench_context *)context->dev_private; + down(&ctx->nrt_mutex); + rt_irqbench_stop(ctx); + rtdm_event_destroy(&ctx->irq_event); + up(&ctx->nrt_mutex); + + return 0; +} + +static int rt_irqbench_ioctl_nrt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void __user *arg) +{ + struct rt_irqbench_context *ctx; + struct rttst_irqbench_config config_buf; + struct rttst_irqbench_config *config; + int err = 0; + + ctx = (struct rt_irqbench_context *)context->dev_private; + + switch (request) { + case RTTST_RTIOC_IRQBENCH_START: + config = (void *)arg; + if (user_info) { + if (rtdm_safe_copy_from_user + (user_info, &config_buf, arg, + sizeof(struct rttst_irqbench_config)) < 0) + return -EFAULT; + + config = &config_buf; + } + + if (config->port_type > RTTST_IRQBENCH_PARPORT) + return -EINVAL; + + down(&ctx->nrt_mutex); + + if (test_bit(RTDM_CLOSING, &context->context_flags)) + goto unlock_start_out; + + ctx->port_type = config->port_type; + ctx->port_ioaddr = config->port_ioaddr; + + /* Initialise hardware */ + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + if (!request_region(ctx->port_ioaddr, 8, + context->device->device_name)) { + err = -EBUSY; + goto unlock_start_out; + } + + ctx->toggle = MCR_OUT2; + + /* Reset DLAB, reset RTS, enable OUT2 */ + outb(0, LCR(ctx)); + outb(MCR_OUT2, MCR(ctx)); + + /* Mask all UART interrupts and clear pending ones. */ + outb(0, IER(ctx)); + inb(IIR(ctx)); + inb(LSR(ctx)); + inb(RHR(ctx)); + inb(MSR(ctx)); + break; + + case RTTST_IRQBENCH_PARPORT: + if (!request_region(ctx->port_ioaddr, 3, + context->device->device_name)) { + err = -EBUSY; + goto unlock_start_out; + } + + ctx->toggle = 0; + outb(0, DATA(ctx)); + outb(CTRL_INIT, CTRL(ctx)); + break; + } + + switch (config->mode) { + case RTTST_IRQBENCH_USER_TASK: + err = + rtdm_irq_request(&ctx->irq_handle, + config->port_irq, + rt_irqbench_task_irq, 0, + "irqbench", ctx); + break; + + case RTTST_IRQBENCH_KERNEL_TASK: + err = + rtdm_irq_request(&ctx->irq_handle, + config->port_irq, + rt_irqbench_task_irq, 0, + "irqbench", ctx); + if (err) + break; + + err = rtdm_task_init(&ctx->irq_task, "irqbench", + rt_irqbench_task, ctx, + config->priority, 0); + if (err) + rtdm_irq_free(&ctx->irq_handle); + break; + + case RTTST_IRQBENCH_HANDLER: + err = + rtdm_irq_request(&ctx->irq_handle, + config->port_irq, + rt_irqbench_direct_irq, 0, + "irqbench", ctx); + break; + + case RTTST_IRQBENCH_HARD_IRQ: + err = + rthal_register_domain(&ctx->domain, + "irqbench", + 0x49525142, + IPIPE_HEAD_PRIORITY, + rt_irqbench_domain_entry); + if (err) + break; + + ctx->port_irq = config->port_irq; + err = + rthal_virtualize_irq(&ctx->domain, + config->port_irq, + rt_irqbench_domain_irq, + ctx, NULL, + IPIPE_HANDLE_MASK | + IPIPE_WIRED_MASK | + IPIPE_EXCLUSIVE_MASK); + if (err) + rthal_unregister_domain(&ctx->domain); + rthal_irq_enable(ctx->port_irq); + break; + + default: + err = -EINVAL; + goto unlock_start_out; + } + + if (err) + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + release_region(ctx->port_ioaddr, 8); + break; + + case RTTST_IRQBENCH_PARPORT: + release_region(ctx->port_ioaddr, 3); + break; + } + else { + ctx->mode = config->mode; + + memset(&ctx->stats, 0, sizeof(ctx->stats)); + + /* Arm IRQ */ + switch (ctx->port_type) { + case RTTST_IRQBENCH_SERPORT: + outb(IER_MODEM, IER(ctx)); + break; + + case RTTST_IRQBENCH_PARPORT: + outb(CTRL_STROBE, CTRL(ctx)); + break; + } + } + + unlock_start_out: + up(&ctx->nrt_mutex); + break; + + case RTTST_RTIOC_IRQBENCH_STOP: + down(&ctx->nrt_mutex); + err = rt_irqbench_stop(ctx); + up(&ctx->nrt_mutex); + break; + + case RTTST_RTIOC_IRQBENCH_GET_STATS: + if (user_info) + err = + rtdm_safe_copy_to_user(user_info, arg, &ctx->stats, + sizeof(struct + rttst_irqbench_stats)); + else + *(struct rttst_irqbench_stats *)arg = ctx->stats; + break; + + case RTTST_RTIOC_IRQBENCH_WAIT_IRQ: + err = -ENOSYS; + break; + + case RTTST_RTIOC_IRQBENCH_REPLY_IRQ: + rt_irqbench_hwreply(ctx); + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static int rt_irqbench_ioctl_rt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void __user *arg) +{ + struct rt_irqbench_context *ctx; + int err = 0; + + ctx = (struct rt_irqbench_context *)context->dev_private; + + switch (request) { + case RTTST_RTIOC_IRQBENCH_WAIT_IRQ: + err = rtdm_event_wait(&ctx->irq_event); + break; + + case RTTST_RTIOC_IRQBENCH_REPLY_IRQ: + rt_irqbench_hwreply(ctx); + break; + + case RTTST_RTIOC_IRQBENCH_START: + case RTTST_RTIOC_IRQBENCH_STOP: + case RTTST_RTIOC_IRQBENCH_GET_STATS: + err = -ENOSYS; + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static struct rtdm_device device = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + + .device_flags = RTDM_NAMED_DEVICE, + .context_size = sizeof(struct rt_irqbench_context), + .device_name = "", + + .open_nrt = rt_irqbench_open, + + .ops = { + .close_nrt = rt_irqbench_close, + + .ioctl_rt = rt_irqbench_ioctl_rt, + .ioctl_nrt = rt_irqbench_ioctl_nrt, + }, + + .device_class = RTDM_CLASS_TESTING, + .device_sub_class = RTDM_SUBCLASS_IRQBENCH, + .profile_version = RTTST_PROFILE_VER, + .driver_name = "xeno_irqbench", + .driver_version = RTDM_DRIVER_VER(0, 1, 1), + .peripheral_name = "IRQ Latency Benchmark", + .provider_name = "Jan Kiszka", + .proc_name = device.device_name, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static const struct pnp_device_id irqbench_pnp_tbl[] = { + /* Standard LPT Printer Port */ + {.id = "PNP0400", .driver_data = 0}, + /* ECP Printer Port */ + {.id = "PNP0401", .driver_data = 0}, + { } +}; + +static int irqbench_pnp_probe(struct pnp_dev *dev, + const struct pnp_device_id *id) +{ + return 0; +} + +static struct pnp_driver irqbench_pnp_driver = { + .name = "irqbench", + .id_table = irqbench_pnp_tbl, + .probe = irqbench_pnp_probe, +}; + +static int pnp_registered; +#endif /* Linux >= 2.6.0 */ + +static int __init __irqbench_init(void) +{ + int err; + + do { + snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN, +#ifdef CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES + "rttest%d", +#else + "rttest-irqbench%d", +#endif + start_index); + err = rtdm_dev_register(&device); + + start_index++; + } while (err == -EEXIST); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (!err && pnp_register_driver(&irqbench_pnp_driver) == 0) + pnp_registered = 1; +#endif /* Linux >= 2.6.0 */ + + return err; +} + +static void __exit __irqbench_exit(void) +{ + rtdm_dev_unregister(&device, 1000); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (pnp_registered) + pnp_unregister_driver(&irqbench_pnp_driver); +#endif /* Linux >= 2.6.0 */ +} + +module_init(__irqbench_init); +module_exit(__irqbench_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/Kconfig relase/linux-2.6.35.9//drivers/xenomai/testing/Kconfig --- orig/linux-2.6.35.9//drivers/xenomai/testing/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/Kconfig 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,54 @@ +menu "Testing drivers" + +config XENO_DRIVERS_TESTING_LEGACY_NAMES + depends on XENO_SKIN_RTDM + bool "Use legacy names for testing drivers" + help + This lets the testing drivers register under legacy names + ("rttest") instead of the new scheme ("rttest-"). + Only enable this if you plan to use old userspace tools with the + drivers. + +config XENO_DRIVERS_TIMERBENCH + depends on XENO_SKIN_RTDM + tristate "Timer benchmark driver" + default y + help + Kernel-based benchmark driver for timer latency evaluation. + See testsuite/latency for a possible front-end. + +config XENO_DRIVERS_KLATENCY + depends on XENO_DRIVERS_TIMERBENCH && m + tristate "Kernel-only latency measurement module" + help + Kernel module for kernel-only latency measurement. + +config XENO_DRIVERS_IRQBENCH + depends on XENO_SKIN_RTDM + tristate "IRQ benchmark driver" + help + Loopback driver for IRQ latency evaluation over serial or parallel + port links. Additionally requires user-space helper and a logging tool + (see testsuite/irqbench). + +config XENO_DRIVERS_SWITCHTEST + depends on XENO_SKIN_RTDM + tristate "Context switch unit testing driver" + default y + help + Kernel-based driver for unit testing context switches and + FPU switches. + +config XENO_DRIVERS_SIGTEST + depends on m + tristate "User-space real-time signals testing module" + help + Elementary skin for unit testing user-space real-time signals. + +config XENO_DRIVERS_RTDMTEST + depends on XENO_SKIN_RTDM && m + tristate "RTDM unit tests driver" + help + Kernel driver for performing RTDM unit tests. + +endmenu diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/klat.c relase/linux-2.6.35.9//drivers/xenomai/testing/klat.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/klat.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/klat.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 Gilles Chanteperdrix . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#define DEV_NR_MAX 256 + +static int pipe = P_MINOR_AUTO; +module_param(pipe, int, 0400); +MODULE_PARM_DESC(pipe, "Index of the RT-pipe used for first connection" + " (-1, the default, means automatic minor allocation)"); + +static int mode = 1; +module_param(mode, int, 0400); +MODULE_PARM_DESC(mode, "Test mode, (1 for kernel task, 2 for timer handler)"); + +static int priority = 99; +module_param(priority, int, 0400); +MODULE_PARM_DESC(priority, "Kernel task priority"); + +static unsigned period = 100; +module_param(period, uint, 0400); +MODULE_PARM_DESC(period, "Sampling period, in microseconds"); + +static int freeze_max = 0; +module_param(freeze_max, int, 0400); +MODULE_PARM_DESC(freeze_max, "Freeze trace for each new max latency"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("gilles.chanteperdrix@xenomai.org"); + +static RT_TASK klat_srvr; +static RT_PIPE klat_pipe; +static int fd; +static struct { + struct rttst_tmbench_config config; + struct rttst_interm_bench_res res; +} pkt; + +static void klat_server(void *cookie) +{ + int err; + + for (;;) { + err = rt_dev_ioctl(fd, RTTST_RTIOC_INTERM_BENCH_RES, &pkt.res); + if (err) { + if (err != -EIDRM) + printk("rt_dev_ioctl(RTTST_RTIOC_INTERM_BENCH_RES): %d", + err); + return; + } + + /* Do not check rt_pipe_write return value, the pipe may well be + full. */ + rt_pipe_write(&klat_pipe, &pkt, sizeof(pkt), P_NORMAL); + } +} + +static int __init klat_mod_init(void) +{ + char devname[RTDM_MAX_DEVNAME_LEN + 1]; + unsigned dev_nr; + int err; + + err = rt_pipe_create(&klat_pipe, "klat_pipe", pipe, 4096); + if (err) { + printk("rt_pipe_create(klat_pipe): %d\n", err); + return err; + } + + err = rt_task_create(&klat_srvr, "klat_srvr", 0, 0, 0); + if (err) { + printk("rt_task_create(klat_srvr): %d\n", err); + goto err_close_pipe; + } + + pkt.config.mode = mode; + pkt.config.priority = priority; + pkt.config.period = period * 1000; + pkt.config.warmup_loops = 1; + pkt.config.histogram_size = 0; + pkt.config.freeze_max = freeze_max; + + for (dev_nr = 0; dev_nr < DEV_NR_MAX; dev_nr++) { + snprintf(devname, sizeof(devname), +#ifdef CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES + "rttest%d", +#else + "rttest-timerbench%d", +#endif + dev_nr); + fd = rt_dev_open(devname, O_RDONLY); + if (fd < 0) + continue; + + err = rt_dev_ioctl(fd, RTTST_RTIOC_TMBENCH_START, &pkt.config); + if (err == -ENOTTY) { + rt_dev_close(fd); + continue; + } + + if (err < 0) { + printk("rt_dev_ioctl(RTTST_RTIOC_TMBENCH_START): %d\n", + err); + goto err_destroy_task; + } + + break; + } + if (fd < 0) { + printk("rt_dev_open: could not find rttest device\n" + "(modprobe timerbench?)"); + err = fd; + goto err_destroy_task; + } + + err = rt_task_start(&klat_srvr, &klat_server, NULL); + if (err) { + printk("rt_task_start: %d\n", err); + goto err_close_dev; + } + + return 0; + + err_close_dev: + rt_dev_close(fd); + err_destroy_task: + rt_task_delete(&klat_srvr); + err_close_pipe: + rt_pipe_delete(&klat_pipe); + return err; +} + + +static void klat_mod_exit(void) +{ + rt_dev_close(fd); + rt_task_delete(&klat_srvr); + rt_pipe_delete(&klat_pipe); +} + +module_init(klat_mod_init); +module_exit(klat_mod_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/Makefile relase/linux-2.6.35.9//drivers/xenomai/testing/Makefile --- orig/linux-2.6.35.9//drivers/xenomai/testing/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/Makefile 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,79 @@ +ifeq ($(PATCHLEVEL),6) + +# Makefile frag for Linux v2.6 + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +obj-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += xeno_timerbench.o +obj-$(CONFIG_XENO_DRIVERS_IRQBENCH) += xeno_irqbench.o +obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o +obj-$(CONFIG_XENO_DRIVERS_KLATENCY) += xeno_klat.o +obj-$(CONFIG_XENO_DRIVERS_SIGTEST) += xeno_sigtest.o +obj-$(CONFIG_XENO_DRIVERS_RTDMTEST) += xeno_rtdmtest.o + +xeno_timerbench-y := timerbench.o + +xeno_irqbench-y := irqbench.o + +xeno_switchtest-y := switchtest.o + +xeno_klat-y := klat.o + +xeno_sigtest-y := sigtest_module.o + +xeno_rtdmtest-y := rtdmtest.o + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai + +else + +# Makefile frag for Linux v2.4 + +O_TARGET := built-in.o + +obj-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += xeno_timerbench.o +obj-$(CONFIG_XENO_DRIVERS_IRQBENCH) += xeno_irqbench.o +obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o +obj-$(CONFIG_XENO_DRIVERS_KLATENCY) += xeno_klat.o +obj-$(CONFIG_XENO_DRIVERS_SIGTEST) += xeno_sigtest.o +obj-$(CONFIG_XENO_DRIVERS_RTDMTEST) += xeno_rtdmtest.o + +xeno_timerbench-objs := timerbench.o + +xeno_irqbench-objs := irqbench.o + +xeno_switchtest-objs := switchtest.o + +xeno_klat-objs := klat.o + +xeno_sigtest-objs := sigtest_module.o + +xeno_rtdmtest-objs := rtdmtest.o + +export-objs := $(xeno_timerbench-objs) $(xeno_irqbench-objs) \ + $(xeno_switchtest-objs) $(xeno_klat-objs) $(xeno_sigtest-objs) \ + $(xeno_rtdmtest-objs) + +EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat + +include $(TOPDIR)/Rules.make + +xeno_timerbench.o: $(xeno_timerbench-objs) + $(LD) -r -o $@ $(xeno_timerbench-objs) + +xeno_irqbench.o: $(xeno_irqbench-objs) + $(LD) -r -o $@ $(xeno_irqbench-objs) + +xeno_switchtest.o: $(xeno_switchtest-objs) + $(LD) -r -o $@ $(xeno_switchtest-objs) + +xeno_klat.o: $(xeno_klat-objs) + $(LD) -r -o $@ $(xeno_klat-objs) + +xeno_sigtest.o: $(xeno_sigtest-objs) + $(LD) -r -o $@ $(xeno_sigtest-objs) + +xeno_rtdmtest.o: $(xeno_rtdmtest-objs) + $(LD) -r -o $@ $(xeno_rtdmtest-objs) + +endif diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/rtdmtest.c relase/linux-2.6.35.9//drivers/xenomai/testing/rtdmtest.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/rtdmtest.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/rtdmtest.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2010 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include + +static unsigned int start_index; + +module_param(start_index, uint, 0400); +MODULE_PARM_DESC(start_index, "First device instance number to be used"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jan.kiszka@web.de"); + +struct rtdm_test_context { + rtdm_timer_t close_timer; + unsigned long close_counter; + unsigned long close_deferral; +}; + +static void close_timer_proc(rtdm_timer_t *timer) +{ + struct rtdm_test_context *ctx = + container_of(timer, struct rtdm_test_context, close_timer); + + if (ctx->close_counter != 1) + printk(KERN_ERR + "rtdmtest: %s: close_counter is %lu, should be 1!\n", + __FUNCTION__, ctx->close_counter); + + rtdm_context_unlock(rtdm_private_to_context(ctx)); +} + +static int rtdm_test_open(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int oflags) +{ + struct rtdm_test_context *ctx = + (struct rtdm_test_context *)context->dev_private; + + rtdm_timer_init(&ctx->close_timer, close_timer_proc, + "rtdm close test"); + ctx->close_counter = 0; + ctx->close_deferral = RTTST_RTDM_NORMAL_CLOSE; + + return 0; +} + +static int rtdm_test_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + struct rtdm_test_context *ctx = + (struct rtdm_test_context *)context->dev_private; + + ctx->close_counter++; + + switch (ctx->close_deferral) { + case RTTST_RTDM_DEFER_CLOSE_HANDLER: + if (ctx->close_counter <= 3) + return -EAGAIN; + if (ctx->close_counter > 4) { + printk(KERN_ERR + "rtdmtest: %s: close_counter is %lu, " + "should be 2!\n", + __FUNCTION__, ctx->close_counter); + return 0; + } + break; + + case RTTST_RTDM_DEFER_CLOSE_CONTEXT: + if (ctx->close_counter == 1) { + rtdm_context_lock(context); + rtdm_timer_start(&ctx->close_timer, 300000000ULL, 0, + RTDM_TIMERMODE_RELATIVE); + return 0; + } + if (ctx->close_counter > 2) { + printk(KERN_ERR + "rtdmtest: %s: close_counter is %lu, " + "should be 2!\n", + __FUNCTION__, ctx->close_counter); + return 0; + } + break; + } + + rtdm_timer_destroy(&ctx->close_timer); + + return 0; +} + +static int rtdm_test_ioctl(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void __user *arg) +{ + struct rtdm_test_context *ctx = + (struct rtdm_test_context *)context->dev_private; + int err = 0; + + switch (request) { + case RTTST_RTIOC_RTDM_DEFER_CLOSE: + ctx->close_deferral = (unsigned long)arg; + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static struct rtdm_device device[2] = { [0 ... 1] = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + + .device_flags = RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE, + .context_size = sizeof(struct rtdm_test_context), + .device_name = "", + + .open_nrt = rtdm_test_open, + + .ops = { + .close_nrt = rtdm_test_close, + + .ioctl_rt = rtdm_test_ioctl, + .ioctl_nrt = rtdm_test_ioctl, + }, + + .device_class = RTDM_CLASS_TESTING, + .device_sub_class = RTDM_SUBCLASS_RTDMTEST, + .profile_version = RTTST_PROFILE_VER, + .driver_name = "xeno_rtdmtest", + .driver_version = RTDM_DRIVER_VER(0, 1, 0), + .peripheral_name = "RTDM unit test", + .provider_name = "Jan Kiszka", +} }; + +static int __init __rtdm_test_init(void) +{ + int dev = 0; + int err; + + while (1) { + device[dev].proc_name = device[dev].device_name; + + snprintf(device[dev].device_name, RTDM_MAX_DEVNAME_LEN, + "rttest-rtdm%d", + start_index); + err = rtdm_dev_register(&device[dev]); + + start_index++; + + if (!err) { + if (++dev >= ARRAY_SIZE(device)) + break; + } else if (err != -EEXIST) { + while (dev > 0) { + dev--; + rtdm_dev_unregister(&device[dev], 1000); + } + return err; + } + } + return 0; +} + +static void __exit __rtdm_test_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(device); i++) + rtdm_dev_unregister(&device[i], 1000); +} + +module_init(__rtdm_test_init); +module_exit(__rtdm_test_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/sigtest_module.c relase/linux-2.6.35.9//drivers/xenomai/testing/sigtest_module.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/sigtest_module.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/sigtest_module.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static int muxid; +static xntbase_t *tbase; + +static int *sigs, next_sig; +static size_t nr_sigs; +static xnthread_t *target; +static xntimer_t sigtest_timer; + +MODULE_DESCRIPTION("signals testing interface"); +MODULE_AUTHOR("gilles.chanteperdrix@xenomai.org"); +MODULE_LICENSE("GPL"); + +static void sigtest_timer_handler(xntimer_t *timer) +{ + xnshadow_mark_sig(target, muxid); + /* xnpod_schedule called later. */ +} + +static int __sigtest_queue(struct pt_regs *regs) +{ + target = xnshadow_thread(current); + if (!target) + return -EPERM; + + nr_sigs = (size_t)__xn_reg_arg2(regs); + sigs = xnmalloc(sizeof(*sigs) * nr_sigs); + next_sig = 0; + + if (__xn_copy_from_user(sigs, (void __user *)__xn_reg_arg1(regs), + sizeof(*sigs) * nr_sigs)) { + xnfree(sigs); + return -EFAULT; + } + + xntimer_set_sched(&sigtest_timer, xnpod_current_sched()); + xntimer_start(&sigtest_timer, 10000000, 0, 0); + + return 0; +} + +static int __sigtest_wait_pri(struct pt_regs *regs) +{ + xnthread_t *thread = xnshadow_thread(current); + xnticks_t ticks = xntbase_ns2ticks(tbase, 20000000); + xnpod_suspend_thread(thread, XNDELAY, ticks, XN_RELATIVE, NULL); + if (xnthread_test_info(thread, XNBREAK)) + return -EINTR; + + return 0; +} + +static int __sigtest_wait_sec(struct pt_regs *regs) +{ + schedule_timeout_interruptible(20 * HZ / 1000 + 1); + if (signal_pending(current)) + return -EINTR; + return 0; +} + +static xnsysent_t __systab[] = { + [__NR_sigtest_queue] = {&__sigtest_queue, __xn_exec_any}, + [__NR_sigtest_wait_pri] = {&__sigtest_wait_pri, __xn_exec_primary}, + [__NR_sigtest_wait_sec] = {&__sigtest_wait_sec, __xn_exec_secondary}, +}; + +static int sigtest_unqueue(xnthread_t *thread, union xnsiginfo __user *si) +{ + struct sigtest_siginfo __user *mysi = (struct sigtest_siginfo __user *)si; + int status = sigs[next_sig]; + + __xn_put_user(next_sig, &mysi->sig_nr); + if (++next_sig == nr_sigs) { + spl_t s; + + xnfree(sigs); + xnlock_get_irqsave(&nklock, s); + xnshadow_clear_sig(thread, muxid); + xnlock_put_irqrestore(&nklock, s); + } + return status; +} + +static struct xnskin_props __props = { + .name = "sigtest", + .magic = SIGTEST_SKIN_MAGIC, + .nrcalls = ARRAY_SIZE(__systab), + .systab = __systab, + .eventcb = NULL, + .sig_unqueue = sigtest_unqueue, + .timebasep = &tbase, + .module = THIS_MODULE +}; + +int SKIN_INIT(sigtest) +{ + int err; + + xnprintf("starting sigtest services\n"); + + err = xnpod_init(); + if (err) + goto fail; + + err = xntbase_alloc("sigtest", 0, 0, &tbase); + if (err) + goto fail_shutdown_pod; + + muxid = xnshadow_register_interface(&__props); + if (muxid < 0) { + err = muxid; + fail_shutdown_pod: + xnpod_shutdown(err); + fail: + return err; + } + + xntimer_init(&sigtest_timer, tbase, sigtest_timer_handler); + + return 0; +} + +void SKIN_EXIT(sigtest) +{ + xnprintf("stopping sigtest services\n"); + xntimer_destroy(&sigtest_timer); + xnshadow_unregister_interface(muxid); + xntbase_free(tbase); + xnpod_shutdown(XNPOD_NORMAL_EXIT); +} +module_init(__sigtest_skin_init); +module_exit(__sigtest_skin_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/switchtest.c relase/linux-2.6.35.9//drivers/xenomai/testing/switchtest.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/switchtest.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/switchtest.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,774 @@ +#include +#include +#include +#include +#include +#include + +#define RTSWITCH_RT 0x4 +#define RTSWITCH_NRT 0 +#define RTSWITCH_KERNEL 0x8 + +typedef struct { + struct rttst_swtest_task base; + rtdm_event_t rt_synch; + struct semaphore nrt_synch; + xnthread_t ktask; /* For kernel-space real-time tasks. */ + unsigned last_switch; +} rtswitch_task_t; + +typedef struct rtswitch_context { + rtswitch_task_t *tasks; + unsigned tasks_count; + unsigned next_index; + struct semaphore lock; + unsigned cpu; + unsigned switches_count; + + unsigned long pause_us; + unsigned next_task; + rtdm_timer_t wake_up_delay; + + unsigned failed; + struct rttst_swtest_error error; + + rtswitch_task_t *utask; + rtdm_nrtsig_t wake_utask; +} rtswitch_context_t; + +static unsigned int start_index; + +module_param(start_index, uint, 0400); +MODULE_PARM_DESC(start_index, "First device instance number to be used"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Gilles.Chanteperdrix@laposte.net"); + +static void handle_ktask_error(rtswitch_context_t *ctx, unsigned fp_val) +{ + rtswitch_task_t *cur = &ctx->tasks[ctx->error.last_switch.to]; + unsigned i; + + ctx->failed = 1; + ctx->error.fp_val = fp_val; + + if ((cur->base.flags & RTSWITCH_RT) == RTSWITCH_RT) + for (i = 0; i < ctx->tasks_count; i++) { + rtswitch_task_t *task = &ctx->tasks[i]; + + /* Find the first non kernel-space task. */ + if ((task->base.flags & RTSWITCH_KERNEL)) + continue; + + /* Unblock it. */ + switch(task->base.flags & RTSWITCH_RT) { + case RTSWITCH_NRT: + ctx->utask = task; + rtdm_nrtsig_pend(&ctx->wake_utask); + break; + + case RTSWITCH_RT: + rtdm_event_signal(&task->rt_synch); + break; + } + + xnpod_suspend_self(); + } +} + +static int rtswitch_pend_rt(rtswitch_context_t *ctx, + unsigned idx) +{ + rtswitch_task_t *task; + int rc; + + if (idx > ctx->tasks_count) + return -EINVAL; + + task = &ctx->tasks[idx]; + task->base.flags |= RTSWITCH_RT; + + rc = rtdm_event_wait(&task->rt_synch); + if (rc < 0) + return rc; + + if (ctx->failed) + return 1; + + return 0; +} + +static void timed_wake_up(rtdm_timer_t *timer) +{ + rtswitch_context_t *ctx = + container_of(timer, rtswitch_context_t, wake_up_delay); + rtswitch_task_t *task; + + task = &ctx->tasks[ctx->next_task]; + + switch (task->base.flags & RTSWITCH_RT) { + case RTSWITCH_NRT: + ctx->utask = task; + rtdm_nrtsig_pend(&ctx->wake_utask); + break; + + case RTSWITCH_RT: + rtdm_event_signal(&task->rt_synch); + } +} + +static int rtswitch_to_rt(rtswitch_context_t *ctx, + unsigned from_idx, + unsigned to_idx) +{ + rtswitch_task_t *from, *to; + int rc; + + if (from_idx > ctx->tasks_count || to_idx > ctx->tasks_count) + return -EINVAL; + + /* to == from is a special case which means + "return to the previous task". */ + if (to_idx == from_idx) + to_idx = ctx->error.last_switch.from; + + from = &ctx->tasks[from_idx]; + to = &ctx->tasks[to_idx]; + + from->base.flags |= RTSWITCH_RT; + from->last_switch = ++ctx->switches_count; + ctx->error.last_switch.from = from_idx; + ctx->error.last_switch.to = to_idx; + barrier(); + + if (ctx->pause_us) { + ctx->next_task = to_idx; + barrier(); + rtdm_timer_start(&ctx->wake_up_delay, + ctx->pause_us * 1000, 0, + RTDM_TIMERMODE_RELATIVE); + xnpod_lock_sched(); + } else + switch (to->base.flags & RTSWITCH_RT) { + case RTSWITCH_NRT: + ctx->utask = to; + barrier(); + rtdm_nrtsig_pend(&ctx->wake_utask); + xnpod_lock_sched(); + break; + + case RTSWITCH_RT: + xnpod_lock_sched(); + rtdm_event_signal(&to->rt_synch); + break; + + default: + return -EINVAL; + } + + rc = rtdm_event_wait(&from->rt_synch); + xnpod_unlock_sched(); + + if (rc < 0) + return rc; + + if (ctx->failed) + return 1; + + return 0; +} + +static int rtswitch_pend_nrt(rtswitch_context_t *ctx, + unsigned idx) +{ + rtswitch_task_t *task; + + if (idx > ctx->tasks_count) + return -EINVAL; + + task = &ctx->tasks[idx]; + + task->base.flags &= ~RTSWITCH_RT; + + if (down_interruptible(&task->nrt_synch)) + return -EINTR; + + if (ctx->failed) + return 1; + + return 0; +} + +static int rtswitch_to_nrt(rtswitch_context_t *ctx, + unsigned from_idx, + unsigned to_idx) +{ + rtswitch_task_t *from, *to; + unsigned expected, fp_val; + int fp_check; + + if (from_idx > ctx->tasks_count || to_idx > ctx->tasks_count) + return -EINVAL; + + /* to == from is a special case which means + "return to the previous task". */ + if (to_idx == from_idx) + to_idx = ctx->error.last_switch.from; + + from = &ctx->tasks[from_idx]; + to = &ctx->tasks[to_idx]; + + fp_check = ctx->switches_count == from->last_switch + 1 + && ctx->error.last_switch.from == to_idx + && ctx->error.last_switch.to == from_idx; + + from->base.flags &= ~RTSWITCH_RT; + from->last_switch = ++ctx->switches_count; + ctx->error.last_switch.from = from_idx; + ctx->error.last_switch.to = to_idx; + barrier(); + + if (ctx->pause_us) { + ctx->next_task = to_idx; + barrier(); + rtdm_timer_start(&ctx->wake_up_delay, + ctx->pause_us * 1000, 0, + RTDM_TIMERMODE_RELATIVE); + } else + switch (to->base.flags & RTSWITCH_RT) { + case RTSWITCH_NRT: + switch_to_nrt: + up(&to->nrt_synch); + break; + + case RTSWITCH_RT: + + if (!fp_check || fp_linux_begin() < 0) { + fp_check = 0; + goto signal_nofp; + } + + expected = from_idx + 500 + + (ctx->switches_count % 4000000) * 1000; + + fp_regs_set(expected); + rtdm_event_signal(&to->rt_synch); + fp_val = fp_regs_check(expected); + fp_linux_end(); + + if(down_interruptible(&from->nrt_synch)) + return -EINTR; + if (ctx->failed) + return 1; + if (fp_val != expected) { + handle_ktask_error(ctx, fp_val); + return 1; + } + + from->base.flags &= ~RTSWITCH_RT; + from->last_switch = ++ctx->switches_count; + ctx->error.last_switch.from = from_idx; + ctx->error.last_switch.to = to_idx; + if ((to->base.flags & RTSWITCH_RT) == RTSWITCH_NRT) + goto switch_to_nrt; + expected = from_idx + 500 + + (ctx->switches_count % 4000000) * 1000; + barrier(); + + fp_linux_begin(); + fp_regs_set(expected); + rtdm_event_signal(&to->rt_synch); + fp_val = fp_regs_check(expected); + fp_linux_end(); + + if (down_interruptible(&from->nrt_synch)) + return -EINTR; + if (ctx->failed) + return 1; + if (fp_val != expected) { + handle_ktask_error(ctx, fp_val); + return 1; + } + + from->base.flags &= ~RTSWITCH_RT; + from->last_switch = ++ctx->switches_count; + ctx->error.last_switch.from = from_idx; + ctx->error.last_switch.to = to_idx; + barrier(); + if ((to->base.flags & RTSWITCH_RT) == RTSWITCH_NRT) + goto switch_to_nrt; + + signal_nofp: + rtdm_event_signal(&to->rt_synch); + break; + + default: + return -EINVAL; + } + + if (down_interruptible(&from->nrt_synch)) + return -EINTR; + + if (ctx->failed) + return 1; + + return 0; +} + +static int rtswitch_set_tasks_count(rtswitch_context_t *ctx, unsigned count) +{ + rtswitch_task_t *tasks; + + if (ctx->tasks_count == count) + return 0; + + tasks = kmalloc(count * sizeof(*tasks), GFP_KERNEL); + + if (!tasks) + return -ENOMEM; + + down(&ctx->lock); + + if (ctx->tasks) + kfree(ctx->tasks); + + ctx->tasks = tasks; + ctx->tasks_count = count; + ctx->next_index = 0; + + up(&ctx->lock); + + return 0; +} + +static int rtswitch_register_task(rtswitch_context_t *ctx, + struct rttst_swtest_task *arg) +{ + rtswitch_task_t *t; + + down(&ctx->lock); + + if (ctx->next_index == ctx->tasks_count) { + up(&ctx->lock); + return -EBUSY; + } + + arg->index = ctx->next_index; + t = &ctx->tasks[arg->index]; + ctx->next_index++; + t->base = *arg; + t->last_switch = 0; + sema_init(&t->nrt_synch, 0); + rtdm_event_init(&t->rt_synch, 0); + + up(&ctx->lock); + + return 0; +} + +struct taskarg { + rtswitch_context_t *ctx; + rtswitch_task_t *task; +}; + +static void rtswitch_ktask(void *cookie) +{ + struct taskarg *arg = (struct taskarg *) cookie; + rtswitch_context_t *ctx = arg->ctx; + rtswitch_task_t *task = arg->task; + unsigned to, i = 0; + + to = task->base.index; + + rtswitch_pend_rt(ctx, task->base.index); + + for(;;) { + if (task->base.flags & RTTST_SWTEST_USE_FPU) + fp_regs_set(task->base.index + i * 1000); + + switch(i % 3) { + case 0: + /* to == from means "return to last task" */ + rtswitch_to_rt(ctx, task->base.index, task->base.index); + break; + case 1: + if (++to == task->base.index) + ++to; + if (to > ctx->tasks_count - 1) + to = 0; + if (to == task->base.index) + ++to; + + /* Fall through. */ + case 2: + rtswitch_to_rt(ctx, task->base.index, to); + } + + if (task->base.flags & RTTST_SWTEST_USE_FPU) { + unsigned fp_val, expected; + + expected = task->base.index + i * 1000; + fp_val = fp_regs_check(expected); + + if (fp_val != expected) { + if (task->base.flags & RTTST_SWTEST_FREEZE) + xntrace_user_freeze(0, 0); + handle_ktask_error(ctx, fp_val); + } + } + + if (++i == 4000000) + i = 0; + } +} + +static int rtswitch_create_ktask(rtswitch_context_t *ctx, + struct rttst_swtest_task *ptask) +{ + union xnsched_policy_param param; + struct xnthread_start_attr sattr; + struct xnthread_init_attr iattr; + rtswitch_task_t *task; + xnflags_t init_flags; + struct taskarg arg; + char name[30]; + int err; + + /* + * Silently disable FP tests in kernel if FPU is not supported + * there. Typical case is math emulation support: we can use + * it from userland as a synthetic FPU, but there is no sane + * way to use it from kernel-based threads (Xenomai or Linux). + */ + if (!fp_kernel_supported()) + ptask->flags &= ~RTTST_SWTEST_USE_FPU; + + ptask->flags |= RTSWITCH_KERNEL; + err = rtswitch_register_task(ctx, ptask); + + if (err) + return err; + + snprintf(name, sizeof(name), "rtk%d/%u", ptask->index, ctx->cpu); + + task = &ctx->tasks[ptask->index]; + + arg.ctx = ctx; + arg.task = task; + + init_flags = (ptask->flags & RTTST_SWTEST_FPU) ? XNFPU : 0; + + /* + * Migrate the calling thread to the same CPU as the created + * task, in order to be sure that the created task is + * suspended when this function returns. This also allow us to + * use the stack to pass the parameters to the created + * task. + */ + set_cpus_allowed(current, cpumask_of_cpu(ctx->cpu)); + + iattr.tbase = rtdm_tbase; + iattr.name = name; + iattr.flags = init_flags; + iattr.ops = NULL; + iattr.stacksize = 0; + param.rt.prio = 1; + + err = xnpod_init_thread(&task->ktask, + &iattr, &xnsched_class_rt, ¶m); + if (!err) { + sattr.mode = 0; + sattr.imask = 0; + sattr.affinity = xnarch_cpumask_of_cpu(ctx->cpu); + sattr.entry = rtswitch_ktask; + sattr.cookie = &arg; + err = xnpod_start_thread(&task->ktask, &sattr); + } else + /* + * In order to avoid calling xnpod_delete_thread with + * invalid thread. + */ + task->base.flags = 0; + /* + * Putting the argument on stack is safe, because the new + * thread will preempt the current thread immediately, and + * will suspend only once the arguments on stack are used. + */ + + return err; +} + +static void rtswitch_utask_waker(rtdm_nrtsig_t sig, void *arg) +{ + rtswitch_context_t *ctx = (rtswitch_context_t *)arg; + up(&ctx->utask->nrt_synch); +} + +static int rtswitch_open(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + int oflags) +{ + rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; + int err; + + ctx->tasks = NULL; + ctx->tasks_count = ctx->next_index = ctx->cpu = ctx->switches_count = 0; + sema_init(&ctx->lock, 1); + ctx->failed = 0; + ctx->error.last_switch.from = ctx->error.last_switch.to = -1; + ctx->pause_us = 0; + + err = rtdm_nrtsig_init(&ctx->wake_utask, rtswitch_utask_waker, ctx); + if (err) + return err; + + rtdm_timer_init(&ctx->wake_up_delay, timed_wake_up, "switchtest timer"); + + return 0; +} + +static int rtswitch_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; + unsigned i; + + if (ctx->tasks) { + set_cpus_allowed(current, cpumask_of_cpu(ctx->cpu)); + + for (i = 0; i < ctx->next_index; i++) { + rtswitch_task_t *task = &ctx->tasks[i]; + + if (task->base.flags & RTSWITCH_KERNEL) + xnpod_delete_thread(&task->ktask); + rtdm_event_destroy(&task->rt_synch); + } + kfree(ctx->tasks); + } + rtdm_timer_destroy(&ctx->wake_up_delay); + rtdm_nrtsig_destroy(&ctx->wake_utask); + + return 0; +} + +static int rtswitch_ioctl_nrt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, + void *arg) +{ + rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; + struct rttst_swtest_task task; + struct rttst_swtest_dir fromto; + unsigned long count; + int err; + + switch (request) { + case RTTST_RTIOC_SWTEST_SET_TASKS_COUNT: + return rtswitch_set_tasks_count(ctx, + (unsigned long) arg); + + case RTTST_RTIOC_SWTEST_SET_CPU: + if ((unsigned long) arg > xnarch_num_online_cpus() - 1) + return -EINVAL; + + ctx->cpu = (unsigned long) arg; + return 0; + + case RTTST_RTIOC_SWTEST_SET_PAUSE: + ctx->pause_us = (unsigned long) arg; + return 0; + + case RTTST_RTIOC_SWTEST_REGISTER_UTASK: + if (!rtdm_rw_user_ok(user_info, arg, sizeof(task))) + return -EFAULT; + + rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); + + err = rtswitch_register_task(ctx, &task); + + if (!err) + rtdm_copy_to_user(user_info, + arg, + &task, + sizeof(task)); + + return err; + + case RTTST_RTIOC_SWTEST_CREATE_KTASK: + if (!rtdm_rw_user_ok(user_info, arg, sizeof(task))) + return -EFAULT; + + rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); + + err = rtswitch_create_ktask(ctx, &task); + + if (!err) + rtdm_copy_to_user(user_info, + arg, + &task, + sizeof(task)); + + return err; + + case RTTST_RTIOC_SWTEST_PEND: + if (!rtdm_read_user_ok(user_info, arg, sizeof(task))) + return -EFAULT; + + rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); + + return rtswitch_pend_nrt(ctx, task.index); + + case RTTST_RTIOC_SWTEST_SWITCH_TO: + if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto))) + return -EFAULT; + + rtdm_copy_from_user(user_info, + &fromto, + arg, + sizeof(fromto)); + + return rtswitch_to_nrt(ctx, fromto.from, fromto.to); + + case RTTST_RTIOC_SWTEST_GET_SWITCHES_COUNT: + if (!rtdm_rw_user_ok(user_info, arg, sizeof(count))) + return -EFAULT; + + count = ctx->switches_count; + + rtdm_copy_to_user(user_info, arg, &count, sizeof(count)); + + return 0; + + case RTTST_RTIOC_SWTEST_GET_LAST_ERROR: + if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error))) + return -EFAULT; + + rtdm_copy_to_user(user_info, + arg, + &ctx->error, + sizeof(ctx->error)); + + return 0; + + default: + return -ENOTTY; + } +} + +static int rtswitch_ioctl_rt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, + void *arg) +{ + rtswitch_context_t *ctx = (rtswitch_context_t *) context->dev_private; + struct rttst_swtest_task task; + struct rttst_swtest_dir fromto; + + switch (request) { + case RTTST_RTIOC_SWTEST_REGISTER_UTASK: + case RTTST_RTIOC_SWTEST_CREATE_KTASK: + case RTTST_RTIOC_SWTEST_GET_SWITCHES_COUNT: + return -ENOSYS; + + case RTTST_RTIOC_SWTEST_PEND: + if (!rtdm_read_user_ok(user_info, arg, sizeof(task))) + return -EFAULT; + + rtdm_copy_from_user(user_info, &task, arg, sizeof(task)); + + return rtswitch_pend_rt(ctx, task.index); + + case RTTST_RTIOC_SWTEST_SWITCH_TO: + if (!rtdm_read_user_ok(user_info, arg, sizeof(fromto))) + return -EFAULT; + + rtdm_copy_from_user(user_info, + &fromto, + arg, + sizeof(fromto)); + + return rtswitch_to_rt(ctx, fromto.from, fromto.to); + + case RTTST_RTIOC_SWTEST_GET_LAST_ERROR: + if (!rtdm_rw_user_ok(user_info, arg, sizeof(ctx->error))) + return -EFAULT; + + rtdm_copy_to_user(user_info, + arg, + &ctx->error, + sizeof(ctx->error)); + + return 0; + + default: + return -ENOTTY; + } +} + +static struct rtdm_device device = { + struct_version: RTDM_DEVICE_STRUCT_VER, + + device_flags: RTDM_NAMED_DEVICE, + context_size: sizeof(rtswitch_context_t), + device_name: "", + + open_rt: NULL, + open_nrt: rtswitch_open, + + ops: { + close_rt: NULL, + close_nrt: rtswitch_close, + + ioctl_rt: rtswitch_ioctl_rt, + ioctl_nrt: rtswitch_ioctl_nrt, + + read_rt: NULL, + read_nrt: NULL, + + write_rt: NULL, + write_nrt: NULL, + + recvmsg_rt: NULL, + recvmsg_nrt: NULL, + + sendmsg_rt: NULL, + sendmsg_nrt: NULL, + }, + + device_class: RTDM_CLASS_TESTING, + device_sub_class: RTDM_SUBCLASS_SWITCHTEST, + profile_version: RTTST_PROFILE_VER, + driver_name: "xeno_switchtest", + driver_version: RTDM_DRIVER_VER(0, 1, 1), + peripheral_name: "Context Switch Test", + provider_name: "Gilles Chanteperdrix", + proc_name: device.device_name, +}; + +int __init __switchtest_init(void) +{ + int err; + + do { + snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN, +#ifdef CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES + "rttest%d", +#else + "rttest-switchtest%d", +#endif + start_index); + err = rtdm_dev_register(&device); + + start_index++; + } while (err == -EEXIST); + + return err; +} + +void __switchtest_exit(void) +{ + rtdm_dev_unregister(&device, 1000); +} + +module_init(__switchtest_init); +module_exit(__switchtest_exit); diff -urN orig/linux-2.6.35.9//drivers/xenomai/testing/timerbench.c relase/linux-2.6.35.9//drivers/xenomai/testing/timerbench.c --- orig/linux-2.6.35.9//drivers/xenomai/testing/timerbench.c 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//drivers/xenomai/testing/timerbench.c 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2005 Jan Kiszka . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#ifdef CONFIG_IPIPE_TRACE +#include +#endif /* CONFIG_IPIPE_TRACE */ + +#include +#include + +struct rt_tmbench_context { + int mode; + unsigned long period; + int freeze_max; + int warmup_loops; + int samples_per_sec; + long *histogram_min; + long *histogram_max; + long *histogram_avg; + int histogram_size; + int bucketsize; + + rtdm_task_t timer_task; + + rtdm_timer_t timer; + int warmup; + uint64_t start_time; + uint64_t date; + struct rttst_bench_res curr; + + rtdm_event_t result_event; + struct rttst_interm_bench_res result; + + struct semaphore nrt_mutex; +}; + +static unsigned int start_index; + +module_param(start_index, uint, 0400); +MODULE_PARM_DESC(start_index, "First device instance number to be used"); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jan.kiszka@web.de"); + +static inline void add_histogram(struct rt_tmbench_context *ctx, + long *histogram, long addval) +{ + /* bucketsize steps */ + long inabs = (addval >= 0 ? addval : -addval) / ctx->bucketsize; + histogram[inabs < ctx->histogram_size ? + inabs : ctx->histogram_size - 1]++; +} + +static inline long long slldiv(long long s, unsigned d) +{ + return s >= 0 ? xnarch_ulldiv(s, d, NULL) : -xnarch_ulldiv(-s, d, NULL); +} + +static void eval_inner_loop(struct rt_tmbench_context *ctx, long dt) +{ + if (dt > ctx->curr.max) + ctx->curr.max = dt; + if (dt < ctx->curr.min) + ctx->curr.min = dt; + ctx->curr.avg += dt; + +#ifdef CONFIG_IPIPE_TRACE + if (ctx->freeze_max && (dt > ctx->result.overall.max) && !ctx->warmup) { + ipipe_trace_frozen_reset(); + ipipe_trace_freeze(dt); + ctx->result.overall.max = dt; + } +#endif /* CONFIG_IPIPE_TRACE */ + + ctx->date += ctx->period; + + if (!ctx->warmup && ctx->histogram_size) + add_histogram(ctx, ctx->histogram_avg, dt); + + /* Evaluate overruns and adjust next release date. + Beware of signedness! */ + while (dt > 0 && (unsigned long)dt > ctx->period) { + ctx->curr.overruns++; + ctx->date += ctx->period; + dt -= ctx->period; + } +} + +static void eval_outer_loop(struct rt_tmbench_context *ctx) +{ + if (!ctx->warmup) { + if (ctx->histogram_size) { + add_histogram(ctx, ctx->histogram_max, ctx->curr.max); + add_histogram(ctx, ctx->histogram_min, ctx->curr.min); + } + + ctx->result.last.min = ctx->curr.min; + if (ctx->curr.min < ctx->result.overall.min) + ctx->result.overall.min = ctx->curr.min; + + ctx->result.last.max = ctx->curr.max; + if (ctx->curr.max > ctx->result.overall.max) + ctx->result.overall.max = ctx->curr.max; + + ctx->result.last.avg = + slldiv(ctx->curr.avg, ctx->samples_per_sec); + ctx->result.overall.avg += ctx->result.last.avg; + ctx->result.overall.overruns += ctx->curr.overruns; + rtdm_event_pulse(&ctx->result_event); + } + + if (ctx->warmup && + (ctx->result.overall.test_loops == ctx->warmup_loops)) { + ctx->result.overall.test_loops = 0; + ctx->warmup = 0; + } + + ctx->curr.min = 10000000; + ctx->curr.max = -10000000; + ctx->curr.avg = 0; + ctx->curr.overruns = 0; + + ctx->result.overall.test_loops++; +} + +static void timer_task_proc(void *arg) +{ + struct rt_tmbench_context *ctx = arg; + int count; + + /* first event: one millisecond from now. */ + ctx->date = rtdm_clock_read_monotonic() + 1000000; + + while (1) { + int err; + + for (count = 0; count < ctx->samples_per_sec; count++) { + RTDM_EXECUTE_ATOMICALLY( + ctx->start_time = rtdm_clock_read_monotonic(); + err = + rtdm_task_sleep_abs(ctx->date, + RTDM_TIMERMODE_ABSOLUTE); + ); + + if (err) + return; + + eval_inner_loop(ctx, + (long)(rtdm_clock_read_monotonic() - + ctx->date)); + } + eval_outer_loop(ctx); + } +} + +static void timer_proc(rtdm_timer_t *timer) +{ + struct rt_tmbench_context *ctx = + container_of(timer, struct rt_tmbench_context, timer); + int err; + + do { + eval_inner_loop(ctx, (long)(rtdm_clock_read_monotonic() - + ctx->date)); + + ctx->start_time = rtdm_clock_read_monotonic(); + err = rtdm_timer_start_in_handler(&ctx->timer, ctx->date, 0, + RTDM_TIMERMODE_ABSOLUTE); + + if (++ctx->curr.test_loops >= ctx->samples_per_sec) { + ctx->curr.test_loops = 0; + eval_outer_loop(ctx); + } + } while (err); +} + +static int rt_tmbench_open(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, int oflags) +{ + struct rt_tmbench_context *ctx; + + ctx = (struct rt_tmbench_context *)context->dev_private; + + ctx->mode = RTTST_TMBENCH_INVALID; + sema_init(&ctx->nrt_mutex, 1); + + return 0; +} + +static int rt_tmbench_close(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info) +{ + struct rt_tmbench_context *ctx; + + ctx = (struct rt_tmbench_context *)context->dev_private; + + down(&ctx->nrt_mutex); + + if (ctx->mode >= 0) { + if (ctx->mode == RTTST_TMBENCH_TASK) + rtdm_task_destroy(&ctx->timer_task); + else if (ctx->mode == RTTST_TMBENCH_HANDLER) + rtdm_timer_destroy(&ctx->timer); + + rtdm_event_destroy(&ctx->result_event); + + if (ctx->histogram_size) + kfree(ctx->histogram_min); + + ctx->mode = RTTST_TMBENCH_INVALID; + ctx->histogram_size = 0; + } + + up(&ctx->nrt_mutex); + + return 0; +} + +static int rt_tmbench_start(struct rtdm_dev_context *context, + struct rt_tmbench_context *ctx, + rtdm_user_info_t *user_info, + struct rttst_tmbench_config __user *user_config) +{ + int err = 0; + + struct rttst_tmbench_config config_buf; + struct rttst_tmbench_config *config = + (struct rttst_tmbench_config *)user_config; + + if (user_info) { + if (rtdm_safe_copy_from_user + (user_info, &config_buf,user_config, + sizeof(struct rttst_tmbench_config)) < 0) + return -EFAULT; + + config = &config_buf; + } + + down(&ctx->nrt_mutex); + + ctx->period = config->period; + ctx->warmup_loops = config->warmup_loops; + ctx->samples_per_sec = 1000000000 / ctx->period; + ctx->histogram_size = config->histogram_size; + ctx->freeze_max = config->freeze_max; + + if (ctx->histogram_size > 0) { + ctx->histogram_min = + kmalloc(3 * ctx->histogram_size * sizeof(long), + GFP_KERNEL); + ctx->histogram_max = + ctx->histogram_min + config->histogram_size; + ctx->histogram_avg = + ctx->histogram_max + config->histogram_size; + + if (!ctx->histogram_min) { + up(&ctx->nrt_mutex); + return -ENOMEM; + } + + memset(ctx->histogram_min, 0, + 3 * ctx->histogram_size * sizeof(long)); + ctx->bucketsize = config->histogram_bucketsize; + } + + ctx->result.overall.min = 10000000; + ctx->result.overall.max = -10000000; + ctx->result.overall.avg = 0; + ctx->result.overall.test_loops = 1; + ctx->result.overall.overruns = 0; + + ctx->warmup = 1; + + ctx->curr.min = 10000000; + ctx->curr.max = -10000000; + ctx->curr.avg = 0; + ctx->curr.overruns = 0; + ctx->mode = RTTST_TMBENCH_INVALID; + + rtdm_event_init(&ctx->result_event, 0); + + if (config->mode == RTTST_TMBENCH_TASK) { + if (!test_bit(RTDM_CLOSING, &context->context_flags)) { + err = rtdm_task_init(&ctx->timer_task, "timerbench", + timer_task_proc, ctx, + config->priority, 0); + if (!err) + ctx->mode = RTTST_TMBENCH_TASK; + } + } else { + rtdm_timer_init(&ctx->timer, timer_proc, + context->device->device_name); + + ctx->curr.test_loops = 0; + + if (!test_bit(RTDM_CLOSING, &context->context_flags)) { + ctx->mode = RTTST_TMBENCH_HANDLER; + + RTDM_EXECUTE_ATOMICALLY( + ctx->start_time = rtdm_clock_read_monotonic(); + + /* first event: one millisecond from now. */ + ctx->date = ctx->start_time + 1000000; + + err = + rtdm_timer_start(&ctx->timer, ctx->date, 0, + RTDM_TIMERMODE_ABSOLUTE); + ); + } + } + + up(&ctx->nrt_mutex); + + return err; +} + +static int rt_tmbench_stop(struct rt_tmbench_context *ctx, + rtdm_user_info_t *user_info, + struct rttst_overall_bench_res __user *user_res) +{ + int err = 0; + + down(&ctx->nrt_mutex); + + if (ctx->mode < 0) { + up(&ctx->nrt_mutex); + return -EINVAL; + } + + if (ctx->mode == RTTST_TMBENCH_TASK) + rtdm_task_destroy(&ctx->timer_task); + else if (ctx->mode == RTTST_TMBENCH_HANDLER) + rtdm_timer_destroy(&ctx->timer); + + rtdm_event_destroy(&ctx->result_event); + + ctx->mode = RTTST_TMBENCH_INVALID; + + ctx->result.overall.avg = + slldiv(ctx->result.overall.avg, + ((ctx->result.overall.test_loops) > 1 ? + ctx->result.overall.test_loops : 2) - 1); + + if (user_info) + err = rtdm_safe_copy_to_user(user_info, &user_res->result, + &ctx->result.overall, + sizeof(struct rttst_bench_res)); + /* Do not break on error here - we may have to free a + histogram buffer first. */ + else { + struct rttst_overall_bench_res *res = + (struct rttst_overall_bench_res *)user_res; + + memcpy(&res->result, &ctx->result.overall, + sizeof(struct rttst_bench_res)); + } + + if (ctx->histogram_size > 0) { + int size = ctx->histogram_size * sizeof(long); + + if (user_info) { + struct rttst_overall_bench_res res_buf; + + if (rtdm_safe_copy_from_user(user_info, + &res_buf, user_res, + sizeof(res_buf)) < 0 || + rtdm_safe_copy_to_user(user_info, + (void __user *)res_buf.histogram_min, + ctx->histogram_min, size) < 0 || + rtdm_safe_copy_to_user(user_info, + (void __user *)res_buf.histogram_max, + ctx->histogram_max, size) < 0 || + rtdm_safe_copy_to_user(user_info, + (void __user *)res_buf.histogram_avg, + ctx->histogram_avg, size) < 0) + err = -EFAULT; + } else { + struct rttst_overall_bench_res *res = + (struct rttst_overall_bench_res *)user_res; + + memcpy(res->histogram_min, ctx->histogram_min, size); + memcpy(res->histogram_max, ctx->histogram_max, size); + memcpy(res->histogram_avg, ctx->histogram_avg, size); + } + + kfree(ctx->histogram_min); + } + + up(&ctx->nrt_mutex); + + return err; +} + +static int rt_tmbench_ioctl_nrt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void __user *arg) +{ + struct rt_tmbench_context *ctx; + int err = 0; + + ctx = (struct rt_tmbench_context *)context->dev_private; + + switch (request) { + case RTTST_RTIOC_TMBENCH_START: + err = rt_tmbench_start(context, ctx, user_info, arg); + break; + + case RTTST_RTIOC_TMBENCH_STOP: + err = rt_tmbench_stop(ctx, user_info, arg); + break; + + case RTTST_RTIOC_INTERM_BENCH_RES: + err = -ENOSYS; + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static int rt_tmbench_ioctl_rt(struct rtdm_dev_context *context, + rtdm_user_info_t *user_info, + unsigned int request, void __user *arg) +{ + struct rt_tmbench_context *ctx; + int err = 0; + + ctx = (struct rt_tmbench_context *)context->dev_private; + + switch (request) { + case RTTST_RTIOC_INTERM_BENCH_RES: + err = rtdm_event_wait(&ctx->result_event); + if (err) + return err; + + if (user_info) { + struct rttst_interm_bench_res __user *user_res = arg; + + err = rtdm_safe_copy_to_user(user_info, user_res, + &ctx->result, + sizeof(*user_res)); + } else { + struct rttst_interm_bench_res *res = (void *)arg; + + memcpy(res, &ctx->result, sizeof(*res)); + } + + break; + + case RTTST_RTIOC_TMBENCH_START: + case RTTST_RTIOC_TMBENCH_STOP: + err = -ENOSYS; + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static struct rtdm_device device = { + .struct_version = RTDM_DEVICE_STRUCT_VER, + + .device_flags = RTDM_NAMED_DEVICE, + .context_size = sizeof(struct rt_tmbench_context), + .device_name = "", + + .open_nrt = rt_tmbench_open, + + .ops = { + .close_nrt = rt_tmbench_close, + + .ioctl_rt = rt_tmbench_ioctl_rt, + .ioctl_nrt = rt_tmbench_ioctl_nrt, + }, + + .device_class = RTDM_CLASS_TESTING, + .device_sub_class = RTDM_SUBCLASS_TIMERBENCH, + .profile_version = RTTST_PROFILE_VER, + .driver_name = "xeno_timerbench", + .driver_version = RTDM_DRIVER_VER(0, 2, 1), + .peripheral_name = "Timer Latency Benchmark", + .provider_name = "Jan Kiszka", + .proc_name = device.device_name, +}; + +static int __init __timerbench_init(void) +{ + int err; + + do { + snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN, +#ifdef CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES + "rttest%d", +#else + "rttest-timerbench%d", +#endif + start_index); + err = rtdm_dev_register(&device); + + start_index++; + } while (err == -EEXIST); + + return err; +} + +static void __timerbench_exit(void) +{ + rtdm_dev_unregister(&device, 1000); +} + +module_init(__timerbench_init); +module_exit(__timerbench_exit); diff -urN orig/linux-2.6.35.9//fs/exec.c relase/linux-2.6.35.9//fs/exec.c --- orig/linux-2.6.35.9//fs/exec.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//fs/exec.c 2011-03-15 10:56:25.921702441 +0100 @@ -733,6 +733,7 @@ { struct task_struct *tsk; struct mm_struct * old_mm, *active_mm; + unsigned long flags; /* Notify parent that we're no longer interested in the old VM */ tsk = current; @@ -756,8 +757,10 @@ task_lock(tsk); active_mm = tsk->active_mm; tsk->mm = mm; + ipipe_mm_switch_protect(flags); tsk->active_mm = mm; activate_mm(active_mm, mm); + ipipe_mm_switch_unprotect(flags); task_unlock(tsk); arch_pick_mmap_layout(mm); if (old_mm) { diff -urN orig/linux-2.6.35.9//fs/proc/array.c relase/linux-2.6.35.9//fs/proc/array.c --- orig/linux-2.6.35.9//fs/proc/array.c 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//fs/proc/array.c 2011-03-15 10:56:25.921702441 +0100 @@ -142,6 +142,10 @@ "x (dead)", /* 64 */ "K (wakekill)", /* 128 */ "W (waking)", /* 256 */ +#ifdef CONFIG_IPIPE + "A (atomic switch)", /* 512 */ + "N (wakeup disabled)", /* 1024 */ +#endif }; static inline const char *get_task_state(struct task_struct *tsk) diff -urN orig/linux-2.6.35.9//include/asm-generic/atomic.h relase/linux-2.6.35.9//include/asm-generic/atomic.h --- orig/linux-2.6.35.9//include/asm-generic/atomic.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/atomic.h 2011-03-15 10:56:25.921702441 +0100 @@ -57,11 +57,11 @@ unsigned long flags; int temp; - local_irq_save(flags); + local_irq_save_hw(flags); temp = v->counter; temp += i; v->counter = temp; - local_irq_restore(flags); + local_irq_restore_hw(flags); return temp; } @@ -78,11 +78,11 @@ unsigned long flags; int temp; - local_irq_save(flags); + local_irq_save_hw(flags); temp = v->counter; temp -= i; v->counter = temp; - local_irq_restore(flags); + local_irq_restore_hw(flags); return temp; } @@ -135,9 +135,9 @@ unsigned long flags; mask = ~mask; - local_irq_save(flags); + local_irq_save_hw(flags); *addr &= mask; - local_irq_restore(flags); + local_irq_restore_hw(flags); } #define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v))) diff -urN orig/linux-2.6.35.9//include/asm-generic/bitops/atomic.h relase/linux-2.6.35.9//include/asm-generic/bitops/atomic.h --- orig/linux-2.6.35.9//include/asm-generic/bitops/atomic.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/bitops/atomic.h 2011-03-15 10:56:25.921702441 +0100 @@ -21,20 +21,20 @@ * this is the substitute */ #define _atomic_spin_lock_irqsave(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ - local_irq_save(f); \ + local_irq_save_hw(f); \ arch_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ arch_spin_unlock(s); \ - local_irq_restore(f); \ + local_irq_restore_hw(f); \ } while(0) #else -# define _atomic_spin_lock_irqsave(l,f) do { local_irq_save(f); } while (0) -# define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0) +# define _atomic_spin_lock_irqsave(l,f) do { local_irq_save_hw(f); } while (0) +# define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore_hw(f); } while (0) #endif /* diff -urN orig/linux-2.6.35.9//include/asm-generic/cmpxchg-local.h relase/linux-2.6.35.9//include/asm-generic/cmpxchg-local.h --- orig/linux-2.6.35.9//include/asm-generic/cmpxchg-local.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/cmpxchg-local.h 2011-03-15 10:56:25.921702441 +0100 @@ -20,7 +20,7 @@ if (size == 8 && sizeof(unsigned long) != 8) wrong_size_cmpxchg(ptr); - local_irq_save(flags); + local_irq_save_hw(flags); switch (size) { case 1: prev = *(u8 *)ptr; if (prev == old) @@ -41,7 +41,7 @@ default: wrong_size_cmpxchg(ptr); } - local_irq_restore(flags); + local_irq_restore_hw(flags); return prev; } @@ -54,11 +54,11 @@ u64 prev; unsigned long flags; - local_irq_save(flags); + local_irq_save_hw(flags); prev = *(u64 *)ptr; if (prev == old) *(u64 *)ptr = new; - local_irq_restore(flags); + local_irq_restore_hw(flags); return prev; } diff -urN orig/linux-2.6.35.9//include/asm-generic/percpu.h relase/linux-2.6.35.9//include/asm-generic/percpu.h --- orig/linux-2.6.35.9//include/asm-generic/percpu.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/percpu.h 2011-03-15 10:56:25.921702441 +0100 @@ -63,6 +63,20 @@ #define this_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, my_cpu_offset) #define __this_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, __my_cpu_offset) +#ifdef CONFIG_IPIPE +#if defined(CONFIG_IPIPE_DEBUG_INTERNAL) && defined(CONFIG_SMP) +extern int __ipipe_check_percpu_access(void); +#define __ipipe_local_cpu_offset \ + ({ \ + WARN_ON_ONCE(__ipipe_check_percpu_access()); \ + __my_cpu_offset; \ + }) +#else +#define __ipipe_local_cpu_offset __my_cpu_offset +#endif +#define __ipipe_get_cpu_var(var) \ + (*SHIFT_PERCPU_PTR(&(var), __ipipe_local_cpu_offset)) +#endif /* CONFIG_IPIPE */ #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA extern void setup_per_cpu_areas(void); @@ -73,6 +87,7 @@ #define per_cpu(var, cpu) (*((void)(cpu), &(var))) #define __get_cpu_var(var) (var) #define __raw_get_cpu_var(var) (var) +#define __ipipe_get_cpu_var(var) __raw_get_cpu_var(var) #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) #define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) diff -urN orig/linux-2.6.35.9//include/asm-generic/resource.h relase/linux-2.6.35.9//include/asm-generic/resource.h --- orig/linux-2.6.35.9//include/asm-generic/resource.h 2010-11-22 20:01:26.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/resource.h 2011-03-15 10:56:25.921702441 +0100 @@ -58,6 +58,14 @@ #endif /* + * Limit the stack by to some sane default: root can always + * increase this limit if needed.. 8MB seems reasonable. + */ +#ifndef _STK_LIM +# define _STK_LIM (8*1024*1024) +#endif + +/* * RLIMIT_STACK default maximum - some architectures override it: */ #ifndef _STK_LIM_MAX diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/arith.h relase/linux-2.6.35.9//include/asm-generic/xenomai/arith.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/arith.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/arith.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,413 @@ +/** + * @ingroup hal + * @file + * + * Generic arithmetic/conversion routines. + * Copyright © 2005 Stelian Pop. + * Copyright © 2005 Gilles Chanteperdrix. + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; 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. + */ + +/** + * @addtogroup hal + *@{*/ + +#ifndef _XENO_ASM_GENERIC_ARITH_H +#define _XENO_ASM_GENERIC_ARITH_H + +#ifdef __KERNEL__ +#include +#include + +#ifdef __BIG_ENDIAN +#define endianstruct struct { unsigned _h; unsigned _l; } _s +#else /* __LITTLE_ENDIAN */ +#define endianstruct struct { unsigned _l; unsigned _h; } _s +#endif + +#else /* !__KERNEL__ */ +#include +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +#define endianstruct struct { unsigned _h; unsigned _l; } _s +#else /* __BYTE_ORDER == __LITTLE_ENDIAN */ +#define endianstruct struct { unsigned _l; unsigned _h; } _s +#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ + +static inline unsigned __rthal_do_div(unsigned long long *a, unsigned d) +{ + unsigned r = *a % d; + *a /= d; + return r; +} + +#define do_div(a, d) __rthal_do_div(&(a), (d)) + +#endif /* !__KERNEL__ */ + +#ifndef __rthal_u64tou32 +#define __rthal_u64tou32(ull, h, l) ({ \ + union { unsigned long long _ull; \ + endianstruct; \ + } _u; \ + _u._ull = (ull); \ + (h) = _u._s._h; \ + (l) = _u._s._l; \ +}) +#endif /* !__rthal_u64tou32 */ + +#ifndef __rthal_u64fromu32 +#define __rthal_u64fromu32(h, l) ({ \ + union { unsigned long long _ull; \ + endianstruct; \ + } _u; \ + _u._s._h = (h); \ + _u._s._l = (l); \ + _u._ull; \ +}) +#endif /* !__rthal_u64fromu32 */ + +#ifndef rthal_ullmul +static inline __attribute__((__const__)) unsigned long long +__rthal_generic_ullmul(const unsigned m0, const unsigned m1) +{ + return (unsigned long long) m0 * m1; +} +#define rthal_ullmul(m0,m1) __rthal_generic_ullmul((m0),(m1)) +#endif /* !rthal_ullmul */ + +#ifndef rthal_ulldiv +static inline unsigned long long __rthal_generic_ulldiv (unsigned long long ull, + const unsigned uld, + unsigned long *const rp) +{ + const unsigned r = do_div(ull, uld); + + if (rp) + *rp = r; + + return ull; +} +#define rthal_ulldiv(ull,uld,rp) __rthal_generic_ulldiv((ull),(uld),(rp)) +#endif /* !rthal_ulldiv */ + +#ifndef rthal_uldivrem +#define rthal_uldivrem(ull,ul,rp) ((unsigned) rthal_ulldiv((ull),(ul),(rp))) +#endif /* !rthal_uldivrem */ + +#ifndef rthal_divmod64 +static inline unsigned long long +__rthal_generic_divmod64(unsigned long long a, + unsigned long long b, + unsigned long long *rem) +{ + unsigned long long q; +#if defined(__KERNEL__) && BITS_PER_LONG < 64 + if (b <= 0xffffffffULL) { + unsigned long r; + q = rthal_ulldiv(a, b, &r); + if (rem) + *rem = r; + } else { + extern unsigned long long + __rthal_generic_full_divmod64(unsigned long long a, + unsigned long long b, + unsigned long long *rem); + if (a < b) { + if (rem) + *rem = a; + return 0; + } + + return __rthal_generic_full_divmod64(a, b, rem); + } +#else /* BITS_PER_LONG >= 64 */ + q = a / b; + if (rem) + *rem = a % b; +#endif /* BITS_PER_LONG < 64 */ + return q; +} +#define rthal_divmod64(a,b,rp) __rthal_generic_divmod64((a),(b),(rp)) +#endif /* !rthal_divmod64 */ + +#ifndef rthal_imuldiv +static inline __attribute__((__const__)) int __rthal_generic_imuldiv(int i, + int mult, + int div) +{ + /* Returns (int)i = (unsigned long long)i*(unsigned)(mult)/(unsigned)div. */ + const unsigned long long ull = rthal_ullmul(i, mult); + return rthal_uldivrem(ull, div, NULL); +} +#define rthal_imuldiv(i,m,d) __rthal_generic_imuldiv((i),(m),(d)) +#endif /* !rthal_imuldiv */ + +#ifndef rthal_imuldiv_ceil +static inline __attribute__((__const__)) int __rthal_generic_imuldiv_ceil(int i, + int mult, + int div) +{ + /* Same as __rthal_generic_imuldiv, rounding up. */ + const unsigned long long ull = rthal_ullmul(i, mult); + return rthal_uldivrem(ull + (unsigned)div - 1, div, NULL); +} +#define rthal_imuldiv_ceil(i,m,d) __rthal_generic_imuldiv_ceil((i),(m),(d)) +#endif /* !rthal_imuldiv_ceil */ + +/* Division of an unsigned 96 bits ((h << 32) + l) by an unsigned 32 bits. + Building block for llimd. Without const qualifiers, gcc reload registers + after each call to uldivrem. */ +static inline unsigned long long +__rthal_generic_div96by32 (const unsigned long long h, + const unsigned l, + const unsigned d, + unsigned long *const rp) +{ + unsigned long rh; + const unsigned qh = rthal_uldivrem(h, d, &rh); + const unsigned long long t = __rthal_u64fromu32(rh, l); + const unsigned ql = rthal_uldivrem(t, d, rp); + + return __rthal_u64fromu32(qh, ql); +} + +#ifndef rthal_llimd +static inline __attribute__((__const__)) +unsigned long long __rthal_generic_ullimd (const unsigned long long op, + const unsigned m, + const unsigned d) +{ + unsigned oph, opl, tlh, tll; + unsigned long long th, tl; + + __rthal_u64tou32(op, oph, opl); + tl = rthal_ullmul(opl, m); + __rthal_u64tou32(tl, tlh, tll); + th = rthal_ullmul(oph, m); + th += tlh; + + return __rthal_generic_div96by32(th, tll, d, NULL); +} + +static inline __attribute__((__const__)) long long +__rthal_generic_llimd (long long op, unsigned m, unsigned d) +{ + long long ret; + int sign = 0; + + if(op < 0LL) { + sign = 1; + op = -op; + } + ret = __rthal_generic_ullimd(op, m, d); + + return sign ? -ret : ret; +} +#define rthal_llimd(ll,m,d) __rthal_generic_llimd((ll),(m),(d)) +#endif /* !rthal_llimd */ + +#ifndef __rthal_u96shift +#define __rthal_u96shift(h, m, l, s) ({ \ + unsigned _l = (l); \ + unsigned _m = (m); \ + unsigned _s = (s); \ + _l >>= _s; \ + _l |= (_m << (32 - _s)); \ + _m >>= _s; \ + _m |= ((h) << (32 - _s)); \ + __rthal_u64fromu32(_m, _l); \ +}) +#endif /* !__rthal_u96shift */ + +static inline long long rthal_llmi(int i, int j) +{ + /* Signed fast 32x32->64 multiplication */ + return (long long) i * j; +} + +#ifndef rthal_llmulshft +/* Fast scaled-math-based replacement for long long multiply-divide */ +static inline long long +__rthal_generic_llmulshft(const long long op, + const unsigned m, + const unsigned s) +{ + unsigned oph, opl, tlh, tll, thh, thl; + unsigned long long th, tl; + + __rthal_u64tou32(op, oph, opl); + tl = rthal_ullmul(opl, m); + __rthal_u64tou32(tl, tlh, tll); + th = rthal_llmi(oph, m); + th += tlh; + __rthal_u64tou32(th, thh, thl); + + return __rthal_u96shift(thh, thl, tll, s); +} +#define rthal_llmulshft(ll, m, s) __rthal_generic_llmulshft((ll), (m), (s)) +#endif /* !rthal_llmulshft */ + +#ifdef XNARCH_HAVE_NODIV_LLIMD + +/* Representation of a 32 bits fraction. */ +typedef struct { + unsigned long long frac; + unsigned integ; +} rthal_u32frac_t; + +static inline void xnarch_init_u32frac(rthal_u32frac_t *const f, + const unsigned m, + const unsigned d) +{ + /* Avoid clever compiler optimizations to occur when d is + known at compile-time. The performance of this function is + not critical since it is only called at init time. */ + volatile unsigned vol_d = d; + f->integ = m / d; + f->frac = __rthal_generic_div96by32 + (__rthal_u64fromu32(m % d, 0), 0, vol_d, NULL); +} + +#ifndef rthal_nodiv_imuldiv +static inline __attribute__((__const__)) unsigned +rthal_generic_nodiv_imuldiv(unsigned op, const rthal_u32frac_t f) +{ + return (rthal_ullmul(op, f.frac >> 32) >> 32) + f.integ * op; +} +#define rthal_nodiv_imuldiv(op, f) rthal_generic_nodiv_imuldiv((op),(f)) +#endif /* rthal_nodiv_imuldiv */ + +#ifndef rthal_nodiv_imuldiv_ceil +static inline __attribute__((__const__)) unsigned +rthal_generic_nodiv_imuldiv_ceil(unsigned op, const rthal_u32frac_t f) +{ + unsigned long long full = rthal_ullmul(op, f.frac >> 32) + ~0U; + return (full >> 32) + f.integ * op; +} +#define rthal_nodiv_imuldiv_ceil(op, f) \ + rthal_generic_nodiv_imuldiv_ceil((op),(f)) +#endif /* rthal_nodiv_imuldiv */ + +#ifndef rthal_nodiv_ullimd + +#ifndef __rthal_add96and64 +#error "__rthal_add96and64 must be implemented." +#endif + +static inline __attribute__((__const__)) unsigned long long +__rthal_mul64by64_high(const unsigned long long op, const unsigned long long m) +{ + /* Compute high 64 bits of multiplication 64 bits x 64 bits. */ + register unsigned long long t0, t1, t2, t3; + register unsigned oph, opl, mh, ml, t0h, t0l, t1h, t1l, t2h, t2l, t3h, t3l; + + __rthal_u64tou32(op, oph, opl); + __rthal_u64tou32(m, mh, ml); + t0 = rthal_ullmul(opl, ml); + __rthal_u64tou32(t0, t0h, t0l); + t3 = rthal_ullmul(oph, mh); + __rthal_u64tou32(t3, t3h, t3l); + __rthal_add96and64(t3h, t3l, t0h, 0, t0l >> 31); + t1 = rthal_ullmul(oph, ml); + __rthal_u64tou32(t1, t1h, t1l); + __rthal_add96and64(t3h, t3l, t0h, t1h, t1l); + t2 = rthal_ullmul(opl, mh); + __rthal_u64tou32(t2, t2h, t2l); + __rthal_add96and64(t3h, t3l, t0h, t2h, t2l); + + return __rthal_u64fromu32(t3h, t3l); +} + +static inline unsigned long long +__rthal_generic_nodiv_ullimd(const unsigned long long op, + const unsigned long long frac, + unsigned integ) +{ + return __rthal_mul64by64_high(op, frac) + integ * op; +} +#define rthal_nodiv_ullimd(op, f, i) __rthal_generic_nodiv_ullimd((op),(f), (i)) +#endif /* !rthal_nodiv_ullimd */ + +#ifndef rthal_nodiv_llimd +static inline __attribute__((__const__)) long long +__rthal_generic_nodiv_llimd (long long op, unsigned long long frac, unsigned integ) +{ + long long ret; + int sign = 0; + + if(op < 0LL) { + sign = 1; + op = -op; + } + ret = rthal_nodiv_ullimd(op, frac, integ); + + return sign ? -ret : ret; +} +#define rthal_nodiv_llimd(ll,frac,integ) __rthal_generic_nodiv_llimd((ll),(frac),(integ)) +#endif /* !rthal_nodiv_llimd */ + +#endif /* XNARCH_HAVE_NODIV_LLIMD */ + +static inline void xnarch_init_llmulshft(const unsigned m_in, + const unsigned d_in, + unsigned *m_out, + unsigned *s_out) +{ + /* Avoid clever compiler optimizations to occur when d is + known at compile-time. The performance of this function is + not critical since it is only called at init time. */ + volatile unsigned vol_d = d_in; + unsigned long long mult; + + *s_out = 31; + while (1) { + mult = ((unsigned long long)m_in) << *s_out; + do_div(mult, vol_d); + if (mult <= 0x7FFFFFFF) + break; + (*s_out)--; + } + *m_out = (unsigned)mult; +} + +#define xnarch_ullmod(ull,uld,rem) ({ xnarch_ulldiv(ull,uld,rem); (*rem); }) +#define xnarch_uldiv(ull, d) rthal_uldivrem(ull, d, NULL) +#define xnarch_ulmod(ull, d) ({ u_long _rem; \ + rthal_uldivrem(ull,d,&_rem); _rem; }) + +#define xnarch_ullmul rthal_ullmul +#define xnarch_uldivrem rthal_uldivrem +#define xnarch_ulldiv rthal_ulldiv +#define xnarch_divmod64 rthal_divmod64 +#define xnarch_div64(a,b) rthal_divmod64((a),(b),NULL) +#define xnarch_mod64(a,b) ({ unsigned long long _rem; \ + rthal_divmod64((a),(b),&_rem); _rem; }) +#define xnarch_imuldiv rthal_imuldiv +#define xnarch_imuldiv_ceil rthal_imuldiv_ceil +#define xnarch_llimd rthal_llimd +#define xnarch_nodiv_ullimd rthal_nodiv_ullimd +#define xnarch_nodiv_llimd rthal_nodiv_llimd +#define xnarch_llmulshft rthal_llmulshft + +unsigned long long xnarch_divrem_billion(unsigned long long value, + unsigned long *rem); + +/*@}*/ + +#endif /* _XENO_ASM_GENERIC_ARITH_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/bind.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/bind.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/bind.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/bind.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,40 @@ +#ifndef _XENO_ASM_GENERIC_BITS_BIND_H +#define _XENO_ASM_GENERIC_BITS_BIND_H + +#include +#include +#include + +union xnsiginfo; + +typedef void xnsighandler(union xnsiginfo *si); + +void xeno_handle_mlock_alert(int sig, siginfo_t *si, void *context); + +int +xeno_bind_skin_opt(unsigned skin_magic, const char *skin, + const char *module, xnsighandler *sighandler); + +static inline int +xeno_bind_skin(unsigned skin_magic, const char *skin, + const char *module, xnsighandler *sighandler) +{ + int muxid = xeno_bind_skin_opt(skin_magic, skin, module, sighandler); + struct sigaction sa; + + if (muxid == -1) { + fprintf(stderr, + "Xenomai: %s skin or CONFIG_XENO_OPT_PERVASIVE disabled.\n" + "(modprobe %s?)\n", skin, module); + exit(EXIT_FAILURE); + } + + sa.sa_sigaction = xeno_handle_mlock_alert; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGXCPU, &sa, NULL); + + return muxid; +} + +#endif /* _XENO_ASM_GENERIC_BITS_BIND_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/current.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/current.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/current.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/current.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,69 @@ +#ifndef _XENO_ASM_GENERIC_CURRENT_H +#define _XENO_ASM_GENERIC_CURRENT_H + +#include +#include + +extern pthread_key_t xeno_current_mode_key; + +xnhandle_t xeno_slow_get_current(void); +unsigned long xeno_slow_get_current_mode(void); +void xeno_current_warn_old(void); + +#ifdef HAVE___THREAD +extern __thread xnhandle_t xeno_current __attribute__ ((tls_model ("initial-exec"))); +extern __thread unsigned long +xeno_current_mode __attribute__ ((tls_model ("initial-exec"))); + +static inline xnhandle_t xeno_get_current(void) +{ + return xeno_current; +} + +#define xeno_get_current_fast() xeno_get_current() + +static inline unsigned long xeno_get_current_mode(void) +{ + unsigned long mode = xeno_current_mode; + + return mode == -1 ? xeno_slow_get_current_mode() : mode; +} + +#else /* ! HAVE___THREAD */ +extern pthread_key_t xeno_current_key; + +xnhandle_t xeno_slow_get_current(void); + +unsigned long xeno_slow_get_current_mode(void); + +static inline xnhandle_t xeno_get_current(void) +{ + void *val = pthread_getspecific(xeno_current_key); + + return (xnhandle_t)val ?: xeno_slow_get_current(); +} + +/* syscall-free, but unreliable in TSD destructor context */ +static inline xnhandle_t xeno_get_current_fast(void) +{ + void *val = pthread_getspecific(xeno_current_key); + + return (xnhandle_t)val ?: XN_NO_HANDLE; +} + +static inline unsigned long xeno_get_current_mode(void) +{ + unsigned long *mode = pthread_getspecific(xeno_current_mode_key); + + return mode ? (*mode) : xeno_slow_get_current_mode(); +} + +#endif /* ! HAVE___THREAD */ + +void xeno_set_current(void); + +unsigned long *xeno_init_current_mode(void); + +void xeno_init_current_keys(void); + +#endif /* _XENO_ASM_GENERIC_CURRENT_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/heap.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/heap.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/heap.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/heap.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_GENERIC_BITS_HEAP_H +#define _XENO_ASM_GENERIC_BITS_HEAP_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +static inline void xnarch_init_heapcb (xnarch_heapcb_t *hcb) + +{ + hcb->numaps = 0; + hcb->kmflags = 0; + hcb->heapbase = NULL; +} + +#endif /* !_XENO_ASM_GENERIC_BITS_HEAP_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/intr.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/intr.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/intr.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/intr.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_GENERIC_BITS_INTR_H +#define _XENO_ASM_GENERIC_BITS_INTR_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +static inline int xnarch_hook_irq (unsigned irq, + rthal_irq_handler_t handler, + rthal_irq_ackfn_t ackfn, + void *cookie) +{ + return rthal_irq_request(irq,handler,ackfn,cookie); +} + +static inline int xnarch_release_irq (unsigned irq) +{ + return rthal_irq_release(irq); +} + +static inline int xnarch_enable_irq (unsigned irq) +{ + return rthal_irq_enable(irq); +} + +static inline int xnarch_disable_irq (unsigned irq) +{ + return rthal_irq_disable(irq); +} + +static inline int xnarch_end_irq (unsigned irq) +{ + return rthal_irq_end(irq); +} + +static inline void xnarch_chain_irq (unsigned irq) +{ + rthal_irq_host_pend(irq); +} + +static inline xnarch_cpumask_t xnarch_set_irq_affinity (unsigned irq, + xnarch_cpumask_t affinity) +{ + return rthal_set_irq_affinity(irq,affinity); +} + +static inline void *xnarch_get_irq_cookie(unsigned irq) +{ + return rthal_irq_cookie(&rthal_domain, irq); +} + +#endif /* !_XENO_ASM_GENERIC_BITS_INTR_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/pod.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/pod.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/pod.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/pod.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * Copyright (C) 2004,2005 Gilles Chanteperdrix . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_GENERIC_BITS_POD_H +#define _XENO_ASM_GENERIC_BITS_POD_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#ifdef CONFIG_GENERIC_CLOCKEVENTS + +#include +#include + +/*! + * @internal + * \fn void xnarch_next_htick_shot(unsigned long delay, struct clock_event_device *cdev) + * + * \brief Next tick setup emulation callback. + * + * Program the next shot for the host tick on the current CPU. + * Emulation is done using a nucleus timer attached to the master + * timebase. + * + * @param delay The time delta from the current date to the next tick, + * expressed as a count of nanoseconds. + * + * @param cdev An pointer to the clock device which notifies us. + * + * Environment: + * + * This routine is a callback invoked from the kernel's clock event + * handlers. + * + * @note Only Linux kernel releases which support clock event devices + * (CONFIG_GENERIC_CLOCKEVENTS) would call this routine when the + * latter are programmed in oneshot mode. Otherwise, periodic host + * tick emulation is directly handled by the nucleus, and does not + * involve any callback mechanism from the Linux kernel. + * + * Rescheduling: never. + */ + +static int xnarch_next_htick_shot(unsigned long delay, struct clock_event_device *cdev) +{ + xnsched_t *sched; + int ret; + spl_t s; + + xnlock_get_irqsave(&nklock, s); + sched = xnpod_current_sched(); + ret = xntimer_start(&sched->htimer, delay, XN_INFINITE, XN_RELATIVE); + xnlock_put_irqrestore(&nklock, s); + + return ret ? -ETIME : 0; +} + +/*! + * @internal + * \fn void xnarch_switch_htick_mode(enum clock_event_mode mode, struct clock_event_device *cdev) + * + * \brief Tick mode switch emulation callback. + * + * Changes the host tick mode for the tick device of the current CPU. + * + * @param mode The new mode to switch to. The possible values are: + * + * - CLOCK_EVT_MODE_ONESHOT, for a switch to oneshot mode. + * + * - CLOCK_EVT_MODE_PERIODIC, for a switch to periodic mode. The current + * implementation for the generic clockevent layer Linux exhibits + * should never downgrade from a oneshot to a periodic tick mode, so + * this mode should not be encountered. This said, the associated code + * is provided, basically for illustration purposes. + * + * - CLOCK_EVT_MODE_SHUTDOWN, indicates the removal of the current + * tick device. Normally, the HAL code only interposes on tick devices + * which should never be shut down, so this mode should not be + * encountered. + * + * @param cdev An opaque pointer to the clock device which notifies us. + * + * Environment: + * + * This routine is a callback invoked from the kernel's clock event + * handlers. + * + * @note Only Linux kernel releases which support clock event devices + * (CONFIG_GENERIC_CLOCKEVENTS) would call this routine. Otherwise, + * host tick mode is always periodic, and does not involve any + * callback mechanism from the Linux kernel. + * + * Rescheduling: never. + */ + +static void xnarch_switch_htick_mode(enum clock_event_mode mode, struct clock_event_device *cdev) +{ + xnsched_t *sched; + xnticks_t tickval; + spl_t s; + +#ifndef __IPIPE_FEATURE_REQUEST_TICKDEV + struct ipipe_tick_device *tdev = (struct ipipe_tick_device *)cdev; + cdev = tdev->slave->evtdev; +#endif + rthal_timer_notify_switch(mode, cdev); + + if (mode == CLOCK_EVT_MODE_ONESHOT) + return; + + xnlock_get_irqsave(&nklock, s); + + sched = xnpod_current_sched(); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + tickval = 1000000000UL / HZ; + xntimer_start(&sched->htimer, tickval, tickval, XN_RELATIVE); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + xntimer_stop(&sched->htimer); + break; + + default: +#if XENO_DEBUG(TIMERS) + xnlogerr("host tick: invalid mode `%d'?\n", mode); +#endif + ; + } + + xnlock_put_irqrestore(&nklock, s); +} + +#endif /* CONFIG_GENERIC_CLOCKEVENTS */ + +#ifdef CONFIG_SMP + +static inline int xnarch_hook_ipi (void (*handler)(void)) +{ + return rthal_virtualize_irq(&rthal_domain, + RTHAL_SERVICE_IPI0, + (rthal_irq_handler_t) handler, + NULL, + NULL, + IPIPE_HANDLE_MASK | IPIPE_WIRED_MASK); +} + +static inline int xnarch_release_ipi (void) +{ + return rthal_virtualize_irq(&rthal_domain, + RTHAL_SERVICE_IPI0, + NULL, + NULL, + NULL, + IPIPE_PASS_MASK); +} + +static struct linux_semaphore xnarch_finalize_sync; + +static void xnarch_finalize_cpu(unsigned irq) +{ + up(&xnarch_finalize_sync); +} + +static inline void xnarch_notify_halt(void) +{ + xnarch_cpumask_t other_cpus = cpu_online_map; + int cpu, nr_cpus = num_online_cpus(); + unsigned long flags; + + sema_init(&xnarch_finalize_sync,0); + + /* Here rthal_current_domain is in fact root, since xnarch_notify_halt is + called from xnpod_shutdown, itself called from Linux + context. */ + + rthal_virtualize_irq(rthal_current_domain, + RTHAL_SERVICE_IPI2, + (rthal_irq_handler_t)xnarch_finalize_cpu, + NULL, + NULL, + IPIPE_HANDLE_MASK); + + rthal_local_irq_save_hw(flags); + cpu_clear(rthal_processor_id(), other_cpus); + rthal_send_ipi(RTHAL_SERVICE_IPI2, other_cpus); + rthal_local_irq_restore_hw(flags); + + for(cpu=0; cpu < nr_cpus-1; ++cpu) + down(&xnarch_finalize_sync); + + rthal_virtualize_irq(rthal_current_domain, + RTHAL_SERVICE_IPI2, + NULL, + NULL, + NULL, + IPIPE_PASS_MASK); + + rthal_release_control(); +} + +#else /* !CONFIG_SMP */ + +static inline int xnarch_hook_ipi (void (*handler)(void)) +{ + return 0; +} + +static inline int xnarch_release_ipi (void) +{ + return 0; +} + +#define xnarch_notify_halt() rthal_release_control() + +#endif /* CONFIG_SMP */ + +static inline void xnarch_notify_shutdown(void) +{ +#if defined(CONFIG_SMP) && defined(MODULE) + /* Make sure the shutdown sequence is kept on the same CPU + when running as a module. */ + set_cpus_allowed(current, cpumask_of_cpu(0)); +#endif /* CONFIG_SMP && MODULE */ +#ifdef CONFIG_XENO_OPT_PERVASIVE + xnshadow_release_events(); +#endif /* CONFIG_XENO_OPT_PERVASIVE */ + /* Wait for the currently processed events to drain. */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(50); + xnarch_release_ipi(); +} + +static void xnarch_notify_ready (void) +{ + rthal_grab_control(); +#ifdef CONFIG_XENO_OPT_PERVASIVE + xnshadow_grab_events(); +#endif /* CONFIG_XENO_OPT_PERVASIVE */ +} + +unsigned long long xnarch_get_host_time(void) +{ + struct timeval tv; + do_gettimeofday(&tv); + return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; +} + +EXPORT_SYMBOL(xnarch_get_host_time); + +unsigned long long xnarch_get_cpu_time(void) +{ + return xnarch_tsc_to_ns(xnarch_get_cpu_tsc()); +} + +EXPORT_SYMBOL(xnarch_get_cpu_time); + +#if defined(CONFIG_SMP) || XENO_DEBUG(XNLOCK) +void __xnlock_spin(xnlock_t *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS) +{ + unsigned int spin_limit; + int cpu = xnarch_current_cpu(); + + xnlock_dbg_prepare_spin(&spin_limit); + + while (atomic_cmpxchg(&lock->owner, ~0, cpu) != ~0) + do { + cpu_relax(); + xnlock_dbg_spinning(lock, cpu, &spin_limit /*, */ + XNLOCK_DBG_PASS_CONTEXT); + } while(atomic_read(&lock->owner) != ~0); +} +EXPORT_SYMBOL(__xnlock_spin); +#endif /* CONFIG_SMP */ + +#endif /* !_XENO_ASM_GENERIC_BITS_POD_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/sigshadow.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/sigshadow.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/sigshadow.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/sigshadow.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,6 @@ +#ifndef _XENO_ASM_GENERIC_BITS_SIGSHADOW_H +#define _XENO_ASM_GENERIC_BITS_SIGSHADOW_H + +void xeno_sigshadow_install_once(void); + +#endif /* _XENO_ASM_GENERIC_BITS_SIGSHADOW_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/timeconv.h relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/timeconv.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/bits/timeconv.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/bits/timeconv.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2009 Philippe Gerum . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _XENO_ASM_GENERIC_BITS_TIMECONV_H +#define _XENO_ASM_GENERIC_BITS_TIMECONV_H + +#include + +static unsigned long long clockfreq; + +#ifdef XNARCH_HAVE_LLMULSHFT +static unsigned int tsc_scale, tsc_shift; +#ifdef XNARCH_HAVE_NODIV_LLIMD +static rthal_u32frac_t tsc_frac; +static rthal_u32frac_t bln_frac; +#endif +#endif + +#ifdef XNARCH_HAVE_LLMULSHFT +long long xnarch_tsc_to_ns(long long ticks) +{ + return xnarch_llmulshft(ticks, tsc_scale, tsc_shift); +} + +long long xnarch_tsc_to_ns_rounded(long long ticks) +{ + unsigned int shift = tsc_shift - 1; + return (xnarch_llmulshft(ticks, tsc_scale, shift) + 1) / 2; +} + +#ifdef XNARCH_HAVE_NODIV_LLIMD +long long xnarch_ns_to_tsc(long long ns) +{ + return xnarch_nodiv_llimd(ns, tsc_frac.frac, tsc_frac.integ); +} + +unsigned long long xnarch_divrem_billion(unsigned long long value, + unsigned long *rem) +{ + unsigned long long q; + unsigned r; + + q = xnarch_nodiv_ullimd(value, bln_frac.frac, bln_frac.integ); + r = value - q * 1000000000; + if (r >= 1000000000) { + ++q; + r -= 1000000000; + } + *rem = r; + return q; +} +#else /* !XNARCH_HAVE_NODIV_LLIMD */ +long long xnarch_ns_to_tsc(long long ns) +{ + return xnarch_llimd(ns, 1 << tsc_shift, tsc_scale); +} +#endif /* !XNARCH_HAVE_NODIV_LLIMD */ + +#else /* !XNARCH_HAVE_LLMULSHFT */ + +long long xnarch_tsc_to_ns(long long ticks) +{ + return xnarch_llimd(ticks, 1000000000, clockfreq); +} + +long long xnarch_tsc_to_ns_rounded(long long ticks) +{ + return (xnarch_llimd(ticks, 1000000000, clockfreq/2) + 1) / 2; +} + +long long xnarch_ns_to_tsc(long long ns) +{ + return xnarch_llimd(ns, clockfreq, 1000000000); +} +#endif /* !XNARCH_HAVE_LLMULSHFT */ + +#ifndef XNARCH_HAVE_NODIV_LLIMD +unsigned long long xnarch_divrem_billion(unsigned long long value, + unsigned long *rem) +{ + return xnarch_ulldiv(value, 1000000000, rem); + +} +#endif /* !XNARCH_HAVE_NODIV_LLIMD */ + +static void xnarch_init_timeconv(unsigned long long freq) +{ + clockfreq = freq; +#ifdef XNARCH_HAVE_LLMULSHFT + xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift); +#ifdef XNARCH_HAVE_NODIV_LLIMD + xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale); + xnarch_init_u32frac(&bln_frac, 1, 1000000000); +#endif +#endif +} + +#ifdef __KERNEL__ +EXPORT_SYMBOL(xnarch_tsc_to_ns); +EXPORT_SYMBOL(xnarch_ns_to_tsc); +EXPORT_SYMBOL(xnarch_divrem_billion); +#endif /* __KERNEL__ */ + +#endif /* !_XENO_ASM_GENERIC_BITS_TIMECONV_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/features.h relase/linux-2.6.35.9//include/asm-generic/xenomai/features.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/features.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/features.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005 Philippe Gerum . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _XENO_ASM_GENERIC_FEATURES_H +#define _XENO_ASM_GENERIC_FEATURES_H + +#ifdef __KERNEL__ +#include +#ifndef xnfeatinfo_archdep +#define collect_arch_features(finfo) do { (void)(finfo); } while (0) +#endif /* !xnfeatinfo_archdep */ +#else /* !__KERNEL__ */ +#include +#endif /* __KERNEL__ */ + +#define XNFEAT_STRING_LEN 64 + +typedef struct xnfeatinfo { + unsigned long feat_all; /* Available feature set. */ + char feat_all_s[XNFEAT_STRING_LEN]; + unsigned long feat_man; /* Mandatory features (when requested). */ + char feat_man_s[XNFEAT_STRING_LEN]; + unsigned long feat_req; /* Requested feature set. */ + char feat_req_s[XNFEAT_STRING_LEN]; + unsigned long feat_mis; /* Missing features. */ + char feat_mis_s[XNFEAT_STRING_LEN]; +#ifdef xnfeatinfo_archdep + struct xnfeatinfo_archdep feat_arch; /* Arch-dep extension. */ +#endif + unsigned long feat_abirev; /* ABI revision level. */ +} xnfeatinfo_t; + +#define __xn_feat_smp 0x80000000 +#define __xn_feat_nosmp 0x40000000 +#define __xn_feat_fastsynch 0x20000000 +#define __xn_feat_nofastsynch 0x10000000 + +#ifdef CONFIG_SMP +#define __xn_feat_smp_mask __xn_feat_smp +#else +#define __xn_feat_smp_mask __xn_feat_nosmp +#endif + +#ifdef CONFIG_XENO_FASTSYNCH +#define __xn_feat_fastsynch_mask __xn_feat_fastsynch +#else +#define __xn_feat_fastsynch_mask __xn_feat_nofastsynch +#endif + +/* List of generic features kernel or userland may support */ +#define __xn_feat_generic_mask \ + (__xn_feat_smp_mask | __xn_feat_fastsynch_mask) + +/* List of features both sides have to agree on: + If userland supports it, the kernel has to provide it, too. */ +#define __xn_feat_generic_man_mask \ + (__xn_feat_fastsynch | __xn_feat_nofastsynch | __xn_feat_nosmp) + +static inline const char *get_generic_feature_label (unsigned feature) +{ + switch (feature) { + case __xn_feat_smp: + return "smp"; + case __xn_feat_nosmp: + return "nosmp"; + case __xn_feat_fastsynch: + return "fastsynch"; + case __xn_feat_nofastsynch: + return "nofastsynch"; + default: + return 0; + } +} + +#endif /* !_XENO_ASM_GENERIC_FEATURES_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/hal.h relase/linux-2.6.35.9//include/asm-generic/xenomai/hal.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/hal.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/hal.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,707 @@ +/** + * @ingroup hal + * @file + * + * Generic Real-Time HAL. + * Copyright © 2005 Philippe Gerum. + * + * 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, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; 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. + */ + +/** + * @addtogroup hal + *@{*/ + +#ifndef _XENO_ASM_GENERIC_HAL_H +#define _XENO_ASM_GENERIC_HAL_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#include +#endif + +#define RTHAL_DOMAIN_ID 0x58454e4f + +#define RTHAL_TIMER_FREQ (rthal_tunables.timer_freq) +#define RTHAL_CLOCK_FREQ (rthal_tunables.clock_freq) +#define RTHAL_CPU_FREQ (rthal_tunables.cpu_freq) +#define RTHAL_NR_APCS BITS_PER_LONG + +#define RTHAL_EVENT_PROPAGATE 0 +#define RTHAL_EVENT_STOP 1 + +#define RTHAL_NR_CPUS IPIPE_NR_CPUS +#define RTHAL_NR_FAULTS IPIPE_NR_FAULTS +#define RTHAL_NR_IRQS IPIPE_NR_IRQS +#define RTHAL_VIRQ_BASE IPIPE_VIRQ_BASE + +#define rthal_virtual_irq_p(irq) ((irq) >= RTHAL_VIRQ_BASE && \ + (irq) < RTHAL_NR_IRQS) + +#define RTHAL_SERVICE_IPI0 IPIPE_SERVICE_IPI0 +#define RTHAL_SERVICE_VECTOR0 IPIPE_SERVICE_VECTOR0 +#define RTHAL_SERVICE_IPI1 IPIPE_SERVICE_IPI1 +#define RTHAL_SERVICE_VECTOR1 IPIPE_SERVICE_VECTOR1 +#define RTHAL_SERVICE_IPI2 IPIPE_SERVICE_IPI2 +#define RTHAL_SERVICE_VECTOR2 IPIPE_SERVICE_VECTOR2 +#define RTHAL_SERVICE_IPI3 IPIPE_SERVICE_IPI3 +#define RTHAL_SERVICE_VECTOR3 IPIPE_SERVICE_VECTOR3 +#define RTHAL_CRITICAL_IPI IPIPE_CRITICAL_IPI + +enum rthal_ktimer_mode { /* Must follow enum clock_event_mode */ + KTIMER_MODE_UNUSED = 0, + KTIMER_MODE_SHUTDOWN, + KTIMER_MODE_PERIODIC, + KTIMER_MODE_ONESHOT, +}; + +typedef struct ipipe_domain rthal_pipeline_stage_t; + +#ifdef IPIPE_SPIN_LOCK_UNLOCKED +typedef ipipe_spinlock_t rthal_spinlock_t; +#define RTHAL_SPIN_LOCK_UNLOCKED IPIPE_SPIN_LOCK_UNLOCKED +#else /* !IPIPE_SPIN_LOCK_UNLOCKED */ +#ifdef RAW_SPIN_LOCK_UNLOCKED +typedef raw_spinlock_t rthal_spinlock_t; +#define RTHAL_SPIN_LOCK_UNLOCKED RAW_SPIN_LOCK_UNLOCKED +#else /* !RAW_SPIN_LOCK_UNLOCKED */ +typedef spinlock_t rthal_spinlock_t; +#define RTHAL_SPIN_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED +#endif /* !RAW_SPIN_LOCK_UNLOCKED */ +#endif /* !IPIPE_SPIN_LOCK_UNLOCKED */ + +#define rthal_irq_cookie(ipd,irq) __ipipe_irq_cookie(ipd,irq) +#define rthal_irq_handler(ipd,irq) __ipipe_irq_handler(ipd,irq) + +#define rthal_cpudata_irq_hits(ipd,cpu,irq) __ipipe_cpudata_irq_hits(ipd,cpu,irq) + +#ifndef local_irq_save_hw_smp +#ifdef CONFIG_SMP +#define local_irq_save_hw_smp(flags) local_irq_save_hw(flags) +#define local_irq_restore_hw_smp(flags) local_irq_restore_hw(flags) +#else /* !CONFIG_SMP */ +#define local_irq_save_hw_smp(flags) do { (void)(flags); } while (0) +#define local_irq_restore_hw_smp(flags) do { } while (0) +#endif /* !CONFIG_SMP */ +#endif /* !local_irq_save_hw_smp */ + +/* I-pipe domain priorities and virtual interrupt mask handling. If + the invariant pipeline head feature is enabled for Xenomai, use + it. */ +#define RTHAL_ROOT_PRIO IPIPE_ROOT_PRIO +#ifdef CONFIG_XENO_OPT_PIPELINE_HEAD +#define RTHAL_XENO_PRIO IPIPE_HEAD_PRIORITY +#define rthal_local_irq_disable() ipipe_stall_pipeline_head() +#define rthal_local_irq_enable() ipipe_unstall_pipeline_head() +#define rthal_local_irq_save(x) ((x) = ipipe_test_and_stall_pipeline_head() & 1) +#define rthal_local_irq_restore(x) ipipe_restore_pipeline_head(x) +#else /* !CONFIG_XENO_OPT_PIPELINE_HEAD */ +#define RTHAL_XENO_PRIO (RTHAL_ROOT_PRIO + 100) +#define rthal_local_irq_disable() ipipe_stall_pipeline_from(&rthal_domain) +#define rthal_local_irq_enable() ipipe_unstall_pipeline_from(&rthal_domain) +#define rthal_local_irq_save(x) ((x) = ipipe_test_and_stall_pipeline_from(&rthal_domain) & 1) +#define rthal_local_irq_restore(x) ipipe_restore_pipeline_from(&rthal_domain,(x)) +#endif /* !CONFIG_XENO_OPT_PIPELINE_HEAD */ +#define rthal_local_irq_flags(x) ((x) = ipipe_test_pipeline_from(&rthal_domain) & 1) +#define rthal_local_irq_test() ipipe_test_pipeline_from(&rthal_domain) +#define rthal_local_irq_disabled() \ +({ \ + unsigned long __flags, __ret; \ + local_irq_save_hw_smp(__flags); \ + __ret = ipipe_test_pipeline_from(&rthal_domain); \ + local_irq_restore_hw_smp(__flags); \ + __ret; \ +}) +#define rthal_stage_irq_enable(dom) ipipe_unstall_pipeline_from(dom) +#define rthal_local_irq_save_hw(x) local_irq_save_hw(x) +#define rthal_local_irq_restore_hw(x) local_irq_restore_hw(x) +#define rthal_local_irq_enable_hw() local_irq_enable_hw() +#define rthal_local_irq_disable_hw() local_irq_disable_hw() +#define rthal_local_irq_flags_hw(x) local_save_flags_hw(x) + +#ifdef spin_lock_hw +#define rthal_spin_lock_init(lock) spin_lock_init(lock) +#define rthal_spin_lock(lock) spin_lock_hw(lock) +#define rthal_spin_unlock(lock) spin_unlock_hw(lock) +#else /* !spin_lock_hw */ +#define rthal_spin_lock_init(lock) *(lock) = IPIPE_SPIN_LOCK_UNLOCKED +#define rthal_spin_lock(lock) spin_lock(lock) +#define rthal_spin_unlock(lock) spin_unlock(lock) +#endif /* !spin_lock_hw */ + +#define rthal_root_domain ipipe_root_domain +#define rthal_current_domain ipipe_current_domain + +#define rthal_suspend_domain() ipipe_suspend_domain() +#define rthal_grab_superlock(syncfn) ipipe_critical_enter(syncfn) +#define rthal_release_superlock(x) ipipe_critical_exit(x) +#define rthal_set_irq_affinity(irq,aff) ipipe_set_irq_affinity(irq,aff) +#ifdef __IPIPE_FEATURE_FASTPEND_IRQ +/* We use the faster form assuming that hw IRQs are off at call site. */ +#define rthal_schedule_irq_head(irq) __ipipe_schedule_irq_head(irq) +#define rthal_schedule_irq_root(irq) __ipipe_schedule_irq_root(irq) +#define rthal_propagate_irq(irq) __ipipe_propagate_irq(irq) +#else /* !__IPIPE_FEATURE_FASTPEND_IRQ */ +#define rthal_schedule_irq_head(irq) ipipe_schedule_irq(irq) +#define rthal_schedule_irq_root(irq) ipipe_schedule_irq(irq) +#define rthal_propagate_irq(irq) ipipe_propagate_irq(irq) +#endif /* !__IPIPE_FEATURE_FASTPEND_IRQ */ +#define rthal_virtualize_irq(dom,irq,isr,cookie,ackfn,mode) \ + ipipe_virtualize_irq(dom,irq,isr,cookie,ackfn,mode) +#define rthal_alloc_virq() ipipe_alloc_virq() +#define rthal_free_virq(irq) ipipe_free_virq(irq) +#define rthal_trigger_irq(irq) ipipe_trigger_irq(irq) +#define rthal_get_sysinfo(ibuf) ipipe_get_sysinfo(ibuf) +#define rthal_alloc_ptdkey() ipipe_alloc_ptdkey() +#define rthal_free_ptdkey(key) ipipe_free_ptdkey(key) +#define rthal_send_ipi(irq,cpus) ipipe_send_ipi(irq,cpus) +#define rthal_lock_irq(dom,cpu,irq) __ipipe_lock_irq(dom,cpu,irq) +#define rthal_unlock_irq(dom,irq) __ipipe_unlock_irq(dom,irq) +#ifdef __IPIPE_FEATURE_PIC_MUTE +#define rthal_mute_pic() ipipe_mute_pic() +#define rthal_unmute_pic() ipipe_unmute_pic() +#else /* !__IPIPE_FEATURE_PIC_MUTE */ +#define rthal_mute_pic() do { } while(0) +#define rthal_unmute_pic() do { } while(0) +#endif /* __IPIPE_FEATURE_PIC_MUTE */ + +#define rthal_processor_id() ipipe_processor_id() + +#define rthal_setsched_root(t,pol,prio) ipipe_setscheduler_root(t,pol,prio) +#define rthal_reenter_root(t,pol,prio) ipipe_reenter_root(t,pol,prio) +#define rthal_emergency_console() ipipe_set_printk_sync(ipipe_current_domain) +#define rthal_read_tsc(v) ipipe_read_tsc(v) + +#ifdef __IPIPE_FEATURE_SYSINFO_V2 + +static inline unsigned long rthal_get_cpufreq(void) +{ + struct ipipe_sysinfo sysinfo; + rthal_get_sysinfo(&sysinfo); + return (unsigned long)sysinfo.sys_cpu_freq; +} + +static inline unsigned long rthal_get_timerfreq(void) +{ + struct ipipe_sysinfo sysinfo; + rthal_get_sysinfo(&sysinfo); + return (unsigned long)sysinfo.sys_hrtimer_freq; +} + +static inline unsigned long rthal_get_clockfreq(void) +{ + struct ipipe_sysinfo sysinfo; + rthal_get_sysinfo(&sysinfo); + return (unsigned long)sysinfo.sys_hrclock_freq; +} + +#else /* !__IPIPE_FEATURE_SYSINFO_V2 */ + +static inline unsigned long rthal_get_cpufreq(void) +{ + struct ipipe_sysinfo sysinfo; + rthal_get_sysinfo(&sysinfo); + return (unsigned long)sysinfo.cpufreq; +} + +static inline unsigned long rthal_get_timerfreq(void) +{ + struct ipipe_sysinfo sysinfo; + rthal_get_sysinfo(&sysinfo); + return (unsigned long)sysinfo.archdep.tmfreq; +} + +static inline unsigned long rthal_get_clockfreq(void) +{ + return rthal_get_cpufreq(); +} + +#endif /* !__IPIPE_FEATURE_SYSINFO_V2 */ + +#define RTHAL_DECLARE_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + return do_##hdlr(event,ipd->domid,data); \ +} + +#define RTHAL_DECLARE_SCHEDULE_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct task_struct *p = (struct task_struct *)data; \ + do_##hdlr(p); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#define RTHAL_DECLARE_SETSCHED_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct task_struct *p = (struct task_struct *)data; \ + do_##hdlr(p, p->rt_priority); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#define RTHAL_DECLARE_SIGWAKE_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct task_struct *p = (struct task_struct *)data; \ + do_##hdlr(p); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#define RTHAL_DECLARE_EXIT_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct task_struct *p = (struct task_struct *)data; \ + do_##hdlr(p); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#define RTHAL_DECLARE_CLEANUP_EVENT(hdlr) \ +static int hdlr (unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct mm_struct *mm = (struct mm_struct *)data; \ + do_##hdlr(mm); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#define RTHAL_DECLARE_MAYDAY_EVENT(hdlr) \ +static int hdlr(unsigned event, struct ipipe_domain *ipd, void *data) \ +{ \ + struct pt_regs *regs = data; \ + do_##hdlr(regs); \ + return RTHAL_EVENT_PROPAGATE; \ +} + +#ifndef TASK_ATOMICSWITCH +#ifdef CONFIG_PREEMPT +/* We want this feature for preemptible kernels, or the behaviour when + switching execution modes between Xenomai and Linux domains would + be unreliable. */ +#error "Adeos: atomic task switch support is missing; upgrading\n" \ + " to a recent I-pipe version is required." +#endif /* CONFIG_PREEMPT */ +/* I-pipe releases for 2.4 kernels don't have this task mode bit + defined, so fake it. */ +#define TASK_ATOMICSWITCH 0 +#endif /* !TASK_ATOMICSWITCH */ + +static inline void set_task_nowakeup(struct task_struct *p) +{ + if (p->state & (TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE)) + set_task_state(p, p->state | TASK_NOWAKEUP); + +} +static inline void clear_task_nowakeup(struct task_struct *p) +{ + set_task_state(p, p->state & ~TASK_NOWAKEUP); +} + +#if defined(VM_PINNED) || defined(MMF_VM_PINNED) +#define rthal_disable_ondemand_mappings(tsk) ipipe_disable_ondemand_mappings(tsk) +#else /* !(VM_PINNED || MMF_VM_PINNED) */ +/* In case the I-pipe does not allow disabling ondemand mappings. */ +#define rthal_disable_ondemand_mappings(tsk) (0) +#endif /* !(VM_PINNED || MMF_VM_PINNED) */ + +#define rthal_set_foreign_stack(ipd) ipipe_set_foreign_stack(ipd) +#define rthal_clear_foreign_stack(ipd) ipipe_clear_foreign_stack(ipd) + +#ifdef __IPIPE_FEATURE_ENABLE_NOTIFIER +#define rthal_enable_notifier(p) ipipe_enable_notifier(p) +#else +static inline void rthal_enable_notifier(struct task_struct *p) +{ + p->flags |= PF_EVNOTIFY; +} +#endif + +#define rthal_catch_cleanup(hdlr) \ + ipipe_catch_event(ipipe_root_domain,IPIPE_EVENT_CLEANUP,hdlr) +#define rthal_catch_taskexit(hdlr) \ + ipipe_catch_event(ipipe_root_domain,IPIPE_EVENT_EXIT,hdlr) +#define rthal_catch_sigwake(hdlr) \ + ipipe_catch_event(ipipe_root_domain,IPIPE_EVENT_SIGWAKE,hdlr) +#define rthal_catch_schedule(hdlr) \ + ipipe_catch_event(ipipe_root_domain,IPIPE_EVENT_SCHEDULE,hdlr) +#define rthal_catch_setsched(hdlr) \ + ipipe_catch_event(&rthal_domain,IPIPE_EVENT_SETSCHED,hdlr) +#define rthal_catch_losyscall(hdlr) \ + ipipe_catch_event(ipipe_root_domain,IPIPE_EVENT_SYSCALL,hdlr) +#define rthal_catch_hisyscall(hdlr) \ + ipipe_catch_event(&rthal_domain,IPIPE_EVENT_SYSCALL,hdlr) +#define rthal_catch_exception(ex,hdlr) \ + ipipe_catch_event(&rthal_domain,ex|IPIPE_EVENT_SELF,hdlr) + +#ifdef IPIPE_EVENT_RETURN +#define RTHAL_HAVE_RETURN_EVENT +#define rthal_catch_return(hdlr) \ + ipipe_catch_event(&rthal_domain,IPIPE_EVENT_RETURN,hdlr) +#define rthal_return_intercept(p) ipipe_return_notify(p) +#else +#define rthal_catch_return(hdlr) do { } while(0) +#endif + +#define rthal_register_domain(_dom,_name,_id,_prio,_entry) \ +({ \ + struct ipipe_domain_attr attr; \ + ipipe_init_attr(&attr); \ + attr.name = _name; \ + attr.entry = _entry; \ + attr.domid = _id; \ + attr.priority = _prio; \ + ipipe_register_domain(_dom,&attr); \ +}) + +#define rthal_unregister_domain(dom) ipipe_unregister_domain(dom) + +#define RTHAL_DECLARE_DOMAIN(entry) \ + void entry (void) \ + { \ + do_##entry(); \ + } + +extern void rthal_domain_entry(void); + +#define rthal_spin_lock_irq(lock) \ + do { \ + rthal_local_irq_disable(); \ + rthal_spin_lock(lock); \ + } while(0) + +#define rthal_spin_unlock_irq(lock) \ + do { \ + rthal_spin_unlock(lock); \ + rthal_local_irq_enable(); \ + } while(0) + +#define rthal_spin_lock_irqsave(lock,x) \ + do { \ + rthal_local_irq_save(x); \ + rthal_spin_lock(lock); \ + } while(0) + +#define rthal_spin_unlock_irqrestore(lock,x) \ + do { \ + rthal_spin_unlock(lock); \ + rthal_local_irq_restore(x); \ + } while(0) + +#define rthal_printk printk + +typedef ipipe_irq_handler_t rthal_irq_handler_t; +typedef ipipe_irq_ackfn_t rthal_irq_ackfn_t; + +struct rthal_calibration_data { + unsigned long cpu_freq; + unsigned long timer_freq; + unsigned long clock_freq; +}; + +typedef int (*rthal_trap_handler_t)(unsigned trapno, + unsigned domid, + void *data); + +extern unsigned long rthal_cpufreq_arg; + +extern unsigned long rthal_timerfreq_arg; + +extern unsigned long rthal_clockfreq_arg; + +extern rthal_pipeline_stage_t rthal_domain; + +extern struct rthal_calibration_data rthal_tunables; + +extern volatile int rthal_sync_op; + +extern rthal_trap_handler_t rthal_trap_handler; + +extern unsigned rthal_realtime_faults[RTHAL_NR_CPUS][RTHAL_NR_FAULTS]; + +extern unsigned long rthal_apc_pending[RTHAL_NR_CPUS]; + +extern unsigned int rthal_apc_virq; + +extern int rthal_arch_init(void); + +extern void rthal_arch_cleanup(void); + + /* Private interface -- Internal use only */ + +unsigned long rthal_critical_enter(void (*synch)(void)); + +void rthal_critical_exit(unsigned long flags); + +#ifdef CONFIG_XENO_HW_NMI_DEBUG_LATENCY + +extern unsigned rthal_maxlat_us; + +extern unsigned long rthal_maxlat_tsc; + +void rthal_nmi_init(void (*emergency)(struct pt_regs *)); + +int rthal_nmi_request(void (*emergency)(struct pt_regs *)); + +void rthal_nmi_release(void); + +void rthal_nmi_arm(unsigned long delay); + +void rthal_nmi_disarm(void); + +void rthal_nmi_proc_register(void); + +void rthal_nmi_proc_unregister(void); + +#else /* !CONFIG_XENO_HW_NMI_DEBUG_LATENCY */ +#define rthal_nmi_init(efn) do { } while(0) +#define rthal_nmi_release() do { } while(0) +#define rthal_nmi_proc_register() do { } while(0) +#define rthal_nmi_proc_unregister() do { } while(0) +#endif /* CONFIG_XENO_HW_NMI_DEBUG_LATENCY */ + + /* Public interface */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int rthal_init(void); + +void rthal_exit(void); + +int rthal_irq_request(unsigned irq, + rthal_irq_handler_t handler, + rthal_irq_ackfn_t ackfn, + void *cookie); + +int rthal_irq_release(unsigned irq); + +int rthal_irq_enable(unsigned irq); + +int rthal_irq_disable(unsigned irq); + +int rthal_irq_end(unsigned irq); + +int rthal_irq_host_request(unsigned irq, + rthal_irq_host_handler_t handler, + char *name, + void *dev_id); + +int rthal_irq_host_release(unsigned irq, + void *dev_id); + +static inline void rthal_irq_host_pend(unsigned irq) +{ + rthal_propagate_irq(irq); +} + +int rthal_apc_alloc(const char *name, + void (*handler)(void *cookie), + void *cookie); + +void rthal_apc_free(int apc); + +static inline void __rthal_apc_schedule(int apc) +{ + int cpu = rthal_processor_id(); + if (!__test_and_set_bit(apc, &rthal_apc_pending[cpu])) + rthal_schedule_irq_root(rthal_apc_virq); +} + +static inline void rthal_apc_schedule(int apc) +{ + unsigned long flags; + + rthal_local_irq_save(flags); + __rthal_apc_schedule(apc); + rthal_local_irq_restore(flags); +} + +int rthal_irq_affinity(unsigned irq, + cpumask_t cpumask, + cpumask_t *oldmask); + +rthal_trap_handler_t rthal_trap_catch(rthal_trap_handler_t handler); + +unsigned long rthal_timer_calibrate(void); + +#ifdef CONFIG_GENERIC_CLOCKEVENTS +int rthal_timer_request(void (*tick_handler)(void), + void (*mode_emul)(enum clock_event_mode mode, struct clock_event_device *cdev), + int (*tick_emul) (unsigned long delay, struct clock_event_device *cdev), + int cpu); + +void rthal_timer_notify_switch(enum clock_event_mode mode, + struct clock_event_device *cdev); + +#else +int rthal_timer_request(void (*tick_handler)(void), + int cpu); +#endif + +void rthal_timer_release(int cpu); + +#ifdef CONFIG_SMP +extern cpumask_t rthal_supported_cpus; + +static inline int rthal_cpu_supported(int cpu) +{ + return cpu_isset(cpu, rthal_supported_cpus); +} +#else /* !CONFIG_SMP */ +#define rthal_supported_cpus CPU_MASK_ALL + +static inline int rthal_cpu_supported(int cpu) +{ + return 1; +} +#endif /* !CONFIG_SMP */ + +#ifdef CONFIG_PROC_FS + +#include + +extern struct proc_dir_entry *rthal_proc_root; + +struct proc_dir_entry *rthal_add_proc_leaf(const char *name, + read_proc_t rdproc, + write_proc_t wrproc, + void *data, + struct proc_dir_entry *parent); + +struct proc_dir_entry *rthal_add_proc_seq(const char *name, + struct file_operations *fops, + size_t size, + struct proc_dir_entry *parent); +#endif /* CONFIG_PROC_FS */ + +#ifdef CONFIG_IPIPE_TRACE +#include + +static inline int rthal_trace_max_begin(unsigned long v) +{ + ipipe_trace_begin(v); + return 0; +} + +static inline int rthal_trace_max_end(unsigned long v) +{ + ipipe_trace_end(v); + return 0; +} + +static inline int rthal_trace_max_reset(void) +{ + ipipe_trace_max_reset(); + return 0; +} + +static inline int rthal_trace_user_start(void) +{ + return ipipe_trace_frozen_reset(); +} + +static inline int rthal_trace_user_stop(unsigned long v) +{ + ipipe_trace_freeze(v); + return 0; +} + +static inline int rthal_trace_user_freeze(unsigned long v, int once) +{ + int err = 0; + + if (!once) + err = ipipe_trace_frozen_reset(); + ipipe_trace_freeze(v); + return err; +} + +static inline int rthal_trace_special(unsigned char id, unsigned long v) +{ + ipipe_trace_special(id, v); + return 0; +} + +static inline int rthal_trace_special_u64(unsigned char id, + unsigned long long v) +{ + ipipe_trace_special(id, (unsigned long)(v >> 32)); + ipipe_trace_special(id, (unsigned long)(v & 0xFFFFFFFF)); + return 0; +} + +static inline int rthal_trace_pid(pid_t pid, short prio) +{ + ipipe_trace_pid(pid, prio); + return 0; +} + +static inline int rthal_trace_tick(unsigned long delay_tsc) +{ +#ifdef __IPIPE_FEATURE_TRACE_EVENT + ipipe_trace_event(0, delay_tsc); + return 0; +#else + return -ENOSYS; +#endif +} + +static inline int rthal_trace_panic_freeze(void) +{ + ipipe_trace_panic_freeze(); + return 0; +} + +static inline int rthal_trace_panic_dump(void) +{ + ipipe_trace_panic_dump(); + return 0; +} + +#else /* !CONFIG_IPIPE_TRACE */ + +#define rthal_trace_max_begin(v) ({int err = -ENOSYS; err; }) +#define rthal_trace_max_end(v) ({int err = -ENOSYS; err; }) +#define rthal_trace_max_reset(v) ({int err = -ENOSYS; err; }) +#define rthal_trace_user_start() ({int err = -ENOSYS; err; }) +#define rthal_trace_user_stop(v) ({int err = -ENOSYS; err; }) +#define rthal_trace_user_freeze(v, once) ({int err = -ENOSYS; err; }) +#define rthal_trace_special(id, v) ({int err = -ENOSYS; err; }) +#define rthal_trace_special_u64(id, v) ({int err = -ENOSYS; err; }) +#define rthal_trace_pid(pid, prio) ({int err = -ENOSYS; err; }) +#define rthal_trace_tick(delay_tsc) ({int err = -ENOSYS; err; }) +#define rthal_trace_panic_freeze() ({int err = -ENOSYS; err; }) +#define rthal_trace_panic_dump() ({int err = -ENOSYS; err; }) + +#endif /* CONFIG_IPIPE_TRACE */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/*@}*/ + +#endif /* !_XENO_ASM_GENERIC_HAL_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/pci_ids.h relase/linux-2.6.35.9//include/asm-generic/xenomai/pci_ids.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/pci_ids.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/pci_ids.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,43 @@ +#ifndef _XENO_ASM_GENERIC_PCI_IDS_H +#define _XENO_ASM_GENERIC_PCI_IDS_H + +#include + +/* SMI */ +#ifndef PCI_DEVICE_ID_INTEL_ESB2_0 +#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH7_0 +#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH7_1 +#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH8_4 +#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH9_1 +#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH9_5 +#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ICH10_1 +#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16 +#endif +#ifndef PCI_DEVICE_ID_INTEL_PCH_LPC_MIN +#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN 0x3b00 +#endif + +/* RTCAN */ +#ifndef PCI_VENDOR_ID_ESDGMBH +#define PCI_VENDOR_ID_ESDGMBH 0x12fe +#endif +#ifndef PCI_DEVICE_ID_PLX_9030 +#define PCI_DEVICE_ID_PLX_9030 0x9030 +#endif +#ifndef PCI_DEVICE_ID_PLX_9056 +#define PCI_DEVICE_ID_PLX_9056 0x9056 +#endif + +#endif /* _XENO_ASM_GENERIC_PCI_IDS_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/stack.h relase/linux-2.6.35.9//include/asm-generic/xenomai/stack.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/stack.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/stack.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,34 @@ +#ifndef STACKSIZE_H +#define STACKSIZE_H + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static inline unsigned xeno_stacksize(unsigned size) +{ + static const unsigned default_size = __WORDSIZE * 1024; + static unsigned min_size; + if (!min_size) + min_size = PTHREAD_STACK_MIN + getpagesize(); + + if (!size) + size = default_size; + if (size < min_size) + size = min_size; + + return size; +} + +void xeno_fault_stack(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STACKSIZE_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/syscall.h relase/linux-2.6.35.9//include/asm-generic/xenomai/syscall.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/syscall.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/syscall.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_GENERIC_SYSCALL_H +#define _XENO_ASM_GENERIC_SYSCALL_H + +#include +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#else /* !__KERNEL__ */ +#include +#include +#endif /* !__KERNEL__ */ + +/* Xenomai multiplexer syscall. */ +#define __xn_sys_mux 555 /* Must fit within 15bit */ +/* Xenomai nucleus syscalls. */ +#define __xn_sys_bind 0 /* muxid = bind_to_interface(magic,featdep,abirev) */ +#define __xn_sys_completion 1 /* xnshadow_completion(&completion) */ +#define __xn_sys_migrate 2 /* switched = xnshadow_relax/harden() */ +#define __xn_sys_barrier 3 /* started = xnshadow_wait_barrier(&entry,&cookie) */ +#define __xn_sys_info 4 /* xnshadow_get_info(muxid,&info) */ +#define __xn_sys_arch 5 /* r = xnarch_local_syscall(args) */ +#define __xn_sys_trace 6 /* r = xntrace_xxx(...) */ +#define __xn_sys_sem_heap 7 +#define __xn_sys_current 8 /* threadh = xnthread_handle(cur) */ +#define __xn_sys_current_info 9 /* r = xnshadow_current_info(&info) */ +#define __xn_sys_get_next_sigs 10 /* only unqueue pending signals. */ +#define __xn_sys_drop_u_mode 11 /* stop updating thread->u_mode */ +#define __xn_sys_mayday 12 /* request mayday fixup */ + +#define XENOMAI_LINUX_DOMAIN 0 +#define XENOMAI_XENO_DOMAIN 1 + +typedef struct xnsysinfo { + unsigned long long clockfreq; /* Real-time clock frequency */ + unsigned long tickval; /* Tick duration (ns) */ + unsigned long vdso; /* Offset of nkvdso in the sem heap */ +} xnsysinfo_t; + +#define SIGSHADOW SIGWINCH +#define SIGSHADOW_ACTION_HARDEN 1 +#define SIGSHADOW_ACTION_RENICE 2 +#define sigshadow_action(code) ((code) & 0xff) +#define sigshadow_arg(code) (((code) >> 8) & 0xff) +#define sigshadow_int(action, arg) ((action) | ((arg) << 8)) + +#define SIGDEBUG SIGXCPU +#define SIGDEBUG_UNDEFINED 0 +#define SIGDEBUG_MIGRATE_SIGNAL 1 +#define SIGDEBUG_MIGRATE_SYSCALL 2 +#define SIGDEBUG_MIGRATE_FAULT 3 +#define SIGDEBUG_MIGRATE_PRIOINV 4 +#define SIGDEBUG_NOMLOCK 5 +#define SIGDEBUG_WATCHDOG 6 + +union xnsiginfo { + struct siginfo pse51_si; +}; + +struct xnsig { + unsigned nsigs; + unsigned remaining; + struct { + unsigned muxid; + union xnsiginfo si; + } pending[16]; +}; + +#ifdef __KERNEL__ + +struct task_struct; +struct pt_regs; + +#define XENOMAI_MAX_SYSENT 255 + +typedef struct _xnsysent { + + int (*svc)(struct pt_regs *regs); + +/* Syscall must run into the Linux domain. */ +#define __xn_exec_lostage 0x1 +/* Syscall must run into the Xenomai domain. */ +#define __xn_exec_histage 0x2 +/* Shadow syscall; caller must be mapped. */ +#define __xn_exec_shadow 0x4 +/* Switch back toggle; caller must return to its original mode. */ +#define __xn_exec_switchback 0x8 +/* Exec in current domain. */ +#define __xn_exec_current 0x10 +/* Exec in conforming domain, Xenomai or Linux. */ +#define __xn_exec_conforming 0x20 +/* Attempt syscall restart in the opposite domain upon -ENOSYS. */ +#define __xn_exec_adaptive 0x40 +/* Do not restart syscall upon signal receipt. */ +#define __xn_exec_norestart 0x80 +/* Context-agnostic syscall. Will actually run in Xenomai domain. */ +#define __xn_exec_any 0x0 +/* Short-hand for shadow init syscall. */ +#define __xn_exec_init __xn_exec_lostage +/* Short-hand for shadow syscall in Xenomai space. */ +#define __xn_exec_primary (__xn_exec_shadow|__xn_exec_histage) +/* Short-hand for shadow syscall in Linux space. */ +#define __xn_exec_secondary (__xn_exec_shadow|__xn_exec_lostage) + + unsigned long flags; + +} xnsysent_t; + +extern int nkthrptd; + +extern int nkerrptd; + +#define xnshadow_thrptd(t) ((t)->ptd[nkthrptd]) +#define xnshadow_thread(t) ((xnthread_t *)xnshadow_thrptd(t)) +/* The errno field must be addressable for plain Linux tasks too. */ +#define xnshadow_errno(t) (*(int *)&((t)->ptd[nkerrptd])) + +#define access_rok(addr, size) access_ok(VERIFY_READ, (addr), (size)) +#define access_wok(addr, size) access_ok(VERIFY_WRITE, (addr), (size)) + +#define __xn_copy_from_user(dstP, srcP, n) __copy_from_user_inatomic(dstP, srcP, n) +#define __xn_copy_to_user(dstP, srcP, n) __copy_to_user_inatomic(dstP, srcP, n) +#define __xn_put_user(src, dstP) __put_user(src, dstP) +#define __xn_get_user(dst, srcP) __get_user(dst, srcP) +#define __xn_strncpy_from_user(dstP, srcP, n) wrap_strncpy_from_user(dstP, srcP, n) + +static inline int __xn_safe_copy_from_user(void *dst, const void __user *src, + size_t size) +{ + return (!access_rok(src, size) || + __xn_copy_from_user(dst, src, size)) ? -EFAULT : 0; +} + +static inline int __xn_safe_copy_to_user(void __user *dst, const void *src, + size_t size) +{ + return (!access_wok(dst, size) || + __xn_copy_to_user(dst, src, size)) ? -EFAULT : 0; +} + +static inline int __xn_safe_strncpy_from_user(char *dst, + const char __user *src, size_t count) +{ + if (unlikely(!access_rok(src, 1))) + return -EFAULT; + return __xn_strncpy_from_user(dst, src, count); +} + +#else /* !__KERNEL__ */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +int __xnsig_dispatch(struct xnsig *sigs, int cumulated_error, int last_error); + +int __xnsig_dispatch_safe(struct xnsig *sigs, int cumulated_error, int last_error); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* Called to dispatch signals which interrupted a system call. */ +static inline int xnsig_dispatch(struct xnsig *sigs, int cumul, int last) +{ + if (sigs->nsigs) + return __xnsig_dispatch(sigs, cumul, last); + return last; +} + +static inline int xnsig_dispatch_safe(struct xnsig *sigs, int cumul, int last) +{ + if (sigs->nsigs) + return __xnsig_dispatch_safe(sigs, cumul, last); + return last; +} + +#endif /* !__KERNEL__ */ + +typedef struct xncompletion { + long syncflag; /* Semaphore variable. */ + pid_t pid; /* Single waiter ID. */ +} xncompletion_t; + +#endif /* !_XENO_ASM_GENERIC_SYSCALL_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/system.h relase/linux-2.6.35.9//include/asm-generic/xenomai/system.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/system.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/system.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum . + * Copyright (C) 2004,2005 Gilles Chanteperdrix . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _XENO_ASM_GENERIC_SYSTEM_H +#define _XENO_ASM_GENERIC_SYSTEM_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* debug support */ +#include + +#ifndef CONFIG_XENO_OPT_DEBUG_XNLOCK +#define CONFIG_XENO_OPT_DEBUG_XNLOCK 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Time base export */ +#define xnarch_declare_tbase(base) do { } while(0) + +/* Tracer interface */ +#define xnarch_trace_max_begin(v) rthal_trace_max_begin(v) +#define xnarch_trace_max_end(v) rthal_trace_max_end(v) +#define xnarch_trace_max_reset() rthal_trace_max_reset() +#define xnarch_trace_user_start() rthal_trace_user_start() +#define xnarch_trace_user_stop(v) rthal_trace_user_stop(v) +#define xnarch_trace_user_freeze(v, once) rthal_trace_user_freeze(v, once) +#define xnarch_trace_special(id, v) rthal_trace_special(id, v) +#define xnarch_trace_special_u64(id, v) rthal_trace_special_u64(id, v) +#define xnarch_trace_pid(pid, prio) rthal_trace_pid(pid, prio) +#define xnarch_trace_tick(delay_tsc) rthal_trace_tick(delay_tsc) +#define xnarch_trace_panic_freeze() rthal_trace_panic_freeze() +#define xnarch_trace_panic_dump() rthal_trace_panic_dump() + +#ifndef xnarch_fault_um +#define xnarch_fault_um(fi) user_mode(fi->regs) +#endif + +#define module_param_value(parm) (parm) + +typedef unsigned long spl_t; + +#define splhigh(x) rthal_local_irq_save(x) +#ifdef CONFIG_SMP +#define splexit(x) rthal_local_irq_restore((x) & 1) +#else /* !CONFIG_SMP */ +#define splexit(x) rthal_local_irq_restore(x) +#endif /* !CONFIG_SMP */ +#define splmax() rthal_local_irq_disable() +#define splnone() rthal_local_irq_enable() +#define spltest() rthal_local_irq_test() +#define splget(x) rthal_local_irq_flags(x) + +static inline unsigned xnarch_current_cpu(void) +{ + return rthal_processor_id(); +} + +#if XENO_DEBUG(XNLOCK) + +typedef struct { + + unsigned long long spin_time; + unsigned long long lock_time; + const char *file; + const char *function; + unsigned line; + +} xnlockinfo_t; + +typedef struct { + + atomic_t owner; + const char *file; + const char *function; + unsigned line; + int cpu; + unsigned long long spin_time; + unsigned long long lock_date; + +} xnlock_t; + +#define XNARCH_LOCK_UNLOCKED (xnlock_t) { \ + { ~0 }, \ + NULL, \ + NULL, \ + 0, \ + -1, \ + 0LL, \ + 0LL, \ +} + +#define XNLOCK_DBG_CONTEXT , __FILE__, __LINE__, __FUNCTION__ +#define XNLOCK_DBG_CONTEXT_ARGS \ + , const char *file, int line, const char *function +#define XNLOCK_DBG_PASS_CONTEXT , file, line, function +#define XNLOCK_DBG_MAX_SPINS 10000000 + +static inline void xnlock_dbg_prepare_acquire(unsigned long long *start) +{ + *start = rthal_rdtsc(); +} + +static inline void xnlock_dbg_prepare_spin(unsigned *spin_limit) +{ + *spin_limit = XNLOCK_DBG_MAX_SPINS; +} + +static inline void +xnlock_dbg_spinning(xnlock_t *lock, int cpu, unsigned int *spin_limit, + const char *file, int line, const char *function) +{ + if (--*spin_limit == 0) { + rthal_emergency_console(); + printk(KERN_ERR "Xenomai: stuck on nucleus lock %p\n" + " waiter = %s:%u (%s(), CPU #%d)\n" + " owner = %s:%u (%s(), CPU #%d)\n", + lock, file, line, function, cpu, + lock->file, lock->line, lock->function, lock->cpu); + show_stack(NULL, NULL); +#ifndef CONFIG_SMP + BUG(); +#endif + } +} + +static inline void +xnlock_dbg_acquired(xnlock_t *lock, int cpu, unsigned long long *start, + const char *file, int line, const char *function) +{ + lock->lock_date = *start; + lock->spin_time = rthal_rdtsc() - *start; + lock->file = file; + lock->function = function; + lock->line = line; + lock->cpu = cpu; +} + +static inline int xnlock_dbg_release(xnlock_t *lock) +{ + extern xnlockinfo_t xnlock_stats[]; + unsigned long long lock_time = rthal_rdtsc() - lock->lock_date; + int cpu = xnarch_current_cpu(); + xnlockinfo_t *stats = &xnlock_stats[cpu]; + + if (unlikely(atomic_read(&lock->owner) != cpu)) { + rthal_emergency_console(); + printk(KERN_ERR "Xenomai: unlocking unlocked nucleus lock %p" + " on CPU #%d\n" + " owner = %s:%u (%s(), CPU #%d)\n", + lock, cpu, lock->file, lock->line, lock->function, + lock->cpu); + show_stack(NULL,NULL); + return 1; + } + + lock->cpu = -lock->cpu; /* File that we released it. */ + + if (lock_time > stats->lock_time) { + stats->lock_time = lock_time; + stats->spin_time = lock->spin_time; + stats->file = lock->file; + stats->function = lock->function; + stats->line = lock->line; + } + return 0; +} + +#else /* !XENO_DEBUG(XNLOCK) */ + +typedef struct { atomic_t owner; } xnlock_t; + +#define XNARCH_LOCK_UNLOCKED (xnlock_t) { { ~0 } } + +#define XNLOCK_DBG_CONTEXT +#define XNLOCK_DBG_CONTEXT_ARGS +#define XNLOCK_DBG_PASS_CONTEXT + +static inline void xnlock_dbg_prepare_acquire(unsigned long long *start) { } +static inline void xnlock_dbg_prepare_spin(unsigned *spin_limit) { } + +static inline void +xnlock_dbg_spinning(xnlock_t *lock, int cpu, unsigned int *spin_limit) { } + +static inline void +xnlock_dbg_acquired(xnlock_t *lock, int cpu, unsigned long long *start) { } + +static inline int xnlock_dbg_release(xnlock_t *lock) +{ + return 0; +} + +#endif /* !XENO_DEBUG(XNLOCK) */ + +#define XNARCH_NR_CPUS RTHAL_NR_CPUS + +#define XNARCH_NR_IRQS RTHAL_NR_IRQS +#define XNARCH_TIMER_IRQ RTHAL_TIMER_IRQ +#define XNARCH_TIMER_DEVICE RTHAL_TIMER_DEVICE +#define XNARCH_CLOCK_DEVICE RTHAL_CLOCK_DEVICE + +#define XNARCH_PROMPT "Xenomai: " +#define xnarch_loginfo(fmt, args...) printk(KERN_INFO XNARCH_PROMPT fmt, ##args) +#define xnarch_logwarn(fmt, args...) printk(KERN_WARNING XNARCH_PROMPT fmt, ##args) +#define xnarch_logerr(fmt, args...) printk(KERN_ERR XNARCH_PROMPT fmt, ##args) +#define xnarch_printf(fmt, args...) printk(KERN_INFO XNARCH_PROMPT fmt, ##args) + +#ifndef RTHAL_SHARED_HEAP_FLAGS +#define XNARCH_SHARED_HEAP_FLAGS 0 +#else /* !RTHAL_SHARED_HEAP_FLAGS */ +#define XNARCH_SHARED_HEAP_FLAGS RTHAL_SHARED_HEAP_FLAGS +#endif /* !RTHAL_SHARED_HEAP_FLAGS */ + +typedef cpumask_t xnarch_cpumask_t; + +#ifdef CONFIG_SMP +#define xnarch_cpu_online_map cpu_online_map +#else +#define xnarch_cpu_online_map cpumask_of_cpu(0) +#endif +#define xnarch_num_online_cpus() num_online_cpus() +#define xnarch_cpu_set(cpu, mask) cpu_set(cpu, (mask)) +#define xnarch_cpu_clear(cpu, mask) cpu_clear(cpu, (mask)) +#define xnarch_cpus_clear(mask) cpus_clear(mask) +#define xnarch_cpu_isset(cpu, mask) cpu_isset(cpu, (mask)) +#define xnarch_cpus_and(dst, src1, src2) cpus_and((dst), (src1), (src2)) +#define xnarch_cpus_equal(mask1, mask2) cpus_equal((mask1), (mask2)) +#define xnarch_cpus_empty(mask) cpus_empty(mask) +#define xnarch_cpumask_of_cpu(cpu) cpumask_of_cpu(cpu) +#define xnarch_cpu_test_and_set(cpu, mask) cpu_test_and_set(cpu, (mask)) +#define xnarch_first_cpu(mask) first_cpu(mask) +#define XNARCH_CPU_MASK_ALL CPU_MASK_ALL + +#define xnarch_supported_cpus rthal_supported_cpus +#define xnarch_cpu_supported(cpu) rthal_cpu_supported(cpu) + +struct xnheap; + +typedef struct xnarch_heapcb { + + unsigned long numaps; /* # of active user-space mappings. */ + int kmflags; /* Kernel memory flags (0 if vmalloc()). */ + void *heapbase; /* Shared heap memory base. */ + void (*release)(struct xnheap *heap); /* callback upon last unmap */ + +} xnarch_heapcb_t; + +unsigned long long xnarch_get_host_time(void); + +unsigned long long xnarch_get_cpu_time(void); + +static inline unsigned long long xnarch_get_cpu_freq(void) +{ + return RTHAL_CPU_FREQ; +} + +static inline unsigned long long xnarch_get_clock_freq(void) +{ + return RTHAL_CLOCK_FREQ; +} + +#define xnarch_get_cpu_tsc rthal_rdtsc + +#define xnarch_halt(emsg) \ + do { \ + rthal_emergency_console(); \ + xnarch_logerr("fatal: %s\n", emsg); \ + show_stack(NULL,NULL); \ + xnarch_trace_panic_dump(); \ + for (;;) \ + cpu_relax(); \ + } while(0) + +static inline int xnarch_setimask (int imask) +{ + spl_t s; + + splhigh(s); + splexit(!!imask); + return !!s; +} + +static inline int xnarch_root_domain_p(void) +{ + return rthal_current_domain == rthal_root_domain; +} + +#if defined(CONFIG_SMP) || XENO_DEBUG(XNLOCK) + +#define xnlock_get(lock) __xnlock_get(lock XNLOCK_DBG_CONTEXT) +#define xnlock_get_irqsave(lock,x) \ + ((x) = __xnlock_get_irqsave(lock XNLOCK_DBG_CONTEXT)) +#define xnlock_clear_irqoff(lock) xnlock_put_irqrestore(lock, 1) +#define xnlock_clear_irqon(lock) xnlock_put_irqrestore(lock, 0) + +static inline void xnlock_init (xnlock_t *lock) +{ + *lock = XNARCH_LOCK_UNLOCKED; +} + +#define DECLARE_XNLOCK(lock) xnlock_t lock +#define DECLARE_EXTERN_XNLOCK(lock) extern xnlock_t lock +#define DEFINE_XNLOCK(lock) xnlock_t lock = XNARCH_LOCK_UNLOCKED +#define DEFINE_PRIVATE_XNLOCK(lock) static DEFINE_XNLOCK(lock) + +void __xnlock_spin(xnlock_t *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS); + +static inline int __xnlock_get(xnlock_t *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS) +{ + unsigned long long start; + int cpu = xnarch_current_cpu(); + + if (atomic_read(&lock->owner) == cpu) + return 1; + + xnlock_dbg_prepare_acquire(&start); + + if (unlikely(atomic_cmpxchg(&lock->owner, ~0, cpu) != ~0)) + __xnlock_spin(lock /*, */ XNLOCK_DBG_PASS_CONTEXT); + + xnlock_dbg_acquired(lock, cpu, &start /*, */ XNLOCK_DBG_PASS_CONTEXT); + + return 0; +} + +static inline void xnlock_put(xnlock_t *lock) +{ + if (xnlock_dbg_release(lock)) + return; + + /* + * Make sure all data written inside the lock is visible to + * other CPUs before we release the lock. + */ + xnarch_memory_barrier(); + + atomic_set(&lock->owner, ~0); +} + +static inline spl_t +__xnlock_get_irqsave(xnlock_t *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS) +{ + unsigned long flags; + + rthal_local_irq_save(flags); + + if (__xnlock_get(lock /*, */ XNLOCK_DBG_PASS_CONTEXT)) + flags |= 2; /* Recursive acquisition */ + + return flags; +} + +static inline void xnlock_put_irqrestore(xnlock_t *lock, spl_t flags) +{ + /* Only release the lock if we didn't take it recursively. */ + if (!(flags & 2)) + xnlock_put(lock); + + rthal_local_irq_restore(flags & 1); +} + +static inline int xnarch_send_ipi(xnarch_cpumask_t cpumask) +{ +#ifdef CONFIG_SMP + return rthal_send_ipi(RTHAL_SERVICE_IPI0, cpumask); +#else /* !CONFIG_SMP */ + return 0; +#endif /* !CONFIG_SMP */ +} + +static inline int xnlock_is_owner(xnlock_t *lock) +{ + return atomic_read(&lock->owner) == xnarch_current_cpu(); +} + +#else /* !(CONFIG_SMP || XENO_DEBUG(XNLOCK) */ + +#define xnlock_init(lock) do { } while(0) +#define xnlock_get(lock) do { } while(0) +#define xnlock_put(lock) do { } while(0) +#define xnlock_get_irqsave(lock,x) rthal_local_irq_save(x) +#define xnlock_put_irqrestore(lock,x) rthal_local_irq_restore(x) +#define xnlock_clear_irqoff(lock) rthal_local_irq_disable() +#define xnlock_clear_irqon(lock) rthal_local_irq_enable() +#define xnlock_is_owner(lock) 1 + +#define DECLARE_XNLOCK(lock) +#define DECLARE_EXTERN_XNLOCK(lock) +#define DEFINE_XNLOCK(lock) +#define DEFINE_PRIVATE_XNLOCK(lock) + +static inline int xnarch_send_ipi (xnarch_cpumask_t cpumask) +{ + return 0; +} + +#endif /* !(CONFIG_SMP || XENO_DEBUG(XNLOCK)) */ + +#define xnlock_sync_irq(lock, x) \ + do { \ + xnlock_put_irqrestore(lock, x); \ + xnlock_get_irqsave(lock, x); \ + } while(0) + +static inline int xnarch_remap_vm_page(struct vm_area_struct *vma, + unsigned long from, + unsigned long to) +{ + return wrap_remap_vm_page(vma, from, to); +} + +static inline int xnarch_remap_io_page_range(struct file *filp, + struct vm_area_struct *vma, + unsigned long from, + phys_addr_t to, + unsigned long size, + pgprot_t prot) +{ + return wrap_remap_io_page_range(vma, from, to, size, + wrap_phys_mem_prot(filp, (to) >> PAGE_SHIFT, + size, prot)); +} + +static inline int xnarch_remap_kmem_page_range(struct vm_area_struct *vma, + unsigned long from, + unsigned long to, + unsigned long size, + pgprot_t prot) +{ + return wrap_remap_kmem_page_range(vma,from,to,size,prot); +} + +#define xnarch_finalize_no_switch(dead_tcb) do { } while(0) + +#ifdef rthal_fault_range +#define xnarch_fault_range(vma) rthal_fault_range(vma) +#else /* !rthal_fault_range */ +#define xnarch_fault_range(vma) do { } while (0) +#endif /*!rthal_fault_range */ + +#ifndef xnarch_hisyscall_entry +static inline void xnarch_hisyscall_entry(void) { } +#endif + +#ifdef __cplusplus +} +#endif + +/* Dashboard and graph control. */ +#define XNARCH_DECL_DISPLAY_CONTEXT(); +#define xnarch_init_display_context(obj) +#define xnarch_create_display(obj,name,tag) +#define xnarch_delete_display(obj) +#define xnarch_post_graph(obj,state) +#define xnarch_post_graph_if(obj,state,cond) + +#endif /* !_XENO_ASM_GENERIC_SYSTEM_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/timeconv.h relase/linux-2.6.35.9//include/asm-generic/xenomai/timeconv.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/timeconv.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/timeconv.h 2011-02-16 15:26:01.000000000 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 Jan Kiszka . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _XENO_ASM_GENERIC_TIMECONV_H +#define _XENO_ASM_GENERIC_TIMECONV_H + +#ifndef __KERNEL__ +extern xnsysinfo_t sysinfo; + +void xeno_init_timeconv(int muxid); +#endif + +long long xnarch_tsc_to_ns(long long ticks); +long long xnarch_tsc_to_ns_rounded(long long ticks); +long long xnarch_ns_to_tsc(long long ns); + +#endif /* !_XENO_ASM_GENERIC_TIMECONV_H */ diff -urN orig/linux-2.6.35.9//include/asm-generic/xenomai/wrappers.h relase/linux-2.6.35.9//include/asm-generic/xenomai/wrappers.h --- orig/linux-2.6.35.9//include/asm-generic/xenomai/wrappers.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/asm-generic/xenomai/wrappers.h 2011-03-08 08:55:42.000000000 +0100 @@ -0,0 +1,642 @@ +/* + * Copyright (C) 2005 Philippe Gerum . + * + * Xenomai 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. + * + * Xenomai 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 Xenomai; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Linux wrappers. + */ + +#ifndef _XENO_ASM_GENERIC_WRAPPERS_H + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +#include +#include +#include +#include +#include +#include /* Use the backport. */ +#include + +#if BITS_PER_LONG != 32 +#error Upgrade to kernel 2.6! +#endif + +/* Compiler */ +#ifndef __attribute_const__ +#define __attribute_const__ /* unimplemented */ +#endif +#ifndef __restrict__ +#define __restrict__ /* unimplemented */ +#endif + +#define module_param_named(name,var,type,mode) module_param(var,type,mode) +#define _MODULE_PARM_STRING_charp "s" +#define compat_module_param_array(name, type, count, perm) \ + static inline void *__check_existence_##name(void) { return &name; } \ + MODULE_PARM(name, "1-" __MODULE_STRING(count) _MODULE_PARM_STRING_##type) + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* VM */ + +#define wrap_remap_vm_page(vma,from,to) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(from,page_to_phys(vmalloc_to_page((void *)to)),PAGE_SIZE,vma->vm_page_prot); \ +}) +#define wrap_remap_io_page_range(vma,from,to,size,prot) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(from,to,size,prot); \ +}) +#define wrap_remap_kmem_page_range(vma,from,to,size,prot) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(from,to,size,prot); \ +}) +#define wrap_switch_mm(prev,next,task) \ + switch_mm(prev,next,task,(task)->processor) +#define wrap_enter_lazy_tlb(mm,task) \ + enter_lazy_tlb(mm,task,(task)->processor) +#define pte_offset_kernel(pmd,addr) pte_offset(pmd,addr) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +/* Seqfiles */ +#define SEQ_START_TOKEN ((void *)1) + +/* Sched and process flags */ +#define MAX_RT_PRIO 100 +#define task_cpu(p) ((p)->processor) +#ifndef CONFIG_PREEMPT +#define preempt_disable() do { } while(0) +#define preempt_enable() do { } while(0) +#endif /* !CONFIG_PREEMPT */ +#ifndef SCHED_NORMAL +#define SCHED_NORMAL SCHED_OTHER +#endif /* !SCHED_NORMAL */ +#define PF_NOFREEZE 0 + +/* Signals */ +#define wrap_get_sigpending(m,p) sigandsets(m, \ + &(p)->pending.signal, \ + &(p)->pending.signal) +/* Wait queues */ +#define DEFINE_WAIT(w) DECLARE_WAITQUEUE(w, current) +#define is_sync_wait(wait) (!(wait) || ((wait)->task)) + +static inline void prepare_to_wait(wait_queue_head_t *q, + wait_queue_t *wait, + int state) +{ + unsigned long flags; + + wait->flags &= ~WQ_FLAG_EXCLUSIVE; + spin_lock_irqsave(&q->lock, flags); + __add_wait_queue(q, wait); + if (is_sync_wait(wait)) + set_current_state(state); + spin_unlock_irqrestore(&q->lock, flags); +} + +static inline void prepare_to_wait_exclusive(wait_queue_head_t *q, + wait_queue_t *wait, + int state) +{ + unsigned long flags; + + wait->flags |= WQ_FLAG_EXCLUSIVE; + spin_lock_irqsave(&q->lock, flags); + __add_wait_queue_tail(q, wait); + if (is_sync_wait(wait)) + set_current_state(state); + spin_unlock_irqrestore(&q->lock, flags); +} + +static inline void finish_wait(wait_queue_head_t *q, + wait_queue_t *wait) +{ + unsigned long flags; + + __set_current_state(TASK_RUNNING); + if (waitqueue_active(q)) { + spin_lock_irqsave(&q->lock, flags); + list_del_init(&wait->task_list); + spin_unlock_irqrestore(&q->lock, flags); + } +} + +#ifndef wait_event_interruptible_timeout +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + DEFINE_WAIT(__wait); \ + \ + for (;;) { \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + finish_wait(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) +#endif + +/* Workqueues. Some 2.4 ports already provide for a limited emulation + of workqueue calls in linux/workqueue.h, except DECLARE_WORK(), so + we define the latter here, and leave the rest in + compat/linux/workqueue.h. */ + +#define __WORK_INITIALIZER(n,f,d) { \ + .list = { &(n).list, &(n).list }, \ + .sync = 0, \ + .routine = (f), \ + .data = (d), \ +} +#define DECLARE_WORK(n,f,d) struct tq_struct n = __WORK_INITIALIZER(n, f, d) +#define DECLARE_WORK_NODATA(n, f) DECLARE_WORK(n, f, NULL) +#define DECLARE_WORK_FUNC(f) void f(void *cookie) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_WORK(n, f, NULL) + +/* + * WARNING: This is not identical to 2.6 schedule_delayed_work as it delayes + * the caller to schedule the task after the specified delay. That's fine for + * our current use cases, though. + */ +#define schedule_delayed_work(work, delay) do { \ + if (delay) { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout(delay); \ + } \ + schedule_task(work); \ +} while (0) + +/* Msleep is unknown before 2.4.28 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28) +#define msleep(x) do { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout(((x)*HZ)/1000); \ +} while(0) +#endif + +/* Shorthand for timeout setup */ +#define schedule_timeout_interruptible(t) do { \ + set_current_state(TASK_INTERRUPTIBLE); \ + schedule_timeout(t); \ +} while(0) + +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED + +#ifndef NSEC_PER_MSEC +#define NSEC_PER_MSEC 1000000L +#endif + +#ifndef USEC_PER_SEC +#define USEC_PER_SEC 1000000L +#endif + +#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28) +static inline unsigned int jiffies_to_usecs(const unsigned long j) +{ +#if HZ <= 1000 && !(1000 % HZ) + return (1000000 / HZ) * j; +#elif HZ > 1000 && !(HZ % 1000) + return (j*1000 + (HZ - 1000))/(HZ / 1000); +#else + return (j * 1000000) / HZ; +#endif +} +#endif + +static inline unsigned long usecs_to_jiffies(const unsigned int u) +{ + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); +#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) + return u * (HZ / USEC_PER_SEC); +#else + return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC; +#endif +} + +#ifdef MODULE +#define try_module_get(mod) try_inc_mod_count(mod) +#define module_put(mod) __MOD_DEC_USE_COUNT(mod) +#else /* !__MODULE__ */ +#define try_module_get(mod) (1) +#define module_put(mod) do { } while (0) +#endif /* !__MODULE__ */ + +/* Types */ +typedef enum __kernel_clockid_t { + CLOCK_REALTIME =0, + CLOCK_MONOTONIC =1 +} clockid_t; + +typedef int timer_t; +typedef int mqd_t; + +/* Decls */ +struct task_struct; +void show_stack(struct task_struct *task, + unsigned long *sp); + +#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) + +#ifndef __deprecated +#define __deprecated __attribute__((deprecated)) +#endif + +#ifndef BITOP_WORD +#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) +#endif + +#define __GFP_BITS_SHIFT 20 +#define pgprot_noncached(p) (p) + +typedef atomic_t atomic_long_t; + +static inline long atomic_long_read(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_read(v); +} + +static inline void atomic_long_set(atomic_long_t *l, long i) +{ + atomic_t *v = (atomic_t *)l; + + atomic_set(v, i); +} + +static inline void atomic_long_inc(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_inc(v); +} + +static inline void atomic_long_dec(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_dec(v); +} + +static inline unsigned long hweight_long(unsigned long w) +{ + return hweight32(w); +} + +#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) +unsigned long find_next_bit(const unsigned long *addr, + unsigned long size, unsigned long offset); + +#define mmiowb() barrier() + +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ + +#define compat_module_param_array(name, type, count, perm) \ + module_param_array(name, type, NULL, perm) + +/* VM */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) && defined(CONFIG_MMU) +#define wrap_remap_vm_page(vma,from,to) \ + vm_insert_page(vma,from,vmalloc_to_page((void *)to)) + +#define wrap_remap_io_page_range(vma,from,to,size,prot) ({ \ + (vma)->vm_page_prot = pgprot_noncached((vma)->vm_page_prot); \ + /* Sets VM_RESERVED | VM_IO | VM_PFNMAP on the vma. */ \ + remap_pfn_range(vma,from,(to) >> PAGE_SHIFT,size,prot); \ + }) +#define wrap_remap_kmem_page_range(vma,from,to,size,prot) ({ \ + /* Sets VM_RESERVED | VM_IO | VM_PFNMAP on the vma. */ \ + remap_pfn_range(vma,from,(to) >> PAGE_SHIFT,size,prot); \ + }) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) +/* Actually, this is a best-effort since we don't have + * vm_insert_page(), and has the unwanted side-effet of setting the + * VM_IO flag on the vma, which prevents GDB inspection of the mmapped + * memory. Anyway, this legacy would only hit setups using pre-2.6.11 + * kernel revisions. */ +#define wrap_remap_vm_page(vma,from,to) \ + remap_pfn_range(vma,from,page_to_pfn(vmalloc_to_page((void *)to)),PAGE_SHIFT,vma->vm_page_prot) +#define wrap_remap_io_page_range(vma,from,to,size,prot) ({ \ + (vma)->vm_page_prot = pgprot_noncached((vma)->vm_page_prot); \ + /* Sets VM_RESERVED | VM_IO | VM_PFNMAP on the vma. */ \ + remap_pfn_range(vma,from,(to) >> PAGE_SHIFT,size,prot); \ + }) +#define wrap_remap_kmem_page_range(vma,from,to,size,prot) ({ \ + /* Sets VM_RESERVED | VM_IO | VM_PFNMAP on the vma. */ \ + remap_pfn_range(vma,from,(to) >> PAGE_SHIFT,size,prot); \ + }) +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) */ +#define wrap_remap_vm_page(vma,from,to) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(from,page_to_phys(vmalloc_to_page((void *)to)),PAGE_SIZE,vma->vm_page_prot); \ +}) +#define wrap_remap_io_page_range(vma,from,to,size,prot) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(vma,from,to,size,prot); \ + }) +#define wrap_remap_kmem_page_range(vma,from,to,size,prot) ({ \ + vma->vm_flags |= VM_RESERVED; \ + remap_page_range(vma,from,to,size,prot); \ + }) +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) */ + +#ifndef __GFP_BITS_SHIFT +#define __GFP_BITS_SHIFT 20 +#endif + +#include + +#ifndef pgprot_noncached +#define pgprot_noncached(p) (p) +#endif /* !pgprot_noncached */ + +#define wrap_switch_mm(prev,next,task) \ + switch_mm(prev,next,task) +#define wrap_enter_lazy_tlb(mm,task) \ + enter_lazy_tlb(mm,task) + +/* Device registration */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) +#define DECLARE_DEVCLASS(clname) struct class *clname +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#define wrap_device_create(c,p,dt,dv,fmt,args...) device_create(c,p,dt,fmt , ##args) +#else /* >= 2.6.27 */ +#define wrap_device_create(c,p,dt,dv,fmt,args...) device_create(c,p,dt,dv,fmt , ##args) +#endif /* >= 2.6.27 */ +#define wrap_device_destroy device_destroy +#define DECLARE_DEVHANDLE(devh) struct device *devh +#else /* <= 2.6.25 */ +#define DECLARE_DEVHANDLE(devh) struct class_device *devh +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) +#define DECLARE_DEVCLASS(clname) struct class *clname +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) || defined(gfp_zone) +/* + * Testing that gfp_zone() exists as a macro is a gross hack used to + * discover DENX-originated 2.6.14 kernels, for which the prototype of + * class_device_create() already conforms to the one found in 2.6.15 + * mainline. + */ +#define wrap_device_create class_device_create +#else /* < 2.6.15 */ +#define wrap_device_create(c,p,dt,dv,fmt,args...) class_device_create(c,dt,dv,fmt , ##args) +#endif /* >= 2.6.15 */ +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#define DECLARE_DEVCLASS(clname) struct class_simple *clname +#define wrap_device_create(c,p,dt,dv,fmt,args...) class_simple_device_add(c,dt,dv,fmt , ##args) +#define class_create class_simple_create +#define class_device_destroy(a,b) class_simple_device_remove(b) +#define class_destroy class_simple_destroy +#endif /* >= 2.6.13 */ +#define wrap_device_destroy(a, b) class_device_destroy(a, b) +#endif /* >= 2.6.26 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) +#endif /* < 2.6.15 */ + +/* Signals */ +#define wrap_get_sigpending(m,p) sigorsets(m, \ + &(p)->pending.signal, \ + &(p)->signal->shared_pending.signal) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#define DECLARE_WORK_NODATA(f, n) DECLARE_WORK(f, n, NULL) +#define DECLARE_WORK_FUNC(f) void f(void *cookie) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_DELAYED_WORK(n, f, NULL) +#else /* >= 2.6.20 */ +#define DECLARE_WORK_NODATA(f, n) DECLARE_WORK(f, n) +#define DECLARE_WORK_FUNC(f) void f(struct work_struct *work) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_DELAYED_WORK(n, f) +#endif /* >= 2.6.20 */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#define IRQF_SHARED SA_SHIRQ +#endif /* < 2.6.18 */ + +#if defined(CONFIG_LTT) || \ + (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31) && defined(CONFIG_MARKERS)) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#define trace_mark(channel, ev, fmt, args...) \ + MARK(channel##_##ev, fmt , ##args) +#else /* >= 2.6.24 */ +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#undef trace_mark +#define trace_mark(channel, ev, fmt, args...) \ + __trace_mark(0, channel##_##ev, NULL, fmt, ## args) +#endif /* < 2.6.27 */ +#endif /* >= 2.6.24 */ + +#else /* !LTTng markers */ + +#undef trace_mark +#define trace_mark(channel, ev, fmt, args...) do { } while (0) + +#endif /* !LTTng markers */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define KMALLOC_MAX_SIZE 131072 +#if BITS_PER_LONG == 64 +#define atomic_long_cmpxchg(l, old, new) \ + atomic_cmpxchg((atomic64_t *)(l), (old), (new)) +#define atomic_long_dec_and_test(l) \ + atomic_dec_and_test((atomic64_t *)l) +#define atomic_long_inc_and_test(l) \ + atomic_inc_and_test((atomic64_t *)l) +#else +#define atomic_long_cmpxchg(l, old, new) \ + atomic_cmpxchg((atomic_t *)(l), (old), (new)) +#define atomic_long_dec_and_test(l) \ + atomic_dec_and_test((atomic_t *)l) +#define atomic_long_inc_and_test(l) \ + atomic_inc_and_test((atomic_t *)l) +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + +static inline struct task_struct *wrap_find_task_by_pid(pid_t nr) +{ + return pid_task(find_pid_ns(nr, &init_pid_ns), PIDTYPE_PID); +} + +#else /* LINUX_VERSION_CODE < 2.6.31 */ + +#define wrap_find_task_by_pid(nr) \ + find_task_by_pid_ns(nr, &init_pid_ns) + +#endif /* LINUX_VERSION_CODE < 2.6.31 */ + +#define kill_proc(pid, sig, priv) \ + kill_proc_info(sig, (priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO, pid) + +#else /* LINUX_VERSION_CODE < 2.6.27 */ + +#include + +#define wrap_find_task_by_pid(nr) find_task_by_pid(nr) + +#endif /* LINUX_VERSION_CODE < 2.6.27 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + +#include + +#ifndef current_cap +#define current_cap() ((current)->cap_effective) +#endif + +static inline int wrap_raise_cap(int cap) +{ + cap_raise(current_cap(), cap); + return 0; +} +#else /* LINUX_VERSION_CODE >= 2.6.29 */ + +#include + +static inline int wrap_raise_cap(int cap) +{ + struct cred *new; + + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; + + cap_raise(new->cap_effective, cap); + + return commit_creds(new); +} +#endif /* LINUX_VERSION_CODE >= 2.6.29 */ + +#ifdef CONFIG_PROC_FS +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) +#include +#include +static inline void wrap_proc_dir_entry_owner(struct proc_dir_entry *entry) +{ + entry->owner = THIS_MODULE; +} +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ +#define wrap_proc_dir_entry_owner(entry) do { (void)entry; } while(0) +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ +#endif /* CONFIG_PROC_FS */ + +#ifndef list_first_entry +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) +#define rthal_irq_descp(irq) (irq_desc + (irq)) +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) */ +#define rthal_irq_descp(irq) irq_to_desc(irq) +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) +#define rthal_irqdesc_lock(irq, flags) \ + spin_lock_irqsave(&rthal_irq_descp(irq)->lock, flags) +#define rthal_irqdesc_unlock(irq, flags) \ + spin_unlock_irqrestore(&rthal_irq_descp(irq)->lock, flags) +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) */ +#define rthal_irqdesc_lock(irq, flags) \ + raw_spin_lock_irqsave(&rthal_irq_descp(irq)->lock, flags) +#define rthal_irqdesc_unlock(irq, flags) \ + raw_spin_unlock_irqrestore(&rthal_irq_descp(irq)->lock, flags) +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +#define unlocked_ioctl ioctl +#endif + +#ifndef DEFINE_SEMAPHORE +/* Legacy DECLARE_MUTEX vanished in 2.6.37 */ +#define DEFINE_SEMAPHORE(sem) DECLARE_MUTEX(sem) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) && defined(CONFIG_GENERIC_HARDIRQS) +/* + * The irq chip descriptor has been heavily revamped in + * 2.6.37. Provide generic accessors to the chip handlers we need for + * kernels implementing those changes. + */ +#define rthal_irq_chip_enable(irq) \ + ({ \ + struct irq_desc *desc = rthal_irq_descp(irq); \ + struct irq_chip *chip = get_irq_desc_chip(desc); \ + int __ret__ = 0; \ + if (unlikely(chip->irq_unmask == NULL)) \ + __ret__ = -ENODEV; \ + else \ + chip->irq_unmask(&desc->irq_data); \ + __ret__; \ + }) +#define rthal_irq_chip_disable(irq) \ + ({ \ + struct irq_desc *desc = rthal_irq_descp(irq); \ + struct irq_chip *chip = get_irq_desc_chip(desc); \ + int __ret__ = 0; \ + if (unlikely(chip->irq_mask == NULL)) \ + __ret__ = -ENODEV; \ + else \ + chip->irq_mask(&desc->irq_data); \ + __ret__; \ + }) +#endif + +#endif /* _XENO_ASM_GENERIC_WRAPPERS_H */ diff -urN orig/linux-2.6.35.9//include/config/auto.conf relase/linux-2.6.35.9//include/config/auto.conf --- orig/linux-2.6.35.9//include/config/auto.conf 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/config/auto.conf 2011-03-15 11:08:30.665702442 +0100 @@ -0,0 +1,1571 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.35.9 +# Tue Mar 15 11:08:30 2011 +# +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_SCSI_DMA=y +CONFIG_KERNEL_GZIP=y +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_INPUT_KEYBOARD=y +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_CRC32=y +CONFIG_I2C_BOARDINFO=y +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_HAVE_AOUT=y +CONFIG_DM_SNAPSHOT=m +CONFIG_IR_JVC_DECODER=m +CONFIG_FSCACHE=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_AEABI=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_DM=m +CONFIG_R3964=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_VLAN_8021Q=m +CONFIG_FLATMEM_MANUAL=y +CONFIG_BT_RFCOMM=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DVB_TDA1004X=m +CONFIG_JOYSTICK_ADI=m +CONFIG_DVB_BCM3510=m +CONFIG_INOTIFY_USER=y +CONFIG_VIDEO_V4L1=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_SCSI_DH=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_IPIPE=y +CONFIG_CRYPTO_MD4=m +CONFIG_BT_HCIBFUSB=m +CONFIG_NET_ETHERNET=y +CONFIG_EXPERIMENTAL=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_USB_G_SERIAL=m +CONFIG_SND_SOC_TPA6130A2=m +CONFIG_LEDS_PCA955X=m +CONFIG_IP_VS_NQ=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_SCSI_DEBUG=m +CONFIG_BINFMT_MISC=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_SSB_POSSIBLE=y +CONFIG_NF_NAT_SIP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_ESI_DONGLE=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_NET_SCH_FIFO=y +CONFIG_REISERFS_FS=y +CONFIG_FSNOTIFY=y +CONFIG_CRYPTO_RMD128=m +CONFIG_STP=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_DVB_AU8522=m +CONFIG_INET6_TUNNEL=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_HIDRAW=y +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_XENO_SKIN_RTDM=y +CONFIG_IP_NF_QUEUE=m +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2800USB_RT30XX=y +CONFIG_IP_VS_SED=m +CONFIG_DVB_DS3000=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_IP6_NF_MANGLE=m +CONFIG_TOUCHSCREEN_USB_ETT_TC5UH=y +CONFIG_BT_MRVL_SDIO=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_BT_HCIBPA10X=m +CONFIG_IP_VS_RR=m +CONFIG_IPV6=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_CRYPTO_AEAD=m +CONFIG_XENO_OPT_TIMING_SCHEDLAT=0 +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_USB_DEVICEFS=y +CONFIG_NET_CLS_FLOW=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_CRYPTO_PCBC=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_IR_NEC_DECODER=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_WLAN=y +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_CONNECTOR=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +CONFIG_DVB_MAX_ADAPTERS=8 +CONFIG_DM_MULTIPATH_QL=m +CONFIG_LEGACY_PTYS=y +CONFIG_LIBERTAS_USB=m +CONFIG_JFS_FS=m +CONFIG_XFRM_IPCOMP=m +CONFIG_CRYPTO_RNG2=m +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_SND_SOC_AD193X=m +CONFIG_MSDOS_FS=y +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_IBMCAM=m +CONFIG_CAN=m +CONFIG_CFG80211=m +CONFIG_SSB_BLOCKIO=y +CONFIG_DM_CRYPT=m +CONFIG_IPIPE_ARM_KUSER_TSC=y +CONFIG_NCP_FS=m +CONFIG_B43LEGACY_PIO=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_LZO_DECOMPRESS=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_EXOFS_FS=m +CONFIG_HID_BELKIN=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +CONFIG_IWM=m +CONFIG_NFSD=m +CONFIG_SENSORS_TSL2550=m +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB=y +CONFIG_SND_SOC_DA7210=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_SND_SOC_TLV320DAC33=m +CONFIG_CRYPTO_HMAC=m +CONFIG_XENO_OPT_NATIVE_COND=y +CONFIG_SND_SOC_WM8900=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_CRC_ITU_T=y +CONFIG_SND_HRTIMER=m +CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_DM_ZERO=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_DVB_DIB8000=m +CONFIG_SND_SEQUENCER=m +CONFIG_TCP_CONG_LP=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_HID_CHERRY=m +CONFIG_HID_SUNPLUS=m +CONFIG_AF_RXRPC=m +CONFIG_CRYPTO_CAST5=m +CONFIG_MTD_PARTITIONS=y +CONFIG_SND_SOC=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_PRINTK=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_TIMERFD=y +CONFIG_HID_THRUSTMASTER=m +CONFIG_B43_PHY_LP=y +CONFIG_MTD_CFI_I2=y +CONFIG_CRYPTO_AUTHENC=m +CONFIG_USB_GPIO_VBUS=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_IRDA=m +CONFIG_XENO_OPT_NATIVE_QUEUE=y +CONFIG_P54_COMMON=m +CONFIG_SHMEM=y +CONFIG_MTD=y +CONFIG_SND_SOC_WM8776=m +CONFIG_NLS_CODEPAGE_850=y +CONFIG_DNOTIFY=y +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_DVB_USB_UMT_010=m +CONFIG_JOYSTICK_DB9=m +CONFIG_INPUT_MOUSEDEV=y +CONFIG_ATA=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_CRYPTO_DES=m +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_MTD_NAND_IDS=y +CONFIG_MCS_FIR=m +CONFIG_NET_CLS_U32=m +CONFIG_EXPORTFS=m +CONFIG_SND_MIXER_OSS=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_SND_AT73C213_TARGET_BITRATE=48000 +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +CONFIG_DVB_AF9013=m +CONFIG_SERIO=y +CONFIG_DVB_USB_DTV5100=m +CONFIG_INPUT_MOUSE=y +CONFIG_VIDEO_TVEEPROM=m +CONFIG_MA600_DONGLE=m +CONFIG_RTC_INTF_SYSFS=y +CONFIG_SND_SOC_SPDIF=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_BLK_DEV_INITRD=y +CONFIG_USB_EMI62=m +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_SND_SOC_WM8510=m +CONFIG_RT2800_LIB=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_DVB_USB_DW2102=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_OSSEMUL=y +CONFIG_TOIM3232_DONGLE=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_ZLIB_INFLATE=y +CONFIG_USB_STV680=m +CONFIG_CRC_T10DIF=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_LCD_LMS283GF05=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_IP_PNP=y +CONFIG_XENO_OPT_RTDM_PERIOD=0 +CONFIG_USB_VIDEO_CLASS=m +CONFIG_SERIAL_ATMEL_PDC=y +CONFIG_RTC_INTF_PROC=y +CONFIG_MMC_AT91=y +CONFIG_MTD_CONCAT=y +CONFIG_USB_SERIAL_TI=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_CRYPTO_SERPENT=m +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_XENO_OPT_PRIOCPL=y +CONFIG_NVRAM=m +CONFIG_LOCKD=m +CONFIG_DVB_S5H1411=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_USB_SN9C102=m +CONFIG_LIBERTAS=m +CONFIG_ARM=y +CONFIG_USB_GSPCA_TV8532=m +CONFIG_VIDEO_CPIA=m +CONFIG_JFFS2_FS=y +CONFIG_SND_SOC_WM8750=m +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_USB_EZUSB=y +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_USB_ZC0301=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_LIBFCOE=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_DVB_STV0299=m +CONFIG_CRYPTO_MANAGER_TESTS=y +CONFIG_DISPLAY_SUPPORT=m +CONFIG_CPU_TLB_V4WBI=y +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_INPUT_TABLET=y +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_LLC2=m +CONFIG_DLM=m +CONFIG_CPU_COPY_V4WB=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_XENO_OPT_TIMER_LIST=y +CONFIG_USB_STORAGE=y +CONFIG_STANDALONE=y +CONFIG_CRYPTO_SEED=m +CONFIG_DONGLE=y +CONFIG_SATA_MV=m +CONFIG_XENO_OPT_SYS_STACKPOOLSZ=128 +CONFIG_DVB_TUNER_DIB0090=m +CONFIG_SND_USB_AUDIO=m +CONFIG_VIDEO_CX231XX=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_IEEE802154=m +CONFIG_XENO_HW_FPU=y +CONFIG_BLOCK=y +CONFIG_HAVE_IDE=y +CONFIG_IP_VS_LC=m +CONFIG_HID_APPLE=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_SND_RAWMIDI_SEQ=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_DVB_USB=m +CONFIG_GENERIC_GPIO=y +CONFIG_DVB_ATBM8830=m +CONFIG_SND_ATMEL_SOC_SSC=m +CONFIG_SCTP_HMAC_MD5=y +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_HFSPLUS_FS=m +CONFIG_BUG=y +CONFIG_KS0108_PORT=0x378 +CONFIG_MAC80211_HAS_RC=y +CONFIG_XENO_OPT_RTDM_FILDES=128 +CONFIG_OCFS2_FS_O2CB=m +CONFIG_CRYPTO_CAST6=m +CONFIG_XENO_OPT_NATIVE_SEM=y +CONFIG_PM=y +CONFIG_PPS=m +CONFIG_USB_LCD=m +CONFIG_SPI=y +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_DEVKMEM=y +CONFIG_USB_STV06XX=m +CONFIG_XENO_OPT_PERVASIVE=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_VT=y +CONFIG_USB_NET_NET1080=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_MACB=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_BT_SCO=m +CONFIG_POWER_SUPPLY=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_WEXT_CORE=y +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_VIDEO_WM8775=m +CONFIG_NLS=y +CONFIG_SPI_SPIDEV=y +CONFIG_SND_SOC_AD73311=m +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_MFD_SUPPORT=y +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_LEGOTOWER=m +CONFIG_MTD_DATAFLASH=y +CONFIG_ARCH_AT91=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_VP702X=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_MD_FAULTY=m +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_VIDEO_USBVISION=m +CONFIG_SPI_BITBANG=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TEKRAM_DONGLE=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_IPW=m +CONFIG_INET_IPCOMP=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_MCP2120_DONGLE=m +CONFIG_ASYNC_PQ=m +CONFIG_HID_CYPRESS=m +CONFIG_XENO_OPT_NATIVE_PERIOD=0 +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_VIDEO_SAA711X=m +CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_WORKQUEUE=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_HID_KENSINGTON=m +CONFIG_BACKLIGHT_GENERIC=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +CONFIG_BT_HCIUART_LL=y +CONFIG_SND_PCM_OSS=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_USB_IRDA=m +CONFIG_SND_SOC_WM8960=m +CONFIG_RFKILL=m +CONFIG_VIDEO_TVP5150=m +CONFIG_NETDEVICES=y +CONFIG_NET_KEY=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_EVENTFD=y +CONFIG_FS_POSIX_ACL=y +CONFIG_IPV6_SIT=m +CONFIG_XFRM=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_USB_MR800=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_SND_SOC_WM9081=m +CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH=y +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_IP_VS_DH=m +CONFIG_SND_SOC_WM8753=m +CONFIG_VIDEO_IR=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_WAN_ROUTER=m +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_KS959_DONGLE=m +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_DM_DELAY=m +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_USB_IOWARRIOR=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_CRYPTO_SHA512=m +CONFIG_PHONET=m +CONFIG_SCSI_WAIT_SCAN=m +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_B43_HWRNG=y +CONFIG_USB_M5602=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CRYPTO_NULL=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_USB_IDMOUSE=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_NETFILTER_ADVANCED=y +CONFIG_CRYPTO_DEFLATE=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_BT_HCIBTSDIO=m +CONFIG_ATM_MPOA=m +CONFIG_CRYPTO_GCM=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_DVB_LGS8GXX=m +CONFIG_SERIAL_ATMEL=y +CONFIG_IP_NF_MANGLE=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_IP_NF_FILTER=m +CONFIG_HID_ZEROPLUS=m +CONFIG_EXT3_FS=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_FAT_FS=y +CONFIG_TEXTSEARCH_FSM=m +CONFIG_IP6_NF_RAW=m +CONFIG_USB_ZD1201=m +CONFIG_INET_TUNNEL=m +CONFIG_EEPROM_93CX6=m +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ROMFS_FS=m +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_DVB_USB_DTT200U=m +CONFIG_LIB80211=m +CONFIG_USB_CXACRU=m +CONFIG_CPU_CP15_MMU=y +CONFIG_RFKILL_LEDS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_PHONE=m +CONFIG_NET_IPGRE=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_LIBERTAS_SPI=m +CONFIG_XENO_OPT_GLOBAL_SEM_HEAPSZ=12 +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_GSPCA=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_DM_MIRROR=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_AR9170_USB=m +CONFIG_USB_G_PRINTER=m +CONFIG_B43=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_USB_RIO500=m +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_XENO_FASTSYNCH=y +CONFIG_CRYPTO_CCM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_NET_CLS_RSVP6=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_QFMT_V2=m +CONFIG_USB_S2255=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_CRYPTO_RNG=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_W1_MASTER_GPIO=y +CONFIG_RAW_DRIVER=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_NET_SCH_ATM=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_USB=y +CONFIG_RD_GZIP=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_TREE_RCU=y +CONFIG_LBDAF=y +CONFIG_CPU_ARM926T=y +CONFIG_SND_USB_CAIAQ=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_HAVE_AT91_USART3=y +CONFIG_XENO_DRIVERS_SWITCHTEST=y +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_CRYPTO_MD5=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_ISCSI_TCP=m +CONFIG_PM_OPS=y +CONFIG_DVB_TDA10023=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_OABI_COMPAT=y +CONFIG_USB_GSPCA_OV519=m +CONFIG_BINFMT_ELF=y +CONFIG_SLOW_WORK=y +CONFIG_SCSI_PROC_FS=y +CONFIG_MD_RAID456=m +CONFIG_HOTPLUG=y +CONFIG_UDF_NLS=y +CONFIG_JOYSTICK_STINGER=m +CONFIG_INET6_AH=m +CONFIG_CPU_CP15=y +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_USB_SERIAL=m +CONFIG_USB_MON=y +CONFIG_SIGMATEL_FIR=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_KEYS=y +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_IP_VS_LBLC=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_XENO_SKIN_POSIX=y +CONFIG_LEDS_BD2802=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_SLABINFO=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_DVB_USB_AF9005=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_CRYPTO_HW=y +CONFIG_USB_STORAGE_KARMA=m +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_HID_GREENASIA=m +CONFIG_SMS_USB_DRV=m +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_SPI_MASTER=y +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_DVB_NXT200X=m +CONFIG_HID_GYRATION=m +CONFIG_SND_SOC_AK4642=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_USB_WDM=m +CONFIG_BT_HCIBCM203X=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_INPUT_JOYDEV=m +CONFIG_MACH_FOXG20=y +CONFIG_SND_SOC_MAX9877=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_USB_ACM=m +CONFIG_CRC16=y +CONFIG_USB_NET_AX8817X=m +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_NET_CLS=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_UIO_PDRV=m +CONFIG_AX25=m +CONFIG_TMPFS=y +CONFIG_HOSTAP=m +CONFIG_ANON_INODES=y +CONFIG_SND_SOC_WM8711=m +CONFIG_VIDEO_EM28XX=m +CONFIG_FUTEX=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_DVB_CORE=m +CONFIG_VMSPLIT_3G=y +CONFIG_RTC_HCTOSYS=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_VIDEO_CQCAM=m +CONFIG_XENO_SKIN_NATIVE=y +CONFIG_USB_HID=y +CONFIG_DVB_USB_AF9015=m +CONFIG_ATM_DRIVERS=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_CRYPTO_TGR192=m +CONFIG_BLK_DEV_MD=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_SND_SOC_WM8978=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_CRYPTO_ZLIB=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_SYSVIPC=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_RT2X00=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_CPU_32v5=y +CONFIG_MODULES=y +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_USB_GADGET=y +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_ETH_RNDIS=y +CONFIG_DVB_SI21XX=m +CONFIG_SOUND=m +CONFIG_DVB_USB_VP7045=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_CRYPTO_TEA=m +CONFIG_ATMEL_SSC=y +CONFIG_UNIX=y +CONFIG_MINIX_FS=m +CONFIG_HAVE_CLK=y +CONFIG_CRYPTO_HASH2=m +CONFIG_SND_SOC_AK4671=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_NFS_FS=m +CONFIG_INET_ESP=m +CONFIG_LCD_TDO24M=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_MD=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_BRIDGE=m +CONFIG_MEDIA_TUNER=m +CONFIG_USB_GADGET_AT91=y +CONFIG_TABLET_USB_GTCO=m +CONFIG_MISC_DEVICES=y +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_SND_SOC_AD1836=m +CONFIG_INPUT_UINPUT=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_KEYBOARD_ATKBD=m +CONFIG_MTD_CFI_I1=y +CONFIG_NF_NAT=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_MOUSE_BCM5974=m +CONFIG_CPU_IDLE=y +CONFIG_NFS_COMMON=y +CONFIG_CHR_DEV_SCH=m +CONFIG_RT2800USB=m +CONFIG_CRYPTO_HASH=m +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_VIRT_TO_BUS=y +CONFIG_VFAT_FS=y +CONFIG_MD_RAID1=m +CONFIG_CRYPTO_VMAC=m +CONFIG_VIDEO_HDPVR=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_GENERIC_TIME=y +CONFIG_BLK_DEV_SR=m +CONFIG_SND_HWDEP=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_IPMI_HANDLER=m +CONFIG_SYSV_FS=m +CONFIG_NF_NAT_IRC=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_INPUT_MISC=y +CONFIG_DVB_STV0288=m +CONFIG_SOC_CAMERA=m +CONFIG_SUSPEND=y +CONFIG_MTD_NAND_ECC=y +CONFIG_CRYPTO_CBC=m +CONFIG_KS0108_DELAY=2 +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_FS_MBCACHE=y +CONFIG_MD_MULTIPATH=m +CONFIG_DS1682=m +CONFIG_GFS2_FS=m +CONFIG_RTC_CLASS=y +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_CRC7=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_USB_EMI26=m +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_SND_SOC_WM8993=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_PATA_AT91=m +CONFIG_W1=y +CONFIG_USB_GSPCA_VC032X=m +CONFIG_DVB_ISL6421=m +CONFIG_IP_VS_WLC=m +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_NF_NAT_TFTP=m +CONFIG_SND_SOC_ADS117X=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NET_SCH_NETEM=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_I2C_SI4713=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_CONFIGFS_FS=m +CONFIG_CRYPTO_TEST=m +CONFIG_ARCH_AT91SAM9G20=y +CONFIG_PM_SLEEP=y +CONFIG_I2C=y +CONFIG_JFFS2_ZLIB=y +CONFIG_VIDEO_CX25840=m +CONFIG_PARPORT_PC=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_FRAME_POINTER=y +CONFIG_BT_HIDP=m +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_IR_CORE=m +CONFIG_XENO_OPT_PIPE_NRDEV=32 +CONFIG_UFS_FS=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VIDEO_CPIA_USB=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_CRYPTO_ECB=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_W9968CF=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_DEBUG_FS=y +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_BASE_FULL=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_SUNRPC=m +CONFIG_VIDEO_SAA5249=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_IP_VS_LBLCR=m +CONFIG_GPIO_SYSFS=y +CONFIG_FW_LOADER=m +CONFIG_LITELINK_DONGLE=m +CONFIG_KALLSYMS=y +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_USB_KONICAWC=m +CONFIG_CRYPTO_XTS=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_XENO_OPT_POSIX_PERIOD=0 +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_MII=y +CONFIG_SIGNALFD=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_VIDEO_CPIA2=m +CONFIG_EXT4_FS=y +CONFIG_NET_SCH_DRR=m +CONFIG_CRYPTO_SHA1=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_BELKIN=y +CONFIG_SATA_PMP=y +CONFIG_ATH_COMMON=m +CONFIG_LOCKD_V4=y +CONFIG_CODA_FS=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_WATCHDOG=y +CONFIG_HAS_IOMEM=y +CONFIG_SND_RAWMIDI=m +CONFIG_HAVE_AT91_USART5=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_SND_SOC_UDA134X=m +CONFIG_USB_GADGETFS=m +CONFIG_IRDA_ULTRA=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_APM_EMULATION=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_NET_SCH_PRIO=m +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_CONSTRUCTORS=y +CONFIG_USB_SERIAL_IUU=m +CONFIG_EPOLL=y +CONFIG_CRYPTO_LZO=m +CONFIG_SND_PCM=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_SDIO_UART=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_KEYBOARD_MAX7359=m +CONFIG_IR_SONY_DECODER=m +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_VIDEO_PVRUSB2=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_NET=y +CONFIG_INPUT_EVDEV=y +CONFIG_SND_JACK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_B43LEGACY_DMA=y +CONFIG_EXT2_FS=y +CONFIG_TABLET_USB_WACOM=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_CRYPTO_WP512=m +CONFIG_SND_SOC_WM9090=m +CONFIG_HID_DRAGONRISE=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_XENO_GENERIC_STACKPOOL=y +CONFIG_HPFS_FS=m +CONFIG_USB_LD=m +CONFIG_QUOTA_TREE=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_PACKET=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NETROM=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_DVB_USB_GL861=m +CONFIG_SND_SOC_PCM3008=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NFS_V3=y +CONFIG_DVB_USB_ANYSEE=m +CONFIG_USB_FILE_STORAGE=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_INET=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_CRYPTO_TWOFISH=m +CONFIG_FREEZER=y +CONFIG_USB_TEST=m +CONFIG_BT=m +CONFIG_BT_HCIVHCI=m +CONFIG_INPUT_CM109=m +CONFIG_LCD_PLATFORM=m +CONFIG_XENO_OPT_SYS_HEAPSZ=256 +CONFIG_SND_AT91_SOC_SAM9G20_WM8731=m +CONFIG_PARPORT=m +CONFIG_HID_WACOM=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_NET_SCH_SFQ=m +CONFIG_RTC_LIB=y +CONFIG_XENO_OPT_REGISTRY_NRSLOTS=512 +CONFIG_USB_UEAGLEATM=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_HAVE_KPROBES=y +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_CRYPTO_AES=m +CONFIG_DVB_DIB7000P=m +CONFIG_AT91SAM9X_WATCHDOG=y +CONFIG_GPIOLIB=y +CONFIG_SSB=m +CONFIG_SND_SOC_WM8961=m +CONFIG_RADIO_TEA5764=m +CONFIG_PARPORT_AX88796=m +CONFIG_AUTOFS_FS=m +CONFIG_GAMEPORT=m +CONFIG_ISO9660_FS=m +CONFIG_BT_HCIUART_H4=y +CONFIG_XENO_OPT_NATIVE_BUFFER=y +CONFIG_DVB_USB_M920X=m +CONFIG_UIO=m +CONFIG_SND_ARM=y +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_B43_PIO=y +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_USB_MDC800=m +CONFIG_SERIO_SERPORT=y +CONFIG_DVB_STV0297=m +CONFIG_BT_BNEP=m +CONFIG_DVB_TDA826X=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_XENO_OPT_NATIVE_MUTEX=y +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_USB_VICAM=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SND_DRIVERS=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_XFS_FS=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_NO_HZ=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_BINFMT_AOUT=m +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CHR_DEV_OSST=m +CONFIG_MTD_BLKDEVS=y +CONFIG_DVB_TDA10086=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_DVB_NXT6000=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_XENO_OPT_NATIVE_ALARM=y +CONFIG_NLS_ISO8859_15=y +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_INET6_ESP=m +CONFIG_IP_VS_WRR=m +CONFIG_AUTOFS4_FS=m +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_SOC_WM8940=m +CONFIG_IP6_NF_FILTER=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_RT2500USB=m +CONFIG_SERIO_LIBPS2=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_NET_SCH_RED=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_USB_PRINTER=m +CONFIG_FONT_8x8=y +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_SERIAL_IR=m +CONFIG_SND_SOC_AK4104=m +CONFIG_XOR_BLOCKS=m +CONFIG_HID_TWINHAN=m +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_INPUT_JOYSTICK=y +CONFIG_QNX4FS_FS=m +CONFIG_RT2X00_LIB=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_USB_LED=m +CONFIG_SND_SOC_WM8974=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_PREEMPT_NONE=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_DVB_ZL10353=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_IP_VS=m +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_USB_XUSBATM=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_LIBCRC32C=m +CONFIG_KEYBOARD_MATRIX=m +CONFIG_CRYPTO_SHA256=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_VIDEO_AU0828=m +CONFIG_INET_TCP_DIAG=y +CONFIG_HID_SONY=m +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_HW_CONSOLE=y +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_IPX=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_OMFS_FS=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_SND_SPI=y +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_HID_MONTEREY=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_HID_EZKEY=m +CONFIG_IOSCHED_NOOP=y +CONFIG_DVB_S5H1409=m +CONFIG_LEDS_CPU=y +CONFIG_SCSI_OSD_ULD=m +CONFIG_BT_MRVL=m +CONFIG_QUOTACTL=y +CONFIG_CRYPTO_CRYPTD=m +CONFIG_SND_SOC_AK4535=m +CONFIG_COMPAT_BRK=y +CONFIG_VIDEO_CX2341X=m +CONFIG_LOCALVERSION="" +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_KEYBOARD_XTKBD=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_CAN_RAW=m +CONFIG_CRYPTO=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_STKWEBCAM=m +CONFIG_LEDS_GPIO_PLATFORM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_IP_NF_IPTABLES=m +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rw rootwait init=/sbin/init" +CONFIG_SPI_GPIO=m +CONFIG_DEFAULT_CUBIC=y +CONFIG_HID_SAMSUNG=m +CONFIG_SND_SOC_WM8955=m +CONFIG_USB_ISIGHTFW=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_DVB_DIB3000MC=m +CONFIG_CACHEFILES=m +CONFIG_LCD_ILI9320=m +CONFIG_JOYSTICK_A3D=m +CONFIG_SND_SOC_CS4270=m +CONFIG_ALIGNMENT_TRAP=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_SCSI_MOD=y +CONFIG_SND_SOC_SSM2602=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_P54_USB=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_SERIAL_CORE=y +CONFIG_FUSE_FS=m +CONFIG_UID16=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +CONFIG_EMBEDDED=y +CONFIG_HID_MICROSOFT=m +CONFIG_HAVE_KRETPROBES=y +CONFIG_USB_GSPCA_CONEX=m +CONFIG_VIDEO_DEV=m +CONFIG_KS0108=m +CONFIG_IRCOMM=m +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_SOUND_PRIME=m +CONFIG_USB_ET61X251=m +CONFIG_HAS_DMA=y +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_BT_L2CAP=m +CONFIG_SCSI=y +CONFIG_AT76C50X_USB=m +CONFIG_NF_NAT_PPTP=m +CONFIG_HID_CHICONY=m +CONFIG_HID=y +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_USB_ARMLINUX=y +CONFIG_JOYSTICK_GF2K=m +CONFIG_FONT_8x16=y +CONFIG_MAC80211_HWSIM=m +CONFIG_DVB_LGDT330X=m +CONFIG_LIBFC=m +CONFIG_RTC_DRV_CMOS=y +CONFIG_IEEE802154_DRIVERS=m +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_USB_PWC=m +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_JBD2=y +CONFIG_ATM_BR2684=m +CONFIG_SPI_TLE62X0=m +CONFIG_INET6_IPCOMP=m +CONFIG_IRDA_FAST_RR=y +CONFIG_PHYLIB=y +CONFIG_IPV6_TUNNEL=m +CONFIG_INPUT_APMPOWER=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_JFFS2_RTIME=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_W1_CON=y +CONFIG_KEYBOARD_ADP5588=m +CONFIG_HID_TOPSEED=m +CONFIG_XENO_OPT_STATS=y +CONFIG_NF_NAT_H323=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JFFS2_SUMMARY=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_HID_A4TECH=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_ZR364XX=m +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_DVB_LNBP21=m +CONFIG_DVB_TDA10048=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_CHR_DEV_SG=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_SMS_SDIO_DRV=m +CONFIG_XENO_FASTSYNCH_DEP=y +CONFIG_SND_MPU401=m +CONFIG_DVB_CX24116=m +CONFIG_CRYPTO_XCBC=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_SND_SOC_WM8731=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_CRYPTO_ARC4=m +CONFIG_DVB_STV0900=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_GL860=m +CONFIG_SCSI_TGT=y +CONFIG_CRYPTO_MANAGER=m +CONFIG_NET_SCH_HTB=m +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_DVB_USB_TTUSB2=m +CONFIG_MTD_NAND=y +CONFIG_RT_MUTEXES=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_XENO_OPT_PIPELINE_HEAD=y +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MD_LINEAR=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_IPIPE_DOMAINS=4 +CONFIG_I2C_ALGOBIT=m +CONFIG_MMC_BLOCK=y +CONFIG_NET_CLS_FW=m +CONFIG_SND_SOC_WM8727=m +CONFIG_LCD_LTV350QV=m +CONFIG_VIDEO_MT9V011=m +CONFIG_TOUCHSCREEN_W90X900=m +CONFIG_WIRELESS=y +CONFIG_WEXT_PROC=y +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SQUASHFS=y +CONFIG_NET_SCH_TBF=m +CONFIG_BT_HCIBTUSB=m +CONFIG_PERF_USE_VMALLOC=y +CONFIG_DVB_CX22702=m +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_ASYNC_XOR=m +CONFIG_NET_CLS_RSVP=m +CONFIG_DVB_STB6100=m +CONFIG_MD_RAID0=m +CONFIG_FRAME_WARN=1024 +CONFIG_ACT200L_DONGLE=m +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_USB_ETH=m +CONFIG_GENERIC_HWEIGHT=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_XENO_OPT_NUCLEUS=y +CONFIG_ATM_CLIP=m +CONFIG_LZO_COMPRESS=m +CONFIG_MMC=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_CRYPTO_SEQIV=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_HID_LOGITECH=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_IPIPE_AT91_TC=0 +CONFIG_XENO_OPT_PIPE=y +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_INLINE_SPIN_UNLOCK=y +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_VIDEO_TUNER=m +CONFIG_HAS_IOPORT=y +CONFIG_LEDS_LP3944=m +CONFIG_USB_SEVSEG=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_MTD_NAND_ATMEL=y +CONFIG_SND_MPU401_UART=m +CONFIG_XENO_OPT_NATIVE_MPS=y +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_DSBR=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_CAN_BCM=m +CONFIG_XENO_OPT_NATIVE_HEAP=y +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 +CONFIG_USB_ATM=m +CONFIG_HZ=100 +CONFIG_SND_AT73C213=m +CONFIG_USB_AT91=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_SND_MTS64=m +CONFIG_XENO_HW_UNLOCKED_SWITCH=y +CONFIG_CRYPTO_RMD160=m +CONFIG_INET_AH=m +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_TABLET_USB_KBTAB=m +CONFIG_UDF_FS=m +CONFIG_IPV6_MIP6=m +CONFIG_VXFS_FS=m +CONFIG_NLATTR=y +CONFIG_ZD1211RW=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_SCSI_NETLINK=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_DVB_DIB7000M=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_HID_KYE=m +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_VSXXXAA=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ=1024 +CONFIG_SYSFS=y +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_RADIO_SI4713=m +CONFIG_ARM_THUMB=y +CONFIG_IP_NF_MATCH_AH=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_DVB_S5H1420=m +CONFIG_AFS_FS=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IRLAN=m +CONFIG_MOUSE_SERIAL=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_WIMAX=m +CONFIG_DVB_LGDT3305=m +CONFIG_FB=m +CONFIG_I2C_COMPAT=y +CONFIG_KEYBOARD_OPENCORES=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_MSDOS_PARTITION=y +CONFIG_PATA_PLATFORM=m +CONFIG_BT_HCIUART=m +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_SND_SOC_WM8903=m +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_INPUT_POWERMATE=m +CONFIG_SND_SOC_WM_HUBS=m +CONFIG_DVB_MT312=m +CONFIG_HID_PETALYNX=m +CONFIG_ATM_LANE=m +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_IP_FIB_HASH=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_B43LEGACY_HWRNG=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_SND_DUMMY=m +CONFIG_USB_WUSB_CBAF=m +CONFIG_USB_NET_ZAURUS=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_DVB_ZL10039=m +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_TABLET_USB_ACECAD=m +CONFIG_VIDEO_MEDIA=m +CONFIG_CUSE=m +CONFIG_SND_SOC_WM8728=m +CONFIG_USB_ZERO=m +CONFIG_CRYPTO_RMD256=m +CONFIG_DVB_MT352=m +CONFIG_SPI_ATMEL=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_DEFAULT_SECURITY="" +CONFIG_TICK_ONESHOT=y +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_CRYPTO_CTR=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_WIRELESS_EXT=y +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_HW_RANDOM=y +CONFIG_DVB_USB_AU6610=m +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_DEFAULT_NOOP=y +CONFIG_IRTTY_SIR=m +CONFIG_NTFS_FS=m +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_SCSI_DH_HP_SW=m +CONFIG_IP_SCTP=m +CONFIG_BASE_SMALL=0 +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_RTL8187=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_MD_RAID6_PQ=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_PROC_FS=y +CONFIG_MTD_BLOCK=y +CONFIG_SND_SOC_WM8523=m +CONFIG_RC_MAP=m +CONFIG_WEXT_PRIV=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ROSE=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_NILFS2_FS=m +CONFIG_HID_PANTHERLORD=m +CONFIG_SND=m +CONFIG_XENO_OPT_NATIVE_EVENT=y +CONFIG_FLATMEM=y +CONFIG_NET_SCH_TEQL=m +CONFIG_IR_RC6_DECODER=m +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +CONFIG_IP_VS_SH=m +CONFIG_VIDEO_MSP3400=m +CONFIG_USB_TMC=m +CONFIG_SND_SOC_L3=m +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_IKCONFIG=m +CONFIG_DVB_STB6000=m +CONFIG_LEDS=y +CONFIG_SUSPEND_NVS=y +CONFIG_SYSCTL=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_W1_SLAVE_THERM=y +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_CIFS=m +CONFIG_XFRM_USER=m +CONFIG_TCP_CONG_BIC=m +CONFIG_SCSI_DH_EMC=m +CONFIG_USB_SE401=m +CONFIG_SND_SOC_WM8988=m +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_ATA_SFF=y +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_CRYPTO_LRW=m +CONFIG_USB_GSPCA_T613=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_MTPAV=m +CONFIG_MD_RAID10=m +CONFIG_ATMEL_TCLIB=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_CRAMFS=y +CONFIG_SLAB=y +CONFIG_KEYBOARD_LM8323=m +CONFIG_CHR_DEV_ST=m +CONFIG_DM_MULTIPATH=m +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_B43LEGACY=m +CONFIG_SND_SOC_WM8904=m +CONFIG_XENO_OPT_NATIVE_PIPE=y +CONFIG_DVB_USB_A800=m +CONFIG_SND_SOC_WM2000=m +CONFIG_SND_TIMER=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_BLK_DEV=y +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_MAC80211_RC_DEFAULT="minstrel" +CONFIG_XENO_DRIVERS_TIMERBENCH=y +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_TRACING_SUPPORT=y +CONFIG_UNIX98_PTYS=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_NET_SCHED=y +CONFIG_XENO_OPT_SEM_HEAPSZ=12 +CONFIG_JBD=y +CONFIG_DVB_PLL=m +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_ASYNC_CORE=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_INET_DIAG=y +CONFIG_CRYPTO_GHASH=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_NF_NAT_FTP=m +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_CRYPTO_RMD320=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_IKCONFIG_PROC=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_ELF_CORE=y +CONFIG_TEXTSEARCH=y +CONFIG_INOTIFY=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SUPPORT=y +CONFIG_INPUT_POLLDEV=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_RTC_DEBUG=y +CONFIG_MTD_CHAR=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_ATM=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_VT_CONSOLE=y +CONFIG_LEDS_GPIO=y +CONFIG_USB_GSPCA_STK014=m +CONFIG_IP_VS_FTP=m +CONFIG_CFG80211_WEXT=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_FPE_NWFPE=y +CONFIG_XENOMAI=y +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_BLK_DEV_RAM=y +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_INPUT_EVBUG=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_LCD_VGG2432A4=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_IR_RC5_DECODER=m +CONFIG_NET_SCH_GRED=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_USB_USS720=m +CONFIG_LEDS_DAC124S085=m +CONFIG_MOUSE_GPIO=m +CONFIG_RT73USB=m +CONFIG_USB_CYTHERM=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEO_V4L2=m +CONFIG_DVB_STV6110=m +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_HID_NTRIG=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_QUOTA=y +CONFIG_I2C_CHARDEV=y +CONFIG_LLC=m +CONFIG_CROSS_COMPILE="" +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_USB_GADGET_SELECTED=y +CONFIG_IPDDP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_AT91_TIMER_HZ=100 +CONFIG_ATA_BMDMA=y +CONFIG_ATALK=m +CONFIG_AT91_PMC_UNIT=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_NLS_UTF8=y +CONFIG_JOYSTICK_XPAD=m +CONFIG_INPUT_YEALINK=m +CONFIG_DVB_DIB3000MB=m +CONFIG_XENO_OPT_TIMING_VIRTICK=1000 +CONFIG_IWMC3200TOP=m +CONFIG_USB_USBNET=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_USB_SERIAL_PL2303=m +CONFIG_HAMRADIO=y +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_USB_MICROTEK=m +CONFIG_IPIPE_DELAYED_ATOMICSW=y +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_NEW_LEDS=y +CONFIG_SWAP=y +CONFIG_NET_SCH_HFSC=m +CONFIG_MAC80211=m +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_AT91_EARLY_USART0=y +CONFIG_CRC_CCITT=m +CONFIG_BLK_DEV_SD=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_MODULE_UNLOAD=y +CONFIG_NF_CT_ACCT=y +CONFIG_DVB_USB_CXUSB=m +CONFIG_RCU_FANOUT=32 +CONFIG_BITREVERSE=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_USB_SERIAL_WWAN=m +CONFIG_CRYPTO_PCOMP=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_NF_CONNTRACK=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_FILE_LOCKING=y +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_AIO=y +CONFIG_VIDEO_USBVIDEO=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_LEDS_CLASS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_DVB_USB_DIGITV=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_RTC_INTF_DEV=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_HID_SUPPORT=y +CONFIG_DVB_USB_CE6230=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_SND_VIRMIDI=m +CONFIG_LIB80211_CRYPT_TKIP=m +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_NF_CT_NETLINK=m +CONFIG_AUXDISPLAY=y +CONFIG_P54_SPI=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_MOUSE_PS2=y +CONFIG_NET_IPIP=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_WEXT_SPY=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_INPUT=y +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_PROC_SYSCTL=y +CONFIG_MMU=y +CONFIG_DVB_CX24123=m +CONFIG_OCFS2_FS=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INLINE_WRITE_UNLOCK=y diff -urN orig/linux-2.6.35.9//include/config/auto.conf.cmd relase/linux-2.6.35.9//include/config/auto.conf.cmd --- orig/linux-2.6.35.9//include/config/auto.conf.cmd 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/config/auto.conf.cmd 2011-03-15 11:08:30.609702442 +0100 @@ -0,0 +1,633 @@ +deps_config := \ + lib/Kconfig \ + drivers/crypto/Kconfig \ + crypto/async_tx/Kconfig \ + crypto/Kconfig \ + security/integrity/ima/Kconfig \ + security/tomoyo/Kconfig \ + security/smack/Kconfig \ + security/selinux/Kconfig \ + security/Kconfig \ + lib/Kconfig.kmemcheck \ + lib/Kconfig.kgdb \ + samples/Kconfig \ + kernel/trace/Kconfig \ + mm/Kconfig.debug \ + kernel/ipipe/Kconfig.debug \ + lib/Kconfig.debug \ + arch/arm/Kconfig.debug \ + fs/dlm/Kconfig \ + fs/nls/Kconfig \ + fs/partitions/Kconfig \ + fs/9p/Kconfig \ + fs/afs/Kconfig \ + fs/coda/Kconfig \ + fs/ncpfs/Kconfig \ + fs/cifs/Kconfig \ + fs/ceph/Kconfig \ + fs/smbfs/Kconfig \ + net/sunrpc/Kconfig \ + fs/nfsd/Kconfig \ + fs/nfs/Kconfig \ + fs/exofs/Kconfig \ + fs/ufs/Kconfig \ + fs/sysv/Kconfig \ + fs/romfs/Kconfig \ + fs/qnx4/Kconfig \ + fs/hpfs/Kconfig \ + fs/omfs/Kconfig \ + fs/minix/Kconfig \ + fs/freevxfs/Kconfig \ + fs/squashfs/Kconfig \ + fs/cramfs/Kconfig \ + fs/logfs/Kconfig \ + fs/ubifs/Kconfig \ + fs/jffs2/Kconfig \ + fs/efs/Kconfig \ + fs/bfs/Kconfig \ + fs/befs/Kconfig \ + fs/hfsplus/Kconfig \ + fs/hfs/Kconfig \ + fs/ecryptfs/Kconfig \ + fs/affs/Kconfig \ + fs/adfs/Kconfig \ + fs/configfs/Kconfig \ + fs/sysfs/Kconfig \ + fs/proc/Kconfig \ + fs/ntfs/Kconfig \ + fs/fat/Kconfig \ + fs/udf/Kconfig \ + fs/isofs/Kconfig \ + fs/cachefiles/Kconfig \ + fs/fscache/Kconfig \ + fs/fuse/Kconfig \ + fs/autofs4/Kconfig \ + fs/autofs/Kconfig \ + fs/quota/Kconfig \ + fs/notify/inotify/Kconfig \ + fs/notify/dnotify/Kconfig \ + fs/notify/Kconfig \ + fs/nilfs2/Kconfig \ + fs/btrfs/Kconfig \ + fs/ocfs2/Kconfig \ + fs/gfs2/Kconfig \ + fs/xfs/Kconfig \ + fs/jfs/Kconfig \ + fs/reiserfs/Kconfig \ + fs/jbd2/Kconfig \ + fs/jbd/Kconfig \ + fs/ext4/Kconfig \ + fs/ext3/Kconfig \ + fs/ext2/Kconfig \ + fs/Kconfig \ + drivers/platform/x86/Kconfig \ + drivers/platform/Kconfig \ + drivers/staging/msm/Kconfig \ + drivers/staging/mrst-touchscreen/Kconfig \ + drivers/staging/xgifb/Kconfig \ + drivers/staging/adis16255/Kconfig \ + drivers/staging/ti-st/Kconfig \ + drivers/staging/cxt1e1/Kconfig \ + drivers/staging/crystalhd/Kconfig \ + drivers/staging/dt3155v4l/Kconfig \ + drivers/staging/dt3155/Kconfig \ + drivers/staging/sm7xx/Kconfig \ + drivers/staging/samsung-laptop/Kconfig \ + drivers/staging/batman-adv/Kconfig \ + drivers/staging/wlags49_h25/Kconfig \ + drivers/staging/wlags49_h2/Kconfig \ + drivers/staging/ramzswap/Kconfig \ + drivers/staging/iio/trigger/Kconfig \ + drivers/staging/iio/light/Kconfig \ + drivers/staging/iio/imu/Kconfig \ + drivers/staging/iio/gyro/Kconfig \ + drivers/staging/iio/adc/Kconfig \ + drivers/staging/iio/accel/Kconfig \ + drivers/staging/iio/Kconfig \ + drivers/staging/sep/Kconfig \ + drivers/staging/memrar/Kconfig \ + drivers/staging/rar_register/Kconfig \ + drivers/staging/vme/boards/Kconfig \ + drivers/staging/vme/devices/Kconfig \ + drivers/staging/vme/bridges/Kconfig \ + drivers/staging/vme/Kconfig \ + drivers/staging/hv/Kconfig \ + drivers/staging/udlfb/Kconfig \ + drivers/staging/vt6656/Kconfig \ + drivers/staging/vt6655/Kconfig \ + drivers/staging/quatech_usb2/Kconfig \ + drivers/staging/serqt_usb2/Kconfig \ + drivers/staging/octeon/Kconfig \ + drivers/gpu/drm/nouveau/Kconfig \ + drivers/gpu/drm/vmwgfx/Kconfig \ + drivers/staging/line6/Kconfig \ + drivers/staging/phison/Kconfig \ + drivers/staging/pohmelfs/Kconfig \ + drivers/staging/dream/camera/Kconfig \ + drivers/staging/dream/Kconfig \ + drivers/staging/frontier/Kconfig \ + drivers/staging/rtl8192e/Kconfig \ + drivers/staging/rtl8192u/Kconfig \ + drivers/staging/rtl8192su/Kconfig \ + drivers/staging/rtl8187se/Kconfig \ + drivers/staging/panel/Kconfig \ + drivers/staging/asus_oled/Kconfig \ + drivers/staging/comedi/Kconfig \ + drivers/staging/rt2870/Kconfig \ + drivers/staging/rt2860/Kconfig \ + drivers/staging/otus/Kconfig \ + drivers/staging/echo/Kconfig \ + drivers/staging/wlan-ng/Kconfig \ + drivers/staging/winbond/Kconfig \ + drivers/staging/usbip/Kconfig \ + drivers/staging/tm6000/Kconfig \ + drivers/staging/cx25821/Kconfig \ + drivers/staging/go7007/Kconfig \ + drivers/staging/slicoss/Kconfig \ + drivers/staging/et131x/Kconfig \ + drivers/staging/Kconfig \ + drivers/xen/Kconfig \ + drivers/vlynq/Kconfig \ + drivers/uio/Kconfig \ + drivers/auxdisplay/Kconfig \ + drivers/dca/Kconfig \ + drivers/dma/Kconfig \ + drivers/rtc/Kconfig \ + drivers/edac/Kconfig \ + drivers/infiniband/ulp/iser/Kconfig \ + drivers/infiniband/ulp/srp/Kconfig \ + drivers/infiniband/ulp/ipoib/Kconfig \ + drivers/infiniband/hw/nes/Kconfig \ + drivers/infiniband/hw/mlx4/Kconfig \ + drivers/infiniband/hw/cxgb4/Kconfig \ + drivers/infiniband/hw/cxgb3/Kconfig \ + drivers/infiniband/hw/amso1100/Kconfig \ + drivers/infiniband/hw/ehca/Kconfig \ + drivers/infiniband/hw/qib/Kconfig \ + drivers/infiniband/hw/ipath/Kconfig \ + drivers/infiniband/hw/mthca/Kconfig \ + drivers/infiniband/Kconfig \ + drivers/accessibility/Kconfig \ + drivers/leds/Kconfig \ + drivers/memstick/host/Kconfig \ + drivers/memstick/core/Kconfig \ + drivers/memstick/Kconfig \ + drivers/mmc/host/Kconfig \ + drivers/mmc/card/Kconfig \ + drivers/mmc/core/Kconfig \ + drivers/mmc/Kconfig \ + drivers/uwb/Kconfig \ + drivers/usb/otg/Kconfig \ + drivers/usb/gadget/Kconfig \ + drivers/usb/atm/Kconfig \ + drivers/usb/misc/sisusbvga/Kconfig \ + drivers/usb/misc/Kconfig \ + drivers/usb/serial/Kconfig \ + drivers/usb/image/Kconfig \ + drivers/usb/storage/Kconfig \ + drivers/usb/class/Kconfig \ + drivers/usb/musb/Kconfig \ + drivers/usb/host/Kconfig \ + drivers/usb/wusbcore/Kconfig \ + drivers/usb/mon/Kconfig \ + drivers/usb/core/Kconfig \ + drivers/usb/Kconfig \ + drivers/hid/usbhid/Kconfig \ + drivers/hid/Kconfig \ + sound/oss/Kconfig \ + sound/soc/codecs/Kconfig \ + sound/soc/txx9/Kconfig \ + sound/soc/sh/Kconfig \ + sound/soc/s6000/Kconfig \ + sound/soc/s3c24xx/Kconfig \ + sound/soc/pxa/Kconfig \ + sound/soc/omap/Kconfig \ + sound/soc/imx/Kconfig \ + sound/soc/fsl/Kconfig \ + sound/soc/davinci/Kconfig \ + sound/soc/blackfin/Kconfig \ + sound/soc/au1x/Kconfig \ + sound/soc/atmel/Kconfig \ + sound/soc/Kconfig \ + sound/parisc/Kconfig \ + sound/sparc/Kconfig \ + sound/pcmcia/Kconfig \ + sound/usb/Kconfig \ + sound/sh/Kconfig \ + sound/mips/Kconfig \ + sound/spi/Kconfig \ + sound/atmel/Kconfig \ + sound/arm/Kconfig \ + sound/aoa/soundbus/Kconfig \ + sound/aoa/codecs/Kconfig \ + sound/aoa/fabrics/Kconfig \ + sound/aoa/Kconfig \ + sound/ppc/Kconfig \ + sound/pci/hda/Kconfig \ + sound/pci/Kconfig \ + sound/isa/Kconfig \ + sound/drivers/Kconfig \ + sound/core/seq/Kconfig \ + sound/core/Kconfig \ + sound/oss/dmasound/Kconfig \ + sound/Kconfig \ + drivers/video/logo/Kconfig \ + drivers/video/console/Kconfig \ + drivers/video/display/Kconfig \ + drivers/video/backlight/Kconfig \ + drivers/video/omap2/displays/Kconfig \ + drivers/video/omap2/omapfb/Kconfig \ + drivers/video/omap2/dss/Kconfig \ + drivers/video/omap2/Kconfig \ + drivers/video/omap/Kconfig \ + drivers/video/geode/Kconfig \ + drivers/gpu/drm/radeon/Kconfig \ + drivers/gpu/drm/Kconfig \ + drivers/gpu/vga/Kconfig \ + drivers/char/agp/Kconfig \ + drivers/video/Kconfig \ + drivers/media/dvb/frontends/Kconfig \ + drivers/media/dvb/ngene/Kconfig \ + drivers/media/dvb/mantis/Kconfig \ + drivers/media/dvb/pt1/Kconfig \ + drivers/media/dvb/firewire/Kconfig \ + drivers/media/dvb/dm1105/Kconfig \ + drivers/media/dvb/pluto2/Kconfig \ + drivers/media/dvb/bt8xx/Kconfig \ + drivers/media/dvb/b2c2/Kconfig \ + drivers/media/dvb/siano/Kconfig \ + drivers/media/dvb/ttusb-dec/Kconfig \ + drivers/media/dvb/ttusb-budget/Kconfig \ + drivers/media/dvb/dvb-usb/Kconfig \ + drivers/media/dvb/ttpci/Kconfig \ + drivers/media/dvb/Kconfig \ + drivers/media/radio/si470x/Kconfig \ + drivers/media/radio/Kconfig \ + drivers/media/video/pwc/Kconfig \ + drivers/media/video/zc0301/Kconfig \ + drivers/media/video/sn9c102/Kconfig \ + drivers/media/video/et61x251/Kconfig \ + drivers/media/video/usbvideo/Kconfig \ + drivers/media/video/usbvision/Kconfig \ + drivers/media/video/cx231xx/Kconfig \ + drivers/media/video/tlg2300/Kconfig \ + drivers/media/video/em28xx/Kconfig \ + drivers/media/video/hdpvr/Kconfig \ + drivers/media/video/pvrusb2/Kconfig \ + drivers/media/video/gspca/gl860/Kconfig \ + drivers/media/video/gspca/stv06xx/Kconfig \ + drivers/media/video/gspca/m5602/Kconfig \ + drivers/media/video/gspca/Kconfig \ + drivers/media/video/uvc/Kconfig \ + drivers/media/video/saa7164/Kconfig \ + drivers/media/video/cx18/Kconfig \ + drivers/media/video/ivtv/Kconfig \ + drivers/media/video/au0828/Kconfig \ + drivers/media/video/cx23885/Kconfig \ + drivers/media/video/cx88/Kconfig \ + drivers/media/video/saa7134/Kconfig \ + drivers/media/video/zoran/Kconfig \ + drivers/media/video/cpia2/Kconfig \ + drivers/media/video/bt8xx/Kconfig \ + drivers/media/video/omap/Kconfig \ + drivers/media/video/cx25840/Kconfig \ + drivers/media/video/Kconfig \ + drivers/media/common/tuners/Kconfig \ + drivers/media/IR/keymaps/Kconfig \ + drivers/media/IR/Kconfig \ + drivers/media/common/Kconfig \ + drivers/media/Kconfig \ + drivers/regulator/Kconfig \ + drivers/mfd/Kconfig \ + drivers/ssb/Kconfig \ + drivers/watchdog/Kconfig \ + drivers/thermal/Kconfig \ + drivers/hwmon/Kconfig \ + drivers/power/Kconfig \ + drivers/w1/slaves/Kconfig \ + drivers/w1/masters/Kconfig \ + drivers/w1/Kconfig \ + drivers/gpio/Kconfig \ + drivers/pps/clients/Kconfig \ + drivers/pps/Kconfig \ + drivers/spi/Kconfig \ + drivers/i2c/busses/Kconfig \ + drivers/i2c/algos/Kconfig \ + drivers/i2c/Kconfig \ + drivers/s390/char/Kconfig \ + drivers/char/tpm/Kconfig \ + drivers/char/pcmcia/Kconfig \ + drivers/char/hw_random/Kconfig \ + drivers/char/ipmi/Kconfig \ + drivers/serial/Kconfig \ + drivers/char/Kconfig \ + drivers/input/gameport/Kconfig \ + drivers/input/serio/Kconfig \ + drivers/input/misc/Kconfig \ + drivers/input/touchscreen/Kconfig \ + drivers/input/tablet/Kconfig \ + drivers/input/joystick/iforce/Kconfig \ + drivers/input/joystick/Kconfig \ + drivers/input/mouse/Kconfig \ + drivers/input/keyboard/Kconfig \ + drivers/input/Kconfig \ + drivers/telephony/Kconfig \ + drivers/isdn/hardware/mISDN/Kconfig \ + drivers/isdn/mISDN/Kconfig \ + drivers/isdn/hysdn/Kconfig \ + drivers/isdn/gigaset/Kconfig \ + drivers/isdn/hardware/eicon/Kconfig \ + drivers/isdn/hardware/avm/Kconfig \ + drivers/isdn/hardware/Kconfig \ + drivers/isdn/capi/Kconfig \ + drivers/isdn/act2000/Kconfig \ + drivers/isdn/sc/Kconfig \ + drivers/isdn/pcbit/Kconfig \ + drivers/isdn/icn/Kconfig \ + drivers/isdn/hisax/Kconfig \ + drivers/isdn/i4l/Kconfig \ + drivers/isdn/Kconfig \ + drivers/net/caif/Kconfig \ + drivers/s390/net/Kconfig \ + drivers/ieee802154/Kconfig \ + drivers/atm/Kconfig \ + drivers/net/wan/Kconfig \ + drivers/net/pcmcia/Kconfig \ + drivers/net/usb/Kconfig \ + drivers/net/wimax/i2400m/Kconfig \ + drivers/net/wimax/Kconfig \ + drivers/net/wireless/zd1211rw/Kconfig \ + drivers/net/wireless/wl12xx/Kconfig \ + drivers/net/wireless/rt2x00/Kconfig \ + drivers/net/wireless/p54/Kconfig \ + drivers/net/wireless/orinoco/Kconfig \ + drivers/net/wireless/libertas/Kconfig \ + drivers/net/wireless/iwmc3200wifi/Kconfig \ + drivers/net/wireless/iwlwifi/Kconfig \ + drivers/net/wireless/ipw2x00/Kconfig \ + drivers/net/wireless/hostap/Kconfig \ + drivers/net/wireless/b43legacy/Kconfig \ + drivers/net/wireless/b43/Kconfig \ + drivers/net/wireless/ath/ar9170/Kconfig \ + drivers/net/wireless/ath/ath9k/Kconfig \ + drivers/net/wireless/ath/ath5k/Kconfig \ + drivers/net/wireless/ath/Kconfig \ + drivers/net/wireless/rtl818x/Kconfig \ + drivers/net/wireless/Kconfig \ + drivers/net/tokenring/Kconfig \ + drivers/net/benet/Kconfig \ + drivers/net/sfc/Kconfig \ + drivers/net/stmmac/Kconfig \ + drivers/net/ixp2000/Kconfig \ + drivers/net/octeon/Kconfig \ + drivers/net/fs_enet/Kconfig \ + drivers/net/ibm_newemac/Kconfig \ + drivers/net/tulip/Kconfig \ + drivers/net/arm/Kconfig \ + drivers/net/phy/Kconfig \ + drivers/net/arcnet/Kconfig \ + drivers/net/Kconfig \ + drivers/macintosh/Kconfig \ + drivers/message/i2o/Kconfig \ + drivers/ieee1394/Kconfig \ + drivers/firewire/Kconfig \ + drivers/message/fusion/Kconfig \ + drivers/md/Kconfig \ + drivers/ata/Kconfig \ + drivers/scsi/osd/Kconfig \ + drivers/scsi/device_handler/Kconfig \ + drivers/scsi/pcmcia/Kconfig \ + drivers/scsi/arm/Kconfig \ + drivers/scsi/qla4xxx/Kconfig \ + drivers/scsi/qla2xxx/Kconfig \ + drivers/scsi/mpt2sas/Kconfig \ + drivers/scsi/megaraid/Kconfig.megaraid \ + drivers/scsi/mvsas/Kconfig \ + drivers/scsi/aic94xx/Kconfig \ + drivers/scsi/aic7xxx/Kconfig.aic79xx \ + drivers/scsi/aic7xxx/Kconfig.aic7xxx \ + drivers/scsi/be2iscsi/Kconfig \ + drivers/scsi/bnx2i/Kconfig \ + drivers/scsi/cxgb3i/Kconfig \ + drivers/scsi/libsas/Kconfig \ + drivers/scsi/Kconfig \ + drivers/ide/Kconfig \ + drivers/misc/iwmc3200top/Kconfig \ + drivers/misc/cb710/Kconfig \ + drivers/misc/eeprom/Kconfig \ + drivers/misc/c2port/Kconfig \ + drivers/misc/Kconfig \ + drivers/s390/block/Kconfig \ + drivers/block/drbd/Kconfig \ + drivers/block/paride/Kconfig \ + drivers/block/Kconfig \ + drivers/pnp/pnpacpi/Kconfig \ + drivers/pnp/pnpbios/Kconfig \ + drivers/pnp/isapnp/Kconfig \ + drivers/pnp/Kconfig \ + drivers/parport/Kconfig \ + drivers/of/Kconfig \ + drivers/mtd/ubi/Kconfig.debug \ + drivers/mtd/ubi/Kconfig \ + drivers/mtd/lpddr/Kconfig \ + drivers/mtd/onenand/Kconfig \ + drivers/mtd/nand/Kconfig \ + drivers/mtd/devices/Kconfig \ + drivers/mtd/maps/Kconfig \ + drivers/mtd/chips/Kconfig \ + drivers/mtd/Kconfig \ + drivers/connector/Kconfig \ + drivers/base/Kconfig \ + drivers/Kconfig \ + net/caif/Kconfig \ + net/9p/Kconfig \ + net/rfkill/Kconfig \ + net/wimax/Kconfig \ + net/mac80211/Kconfig \ + net/wireless/Kconfig \ + net/rxrpc/Kconfig \ + drivers/bluetooth/Kconfig \ + net/bluetooth/hidp/Kconfig \ + net/bluetooth/cmtp/Kconfig \ + net/bluetooth/bnep/Kconfig \ + net/bluetooth/rfcomm/Kconfig \ + net/bluetooth/Kconfig \ + drivers/net/irda/Kconfig \ + net/irda/ircomm/Kconfig \ + net/irda/irnet/Kconfig \ + net/irda/irlan/Kconfig \ + net/irda/Kconfig \ + drivers/net/can/usb/Kconfig \ + drivers/net/can/sja1000/Kconfig \ + drivers/net/can/mscan/Kconfig \ + drivers/net/can/Kconfig \ + net/can/Kconfig \ + drivers/net/hamradio/Kconfig \ + net/ax25/Kconfig \ + net/dcb/Kconfig \ + net/sched/Kconfig \ + net/ieee802154/Kconfig \ + net/phonet/Kconfig \ + net/wanrouter/Kconfig \ + net/econet/Kconfig \ + net/lapb/Kconfig \ + net/x25/Kconfig \ + drivers/net/appletalk/Kconfig \ + net/ipx/Kconfig \ + net/llc/Kconfig \ + net/decnet/Kconfig \ + net/8021q/Kconfig \ + net/dsa/Kconfig \ + net/bridge/Kconfig \ + net/802/Kconfig \ + net/l2tp/Kconfig \ + net/atm/Kconfig \ + net/tipc/Kconfig \ + net/rds/Kconfig \ + net/sctp/Kconfig \ + net/dccp/ccids/Kconfig \ + net/dccp/Kconfig \ + net/bridge/netfilter/Kconfig \ + net/decnet/netfilter/Kconfig \ + net/ipv6/netfilter/Kconfig \ + net/ipv4/netfilter/Kconfig \ + net/netfilter/ipvs/Kconfig \ + net/netfilter/Kconfig \ + net/netlabel/Kconfig \ + net/ipv6/Kconfig \ + net/ipv4/Kconfig \ + net/iucv/Kconfig \ + net/xfrm/Kconfig \ + net/unix/Kconfig \ + net/packet/Kconfig \ + net/Kconfig \ + kernel/power/Kconfig \ + fs/Kconfig.binfmt \ + drivers/cpuidle/Kconfig \ + drivers/cpufreq/Kconfig \ + mm/Kconfig \ + kernel/Kconfig.preempt \ + kernel/ipipe/Kconfig \ + kernel/time/Kconfig \ + drivers/pcmcia/Kconfig \ + drivers/pci/Kconfig \ + arch/arm/common/Kconfig \ + arch/arm/Kconfig-nommu \ + arch/arm/mm/Kconfig \ + arch/arm/mach-w90x900/Kconfig \ + arch/arm/mach-vexpress/Kconfig \ + arch/arm/mach-versatile/Kconfig \ + arch/arm/mach-ux500/Kconfig \ + arch/arm/mach-u300/Kconfig \ + arch/arm/plat-stmp3xxx/Kconfig \ + arch/arm/mach-shmobile/Kconfig \ + arch/arm/mach-s5pv210/Kconfig \ + arch/arm/mach-s5pc100/Kconfig \ + arch/arm/mach-s5p6442/Kconfig \ + arch/arm/mach-s5p6440/Kconfig \ + arch/arm/mach-s3c64xx/Kconfig \ + arch/arm/mach-s3c2443/Kconfig \ + arch/arm/mach-s3c2440/Kconfig \ + arch/arm/mach-s3c2416/Kconfig \ + arch/arm/mach-s3c2412/Kconfig \ + arch/arm/mach-s3c2410/Kconfig \ + arch/arm/mach-s3c2400/Kconfig \ + arch/arm/mach-spear6xx/Kconfig600 \ + arch/arm/mach-spear6xx/Kconfig \ + arch/arm/mach-spear3xx/Kconfig320 \ + arch/arm/mach-spear3xx/Kconfig310 \ + arch/arm/mach-spear3xx/Kconfig300 \ + arch/arm/mach-spear3xx/Kconfig \ + arch/arm/plat-spear/Kconfig \ + arch/arm/plat-s5p/Kconfig \ + arch/arm/plat-s3c24xx/Kconfig \ + arch/arm/plat-samsung/Kconfig \ + arch/arm/mach-sa1100/Kconfig \ + arch/arm/mach-realview/Kconfig \ + arch/arm/mach-mmp/Kconfig \ + arch/arm/plat-pxa/Kconfig \ + arch/arm/mach-pxa/Kconfig \ + arch/arm/mach-orion5x/Kconfig \ + arch/arm/mach-omap2/Kconfig \ + arch/arm/mach-omap1/Kconfig \ + arch/arm/plat-omap/Kconfig \ + arch/arm/mach-nuc93x/Kconfig \ + arch/arm/mach-ns9xxx/Kconfig \ + arch/arm/plat-nomadik/Kconfig \ + arch/arm/mach-nomadik/Kconfig \ + arch/arm/mach-netx/Kconfig \ + arch/arm/mach-mx5/Kconfig \ + arch/arm/mach-mxc91231/Kconfig \ + arch/arm/mach-mx25/Kconfig \ + arch/arm/mach-mx3/Kconfig \ + arch/arm/mach-mx2/Kconfig \ + arch/arm/mach-mx1/Kconfig \ + arch/arm/plat-mxc/Kconfig \ + arch/arm/mach-mv78xx0/Kconfig \ + arch/arm/mach-msm/Kconfig \ + arch/arm/mach-loki/Kconfig \ + arch/arm/mach-lh7a40x/Kconfig \ + arch/arm/mach-ks8695/Kconfig \ + arch/arm/mach-kirkwood/Kconfig \ + arch/arm/mach-ixp23xx/Kconfig \ + arch/arm/mach-ixp2000/Kconfig \ + arch/arm/mach-ixp4xx/Kconfig \ + arch/arm/mach-iop13xx/Kconfig \ + arch/arm/mach-iop33x/Kconfig \ + arch/arm/mach-iop32x/Kconfig \ + arch/arm/mach-integrator/Kconfig \ + arch/arm/mach-h720x/Kconfig \ + arch/arm/mach-gemini/Kconfig \ + arch/arm/mach-footbridge/Kconfig \ + arch/arm/mach-ep93xx/Kconfig \ + arch/arm/mach-dove/Kconfig \ + arch/arm/mach-davinci/Kconfig \ + arch/arm/mach-cns3xxx/Kconfig \ + arch/arm/mach-clps711x/Kconfig \ + arch/arm/mach-bcmring/Kconfig \ + arch/arm/mach-at91/Kconfig \ + arch/arm/mach-aaec2000/Kconfig \ + kernel/Kconfig.freezer \ + drivers/xenomai/ipc/Kconfig \ + drivers/xenomai/analogy/sensoray/Kconfig \ + drivers/xenomai/analogy/national_instruments/Kconfig \ + drivers/xenomai/analogy/intel/Kconfig \ + drivers/xenomai/analogy/testing/Kconfig \ + drivers/xenomai/analogy/Kconfig \ + drivers/xenomai/can/sja1000/Kconfig \ + drivers/xenomai/can/mscan/Kconfig \ + drivers/xenomai/can/Kconfig \ + drivers/xenomai/testing/Kconfig \ + drivers/xenomai/serial/Kconfig \ + drivers/xenomai/Kconfig \ + kernel/xenomai/skins/rtdm/Kconfig \ + kernel/xenomai/skins/rtai/Kconfig \ + kernel/xenomai/skins/vxworks/Kconfig \ + kernel/xenomai/skins/vrtx/Kconfig \ + kernel/xenomai/skins/uitron/Kconfig \ + kernel/xenomai/skins/psos+/Kconfig \ + kernel/xenomai/skins/posix/Kconfig \ + kernel/xenomai/skins/native/Kconfig \ + kernel/xenomai/skins/Kconfig \ + kernel/xenomai/nucleus/Kconfig \ + arch/arm/xenomai/Kconfig \ + kernel/Kconfig.locks \ + block/Kconfig.iosched \ + block/Kconfig \ + kernel/gcov/Kconfig \ + arch/Kconfig \ + usr/Kconfig \ + init/Kconfig \ + arch/arm/Kconfig + +include/config/auto.conf: \ + $(deps_config) + +ifneq "$(KERNELVERSION)" "2.6.35.9" +include/config/auto.conf: FORCE +endif +ifneq "$(ARCH)" "arm" +include/config/auto.conf: FORCE +endif + +$(deps_config): ; diff -urN orig/linux-2.6.35.9//include/config/kernel.release relase/linux-2.6.35.9//include/config/kernel.release --- orig/linux-2.6.35.9//include/config/kernel.release 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/config/kernel.release 2011-03-15 17:50:14.422032001 +0100 @@ -0,0 +1 @@ +2.6.35.9 diff -urN orig/linux-2.6.35.9//include/config/tristate.conf relase/linux-2.6.35.9//include/config/tristate.conf --- orig/linux-2.6.35.9//include/config/tristate.conf 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/config/tristate.conf 2011-03-15 11:08:30.665702442 +0100 @@ -0,0 +1,1087 @@ +# +# Automatically generated - do not edit + +CONFIG_IP6_NF_MATCH_AH=M +CONFIG_NF_CONNTRACK_H323=M +CONFIG_TOUCHSCREEN_INEXIO=M +CONFIG_IP_NF_TARGET_REDIRECT=M +CONFIG_CRC32=Y +CONFIG_NF_NAT_PROTO_SCTP=M +CONFIG_DM_SNAPSHOT=M +CONFIG_IR_JVC_DECODER=M +CONFIG_FSCACHE=M +CONFIG_BLK_DEV_DM=M +CONFIG_R3964=M +CONFIG_USB_SERIAL_HP4X=M +CONFIG_VLAN_8021Q=M +CONFIG_BT_RFCOMM=M +CONFIG_LEDS_TRIGGER_HEARTBEAT=Y +CONFIG_DEV_APPLETALK=M +CONFIG_DVB_TDA1004X=M +CONFIG_JOYSTICK_ADI=M +CONFIG_DVB_BCM3510=M +CONFIG_VIDEO_V4L1=M +CONFIG_NF_CONNTRACK_NETBIOS_NS=M +CONFIG_SCSI_DH=M +CONFIG_CRYPTO_MD4=M +CONFIG_BT_HCIBFUSB=M +CONFIG_USB_G_SERIAL=M +CONFIG_SND_SOC_TPA6130A2=M +CONFIG_LEDS_PCA955X=M +CONFIG_IP_VS_NQ=M +CONFIG_USB_SERIAL_NAVMAN=M +CONFIG_JOYSTICK_SPACEORB=M +CONFIG_TCP_CONG_HTCP=M +CONFIG_SCSI_DEBUG=M +CONFIG_BINFMT_MISC=M +CONFIG_NETFILTER_XT_MATCH_HELPER=M +CONFIG_NF_NAT_SIP=M +CONFIG_NETFILTER_XT_MATCH_STATISTIC=M +CONFIG_ESI_DONGLE=M +CONFIG_USB_SERIAL_EDGEPORT_TI=M +CONFIG_USB_SERIAL_SAFE=M +CONFIG_REISERFS_FS=Y +CONFIG_CRYPTO_RMD128=M +CONFIG_STP=M +CONFIG_USB_GSPCA_SQ905=M +CONFIG_DVB_AU8522=M +CONFIG_INET6_TUNNEL=M +CONFIG_NF_CONNTRACK_SIP=M +CONFIG_KSDAZZLE_DONGLE=M +CONFIG_XENO_SKIN_RTDM=Y +CONFIG_IP_NF_QUEUE=M +CONFIG_IP_VS_SED=M +CONFIG_DVB_DS3000=M +CONFIG_USB_SERIAL_FTDI_SIO=M +CONFIG_IP6_NF_MANGLE=M +CONFIG_BT_MRVL_SDIO=M +CONFIG_NETFILTER_XT_MATCH_REALM=M +CONFIG_BT_HCIBPA10X=M +CONFIG_IP_VS_RR=M +CONFIG_IPV6=M +CONFIG_USB_SERIAL_QUALCOMM=M +CONFIG_CRYPTO_AEAD=M +CONFIG_NET_CLS_FLOW=M +CONFIG_USB_STORAGE_USBAT=M +CONFIG_NF_NAT_PROTO_GRE=M +CONFIG_CRYPTO_PCBC=M +CONFIG_IP6_NF_TARGET_REJECT=M +CONFIG_ASYNC_MEMCPY=M +CONFIG_IR_NEC_DECODER=M +CONFIG_USB_SERIAL_MOS7840=M +CONFIG_VIDEO_BWQCAM=M +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=M +CONFIG_CONNECTOR=M +CONFIG_NETFILTER_XT_TARGET_RATEEST=M +CONFIG_DM_MULTIPATH_QL=M +CONFIG_LIBERTAS_USB=M +CONFIG_JFS_FS=M +CONFIG_XFRM_IPCOMP=M +CONFIG_CRYPTO_RNG2=M +CONFIG_NETFILTER_NETLINK_QUEUE=M +CONFIG_SND_SOC_AD193X=M +CONFIG_MSDOS_FS=Y +CONFIG_USB_GSPCA_SUNPLUS=M +CONFIG_USB_IBMCAM=M +CONFIG_CAN=M +CONFIG_CFG80211=M +CONFIG_DM_CRYPT=M +CONFIG_NCP_FS=M +CONFIG_LZO_DECOMPRESS=M +CONFIG_LIBERTAS_THINFIRM=M +CONFIG_EXOFS_FS=M +CONFIG_HID_BELKIN=M +CONFIG_VIDEO_IR_I2C=M +CONFIG_IWM=M +CONFIG_NFSD=M +CONFIG_SENSORS_TSL2550=M +CONFIG_USB_SERIAL_OPTION=M +CONFIG_USB=Y +CONFIG_SND_SOC_DA7210=M +CONFIG_USB_SPEEDTOUCH=M +CONFIG_SND_SOC_TLV320DAC33=M +CONFIG_CRYPTO_HMAC=M +CONFIG_SND_SOC_WM8900=M +CONFIG_USB_GSPCA_JEILINJ=M +CONFIG_CRC_ITU_T=Y +CONFIG_SND_HRTIMER=M +CONFIG_FRAMEBUFFER_CONSOLE=M +CONFIG_DM_ZERO=M +CONFIG_IP6_NF_TARGET_LOG=M +CONFIG_DVB_DIB8000=M +CONFIG_SND_SEQUENCER=M +CONFIG_TCP_CONG_LP=M +CONFIG_IP_NF_ARPTABLES=M +CONFIG_DVB_USB_GP8PSK=M +CONFIG_HID_CHERRY=M +CONFIG_HID_SUNPLUS=M +CONFIG_AF_RXRPC=M +CONFIG_CRYPTO_CAST5=M +CONFIG_SND_SOC=M +CONFIG_MEDIA_TUNER_XC5000=M +CONFIG_HID_THRUSTMASTER=M +CONFIG_CRYPTO_AUTHENC=M +CONFIG_USB_GPIO_VBUS=M +CONFIG_JOYSTICK_SIDEWINDER=M +CONFIG_IRDA=M +CONFIG_P54_COMMON=M +CONFIG_MTD=Y +CONFIG_SND_SOC_WM8776=M +CONFIG_NLS_CODEPAGE_850=Y +CONFIG_DVB_USB_UMT_010=M +CONFIG_JOYSTICK_DB9=M +CONFIG_INPUT_MOUSEDEV=Y +CONFIG_ATA=M +CONFIG_KEYBOARD_SUNKBD=M +CONFIG_CRYPTO_DES=M +CONFIG_NLS_CODEPAGE_437=Y +CONFIG_MTD_NAND_IDS=Y +CONFIG_MCS_FIR=M +CONFIG_NET_CLS_U32=M +CONFIG_EXPORTFS=M +CONFIG_SND_MIXER_OSS=M +CONFIG_TOUCHSCREEN_PENMOUNT=M +CONFIG_IP6_NF_MATCH_MH=M +CONFIG_SCSI_OSD_INITIATOR=M +CONFIG_DVB_AF9013=M +CONFIG_SERIO=Y +CONFIG_DVB_USB_DTV5100=M +CONFIG_VIDEO_TVEEPROM=M +CONFIG_MA600_DONGLE=M +CONFIG_SND_SOC_SPDIF=M +CONFIG_TOUCHSCREEN_TOUCHWIN=M +CONFIG_USB_EMI62=M +CONFIG_LEDS_TRIGGER_TIMER=Y +CONFIG_SND_SOC_WM8510=M +CONFIG_RT2800_LIB=M +CONFIG_SND_SOC_TLV320AIC3X=M +CONFIG_DVB_USB_DW2102=M +CONFIG_NF_CONNTRACK_SANE=M +CONFIG_SND_SOC_WM8990=M +CONFIG_TOIM3232_DONGLE=M +CONFIG_USB_SERIAL_MOS7720=M +CONFIG_NF_CT_PROTO_DCCP=M +CONFIG_ZLIB_INFLATE=Y +CONFIG_USB_STV680=M +CONFIG_CRC_T10DIF=M +CONFIG_MEDIA_TUNER_QT1010=M +CONFIG_LCD_LMS283GF05=M +CONFIG_CRYPTO_TWOFISH_COMMON=M +CONFIG_USB_VIDEO_CLASS=M +CONFIG_MMC_AT91=Y +CONFIG_MTD_CONCAT=Y +CONFIG_USB_SERIAL_TI=M +CONFIG_NET_SCH_CBQ=M +CONFIG_CRYPTO_SERPENT=M +CONFIG_NVRAM=M +CONFIG_LOCKD=M +CONFIG_DVB_S5H1411=M +CONFIG_USB_SN9C102=M +CONFIG_LIBERTAS=M +CONFIG_USB_GSPCA_TV8532=M +CONFIG_VIDEO_CPIA=M +CONFIG_JFFS2_FS=Y +CONFIG_SND_SOC_WM8750=M +CONFIG_VIDEO_OUTPUT_CONTROL=M +CONFIG_SCSI_DH_ALUA=M +CONFIG_USB_ZC0301=M +CONFIG_LIBFCOE=M +CONFIG_VIDEOBUF_VMALLOC=M +CONFIG_DVB_STV0299=M +CONFIG_DISPLAY_SUPPORT=M +CONFIG_NETFILTER_XT_MATCH_STRING=M +CONFIG_IP_NF_TARGET_LOG=M +CONFIG_MEDIA_TUNER_MAX2165=M +CONFIG_LLC2=M +CONFIG_DLM=M +CONFIG_USB_STORAGE=Y +CONFIG_CRYPTO_SEED=M +CONFIG_SATA_MV=M +CONFIG_DVB_TUNER_DIB0090=M +CONFIG_SND_USB_AUDIO=M +CONFIG_VIDEO_CX231XX=M +CONFIG_TCP_CONG_YEAH=M +CONFIG_IEEE802154=M +CONFIG_IP_VS_LC=M +CONFIG_HID_APPLE=M +CONFIG_MEDIA_TUNER_TDA827X=M +CONFIG_SND_RAWMIDI_SEQ=M +CONFIG_IP_NF_ARP_MANGLE=M +CONFIG_DVB_USB=M +CONFIG_DVB_ATBM8830=M +CONFIG_SND_ATMEL_SOC_SSC=M +CONFIG_NF_CONNTRACK_PPTP=M +CONFIG_VIDEO_CX231XX_ALSA=M +CONFIG_HFSPLUS_FS=M +CONFIG_OCFS2_FS_O2CB=M +CONFIG_CRYPTO_CAST6=M +CONFIG_PPS=M +CONFIG_USB_LCD=M +CONFIG_NF_CONNTRACK_IRC=M +CONFIG_USB_STV06XX=M +CONFIG_TEXTSEARCH_KMP=M +CONFIG_USB_NET_NET1080=M +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=M +CONFIG_MACB=Y +CONFIG_DVB_TUNER_ITD1000=M +CONFIG_BT_SCO=M +CONFIG_POWER_SUPPLY=M +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=M +CONFIG_USB_GSPCA_MR97310A=M +CONFIG_VIDEO_WM8775=M +CONFIG_NLS=Y +CONFIG_SPI_SPIDEV=Y +CONFIG_SND_SOC_AD73311=M +CONFIG_USB_GSPCA_SPCA508=M +CONFIG_USB_LEGOTOWER=M +CONFIG_MTD_DATAFLASH=Y +CONFIG_DVB_USB_DIBUSB_MC=M +CONFIG_DVB_USB_VP702X=M +CONFIG_NETFILTER_XT_MATCH_OWNER=M +CONFIG_IP_NF_TARGET_ECN=M +CONFIG_MD_FAULTY=M +CONFIG_VIDEO_USBVISION=M +CONFIG_SPI_BITBANG=M +CONFIG_USB_STORAGE_ALAUDA=M +CONFIG_JOYSTICK_GRIP_MP=M +CONFIG_MEDIA_TUNER_TDA18271=M +CONFIG_IP6_NF_IPTABLES=M +CONFIG_TEKRAM_DONGLE=M +CONFIG_USB_SERIAL_IPW=M +CONFIG_INET_IPCOMP=M +CONFIG_DVB_USB_DIB0700=M +CONFIG_TOUCHSCREEN_FUJITSU=M +CONFIG_MCP2120_DONGLE=M +CONFIG_ASYNC_PQ=M +CONFIG_HID_CYPRESS=M +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=M +CONFIG_VIDEO_SAA711X=M +CONFIG_NLS_ISO8859_1=Y +CONFIG_CRYPTO_WORKQUEUE=M +CONFIG_TCP_CONG_HYBLA=M +CONFIG_HID_KENSINGTON=M +CONFIG_BACKLIGHT_GENERIC=M +CONFIG_TEXTSEARCH_BM=M +CONFIG_SND_PCM_OSS=M +CONFIG_DVB_B2C2_FLEXCOP=M +CONFIG_USB_IRDA=M +CONFIG_SND_SOC_WM8960=M +CONFIG_RFKILL=M +CONFIG_VIDEO_TVP5150=M +CONFIG_NET_KEY=M +CONFIG_SMS_SIANO_MDTV=M +CONFIG_IP6_NF_TARGET_HL=M +CONFIG_IPV6_SIT=M +CONFIG_USB_MR800=M +CONFIG_USB_SERIAL_WHITEHEAT=M +CONFIG_NET_CLS_ROUTE4=M +CONFIG_SND_SOC_WM9081=M +CONFIG_IP_VS_DH=M +CONFIG_SND_SOC_WM8753=M +CONFIG_VIDEO_IR=M +CONFIG_IP_NF_TARGET_MASQUERADE=M +CONFIG_WAN_ROUTER=M +CONFIG_KS959_DONGLE=M +CONFIG_JOYSTICK_MAGELLAN=M +CONFIG_KINGSUN_DONGLE=M +CONFIG_NF_NAT_PROTO_DCCP=M +CONFIG_DM_DELAY=M +CONFIG_USB_SERIAL_CH341=M +CONFIG_USB_FTDI_ELAN=M +CONFIG_DVB_USB_FRIIO=M +CONFIG_USB_IOWARRIOR=M +CONFIG_SCSI_SPI_ATTRS=M +CONFIG_CRYPTO_SHA512=M +CONFIG_PHONET=M +CONFIG_SCSI_WAIT_SCAN=M +CONFIG_BACKLIGHT_CLASS_DEVICE=M +CONFIG_USB_M5602=M +CONFIG_RT2X00_LIB_USB=M +CONFIG_CRYPTO_NULL=M +CONFIG_DVB_USB_AF9005_REMOTE=M +CONFIG_NF_DEFRAG_IPV4=M +CONFIG_USB_IDMOUSE=M +CONFIG_INET_XFRM_MODE_BEET=M +CONFIG_CRYPTO_DEFLATE=M +CONFIG_USB_APPLEDISPLAY=M +CONFIG_USB_SERIAL_KLSI=M +CONFIG_NETFILTER_XT_MATCH_TCPMSS=M +CONFIG_BT_HCIBTSDIO=M +CONFIG_ATM_MPOA=M +CONFIG_CRYPTO_GCM=M +CONFIG_NETFILTER_NETLINK_LOG=M +CONFIG_NETFILTER_XT_MATCH_MARK=M +CONFIG_DVB_LGS8GXX=M +CONFIG_IP_NF_MANGLE=M +CONFIG_TOUCHSCREEN_MCS5000=M +CONFIG_INET6_XFRM_MODE_TUNNEL=M +CONFIG_MEDIA_SUPPORT=M +CONFIG_IP_NF_FILTER=M +CONFIG_HID_ZEROPLUS=M +CONFIG_EXT3_FS=Y +CONFIG_SOC_CAMERA_OV772X=M +CONFIG_NETFILTER_XT_MATCH_LENGTH=M +CONFIG_FAT_FS=Y +CONFIG_TEXTSEARCH_FSM=M +CONFIG_IP6_NF_RAW=M +CONFIG_USB_ZD1201=M +CONFIG_INET_TUNNEL=M +CONFIG_EEPROM_93CX6=M +CONFIG_ROMFS_FS=M +CONFIG_DVB_USB_DTT200U=M +CONFIG_LIB80211=M +CONFIG_USB_CXACRU=M +CONFIG_PHONE=M +CONFIG_NET_IPGRE=M +CONFIG_LIBERTAS_SDIO=M +CONFIG_NF_NAT_SNMP_BASIC=M +CONFIG_LIBERTAS_SPI=M +CONFIG_USB_OHCI_HCD=Y +CONFIG_USB_GSPCA=M +CONFIG_DM_MIRROR=M +CONFIG_CRYPTO_BLOWFISH=M +CONFIG_AR9170_USB=M +CONFIG_USB_G_PRINTER=M +CONFIG_B43=M +CONFIG_JOYSTICK_GRIP=M +CONFIG_USB_RIO500=M +CONFIG_CRYPTO_CCM=M +CONFIG_NET_CLS_RSVP6=M +CONFIG_USB_NET_CDC_SUBSET=M +CONFIG_QFMT_V2=M +CONFIG_USB_S2255=M +CONFIG_NETFILTER_XT_MATCH_CONNMARK=M +CONFIG_USB_SERIAL_MCT_U232=M +CONFIG_UIO_PDRV_GENIRQ=M +CONFIG_CRYPTO_RNG=M +CONFIG_USB_SERIAL_GARMIN=M +CONFIG_W1_MASTER_GPIO=Y +CONFIG_RAW_DRIVER=M +CONFIG_JOYSTICK_COBRA=M +CONFIG_NET_SCH_ATM=M +CONFIG_SND_SOC_UDA1380=M +CONFIG_USB_SERIAL_KEYSPAN=M +CONFIG_SND_USB_CAIAQ=M +CONFIG_USB_STORAGE_CYPRESS_ATACB=M +CONFIG_SOC_CAMERA_MT9M111=M +CONFIG_XENO_DRIVERS_SWITCHTEST=Y +CONFIG_INET_XFRM_MODE_TRANSPORT=M +CONFIG_CRYPTO_MD5=M +CONFIG_VIDEO_CS53L32A=M +CONFIG_ISCSI_TCP=M +CONFIG_DVB_TDA10023=M +CONFIG_MEDIA_TUNER_TEA5767=M +CONFIG_VIDEOBUF_DVB=M +CONFIG_USB_GSPCA_OV519=M +CONFIG_MD_RAID456=M +CONFIG_JOYSTICK_STINGER=M +CONFIG_INET6_AH=M +CONFIG_RTC_DRV_AT91SAM9=Y +CONFIG_USB_SERIAL=M +CONFIG_USB_MON=Y +CONFIG_SIGMATEL_FIR=M +CONFIG_IP_NF_TARGET_ULOG=M +CONFIG_INET_XFRM_TUNNEL=M +CONFIG_NETFILTER_XT_MARK=M +CONFIG_NETFILTER_XTABLES=M +CONFIG_IP_VS_LBLC=M +CONFIG_DVB_USB_OPERA1=M +CONFIG_XENO_SKIN_POSIX=Y +CONFIG_LEDS_BD2802=M +CONFIG_KEYBOARD_STOWAWAY=M +CONFIG_USB_STORAGE_DATAFAB=M +CONFIG_DVB_USB_AF9005=M +CONFIG_TCP_CONG_VEGAS=M +CONFIG_USB_STORAGE_KARMA=M +CONFIG_HID_GREENASIA=M +CONFIG_SMS_USB_DRV=M +CONFIG_USB_SERIAL_OPTICON=M +CONFIG_DVB_NXT200X=M +CONFIG_HID_GYRATION=M +CONFIG_SND_SOC_AK4642=M +CONFIG_USB_WDM=M +CONFIG_BT_HCIBCM203X=M +CONFIG_TOUCHSCREEN_USB_COMPOSITE=M +CONFIG_VIDEO_EM28XX_DVB=M +CONFIG_USB_SERIAL_KOBIL_SCT=M +CONFIG_INPUT_JOYDEV=M +CONFIG_SND_SOC_MAX9877=M +CONFIG_KEYBOARD_LKKBD=M +CONFIG_USB_ACM=M +CONFIG_CRC16=Y +CONFIG_USB_NET_AX8817X=M +CONFIG_CRYPTO_GF128MUL=M +CONFIG_UIO_PDRV=M +CONFIG_AX25=M +CONFIG_HOSTAP=M +CONFIG_SND_SOC_WM8711=M +CONFIG_VIDEO_EM28XX=M +CONFIG_CRYPTO_ANUBIS=M +CONFIG_JOYSTICK_SPACEBALL=M +CONFIG_NETFILTER_XT_TARGET_HL=M +CONFIG_DVB_CORE=M +CONFIG_TOUCHSCREEN_GUNZE=M +CONFIG_VIDEO_CQCAM=M +CONFIG_XENO_SKIN_NATIVE=Y +CONFIG_USB_HID=Y +CONFIG_DVB_USB_AF9015=M +CONFIG_CRYPTO_TGR192=M +CONFIG_BLK_DEV_MD=M +CONFIG_USB_SERIAL_AIRCABLE=M +CONFIG_SND_SOC_WM8978=M +CONFIG_CRYPTO_ZLIB=M +CONFIG_USB_SERIAL_FUNSOFT=M +CONFIG_JOYSTICK_INTERACT=M +CONFIG_RT2X00=M +CONFIG_KEYBOARD_GPIO=Y +CONFIG_NF_CONNTRACK_FTP=M +CONFIG_IP_NF_MATCH_ECN=M +CONFIG_USB_GADGET=Y +CONFIG_USB_GSPCA_SPCA506=M +CONFIG_KEYBOARD_NEWTON=M +CONFIG_VIDEO_EM28XX_ALSA=M +CONFIG_MEDIA_TUNER_MXL5005S=M +CONFIG_DVB_SI21XX=M +CONFIG_SOUND=M +CONFIG_DVB_USB_VP7045=M +CONFIG_MEDIA_TUNER_TDA9887=M +CONFIG_CRYPTO_TEA=M +CONFIG_ATMEL_SSC=Y +CONFIG_UNIX=Y +CONFIG_MINIX_FS=M +CONFIG_CRYPTO_HASH2=M +CONFIG_SND_SOC_AK4671=M +CONFIG_USB_GSPCA_SONIXB=M +CONFIG_USB_STORAGE_ISD200=M +CONFIG_NFS_FS=M +CONFIG_INET_ESP=M +CONFIG_LCD_TDO24M=M +CONFIG_NF_CONNTRACK_IPV6=M +CONFIG_CRYPTO_ALGAPI=M +CONFIG_SOC_CAMERA_PLATFORM=M +CONFIG_BRIDGE=M +CONFIG_MEDIA_TUNER=M +CONFIG_TABLET_USB_GTCO=M +CONFIG_USB_CYPRESS_CY7C63=M +CONFIG_SND_SOC_AD1836=M +CONFIG_INPUT_UINPUT=M +CONFIG_MEDIA_TUNER_SIMPLE=M +CONFIG_KEYBOARD_ATKBD=M +CONFIG_NF_NAT=M +CONFIG_USB_SERIAL_XIRCOM=M +CONFIG_MOUSE_BCM5974=M +CONFIG_CHR_DEV_SCH=M +CONFIG_RT2800USB=M +CONFIG_CRYPTO_HASH=M +CONFIG_VFAT_FS=Y +CONFIG_MD_RAID1=M +CONFIG_CRYPTO_VMAC=M +CONFIG_VIDEO_HDPVR=M +CONFIG_OLD_BELKIN_DONGLE=M +CONFIG_BLK_DEV_SR=M +CONFIG_SND_HWDEP=M +CONFIG_BLK_DEV_LOOP=Y +CONFIG_IPMI_HANDLER=M +CONFIG_SYSV_FS=M +CONFIG_NF_NAT_IRC=M +CONFIG_MEDIA_TUNER_XC2028=M +CONFIG_DVB_STV0288=M +CONFIG_SOC_CAMERA=M +CONFIG_MTD_NAND_ECC=Y +CONFIG_CRYPTO_CBC=M +CONFIG_IP6_NF_MATCH_RT=M +CONFIG_FS_MBCACHE=Y +CONFIG_MD_MULTIPATH=M +CONFIG_DS1682=M +CONFIG_GFS2_FS=M +CONFIG_RTC_CLASS=Y +CONFIG_DVB_TUNER_DIB0070=M +CONFIG_CRC7=M +CONFIG_NET_CLS_TCINDEX=M +CONFIG_USB_EMI26=M +CONFIG_SND_SOC_WM8993=M +CONFIG_TOUCHSCREEN_TSC2007=M +CONFIG_PATA_AT91=M +CONFIG_W1=Y +CONFIG_USB_GSPCA_VC032X=M +CONFIG_DVB_ISL6421=M +CONFIG_IP_VS_WLC=M +CONFIG_NF_NAT_TFTP=M +CONFIG_SND_SOC_ADS117X=M +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=M +CONFIG_NET_SCH_NETEM=M +CONFIG_CRYPTO_CAMELLIA=M +CONFIG_I2C_SI4713=M +CONFIG_TCP_CONG_ILLINOIS=M +CONFIG_CRYPTO_MANAGER2=M +CONFIG_CONFIGFS_FS=M +CONFIG_CRYPTO_TEST=M +CONFIG_I2C=Y +CONFIG_VIDEO_CX25840=M +CONFIG_PARPORT_PC=M +CONFIG_SCSI_SRP_ATTRS=M +CONFIG_BT_HIDP=M +CONFIG_IR_CORE=M +CONFIG_UFS_FS=M +CONFIG_VIDEO_CPIA_USB=M +CONFIG_USB_GSPCA_FINEPIX=M +CONFIG_CRYPTO_ECB=M +CONFIG_USB_GSPCA_ETOMS=M +CONFIG_USB_W9968CF=M +CONFIG_NF_CONNTRACK_AMANDA=M +CONFIG_USB_SERIAL_EDGEPORT=M +CONFIG_ZLIB_DEFLATE=Y +CONFIG_SUNRPC=M +CONFIG_VIDEO_SAA5249=M +CONFIG_SCSI_DH_RDAC=M +CONFIG_INPUT_ATI_REMOTE2=M +CONFIG_IP_VS_LBLCR=M +CONFIG_FW_LOADER=M +CONFIG_LITELINK_DONGLE=M +CONFIG_USB_GSPCA_SPCA501=M +CONFIG_USB_KONICAWC=M +CONFIG_CRYPTO_XTS=M +CONFIG_NETFILTER_XT_MATCH_RECENT=M +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=M +CONFIG_MII=Y +CONFIG_VIDEO_CPIA2=M +CONFIG_EXT4_FS=Y +CONFIG_NET_SCH_DRR=M +CONFIG_CRYPTO_SHA1=M +CONFIG_JOYSTICK_JOYDUMP=M +CONFIG_USB_ADUTUX=M +CONFIG_ATH_COMMON=M +CONFIG_CODA_FS=M +CONFIG_DVB_TUNER_CX24113=M +CONFIG_SND_RAWMIDI=M +CONFIG_USB_STORAGE_SDDR09=M +CONFIG_IP_NF_MATCH_TTL=M +CONFIG_ASYNC_RAID6_RECOV=M +CONFIG_SND_SOC_UDA134X=M +CONFIG_USB_GADGETFS=M +CONFIG_IP6_NF_MATCH_FRAG=M +CONFIG_APM_EMULATION=M +CONFIG_USB_SERIAL_CYBERJACK=M +CONFIG_NET_SCH_PRIO=M +CONFIG_USB_SERIAL_IUU=M +CONFIG_CRYPTO_LZO=M +CONFIG_SND_PCM=M +CONFIG_GIRBIL_DONGLE=M +CONFIG_SDIO_UART=M +CONFIG_NETFILTER_XT_MATCH_DCCP=M +CONFIG_SND_SOC_WM8971=M +CONFIG_SCSI_ISCSI_ATTRS=M +CONFIG_USB_SERIAL_EMPEG=M +CONFIG_KEYBOARD_MAX7359=M +CONFIG_IR_SONY_DECODER=M +CONFIG_VIDEO_PVRUSB2=M +CONFIG_NETFILTER_XT_MATCH_COMMENT=M +CONFIG_USB_NET_RNDIS_HOST=M +CONFIG_INPUT_EVDEV=Y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=M +CONFIG_EXT2_FS=Y +CONFIG_TABLET_USB_WACOM=M +CONFIG_NETFILTER_XT_MATCH_DSCP=M +CONFIG_CRYPTO_WP512=M +CONFIG_SND_SOC_WM9090=M +CONFIG_HID_DRAGONRISE=M +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=M +CONFIG_NETFILTER_XT_MATCH_RATEEST=M +CONFIG_HPFS_FS=M +CONFIG_USB_LD=M +CONFIG_QUOTA_TREE=M +CONFIG_USB_NET_CDCETHER=M +CONFIG_PACKET=Y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=M +CONFIG_NET_CLS_BASIC=M +CONFIG_NETROM=M +CONFIG_USB_GSPCA_OV534=M +CONFIG_DVB_USB_GL861=M +CONFIG_SND_SOC_PCM3008=M +CONFIG_NF_CONNTRACK_TFTP=M +CONFIG_DVB_USB_ANYSEE=M +CONFIG_USB_FILE_STORAGE=M +CONFIG_CRYPTO_TWOFISH=M +CONFIG_USB_TEST=M +CONFIG_BT=M +CONFIG_BT_HCIVHCI=M +CONFIG_INPUT_CM109=M +CONFIG_LCD_PLATFORM=M +CONFIG_SND_AT91_SOC_SAM9G20_WM8731=M +CONFIG_PARPORT=M +CONFIG_HID_WACOM=M +CONFIG_USB_SERIAL_CP210X=M +CONFIG_NET_SCH_SFQ=M +CONFIG_RTC_LIB=Y +CONFIG_USB_UEAGLEATM=M +CONFIG_NETFILTER_XT_MATCH_POLICY=M +CONFIG_MOUSE_SYNAPTICS_I2C=M +CONFIG_CRYPTO_AES=M +CONFIG_DVB_DIB7000P=M +CONFIG_AT91SAM9X_WATCHDOG=Y +CONFIG_SSB=M +CONFIG_SND_SOC_WM8961=M +CONFIG_RADIO_TEA5764=M +CONFIG_PARPORT_AX88796=M +CONFIG_AUTOFS_FS=M +CONFIG_GAMEPORT=M +CONFIG_ISO9660_FS=M +CONFIG_DVB_USB_M920X=M +CONFIG_UIO=M +CONFIG_SOC_CAMERA_MT9T031=M +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=M +CONFIG_NETFILTER_XT_MATCH_CLUSTER=M +CONFIG_USB_MDC800=M +CONFIG_SERIO_SERPORT=Y +CONFIG_DVB_STV0297=M +CONFIG_BT_BNEP=M +CONFIG_DVB_TDA826X=M +CONFIG_INET_XFRM_MODE_TUNNEL=M +CONFIG_USB_VICAM=M +CONFIG_SND_SOC_TLV320AIC23=M +CONFIG_USB_SERIAL_BELKIN=M +CONFIG_MEDIA_TUNER_MT2266=M +CONFIG_XFS_FS=M +CONFIG_INPUT_KEYSPAN_REMOTE=M +CONFIG_TOUCHSCREEN_ELO=M +CONFIG_TOUCHSCREEN_TOUCHIT213=M +CONFIG_BINFMT_AOUT=M +CONFIG_CHR_DEV_OSST=M +CONFIG_MTD_BLKDEVS=Y +CONFIG_DVB_TDA10086=M +CONFIG_DVB_NXT6000=M +CONFIG_NLS_ISO8859_15=Y +CONFIG_TOUCHSCREEN_EETI=M +CONFIG_INET6_ESP=M +CONFIG_IP_VS_WRR=M +CONFIG_AUTOFS4_FS=M +CONFIG_SND_ATMEL_SOC=M +CONFIG_SND_SOC_WM8940=M +CONFIG_IP6_NF_FILTER=M +CONFIG_RT2500USB=M +CONFIG_SERIO_LIBPS2=Y +CONFIG_NET_SCH_RED=M +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=M +CONFIG_USB_PRINTER=M +CONFIG_USB_GSPCA_PAC207=M +CONFIG_USB_SERIAL_IR=M +CONFIG_SND_SOC_AK4104=M +CONFIG_XOR_BLOCKS=M +CONFIG_HID_TWINHAN=M +CONFIG_QNX4FS_FS=M +CONFIG_RT2X00_LIB=M +CONFIG_USB_STORAGE_SDDR55=M +CONFIG_IP_NF_TARGET_TTL=M +CONFIG_USB_LED=M +CONFIG_SND_SOC_WM8974=M +CONFIG_TOUCHSCREEN_WACOM_W8001=M +CONFIG_DVB_ZL10353=M +CONFIG_NETFILTER_XT_MATCH_TIME=M +CONFIG_IP_VS=M +CONFIG_USB_XUSBATM=M +CONFIG_NETFILTER_XT_MATCH_MAC=M +CONFIG_NETFILTER_XT_TARGET_NFLOG=M +CONFIG_DVB_B2C2_FLEXCOP_USB=M +CONFIG_TCP_CONG_WESTWOOD=M +CONFIG_USB_GSPCA_SPCA561=M +CONFIG_LIBCRC32C=M +CONFIG_KEYBOARD_MATRIX=M +CONFIG_CRYPTO_SHA256=M +CONFIG_JOYSTICK_GUILLEMOT=M +CONFIG_VIDEO_AU0828=M +CONFIG_INET_TCP_DIAG=Y +CONFIG_HID_SONY=M +CONFIG_SOC_CAMERA_TW9910=M +CONFIG_SOC_CAMERA_MT9V022=M +CONFIG_IPX=M +CONFIG_OMFS_FS=M +CONFIG_USB_GSPCA_ZC3XX=M +CONFIG_TOUCHSCREEN_MTOUCH=M +CONFIG_HID_MONTEREY=M +CONFIG_USB_SERIAL_CYPRESS_M8=M +CONFIG_HID_EZKEY=M +CONFIG_DVB_S5H1409=M +CONFIG_SCSI_OSD_ULD=M +CONFIG_BT_MRVL=M +CONFIG_CRYPTO_CRYPTD=M +CONFIG_SND_SOC_AK4535=M +CONFIG_VIDEO_CX2341X=M +CONFIG_KEYBOARD_XTKBD=M +CONFIG_USB_GSPCA_MARS=M +CONFIG_CAN_RAW=M +CONFIG_CRYPTO=Y +CONFIG_USB_TRANCEVIBRATOR=M +CONFIG_USB_STKWEBCAM=M +CONFIG_IP_NF_IPTABLES=M +CONFIG_SPI_GPIO=M +CONFIG_HID_SAMSUNG=M +CONFIG_SND_SOC_WM8955=M +CONFIG_USB_ISIGHTFW=M +CONFIG_DVB_DIB3000MC=M +CONFIG_CACHEFILES=M +CONFIG_LCD_ILI9320=M +CONFIG_JOYSTICK_A3D=M +CONFIG_SND_SOC_CS4270=M +CONFIG_TCP_CONG_HSTCP=M +CONFIG_SCSI_MOD=Y +CONFIG_SND_SOC_SSM2602=M +CONFIG_JOYSTICK_ZHENHUA=M +CONFIG_USB_SERIAL_SPCP8X5=M +CONFIG_SND_SOC_TLV320AIC26=M +CONFIG_P54_USB=M +CONFIG_TOUCHSCREEN_MK712=M +CONFIG_CRYPTO_CRC32C=M +CONFIG_SERIAL_CORE=Y +CONFIG_FUSE_FS=M +CONFIG_HID_MICROSOFT=M +CONFIG_USB_GSPCA_CONEX=M +CONFIG_VIDEO_DEV=M +CONFIG_KS0108=M +CONFIG_IRCOMM=M +CONFIG_SOUND_PRIME=M +CONFIG_USB_ET61X251=M +CONFIG_NF_CT_PROTO_SCTP=M +CONFIG_USB_SERIAL_VISOR=M +CONFIG_BT_L2CAP=M +CONFIG_SCSI=Y +CONFIG_AT76C50X_USB=M +CONFIG_NF_NAT_PPTP=M +CONFIG_HID_CHICONY=M +CONFIG_HID=Y +CONFIG_LIBERTAS_THINFIRM_USB=M +CONFIG_SND_SERIAL_U16550=M +CONFIG_JOYSTICK_GF2K=M +CONFIG_MAC80211_HWSIM=M +CONFIG_DVB_LGDT330X=M +CONFIG_LIBFC=M +CONFIG_RTC_DRV_CMOS=Y +CONFIG_IEEE802154_DRIVERS=M +CONFIG_USB_PWC=M +CONFIG_MEDIA_TUNER_TDA8290=M +CONFIG_JBD2=Y +CONFIG_ATM_BR2684=M +CONFIG_SPI_TLE62X0=M +CONFIG_INET6_IPCOMP=M +CONFIG_PHYLIB=Y +CONFIG_IPV6_TUNNEL=M +CONFIG_INPUT_APMPOWER=M +CONFIG_MEDIA_TUNER_MT20XX=M +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=M +CONFIG_IP_NF_RAW=M +CONFIG_IP_NF_ARPFILTER=M +CONFIG_KEYBOARD_ADP5588=M +CONFIG_HID_TOPSEED=M +CONFIG_NF_NAT_H323=M +CONFIG_JOYSTICK_TURBOGRAFX=M +CONFIG_HID_A4TECH=M +CONFIG_MEDIA_TUNER_MC44S803=M +CONFIG_NETFILTER_XT_MATCH_ESP=M +CONFIG_IP_NF_TARGET_NETMAP=M +CONFIG_USB_GSPCA_SPCA505=M +CONFIG_USB_GSPCA_SQ905C=M +CONFIG_USB_ZR364XX=M +CONFIG_DVB_LNBP21=M +CONFIG_DVB_TDA10048=M +CONFIG_INPUT_FF_MEMLESS=M +CONFIG_CHR_DEV_SG=M +CONFIG_NET_SCH_DSMARK=M +CONFIG_SMS_SDIO_DRV=M +CONFIG_SND_MPU401=M +CONFIG_DVB_CX24116=M +CONFIG_CRYPTO_XCBC=M +CONFIG_NF_NAT_AMANDA=M +CONFIG_IP6_NF_MATCH_IPV6HEADER=M +CONFIG_JOYSTICK_IFORCE=M +CONFIG_SND_SOC_WM8731=M +CONFIG_INET6_XFRM_MODE_TRANSPORT=M +CONFIG_CRYPTO_ARC4=M +CONFIG_DVB_STV0900=M +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=M +CONFIG_USB_GL860=M +CONFIG_SCSI_TGT=Y +CONFIG_CRYPTO_MANAGER=M +CONFIG_NET_SCH_HTB=M +CONFIG_DVB_USB_TTUSB2=M +CONFIG_MTD_NAND=Y +CONFIG_NETFILTER_XT_TARGET_MARK=M +CONFIG_MEDIA_TUNER_MXL5007T=M +CONFIG_MD_LINEAR=M +CONFIG_VIDEO_CX231XX_DVB=M +CONFIG_I2C_ALGOBIT=M +CONFIG_MMC_BLOCK=Y +CONFIG_NET_CLS_FW=M +CONFIG_SND_SOC_WM8727=M +CONFIG_LCD_LTV350QV=M +CONFIG_VIDEO_MT9V011=M +CONFIG_TOUCHSCREEN_W90X900=M +CONFIG_SND_SOC_ALL_CODECS=M +CONFIG_SQUASHFS=Y +CONFIG_NET_SCH_TBF=M +CONFIG_BT_HCIBTUSB=M +CONFIG_DVB_CX22702=M +CONFIG_ASYNC_XOR=M +CONFIG_NET_CLS_RSVP=M +CONFIG_DVB_STB6100=M +CONFIG_MD_RAID0=M +CONFIG_ACT200L_DONGLE=M +CONFIG_ASYNC_RAID6_TEST=M +CONFIG_USB_ETH=M +CONFIG_XENO_OPT_NUCLEUS=Y +CONFIG_ATM_CLIP=M +CONFIG_LZO_COMPRESS=M +CONFIG_MMC=Y +CONFIG_CRYPTO_SEQIV=M +CONFIG_TOUCHSCREEN_AD7877=M +CONFIG_HID_LOGITECH=M +CONFIG_DM_LOG_USERSPACE=M +CONFIG_JOYSTICK_GAMECON=M +CONFIG_SCSI_SAS_LIBSAS=M +CONFIG_USB_NET_RNDIS_WLAN=M +CONFIG_VIDEO_TUNER=M +CONFIG_LEDS_LP3944=M +CONFIG_USB_SEVSEG=M +CONFIG_VIDEOBUF_DMA_CONTIG=M +CONFIG_MTD_NAND_ATMEL=Y +CONFIG_SND_MPU401_UART=M +CONFIG_USB_CDC_COMPOSITE=M +CONFIG_USB_DSBR=M +CONFIG_USB_SERIAL_OTI6858=M +CONFIG_ACTISYS_DONGLE=M +CONFIG_CAN_BCM=M +CONFIG_USB_ATM=M +CONFIG_SND_AT73C213=M +CONFIG_USB_AT91=Y +CONFIG_NETFILTER_XT_MATCH_U32=M +CONFIG_TOUCHSCREEN_AD7879_I2C=M +CONFIG_SND_MTS64=M +CONFIG_CRYPTO_RMD160=M +CONFIG_INET_AH=M +CONFIG_TABLET_USB_KBTAB=M +CONFIG_UDF_FS=M +CONFIG_IPV6_MIP6=M +CONFIG_VXFS_FS=M +CONFIG_ZD1211RW=M +CONFIG_TCP_CONG_CUBIC=Y +CONFIG_DVB_DIB7000M=M +CONFIG_NETFILTER_XT_CONNMARK=M +CONFIG_HID_KYE=M +CONFIG_MOUSE_VSXXXAA=M +CONFIG_LIB80211_CRYPT_WEP=M +CONFIG_RADIO_SI4713=M +CONFIG_IP_NF_MATCH_AH=M +CONFIG_VIDEO_OVCAMCHIP=M +CONFIG_TCP_CONG_VENO=M +CONFIG_DVB_S5H1420=M +CONFIG_AFS_FS=M +CONFIG_SOC_CAMERA_MT9M001=M +CONFIG_NETFILTER_XT_MATCH_LIMIT=M +CONFIG_IP6_NF_QUEUE=M +CONFIG_IRLAN=M +CONFIG_MOUSE_SERIAL=M +CONFIG_JOYSTICK_ANALOG=M +CONFIG_WIMAX=M +CONFIG_DVB_LGDT3305=M +CONFIG_FB=M +CONFIG_KEYBOARD_OPENCORES=M +CONFIG_USB_GSPCA_SPCA500=M +CONFIG_PATA_PLATFORM=M +CONFIG_BT_HCIUART=M +CONFIG_SND_SOC_WM8903=M +CONFIG_TOUCHSCREEN_TOUCHRIGHT=M +CONFIG_INPUT_POWERMATE=M +CONFIG_SND_SOC_WM_HUBS=M +CONFIG_DVB_MT312=M +CONFIG_HID_PETALYNX=M +CONFIG_ATM_LANE=M +CONFIG_NF_CONNTRACK_IPV4=M +CONFIG_SND_DUMMY=M +CONFIG_USB_WUSB_CBAF=M +CONFIG_USB_NET_ZAURUS=M +CONFIG_INET6_XFRM_TUNNEL=M +CONFIG_DM_MULTIPATH_ST=M +CONFIG_DVB_ZL10039=M +CONFIG_USB_SERIAL_DEBUG=M +CONFIG_TABLET_USB_ACECAD=M +CONFIG_VIDEO_MEDIA=M +CONFIG_CUSE=M +CONFIG_SND_SOC_WM8728=M +CONFIG_USB_ZERO=M +CONFIG_CRYPTO_RMD256=M +CONFIG_DVB_MT352=M +CONFIG_SPI_ATMEL=Y +CONFIG_MOUSE_APPLETOUCH=M +CONFIG_NF_NAT_PROTO_UDPLITE=M +CONFIG_USB_SERIAL_SIERRAWIRELESS=M +CONFIG_CRYPTO_CTR=M +CONFIG_VIDEO_SAA5246A=M +CONFIG_USB_SERIAL_KEYSPAN_PDA=M +CONFIG_MEDIA_TUNER_MT2060=M +CONFIG_HW_RANDOM=Y +CONFIG_DVB_USB_AU6610=M +CONFIG_IRTTY_SIR=M +CONFIG_NTFS_FS=M +CONFIG_SCSI_DH_HP_SW=M +CONFIG_IP_SCTP=M +CONFIG_CRYPTO_BLKCIPHER2=M +CONFIG_SCSI_SAS_ATTRS=M +CONFIG_RTL8187=M +CONFIG_SND_SEQ_DUMMY=M +CONFIG_USB_SERIAL_SIEMENS_MPI=M +CONFIG_MD_RAID6_PQ=M +CONFIG_USB_GSPCA_SONIXJ=M +CONFIG_CRYPTO_KHAZAD=M +CONFIG_MTD_BLOCK=Y +CONFIG_SND_SOC_WM8523=M +CONFIG_RC_MAP=M +CONFIG_ROSE=M +CONFIG_INPUT_GPIO_ROTARY_ENCODER=M +CONFIG_NILFS2_FS=M +CONFIG_HID_PANTHERLORD=M +CONFIG_SND=M +CONFIG_NET_SCH_TEQL=M +CONFIG_IR_RC6_DECODER=M +CONFIG_IP_VS_SH=M +CONFIG_VIDEO_MSP3400=M +CONFIG_USB_TMC=M +CONFIG_SND_SOC_L3=M +CONFIG_IKCONFIG=M +CONFIG_DVB_STB6000=M +CONFIG_IP_NF_TARGET_CLUSTERIP=M +CONFIG_W1_SLAVE_THERM=Y +CONFIG_JOYSTICK_TWIDJOY=M +CONFIG_CIFS=M +CONFIG_XFRM_USER=M +CONFIG_TCP_CONG_BIC=M +CONFIG_SCSI_DH_EMC=M +CONFIG_USB_SE401=M +CONFIG_SND_SOC_WM8988=M +CONFIG_JOYSTICK_WALKERA0701=M +CONFIG_CRYPTO_LRW=M +CONFIG_USB_GSPCA_T613=M +CONFIG_SND_SOC_WM8580=M +CONFIG_SND_MTPAV=M +CONFIG_MD_RAID10=M +CONFIG_CRAMFS=Y +CONFIG_KEYBOARD_LM8323=M +CONFIG_CHR_DEV_ST=M +CONFIG_DM_MULTIPATH=M +CONFIG_B43LEGACY=M +CONFIG_SND_SOC_WM8904=M +CONFIG_DVB_USB_A800=M +CONFIG_SND_SOC_WM2000=M +CONFIG_SND_TIMER=M +CONFIG_USB_SERIAL_MOTOROLA=M +CONFIG_XENO_DRIVERS_TIMERBENCH=Y +CONFIG_USB_SERIAL_OMNINET=M +CONFIG_TCP_CONG_SCALABLE=M +CONFIG_JOYSTICK_TMDC=M +CONFIG_NETFILTER_XT_TARGET_CONNMARK=M +CONFIG_CRYPTO_MICHAEL_MIC=M +CONFIG_CRYPTO_ANSI_CPRNG=M +CONFIG_JBD=Y +CONFIG_DVB_PLL=M +CONFIG_VIDEO_SH_MOBILE_CEU=M +CONFIG_NETFILTER_XT_MATCH_QUOTA=M +CONFIG_ASYNC_CORE=M +CONFIG_NET_SCH_MULTIQ=M +CONFIG_INET_DIAG=Y +CONFIG_CRYPTO_GHASH=M +CONFIG_NF_NAT_FTP=M +CONFIG_CRYPTO_RMD320=M +CONFIG_NF_CT_PROTO_UDPLITE=M +CONFIG_JOYSTICK_WARRIOR=M +CONFIG_INPUT_POLLDEV=M +CONFIG_USB_GSPCA_PAC7311=M +CONFIG_MTD_CHAR=Y +CONFIG_ATM=M +CONFIG_SCSI_FC_ATTRS=M +CONFIG_LEDS_GPIO=Y +CONFIG_USB_GSPCA_STK014=M +CONFIG_IP_VS_FTP=M +CONFIG_NOP_USB_XCEIV=M +CONFIG_DVB_USB_DIBUSB_MB=M +CONFIG_BLK_DEV_RAM=Y +CONFIG_TOUCHSCREEN_AD7879=M +CONFIG_NETFILTER_XT_MATCH_STATE=M +CONFIG_INPUT_EVBUG=M +CONFIG_USB_STORAGE_FREECOM=M +CONFIG_LCD_VGG2432A4=M +CONFIG_TOUCHSCREEN_ADS7846=M +CONFIG_IR_RC5_DECODER=M +CONFIG_NET_SCH_GRED=M +CONFIG_INET6_XFRM_MODE_BEET=M +CONFIG_USB_USS720=M +CONFIG_LEDS_DAC124S085=M +CONFIG_MOUSE_GPIO=M +CONFIG_RT73USB=M +CONFIG_USB_CYTHERM=M +CONFIG_IP6_NF_MATCH_EUI64=M +CONFIG_USB_STORAGE_JUMPSHOT=M +CONFIG_VIDEOBUF_GEN=M +CONFIG_VIDEO_V4L2=M +CONFIG_DVB_STV6110=M +CONFIG_HID_NTRIG=M +CONFIG_DVB_USB_NOVA_T_USB2=M +CONFIG_SND_PORTMAN2X4=M +CONFIG_DECOMPRESS_GZIP=Y +CONFIG_USB_SERIAL_ARK3116=M +CONFIG_I2C_CHARDEV=Y +CONFIG_LLC=M +CONFIG_MEDIA_TUNER_TEA5761=M +CONFIG_IPDDP=M +CONFIG_LIB80211_CRYPT_CCMP=M +CONFIG_ATALK=M +CONFIG_NLS_UTF8=Y +CONFIG_JOYSTICK_XPAD=M +CONFIG_INPUT_YEALINK=M +CONFIG_DVB_DIB3000MB=M +CONFIG_IWMC3200TOP=M +CONFIG_USB_USBNET=M +CONFIG_USB_SERIAL_PL2303=M +CONFIG_DVB_USB_CINERGY_T2=M +CONFIG_USB_MICROTEK=M +CONFIG_HID_SMARTJOYPLUS=M +CONFIG_NET_SCH_HFSC=M +CONFIG_MAC80211=M +CONFIG_CRC_CCITT=M +CONFIG_BLK_DEV_SD=Y +CONFIG_NETFILTER_NETLINK=M +CONFIG_DVB_USB_CXUSB=M +CONFIG_BITREVERSE=Y +CONFIG_USB_SERIAL_WWAN=M +CONFIG_CRYPTO_PCOMP=M +CONFIG_VIDEO_V4L2_COMMON=M +CONFIG_CRYPTO_BLKCIPHER=M +CONFIG_USB_STORAGE_ONETOUCH=M +CONFIG_NF_CONNTRACK=M +CONFIG_LCD_CLASS_DEVICE=M +CONFIG_USB_GSPCA_SN9C20X=M +CONFIG_SND_SOC_I2C_AND_SPI=M +CONFIG_VIDEO_USBVIDEO=M +CONFIG_IP_NF_TARGET_REJECT=M +CONFIG_LEDS_CLASS=Y +CONFIG_DVB_USB_DIGITV=M +CONFIG_IP6_NF_MATCH_HL=M +CONFIG_IP6_NF_MATCH_OPTS=M +CONFIG_DVB_USB_CE6230=M +CONFIG_USB_SERIAL_SYMBOL=M +CONFIG_NETFILTER_XT_MATCH_OSF=M +CONFIG_SND_VIRMIDI=M +CONFIG_LIB80211_CRYPT_TKIP=M +CONFIG_NF_CT_PROTO_GRE=M +CONFIG_NF_CT_NETLINK=M +CONFIG_P54_SPI=M +CONFIG_CRYPTO_AEAD2=M +CONFIG_CRYPTO_FCRYPT=M +CONFIG_MOUSE_PS2=Y +CONFIG_NET_IPIP=M +CONFIG_USB_SERIAL_IPAQ=M +CONFIG_NETFILTER_XT_MATCH_HL=M +CONFIG_CRYPTO_ALGAPI2=M +CONFIG_NETFILTER_XT_TARGET_LED=M +CONFIG_INPUT=Y +CONFIG_IP_NF_MATCH_ADDRTYPE=M +CONFIG_DVB_CX24123=M +CONFIG_OCFS2_FS=M +CONFIG_TABLET_USB_AIPTEK=M +CONFIG_INPUT_ATI_REMOTE=M diff -urN orig/linux-2.6.35.9//include/generated/autoconf.h relase/linux-2.6.35.9//include/generated/autoconf.h --- orig/linux-2.6.35.9//include/generated/autoconf.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/generated/autoconf.h 2011-03-15 11:08:30.665702442 +0100 @@ -0,0 +1,1572 @@ +/* + * Automatically generated C config: don't edit + * Linux kernel version: 2.6.35.9 + * Tue Mar 15 11:08:30 2011 + */ +#define AUTOCONF_INCLUDED +#define CONFIG_IP6_NF_MATCH_AH_MODULE 1 +#define CONFIG_NF_CONNTRACK_H323_MODULE 1 +#define CONFIG_SCSI_DMA 1 +#define CONFIG_KERNEL_GZIP 1 +#define CONFIG_TOUCHSCREEN_INEXIO_MODULE 1 +#define CONFIG_INPUT_KEYBOARD 1 +#define CONFIG_IP_NF_TARGET_REDIRECT_MODULE 1 +#define CONFIG_CRC32 1 +#define CONFIG_I2C_BOARDINFO 1 +#define CONFIG_NF_NAT_PROTO_SCTP_MODULE 1 +#define CONFIG_HAVE_AOUT 1 +#define CONFIG_DM_SNAPSHOT_MODULE 1 +#define CONFIG_IR_JVC_DECODER_MODULE 1 +#define CONFIG_FSCACHE_MODULE 1 +#define CONFIG_PARPORT_NOT_PC 1 +#define CONFIG_EXT3_FS_XATTR 1 +#define CONFIG_AEABI 1 +#define CONFIG_HIGH_RES_TIMERS 1 +#define CONFIG_BLK_DEV_DM_MODULE 1 +#define CONFIG_R3964_MODULE 1 +#define CONFIG_USB_SERIAL_HP4X_MODULE 1 +#define CONFIG_VLAN_8021Q_MODULE 1 +#define CONFIG_FLATMEM_MANUAL 1 +#define CONFIG_BT_RFCOMM_MODULE 1 +#define CONFIG_LEDS_TRIGGER_HEARTBEAT 1 +#define CONFIG_DEV_APPLETALK_MODULE 1 +#define CONFIG_DVB_TDA1004X_MODULE 1 +#define CONFIG_JOYSTICK_ADI_MODULE 1 +#define CONFIG_DVB_BCM3510_MODULE 1 +#define CONFIG_INOTIFY_USER 1 +#define CONFIG_VIDEO_V4L1_MODULE 1 +#define CONFIG_NF_CONNTRACK_NETBIOS_NS_MODULE 1 +#define CONFIG_SCSI_DH_MODULE 1 +#define CONFIG_NETWORK_FILESYSTEMS 1 +#define CONFIG_IPIPE 1 +#define CONFIG_CRYPTO_MD4_MODULE 1 +#define CONFIG_BT_HCIBFUSB_MODULE 1 +#define CONFIG_NET_ETHERNET 1 +#define CONFIG_EXPERIMENTAL 1 +#define CONFIG_ARCH_SUSPEND_POSSIBLE 1 +#define CONFIG_INLINE_WRITE_UNLOCK_IRQ 1 +#define CONFIG_USB_G_SERIAL_MODULE 1 +#define CONFIG_SND_SOC_TPA6130A2_MODULE 1 +#define CONFIG_LEDS_PCA955X_MODULE 1 +#define CONFIG_IP_VS_NQ_MODULE 1 +#define CONFIG_USB_SERIAL_NAVMAN_MODULE 1 +#define CONFIG_JOYSTICK_SPACEORB_MODULE 1 +#define CONFIG_TCP_CONG_HTCP_MODULE 1 +#define CONFIG_SCSI_DEBUG_MODULE 1 +#define CONFIG_BINFMT_MISC_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_HELPER_MODULE 1 +#define CONFIG_SSB_POSSIBLE 1 +#define CONFIG_NF_NAT_SIP_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_STATISTIC_MODULE 1 +#define CONFIG_MTD_CMDLINE_PARTS 1 +#define CONFIG_ESI_DONGLE_MODULE 1 +#define CONFIG_USB_SERIAL_EDGEPORT_TI_MODULE 1 +#define CONFIG_USB_SERIAL_SAFE_MODULE 1 +#define CONFIG_USB_OHCI_LITTLE_ENDIAN 1 +#define CONFIG_NET_SCH_FIFO 1 +#define CONFIG_REISERFS_FS 1 +#define CONFIG_FSNOTIFY 1 +#define CONFIG_CRYPTO_RMD128_MODULE 1 +#define CONFIG_STP_MODULE 1 +#define CONFIG_USB_GSPCA_SQ905_MODULE 1 +#define CONFIG_DVB_AU8522_MODULE 1 +#define CONFIG_INET6_TUNNEL_MODULE 1 +#define CONFIG_NF_CONNTRACK_SIP_MODULE 1 +#define CONFIG_HIDRAW 1 +#define CONFIG_KSDAZZLE_DONGLE_MODULE 1 +#define CONFIG_HAVE_KERNEL_LZMA 1 +#define CONFIG_XENO_SKIN_RTDM 1 +#define CONFIG_IP_NF_QUEUE_MODULE 1 +#define CONFIG_RT2X00_LIB_LEDS 1 +#define CONFIG_RT2800USB_RT30XX 1 +#define CONFIG_IP_VS_SED_MODULE 1 +#define CONFIG_DVB_DS3000_MODULE 1 +#define CONFIG_USB_SERIAL_FTDI_SIO_MODULE 1 +#define CONFIG_DEFAULT_SECURITY_DAC 1 +#define CONFIG_IP6_NF_MANGLE_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_ETT_TC5UH 1 +#define CONFIG_BT_MRVL_SDIO_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_REALM_MODULE 1 +#define CONFIG_BT_HCIBPA10X_MODULE 1 +#define CONFIG_IP_VS_RR_MODULE 1 +#define CONFIG_IPV6_MODULE 1 +#define CONFIG_USB_SERIAL_QUALCOMM_MODULE 1 +#define CONFIG_CRYPTO_AEAD_MODULE 1 +#define CONFIG_XENO_OPT_TIMING_SCHEDLAT 0 +#define CONFIG_DEFAULT_TCP_CONG "cubic" +#define CONFIG_UEVENT_HELPER_PATH "/sbin/hotplug" +#define CONFIG_USB_DEVICEFS 1 +#define CONFIG_NET_CLS_FLOW_MODULE 1 +#define CONFIG_USB_STORAGE_USBAT_MODULE 1 +#define CONFIG_NF_NAT_PROTO_GRE_MODULE 1 +#define CONFIG_CRYPTO_PCBC_MODULE 1 +#define CONFIG_IP6_NF_TARGET_REJECT_MODULE 1 +#define CONFIG_ASYNC_MEMCPY_MODULE 1 +#define CONFIG_IR_NEC_DECODER_MODULE 1 +#define CONFIG_USB_SERIAL_MOS7840_MODULE 1 +#define CONFIG_VIDEO_BWQCAM_MODULE 1 +#define CONFIG_WLAN 1 +#define CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA49W 1 +#define CONFIG_CONNECTOR_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_RATEEST_MODULE 1 +#define CONFIG_B43LEGACY_DMA_AND_PIO_MODE 1 +#define CONFIG_DVB_MAX_ADAPTERS 8 +#define CONFIG_DM_MULTIPATH_QL_MODULE 1 +#define CONFIG_LEGACY_PTYS 1 +#define CONFIG_LIBERTAS_USB_MODULE 1 +#define CONFIG_JFS_FS_MODULE 1 +#define CONFIG_XFRM_IPCOMP_MODULE 1 +#define CONFIG_CRYPTO_RNG2_MODULE 1 +#define CONFIG_USB_PWC_INPUT_EVDEV 1 +#define CONFIG_NETFILTER_NETLINK_QUEUE_MODULE 1 +#define CONFIG_SND_SOC_AD193X_MODULE 1 +#define CONFIG_MSDOS_FS 1 +#define CONFIG_USB_OTG_UTILS 1 +#define CONFIG_USB_GSPCA_SUNPLUS_MODULE 1 +#define CONFIG_USB_IBMCAM_MODULE 1 +#define CONFIG_CAN_MODULE 1 +#define CONFIG_CFG80211_MODULE 1 +#define CONFIG_SSB_BLOCKIO 1 +#define CONFIG_DM_CRYPT_MODULE 1 +#define CONFIG_IPIPE_ARM_KUSER_TSC 1 +#define CONFIG_NCP_FS_MODULE 1 +#define CONFIG_B43LEGACY_PIO 1 +#define CONFIG_HAVE_PROC_CPU 1 +#define CONFIG_LZO_DECOMPRESS_MODULE 1 +#define CONFIG_LIBERTAS_THINFIRM_MODULE 1 +#define CONFIG_IP_VS_PROTO_AH 1 +#define CONFIG_EXOFS_FS_MODULE 1 +#define CONFIG_HID_BELKIN_MODULE 1 +#define CONFIG_VIDEO_IR_I2C_MODULE 1 +#define CONFIG_ROMFS_BACKED_BY_BLOCK 1 +#define CONFIG_IWM_MODULE 1 +#define CONFIG_NFSD_MODULE 1 +#define CONFIG_SENSORS_TSL2550_MODULE 1 +#define CONFIG_WIRELESS_EXT_SYSFS 1 +#define CONFIG_USB_SERIAL_OPTION_MODULE 1 +#define CONFIG_USB 1 +#define CONFIG_SND_SOC_DA7210_MODULE 1 +#define CONFIG_USB_SPEEDTOUCH_MODULE 1 +#define CONFIG_SND_SOC_TLV320DAC33_MODULE 1 +#define CONFIG_CRYPTO_HMAC_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_COND 1 +#define CONFIG_SND_SOC_WM8900_MODULE 1 +#define CONFIG_USB_GSPCA_JEILINJ_MODULE 1 +#define CONFIG_CRC_ITU_T 1 +#define CONFIG_SND_HRTIMER_MODULE 1 +#define CONFIG_FRAMEBUFFER_CONSOLE_MODULE 1 +#define CONFIG_DM_ZERO_MODULE 1 +#define CONFIG_IP6_NF_TARGET_LOG_MODULE 1 +#define CONFIG_DVB_DIB8000_MODULE 1 +#define CONFIG_SND_SEQUENCER_MODULE 1 +#define CONFIG_TCP_CONG_LP_MODULE 1 +#define CONFIG_IP_NF_ARPTABLES_MODULE 1 +#define CONFIG_DVB_USB_GP8PSK_MODULE 1 +#define CONFIG_USB_SERIAL_GENERIC 1 +#define CONFIG_HID_CHERRY_MODULE 1 +#define CONFIG_HID_SUNPLUS_MODULE 1 +#define CONFIG_AF_RXRPC_MODULE 1 +#define CONFIG_CRYPTO_CAST5_MODULE 1 +#define CONFIG_MTD_PARTITIONS 1 +#define CONFIG_SND_SOC_MODULE 1 +#define CONFIG_MEDIA_TUNER_XC5000_MODULE 1 +#define CONFIG_PRINTK 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA28X 1 +#define CONFIG_NF_CONNTRACK_PROC_COMPAT 1 +#define CONFIG_TIMERFD 1 +#define CONFIG_HID_THRUSTMASTER_MODULE 1 +#define CONFIG_B43_PHY_LP 1 +#define CONFIG_MTD_CFI_I2 1 +#define CONFIG_CRYPTO_AUTHENC_MODULE 1 +#define CONFIG_USB_GPIO_VBUS_MODULE 1 +#define CONFIG_JOYSTICK_SIDEWINDER_MODULE 1 +#define CONFIG_IRDA_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_QUEUE 1 +#define CONFIG_P54_COMMON_MODULE 1 +#define CONFIG_SHMEM 1 +#define CONFIG_MTD 1 +#define CONFIG_SND_SOC_WM8776_MODULE 1 +#define CONFIG_NLS_CODEPAGE_850 1 +#define CONFIG_DNOTIFY 1 +#define CONFIG_ASK_IP_FIB_HASH 1 +#define CONFIG_DVB_USB_UMT_010_MODULE 1 +#define CONFIG_JOYSTICK_DB9_MODULE 1 +#define CONFIG_INPUT_MOUSEDEV 1 +#define CONFIG_ATA_MODULE 1 +#define CONFIG_KEYBOARD_SUNKBD_MODULE 1 +#define CONFIG_CRYPTO_DES_MODULE 1 +#define CONFIG_ENABLE_MUST_CHECK 1 +#define CONFIG_NLS_CODEPAGE_437 1 +#define CONFIG_MTD_NAND_IDS 1 +#define CONFIG_MCS_FIR_MODULE 1 +#define CONFIG_NET_CLS_U32_MODULE 1 +#define CONFIG_EXPORTFS_MODULE 1 +#define CONFIG_SND_MIXER_OSS_MODULE 1 +#define CONFIG_TOUCHSCREEN_PENMOUNT_MODULE 1 +#define CONFIG_IP6_NF_MATCH_MH_MODULE 1 +#define CONFIG_SND_AT73C213_TARGET_BITRATE 48000 +#define CONFIG_SCSI_OSD_INITIATOR_MODULE 1 +#define CONFIG_SCSI_OSD_DPRINT_SENSE 1 +#define CONFIG_DVB_AF9013_MODULE 1 +#define CONFIG_SERIO 1 +#define CONFIG_DVB_USB_DTV5100_MODULE 1 +#define CONFIG_INPUT_MOUSE 1 +#define CONFIG_VIDEO_TVEEPROM_MODULE 1 +#define CONFIG_MA600_DONGLE_MODULE 1 +#define CONFIG_RTC_INTF_SYSFS 1 +#define CONFIG_SND_SOC_SPDIF_MODULE 1 +#define CONFIG_TOUCHSCREEN_TOUCHWIN_MODULE 1 +#define CONFIG_BLK_DEV_INITRD 1 +#define CONFIG_USB_EMI62_MODULE 1 +#define CONFIG_LEDS_TRIGGER_TIMER 1 +#define CONFIG_SND_SOC_WM8510_MODULE 1 +#define CONFIG_RT2800_LIB_MODULE 1 +#define CONFIG_SND_SOC_TLV320AIC3X_MODULE 1 +#define CONFIG_DVB_USB_DW2102_MODULE 1 +#define CONFIG_NF_CONNTRACK_SANE_MODULE 1 +#define CONFIG_SND_SOC_WM8990_MODULE 1 +#define CONFIG_SND_OSSEMUL 1 +#define CONFIG_TOIM3232_DONGLE_MODULE 1 +#define CONFIG_USB_SERIAL_MOS7720_MODULE 1 +#define CONFIG_NF_CT_PROTO_DCCP_MODULE 1 +#define CONFIG_ZLIB_INFLATE 1 +#define CONFIG_USB_STV680_MODULE 1 +#define CONFIG_CRC_T10DIF_MODULE 1 +#define CONFIG_MEDIA_TUNER_QT1010_MODULE 1 +#define CONFIG_LCD_LMS283GF05_MODULE 1 +#define CONFIG_CRYPTO_TWOFISH_COMMON_MODULE 1 +#define CONFIG_IP_PNP 1 +#define CONFIG_XENO_OPT_RTDM_PERIOD 0 +#define CONFIG_USB_VIDEO_CLASS_MODULE 1 +#define CONFIG_SERIAL_ATMEL_PDC 1 +#define CONFIG_RTC_INTF_PROC 1 +#define CONFIG_MMC_AT91 1 +#define CONFIG_MTD_CONCAT 1 +#define CONFIG_USB_SERIAL_TI_MODULE 1 +#define CONFIG_NET_SCH_CBQ_MODULE 1 +#define CONFIG_NET_CLS_ROUTE 1 +#define CONFIG_CRYPTO_SERPENT_MODULE 1 +#define CONFIG_CPU_IDLE_GOV_MENU 1 +#define CONFIG_STACKTRACE_SUPPORT 1 +#define CONFIG_XENO_OPT_PRIOCPL 1 +#define CONFIG_NVRAM_MODULE 1 +#define CONFIG_LOCKD_MODULE 1 +#define CONFIG_DVB_S5H1411_MODULE 1 +#define CONFIG_SOUND_OSS_CORE 1 +#define CONFIG_USB_SN9C102_MODULE 1 +#define CONFIG_LIBERTAS_MODULE 1 +#define CONFIG_ARM 1 +#define CONFIG_USB_GSPCA_TV8532_MODULE 1 +#define CONFIG_VIDEO_CPIA_MODULE 1 +#define CONFIG_JFFS2_FS 1 +#define CONFIG_SND_SOC_WM8750_MODULE 1 +#define CONFIG_ARM_L1_CACHE_SHIFT 5 +#define CONFIG_USB_EZUSB 1 +#define CONFIG_VIDEO_OUTPUT_CONTROL_MODULE 1 +#define CONFIG_SCSI_DH_ALUA_MODULE 1 +#define CONFIG_USB_ZC0301_MODULE 1 +#define CONFIG_BT_RFCOMM_TTY 1 +#define CONFIG_LIBFCOE_MODULE 1 +#define CONFIG_VIDEOBUF_VMALLOC_MODULE 1 +#define CONFIG_DVB_STV0299_MODULE 1 +#define CONFIG_CRYPTO_MANAGER_TESTS 1 +#define CONFIG_DISPLAY_SUPPORT_MODULE 1 +#define CONFIG_CPU_TLB_V4WBI 1 +#define CONFIG_NETFILTER_XT_MATCH_STRING_MODULE 1 +#define CONFIG_INPUT_TABLET 1 +#define CONFIG_IP_NF_TARGET_LOG_MODULE 1 +#define CONFIG_MEDIA_TUNER_MAX2165_MODULE 1 +#define CONFIG_LLC2_MODULE 1 +#define CONFIG_DLM_MODULE 1 +#define CONFIG_CPU_COPY_V4WB 1 +#define CONFIG_TOUCHSCREEN_USB_GOTOP 1 +#define CONFIG_XENO_OPT_TIMER_LIST 1 +#define CONFIG_USB_STORAGE 1 +#define CONFIG_STANDALONE 1 +#define CONFIG_CRYPTO_SEED_MODULE 1 +#define CONFIG_DONGLE 1 +#define CONFIG_SATA_MV_MODULE 1 +#define CONFIG_XENO_OPT_SYS_STACKPOOLSZ 128 +#define CONFIG_DVB_TUNER_DIB0090_MODULE 1 +#define CONFIG_SND_USB_AUDIO_MODULE 1 +#define CONFIG_VIDEO_CX231XX_MODULE 1 +#define CONFIG_TCP_CONG_YEAH_MODULE 1 +#define CONFIG_IEEE802154_MODULE 1 +#define CONFIG_XENO_HW_FPU 1 +#define CONFIG_BLOCK 1 +#define CONFIG_HAVE_IDE 1 +#define CONFIG_IP_VS_LC_MODULE 1 +#define CONFIG_HID_APPLE_MODULE 1 +#define CONFIG_MEDIA_TUNER_TDA827X_MODULE 1 +#define CONFIG_INIT_ENV_ARG_LIMIT 32 +#define CONFIG_SND_RAWMIDI_SEQ_MODULE 1 +#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1 +#define CONFIG_DVB_USB_MODULE 1 +#define CONFIG_GENERIC_GPIO 1 +#define CONFIG_DVB_ATBM8830_MODULE 1 +#define CONFIG_SND_ATMEL_SOC_SSC_MODULE 1 +#define CONFIG_SCTP_HMAC_MD5 1 +#define CONFIG_NF_CONNTRACK_PPTP_MODULE 1 +#define CONFIG_VIDEO_CX231XX_ALSA_MODULE 1 +#define CONFIG_HFSPLUS_FS_MODULE 1 +#define CONFIG_BUG 1 +#define CONFIG_KS0108_PORT 0x378 +#define CONFIG_MAC80211_HAS_RC 1 +#define CONFIG_XENO_OPT_RTDM_FILDES 128 +#define CONFIG_OCFS2_FS_O2CB_MODULE 1 +#define CONFIG_CRYPTO_CAST6_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_SEM 1 +#define CONFIG_PM 1 +#define CONFIG_PPS_MODULE 1 +#define CONFIG_USB_LCD_MODULE 1 +#define CONFIG_SPI 1 +#define CONFIG_NF_CONNTRACK_IRC_MODULE 1 +#define CONFIG_DEVKMEM 1 +#define CONFIG_USB_STV06XX_MODULE 1 +#define CONFIG_XENO_OPT_PERVASIVE 1 +#define CONFIG_TEXTSEARCH_KMP_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA28XA 1 +#define CONFIG_VT 1 +#define CONFIG_USB_NET_NET1080_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_CLASSIFY_MODULE 1 +#define CONFIG_MACB 1 +#define CONFIG_SPLIT_PTLOCK_CPUS 999999 +#define CONFIG_DVB_TUNER_ITD1000_MODULE 1 +#define CONFIG_BT_SCO_MODULE 1 +#define CONFIG_POWER_SUPPLY_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_NFQUEUE_MODULE 1 +#define CONFIG_V4L_USB_DRIVERS 1 +#define CONFIG_WEXT_CORE 1 +#define CONFIG_USB_GSPCA_MR97310A_MODULE 1 +#define CONFIG_VIDEO_WM8775_MODULE 1 +#define CONFIG_NLS 1 +#define CONFIG_SPI_SPIDEV 1 +#define CONFIG_SND_SOC_AD73311_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_ETURBO 1 +#define CONFIG_MFD_SUPPORT 1 +#define CONFIG_USB_GSPCA_SPCA508_MODULE 1 +#define CONFIG_USB_LEGOTOWER_MODULE 1 +#define CONFIG_MTD_DATAFLASH 1 +#define CONFIG_ARCH_AT91 1 +#define CONFIG_DVB_USB_DIBUSB_MC_MODULE 1 +#define CONFIG_DVB_USB_VP702X_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_OWNER_MODULE 1 +#define CONFIG_IP_NF_TARGET_ECN_MODULE 1 +#define CONFIG_MD_FAULTY_MODULE 1 +#define CONFIG_IP_ADVANCED_ROUTER 1 +#define CONFIG_VIDEO_USBVISION_MODULE 1 +#define CONFIG_SPI_BITBANG_MODULE 1 +#define CONFIG_USB_STORAGE_ALAUDA_MODULE 1 +#define CONFIG_JOYSTICK_GRIP_MP_MODULE 1 +#define CONFIG_MEDIA_TUNER_TDA18271_MODULE 1 +#define CONFIG_IP6_NF_IPTABLES_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_ZYTRONIC 1 +#define CONFIG_TEKRAM_DONGLE_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA18X 1 +#define CONFIG_USB_SERIAL_IPW_MODULE 1 +#define CONFIG_INET_IPCOMP_MODULE 1 +#define CONFIG_DVB_USB_DIB0700_MODULE 1 +#define CONFIG_TOUCHSCREEN_FUJITSU_MODULE 1 +#define CONFIG_MCP2120_DONGLE_MODULE 1 +#define CONFIG_ASYNC_PQ_MODULE 1 +#define CONFIG_HID_CYPRESS_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_PERIOD 0 +#define CONFIG_OCFS2_FS_USERSPACE_CLUSTER_MODULE 1 +#define CONFIG_VIDEO_SAA711X_MODULE 1 +#define CONFIG_NLS_ISO8859_1 1 +#define CONFIG_CRYPTO_WORKQUEUE_MODULE 1 +#define CONFIG_TCP_CONG_HYBLA_MODULE 1 +#define CONFIG_HID_KENSINGTON_MODULE 1 +#define CONFIG_BACKLIGHT_GENERIC_MODULE 1 +#define CONFIG_TEXTSEARCH_BM_MODULE 1 +#define CONFIG_SCSI_SAS_LIBSAS_DEBUG 1 +#define CONFIG_BT_HCIUART_LL 1 +#define CONFIG_SND_PCM_OSS_MODULE 1 +#define CONFIG_DVB_B2C2_FLEXCOP_MODULE 1 +#define CONFIG_USB_IRDA_MODULE 1 +#define CONFIG_SND_SOC_WM8960_MODULE 1 +#define CONFIG_RFKILL_MODULE 1 +#define CONFIG_VIDEO_TVP5150_MODULE 1 +#define CONFIG_NETDEVICES 1 +#define CONFIG_NET_KEY_MODULE 1 +#define CONFIG_SMS_SIANO_MDTV_MODULE 1 +#define CONFIG_IP6_NF_TARGET_HL_MODULE 1 +#define CONFIG_EVENTFD 1 +#define CONFIG_FS_POSIX_ACL 1 +#define CONFIG_IPV6_SIT_MODULE 1 +#define CONFIG_XFRM 1 +#define CONFIG_DEFCONFIG_LIST "/lib/modules/$UNAME_RELEASE/.config" +#define CONFIG_USB_MR800_MODULE 1 +#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1 +#define CONFIG_NET_CLS_ROUTE4_MODULE 1 +#define CONFIG_SND_SOC_WM9081_MODULE 1 +#define CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH 1 +#define CONFIG_AT91_PROGRAMMABLE_CLOCKS 1 +#define CONFIG_IP_VS_DH_MODULE 1 +#define CONFIG_SND_SOC_WM8753_MODULE 1 +#define CONFIG_VIDEO_IR_MODULE 1 +#define CONFIG_AX25_DAMA_SLAVE 1 +#define CONFIG_IP_NF_TARGET_MASQUERADE_MODULE 1 +#define CONFIG_WAN_ROUTER_MODULE 1 +#define CONFIG_PROC_PAGE_MONITOR 1 +#define CONFIG_KS959_DONGLE_MODULE 1 +#define CONFIG_CC_OPTIMIZE_FOR_SIZE 1 +#define CONFIG_JOYSTICK_MAGELLAN_MODULE 1 +#define CONFIG_KINGSUN_DONGLE_MODULE 1 +#define CONFIG_NF_NAT_PROTO_DCCP_MODULE 1 +#define CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV 1 +#define CONFIG_DM_DELAY_MODULE 1 +#define CONFIG_RTC_DRV_AT91SAM9_RTT 0 +#define CONFIG_USB_SERIAL_CH341_MODULE 1 +#define CONFIG_USB_FTDI_ELAN_MODULE 1 +#define CONFIG_DVB_USB_FRIIO_MODULE 1 +#define CONFIG_USB_IOWARRIOR_MODULE 1 +#define CONFIG_SCSI_SPI_ATTRS_MODULE 1 +#define CONFIG_CRYPTO_SHA512_MODULE 1 +#define CONFIG_PHONET_MODULE 1 +#define CONFIG_SCSI_WAIT_SCAN_MODULE 1 +#define CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE 1 +#define CONFIG_B43_HWRNG 1 +#define CONFIG_USB_M5602_MODULE 1 +#define CONFIG_RT2X00_LIB_USB_MODULE 1 +#define CONFIG_CPU_CACHE_VIVT 1 +#define CONFIG_CRYPTO_NULL_MODULE 1 +#define CONFIG_DVB_USB_AF9005_REMOTE_MODULE 1 +#define CONFIG_NF_DEFRAG_IPV4_MODULE 1 +#define CONFIG_USB_IDMOUSE_MODULE 1 +#define CONFIG_SELECT_MEMORY_MODEL 1 +#define CONFIG_INET_XFRM_MODE_BEET_MODULE 1 +#define CONFIG_NETFILTER_ADVANCED 1 +#define CONFIG_CRYPTO_DEFLATE_MODULE 1 +#define CONFIG_USB_APPLEDISPLAY_MODULE 1 +#define CONFIG_USB_SERIAL_KLSI_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_TCPMSS_MODULE 1 +#define CONFIG_JFFS2_FS_DEBUG 0 +#define CONFIG_BT_HCIBTSDIO_MODULE 1 +#define CONFIG_ATM_MPOA_MODULE 1 +#define CONFIG_CRYPTO_GCM_MODULE 1 +#define CONFIG_NETFILTER_NETLINK_LOG_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MARK_MODULE 1 +#define CONFIG_VIDEO_PVRUSB2_SYSFS 1 +#define CONFIG_MAC80211_RC_DEFAULT_MINSTREL 1 +#define CONFIG_DVB_LGS8GXX_MODULE 1 +#define CONFIG_SERIAL_ATMEL 1 +#define CONFIG_IP_NF_MANGLE_MODULE 1 +#define CONFIG_TOUCHSCREEN_MCS5000_MODULE 1 +#define CONFIG_INET6_XFRM_MODE_TUNNEL_MODULE 1 +#define CONFIG_MEDIA_SUPPORT_MODULE 1 +#define CONFIG_DEBUG_BUGVERBOSE 1 +#define CONFIG_IP_NF_FILTER_MODULE 1 +#define CONFIG_HID_ZEROPLUS_MODULE 1 +#define CONFIG_EXT3_FS 1 +#define CONFIG_VIDEO_ALLOW_V4L1 1 +#define CONFIG_SOC_CAMERA_OV772X_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_LENGTH_MODULE 1 +#define CONFIG_FAT_FS 1 +#define CONFIG_TEXTSEARCH_FSM_MODULE 1 +#define CONFIG_IP6_NF_RAW_MODULE 1 +#define CONFIG_USB_ZD1201_MODULE 1 +#define CONFIG_INET_TUNNEL_MODULE 1 +#define CONFIG_EEPROM_93CX6_MODULE 1 +#define CONFIG_MMC_BLOCK_BOUNCE 1 +#define CONFIG_GENERIC_CLOCKEVENTS 1 +#define CONFIG_ROMFS_FS_MODULE 1 +#define CONFIG_GENERIC_FIND_LAST_BIT 1 +#define CONFIG_DVB_USB_DTT200U_MODULE 1 +#define CONFIG_LIB80211_MODULE 1 +#define CONFIG_USB_CXACRU_MODULE 1 +#define CONFIG_CPU_CP15_MMU 1 +#define CONFIG_RFKILL_LEDS 1 +#define CONFIG_CONSOLE_TRANSLATIONS 1 +#define CONFIG_PHONE_MODULE 1 +#define CONFIG_NET_IPGRE_MODULE 1 +#define CONFIG_LIBERTAS_SDIO_MODULE 1 +#define CONFIG_VIDEO_HELPER_CHIPS_AUTO 1 +#define CONFIG_NF_NAT_SNMP_BASIC_MODULE 1 +#define CONFIG_VIDEO_V4L1_COMPAT 1 +#define CONFIG_LIBERTAS_SPI_MODULE 1 +#define CONFIG_XENO_OPT_GLOBAL_SEM_HEAPSZ 12 +#define CONFIG_USB_OHCI_HCD 1 +#define CONFIG_USB_GSPCA_MODULE 1 +#define CONFIG_HOSTAP_FIRMWARE 1 +#define CONFIG_DM_MIRROR_MODULE 1 +#define CONFIG_CRYPTO_BLOWFISH_MODULE 1 +#define CONFIG_DUMMY_CONSOLE 1 +#define CONFIG_AR9170_USB_MODULE 1 +#define CONFIG_USB_G_PRINTER_MODULE 1 +#define CONFIG_B43_MODULE 1 +#define CONFIG_JOYSTICK_GRIP_MODULE 1 +#define CONFIG_WIMAX_DEBUG_LEVEL 8 +#define CONFIG_USB_RIO500_MODULE 1 +#define CONFIG_TRACE_IRQFLAGS_SUPPORT 1 +#define CONFIG_DVB_CAPTURE_DRIVERS 1 +#define CONFIG_XENO_FASTSYNCH 1 +#define CONFIG_CRYPTO_CCM_MODULE 1 +#define CONFIG_TCP_CONG_ADVANCED 1 +#define CONFIG_NET_CLS_RSVP6_MODULE 1 +#define CONFIG_USB_NET_CDC_SUBSET_MODULE 1 +#define CONFIG_QFMT_V2_MODULE 1 +#define CONFIG_USB_S2255_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNMARK_MODULE 1 +#define CONFIG_USB_SERIAL_MCT_U232_MODULE 1 +#define CONFIG_UIO_PDRV_GENIRQ_MODULE 1 +#define CONFIG_LEDS_TRIGGERS 1 +#define CONFIG_CRYPTO_RNG_MODULE 1 +#define CONFIG_USB_SERIAL_GARMIN_MODULE 1 +#define CONFIG_W1_MASTER_GPIO 1 +#define CONFIG_RAW_DRIVER_MODULE 1 +#define CONFIG_JOYSTICK_COBRA_MODULE 1 +#define CONFIG_NET_SCH_ATM_MODULE 1 +#define CONFIG_SND_SOC_UDA1380_MODULE 1 +#define CONFIG_SND_USB 1 +#define CONFIG_RD_GZIP 1 +#define CONFIG_TOUCHSCREEN_USB_E2I 1 +#define CONFIG_USB_SERIAL_KEYSPAN_MODULE 1 +#define CONFIG_TREE_RCU 1 +#define CONFIG_LBDAF 1 +#define CONFIG_CPU_ARM926T 1 +#define CONFIG_SND_USB_CAIAQ_MODULE 1 +#define CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE 1 +#define CONFIG_SOC_CAMERA_MT9M111_MODULE 1 +#define CONFIG_HAVE_AT91_USART3 1 +#define CONFIG_XENO_DRIVERS_SWITCHTEST 1 +#define CONFIG_INET_XFRM_MODE_TRANSPORT_MODULE 1 +#define CONFIG_CRYPTO_MD5_MODULE 1 +#define CONFIG_VIDEO_CS53L32A_MODULE 1 +#define CONFIG_ISCSI_TCP_MODULE 1 +#define CONFIG_PM_OPS 1 +#define CONFIG_DVB_TDA10023_MODULE 1 +#define CONFIG_MEDIA_TUNER_TEA5767_MODULE 1 +#define CONFIG_VIDEOBUF_DVB_MODULE 1 +#define CONFIG_OABI_COMPAT 1 +#define CONFIG_USB_GSPCA_OV519_MODULE 1 +#define CONFIG_BINFMT_ELF 1 +#define CONFIG_SLOW_WORK 1 +#define CONFIG_SCSI_PROC_FS 1 +#define CONFIG_MD_RAID456_MODULE 1 +#define CONFIG_HOTPLUG 1 +#define CONFIG_UDF_NLS 1 +#define CONFIG_JOYSTICK_STINGER_MODULE 1 +#define CONFIG_INET6_AH_MODULE 1 +#define CONFIG_CPU_CP15 1 +#define CONFIG_RTC_DRV_AT91SAM9 1 +#define CONFIG_USB_SERIAL_MODULE 1 +#define CONFIG_USB_MON 1 +#define CONFIG_SIGMATEL_FIR_MODULE 1 +#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1 +#define CONFIG_KEYS 1 +#define CONFIG_INET_XFRM_TUNNEL_MODULE 1 +#define CONFIG_NETFILTER_XT_MARK_MODULE 1 +#define CONFIG_NETFILTER_XTABLES_MODULE 1 +#define CONFIG_IP_VS_LBLC_MODULE 1 +#define CONFIG_DVB_USB_OPERA1_MODULE 1 +#define CONFIG_XENO_SKIN_POSIX 1 +#define CONFIG_LEDS_BD2802_MODULE 1 +#define CONFIG_KEYBOARD_STOWAWAY_MODULE 1 +#define CONFIG_SLABINFO 1 +#define CONFIG_USB_STORAGE_DATAFAB_MODULE 1 +#define CONFIG_DVB_USB_AF9005_MODULE 1 +#define CONFIG_TCP_CONG_VEGAS_MODULE 1 +#define CONFIG_CRYPTO_HW 1 +#define CONFIG_USB_STORAGE_KARMA_MODULE 1 +#define CONFIG_AT91_SLOW_CLOCK 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA19W 1 +#define CONFIG_HID_GREENASIA_MODULE 1 +#define CONFIG_SMS_USB_DRV_MODULE 1 +#define CONFIG_HARDIRQS_SW_RESEND 1 +#define CONFIG_JFFS2_FS_WRITEBUFFER 1 +#define CONFIG_SPI_MASTER 1 +#define CONFIG_USB_SERIAL_OPTICON_MODULE 1 +#define CONFIG_DVB_NXT200X_MODULE 1 +#define CONFIG_HID_GYRATION_MODULE 1 +#define CONFIG_SND_SOC_AK4642_MODULE 1 +#define CONFIG_IRDA_CACHE_LAST_LSAP 1 +#define CONFIG_USB_WDM_MODULE 1 +#define CONFIG_BT_HCIBCM203X_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_COMPOSITE_MODULE 1 +#define CONFIG_VIDEO_EM28XX_DVB_MODULE 1 +#define CONFIG_USB_SERIAL_KOBIL_SCT_MODULE 1 +#define CONFIG_INPUT_JOYDEV_MODULE 1 +#define CONFIG_MACH_FOXG20 1 +#define CONFIG_SND_SOC_MAX9877_MODULE 1 +#define CONFIG_KEYBOARD_LKKBD_MODULE 1 +#define CONFIG_USB_ACM_MODULE 1 +#define CONFIG_CRC16 1 +#define CONFIG_USB_NET_AX8817X_MODULE 1 +#define CONFIG_GENERIC_CALIBRATE_DELAY 1 +#define CONFIG_CRYPTO_GF128MUL_MODULE 1 +#define CONFIG_NET_CLS 1 +#define CONFIG_BROKEN_ON_SMP 1 +#define CONFIG_ARCH_REQUIRE_GPIOLIB 1 +#define CONFIG_UIO_PDRV_MODULE 1 +#define CONFIG_AX25_MODULE 1 +#define CONFIG_TMPFS 1 +#define CONFIG_HOSTAP_MODULE 1 +#define CONFIG_ANON_INODES 1 +#define CONFIG_SND_SOC_WM8711_MODULE 1 +#define CONFIG_VIDEO_EM28XX_MODULE 1 +#define CONFIG_FUTEX 1 +#define CONFIG_CRYPTO_ANUBIS_MODULE 1 +#define CONFIG_JOYSTICK_SPACEBALL_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_HL_MODULE 1 +#define CONFIG_DVB_CORE_MODULE 1 +#define CONFIG_VMSPLIT_3G 1 +#define CONFIG_RTC_HCTOSYS 1 +#define CONFIG_SERIAL_CORE_CONSOLE 1 +#define CONFIG_TOUCHSCREEN_GUNZE_MODULE 1 +#define CONFIG_VIDEO_CQCAM_MODULE 1 +#define CONFIG_XENO_SKIN_NATIVE 1 +#define CONFIG_USB_HID 1 +#define CONFIG_DVB_USB_AF9015_MODULE 1 +#define CONFIG_ATM_DRIVERS 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA28 1 +#define CONFIG_CRYPTO_TGR192_MODULE 1 +#define CONFIG_BLK_DEV_MD_MODULE 1 +#define CONFIG_USB_SERIAL_AIRCABLE_MODULE 1 +#define CONFIG_SND_SOC_WM8978_MODULE 1 +#define CONFIG_IPV6_NDISC_NODETYPE 1 +#define CONFIG_CRYPTO_ZLIB_MODULE 1 +#define CONFIG_USB_SERIAL_FUNSOFT_MODULE 1 +#define CONFIG_SYSVIPC 1 +#define CONFIG_JOYSTICK_INTERACT_MODULE 1 +#define CONFIG_RT2X00_MODULE 1 +#define CONFIG_KEYBOARD_GPIO 1 +#define CONFIG_NF_CONNTRACK_FTP_MODULE 1 +#define CONFIG_CPU_32v5 1 +#define CONFIG_MODULES 1 +#define CONFIG_IP_NF_MATCH_ECN_MODULE 1 +#define CONFIG_USB_GADGET 1 +#define CONFIG_USB_GSPCA_SPCA506_MODULE 1 +#define CONFIG_KEYBOARD_NEWTON_MODULE 1 +#define CONFIG_VIDEO_EM28XX_ALSA_MODULE 1 +#define CONFIG_MEDIA_TUNER_MXL5005S_MODULE 1 +#define CONFIG_USB_HIDDEV 1 +#define CONFIG_USB_ETH_RNDIS 1 +#define CONFIG_DVB_SI21XX_MODULE 1 +#define CONFIG_SOUND_MODULE 1 +#define CONFIG_DVB_USB_VP7045_MODULE 1 +#define CONFIG_MEDIA_TUNER_TDA9887_MODULE 1 +#define CONFIG_CRYPTO_TEA_MODULE 1 +#define CONFIG_ATMEL_SSC 1 +#define CONFIG_UNIX 1 +#define CONFIG_MINIX_FS_MODULE 1 +#define CONFIG_HAVE_CLK 1 +#define CONFIG_CRYPTO_HASH2_MODULE 1 +#define CONFIG_SND_SOC_AK4671_MODULE 1 +#define CONFIG_USB_GSPCA_SONIXB_MODULE 1 +#define CONFIG_USB_STORAGE_ISD200_MODULE 1 +#define CONFIG_NFS_FS_MODULE 1 +#define CONFIG_INET_ESP_MODULE 1 +#define CONFIG_LCD_TDO24M_MODULE 1 +#define CONFIG_NF_CONNTRACK_IPV6_MODULE 1 +#define CONFIG_MD 1 +#define CONFIG_CRYPTO_ALGAPI_MODULE 1 +#define CONFIG_SOC_CAMERA_PLATFORM_MODULE 1 +#define CONFIG_BRIDGE_MODULE 1 +#define CONFIG_MEDIA_TUNER_MODULE 1 +#define CONFIG_USB_GADGET_AT91 1 +#define CONFIG_TABLET_USB_GTCO_MODULE 1 +#define CONFIG_MISC_DEVICES 1 +#define CONFIG_USB_CYPRESS_CY7C63_MODULE 1 +#define CONFIG_SND_SOC_AD1836_MODULE 1 +#define CONFIG_INPUT_UINPUT_MODULE 1 +#define CONFIG_MEDIA_TUNER_SIMPLE_MODULE 1 +#define CONFIG_KEYBOARD_ATKBD_MODULE 1 +#define CONFIG_MTD_CFI_I1 1 +#define CONFIG_NF_NAT_MODULE 1 +#define CONFIG_MAX_RAW_DEVS 256 +#define CONFIG_USB_SERIAL_XIRCOM_MODULE 1 +#define CONFIG_MOUSE_BCM5974_MODULE 1 +#define CONFIG_CPU_IDLE 1 +#define CONFIG_NFS_COMMON 1 +#define CONFIG_CHR_DEV_SCH_MODULE 1 +#define CONFIG_RT2800USB_MODULE 1 +#define CONFIG_CRYPTO_HASH_MODULE 1 +#define CONFIG_LOG_BUF_SHIFT 14 +#define CONFIG_SOUND_OSS_CORE_PRECLAIM 1 +#define CONFIG_EXTRA_FIRMWARE "" +#define CONFIG_VIRT_TO_BUS 1 +#define CONFIG_VFAT_FS 1 +#define CONFIG_MD_RAID1_MODULE 1 +#define CONFIG_CRYPTO_VMAC_MODULE 1 +#define CONFIG_VIDEO_HDPVR_MODULE 1 +#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1 +#define CONFIG_ROMFS_ON_BLOCK 1 +#define CONFIG_GENERIC_TIME 1 +#define CONFIG_BLK_DEV_SR_MODULE 1 +#define CONFIG_SND_HWDEP_MODULE 1 +#define CONFIG_BLK_DEV_LOOP 1 +#define CONFIG_IPMI_HANDLER_MODULE 1 +#define CONFIG_SYSV_FS_MODULE 1 +#define CONFIG_NF_NAT_IRC_MODULE 1 +#define CONFIG_MEDIA_TUNER_XC2028_MODULE 1 +#define CONFIG_INPUT_MISC 1 +#define CONFIG_DVB_STV0288_MODULE 1 +#define CONFIG_SOC_CAMERA_MODULE 1 +#define CONFIG_SUSPEND 1 +#define CONFIG_MTD_NAND_ECC 1 +#define CONFIG_CRYPTO_CBC_MODULE 1 +#define CONFIG_KS0108_DELAY 2 +#define CONFIG_IP6_NF_MATCH_RT_MODULE 1 +#define CONFIG_FS_MBCACHE 1 +#define CONFIG_MD_MULTIPATH_MODULE 1 +#define CONFIG_DS1682_MODULE 1 +#define CONFIG_GFS2_FS_MODULE 1 +#define CONFIG_RTC_CLASS 1 +#define CONFIG_DVB_TUNER_DIB0070_MODULE 1 +#define CONFIG_CRC7_MODULE 1 +#define CONFIG_NET_CLS_TCINDEX_MODULE 1 +#define CONFIG_USB_EMI26_MODULE 1 +#define CONFIG_IP_VS_PROTO_ESP 1 +#define CONFIG_HAVE_LATENCYTOP_SUPPORT 1 +#define CONFIG_SND_SOC_WM8993_MODULE 1 +#define CONFIG_TOUCHSCREEN_TSC2007_MODULE 1 +#define CONFIG_PATA_AT91_MODULE 1 +#define CONFIG_W1 1 +#define CONFIG_USB_GSPCA_VC032X_MODULE 1 +#define CONFIG_DVB_ISL6421_MODULE 1 +#define CONFIG_IP_VS_WLC_MODULE 1 +#define CONFIG_HAVE_FUNCTION_TRACER 1 +#define CONFIG_NF_NAT_TFTP_MODULE 1 +#define CONFIG_SND_SOC_ADS117X_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MULTIPORT_MODULE 1 +#define CONFIG_NET_SCH_NETEM_MODULE 1 +#define CONFIG_CRYPTO_CAMELLIA_MODULE 1 +#define CONFIG_I2C_SI4713_MODULE 1 +#define CONFIG_TCP_CONG_ILLINOIS_MODULE 1 +#define CONFIG_CRYPTO_MANAGER2_MODULE 1 +#define CONFIG_USB_GADGET_VBUS_DRAW 2 +#define CONFIG_TOUCHSCREEN_USB_3M 1 +#define CONFIG_TOUCHSCREEN_USB_EGALAX 1 +#define CONFIG_CONFIGFS_FS_MODULE 1 +#define CONFIG_CRYPTO_TEST_MODULE 1 +#define CONFIG_ARCH_AT91SAM9G20 1 +#define CONFIG_PM_SLEEP 1 +#define CONFIG_I2C 1 +#define CONFIG_JFFS2_ZLIB 1 +#define CONFIG_VIDEO_CX25840_MODULE 1 +#define CONFIG_PARPORT_PC_MODULE 1 +#define CONFIG_SCSI_SRP_ATTRS_MODULE 1 +#define CONFIG_FRAME_POINTER 1 +#define CONFIG_BT_HIDP_MODULE 1 +#define CONFIG_MOUSE_PS2_LOGIPS2PP 1 +#define CONFIG_IR_CORE_MODULE 1 +#define CONFIG_XENO_OPT_PIPE_NRDEV 32 +#define CONFIG_UFS_FS_MODULE 1 +#define CONFIG_VM_EVENT_COUNTERS 1 +#define CONFIG_VIDEO_CPIA_USB_MODULE 1 +#define CONFIG_USB_GSPCA_FINEPIX_MODULE 1 +#define CONFIG_CRYPTO_ECB_MODULE 1 +#define CONFIG_USB_GSPCA_ETOMS_MODULE 1 +#define CONFIG_USB_W9968CF_MODULE 1 +#define CONFIG_NF_CONNTRACK_AMANDA_MODULE 1 +#define CONFIG_DEBUG_FS 1 +#define CONFIG_USB_SERIAL_EDGEPORT_MODULE 1 +#define CONFIG_BASE_FULL 1 +#define CONFIG_ZLIB_DEFLATE 1 +#define CONFIG_SUNRPC_MODULE 1 +#define CONFIG_VIDEO_SAA5249_MODULE 1 +#define CONFIG_SCSI_DH_RDAC_MODULE 1 +#define CONFIG_INPUT_ATI_REMOTE2_MODULE 1 +#define CONFIG_IP_VS_LBLCR_MODULE 1 +#define CONFIG_GPIO_SYSFS 1 +#define CONFIG_FW_LOADER_MODULE 1 +#define CONFIG_LITELINK_DONGLE_MODULE 1 +#define CONFIG_KALLSYMS 1 +#define CONFIG_USB_GSPCA_SPCA501_MODULE 1 +#define CONFIG_SERIAL_ATMEL_CONSOLE 1 +#define CONFIG_GENERIC_ATOMIC64 1 +#define CONFIG_RTC_HCTOSYS_DEVICE "rtc0" +#define CONFIG_USB_KONICAWC_MODULE 1 +#define CONFIG_CRYPTO_XTS_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_RECENT_MODULE 1 +#define CONFIG_XENO_OPT_POSIX_PERIOD 0 +#define CONFIG_NETFILTER_XT_MATCH_PKTTYPE_MODULE 1 +#define CONFIG_MII 1 +#define CONFIG_SIGNALFD 1 +#define CONFIG_MOUSE_PS2_ALPS 1 +#define CONFIG_VIDEO_CPIA2_MODULE 1 +#define CONFIG_EXT4_FS 1 +#define CONFIG_NET_SCH_DRR_MODULE 1 +#define CONFIG_CRYPTO_SHA1_MODULE 1 +#define CONFIG_JOYSTICK_JOYDUMP_MODULE 1 +#define CONFIG_USB_ADUTUX_MODULE 1 +#define CONFIG_USB_BELKIN 1 +#define CONFIG_SATA_PMP 1 +#define CONFIG_ATH_COMMON_MODULE 1 +#define CONFIG_LOCKD_V4 1 +#define CONFIG_CODA_FS_MODULE 1 +#define CONFIG_DVB_TUNER_CX24113_MODULE 1 +#define CONFIG_WATCHDOG 1 +#define CONFIG_HAS_IOMEM 1 +#define CONFIG_SND_RAWMIDI_MODULE 1 +#define CONFIG_HAVE_AT91_USART5 1 +#define CONFIG_GENERIC_IRQ_PROBE 1 +#define CONFIG_USB_STORAGE_SDDR09_MODULE 1 +#define CONFIG_IP_NF_MATCH_TTL_MODULE 1 +#define CONFIG_ASYNC_RAID6_RECOV_MODULE 1 +#define CONFIG_SND_SOC_UDA134X_MODULE 1 +#define CONFIG_USB_GADGETFS_MODULE 1 +#define CONFIG_IRDA_ULTRA 1 +#define CONFIG_MTD_MAP_BANK_WIDTH_1 1 +#define CONFIG_IP6_NF_MATCH_FRAG_MODULE 1 +#define CONFIG_APM_EMULATION_MODULE 1 +#define CONFIG_USB_SERIAL_CYBERJACK_MODULE 1 +#define CONFIG_NET_SCH_PRIO_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA28XB 1 +#define CONFIG_CONSTRUCTORS 1 +#define CONFIG_USB_SERIAL_IUU_MODULE 1 +#define CONFIG_EPOLL 1 +#define CONFIG_CRYPTO_LZO_MODULE 1 +#define CONFIG_SND_PCM_MODULE 1 +#define CONFIG_GIRBIL_DONGLE_MODULE 1 +#define CONFIG_SDIO_UART_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_DCCP_MODULE 1 +#define CONFIG_SND_SOC_WM8971_MODULE 1 +#define CONFIG_SCSI_ISCSI_ATTRS_MODULE 1 +#define CONFIG_USB_SERIAL_EMPEG_MODULE 1 +#define CONFIG_KEYBOARD_MAX7359_MODULE 1 +#define CONFIG_IR_SONY_DECODER_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_IDEALTEK 1 +#define CONFIG_VIDEO_PVRUSB2_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_COMMENT_MODULE 1 +#define CONFIG_USB_NET_RNDIS_HOST_MODULE 1 +#define CONFIG_NET 1 +#define CONFIG_INPUT_EVDEV 1 +#define CONFIG_SND_JACK 1 +#define CONFIG_NETFILTER_XT_TARGET_TCPMSS_MODULE 1 +#define CONFIG_B43LEGACY_DMA 1 +#define CONFIG_EXT2_FS 1 +#define CONFIG_TABLET_USB_WACOM_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_DSCP_MODULE 1 +#define CONFIG_CRYPTO_WP512_MODULE 1 +#define CONFIG_SND_SOC_WM9090_MODULE 1 +#define CONFIG_HID_DRAGONRISE_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNTRACK_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_RATEEST_MODULE 1 +#define CONFIG_XENO_GENERIC_STACKPOOL 1 +#define CONFIG_HPFS_FS_MODULE 1 +#define CONFIG_USB_LD_MODULE 1 +#define CONFIG_QUOTA_TREE_MODULE 1 +#define CONFIG_USB_NET_CDCETHER_MODULE 1 +#define CONFIG_PACKET 1 +#define CONFIG_NETFILTER_XT_MATCH_IPRANGE_MODULE 1 +#define CONFIG_NET_CLS_BASIC_MODULE 1 +#define CONFIG_NETROM_MODULE 1 +#define CONFIG_USB_GSPCA_OV534_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_MPR 1 +#define CONFIG_DVB_USB_GL861_MODULE 1 +#define CONFIG_SND_SOC_PCM3008_MODULE 1 +#define CONFIG_NF_CONNTRACK_TFTP_MODULE 1 +#define CONFIG_NFS_V3 1 +#define CONFIG_DVB_USB_ANYSEE_MODULE 1 +#define CONFIG_USB_FILE_STORAGE_MODULE 1 +#define CONFIG_BACKLIGHT_LCD_SUPPORT 1 +#define CONFIG_INET 1 +#define CONFIG_IP_PNP_BOOTP 1 +#define CONFIG_CRYPTO_TWOFISH_MODULE 1 +#define CONFIG_FREEZER 1 +#define CONFIG_USB_TEST_MODULE 1 +#define CONFIG_BT_MODULE 1 +#define CONFIG_BT_HCIVHCI_MODULE 1 +#define CONFIG_INPUT_CM109_MODULE 1 +#define CONFIG_LCD_PLATFORM_MODULE 1 +#define CONFIG_XENO_OPT_SYS_HEAPSZ 256 +#define CONFIG_SND_AT91_SOC_SAM9G20_WM8731_MODULE 1 +#define CONFIG_PARPORT_MODULE 1 +#define CONFIG_HID_WACOM_MODULE 1 +#define CONFIG_USB_SERIAL_CP210X_MODULE 1 +#define CONFIG_NET_SCH_SFQ_MODULE 1 +#define CONFIG_RTC_LIB 1 +#define CONFIG_XENO_OPT_REGISTRY_NRSLOTS 512 +#define CONFIG_USB_UEAGLEATM_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_POLICY_MODULE 1 +#define CONFIG_HAVE_KPROBES 1 +#define CONFIG_MOUSE_SYNAPTICS_I2C_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_ITM 1 +#define CONFIG_CRYPTO_AES_MODULE 1 +#define CONFIG_DVB_DIB7000P_MODULE 1 +#define CONFIG_AT91SAM9X_WATCHDOG 1 +#define CONFIG_GPIOLIB 1 +#define CONFIG_SSB_MODULE 1 +#define CONFIG_SND_SOC_WM8961_MODULE 1 +#define CONFIG_RADIO_TEA5764_MODULE 1 +#define CONFIG_PARPORT_AX88796_MODULE 1 +#define CONFIG_AUTOFS_FS_MODULE 1 +#define CONFIG_GAMEPORT_MODULE 1 +#define CONFIG_ISO9660_FS_MODULE 1 +#define CONFIG_BT_HCIUART_H4 1 +#define CONFIG_XENO_OPT_NATIVE_BUFFER 1 +#define CONFIG_DVB_USB_M920X_MODULE 1 +#define CONFIG_UIO_MODULE 1 +#define CONFIG_SND_ARM 1 +#define CONFIG_SOC_CAMERA_MT9T031_MODULE 1 +#define CONFIG_B43LEGACY_DEBUG 1 +#define CONFIG_NF_CONNTRACK_MARK 1 +#define CONFIG_NETFILTER 1 +#define CONFIG_NETFILTER_XT_MATCH_HASHLIMIT_MODULE 1 +#define CONFIG_B43_PIO 1 +#define CONFIG_NETFILTER_XT_MATCH_CLUSTER_MODULE 1 +#define CONFIG_USB_MDC800_MODULE 1 +#define CONFIG_SERIO_SERPORT 1 +#define CONFIG_DVB_STV0297_MODULE 1 +#define CONFIG_BT_BNEP_MODULE 1 +#define CONFIG_DVB_TDA826X_MODULE 1 +#define CONFIG_BLK_DEV_RAM_COUNT 16 +#define CONFIG_XENO_OPT_NATIVE_MUTEX 1 +#define CONFIG_INET_XFRM_MODE_TUNNEL_MODULE 1 +#define CONFIG_USB_VICAM_MODULE 1 +#define CONFIG_SND_SOC_TLV320AIC23_MODULE 1 +#define CONFIG_NF_NAT_NEEDED 1 +#define CONFIG_ATA_VERBOSE_ERROR 1 +#define CONFIG_SND_DRIVERS 1 +#define CONFIG_USB_SERIAL_BELKIN_MODULE 1 +#define CONFIG_MEDIA_TUNER_MT2266_MODULE 1 +#define CONFIG_XFS_FS_MODULE 1 +#define CONFIG_INPUT_KEYSPAN_REMOTE_MODULE 1 +#define CONFIG_LOCKDEP_SUPPORT 1 +#define CONFIG_TOUCHSCREEN_ELO_MODULE 1 +#define CONFIG_NO_HZ 1 +#define CONFIG_TOUCHSCREEN_TOUCHIT213_MODULE 1 +#define CONFIG_BINFMT_AOUT_MODULE 1 +#define CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ 1 +#define CONFIG_CHR_DEV_OSST_MODULE 1 +#define CONFIG_MTD_BLKDEVS 1 +#define CONFIG_DVB_TDA10086_MODULE 1 +#define CONFIG_VIDEO_CAPTURE_DRIVERS 1 +#define CONFIG_DVB_NXT6000_MODULE 1 +#define CONFIG_SND_PCM_OSS_PLUGINS 1 +#define CONFIG_XENO_OPT_NATIVE_ALARM 1 +#define CONFIG_NLS_ISO8859_15 1 +#define CONFIG_TOUCHSCREEN_EETI_MODULE 1 +#define CONFIG_INET6_ESP_MODULE 1 +#define CONFIG_IP_VS_WRR_MODULE 1 +#define CONFIG_AUTOFS4_FS_MODULE 1 +#define CONFIG_SYSCTL_SYSCALL 1 +#define CONFIG_SND_ATMEL_SOC_MODULE 1 +#define CONFIG_SND_SOC_WM8940_MODULE 1 +#define CONFIG_IP6_NF_FILTER_MODULE 1 +#define CONFIG_INPUT_MOUSEDEV_SCREEN_X 320 +#define CONFIG_NEED_DMA_MAP_STATE 1 +#define CONFIG_RT2500USB_MODULE 1 +#define CONFIG_SERIO_LIBPS2 1 +#define CONFIG_IP_VS_PROTO_TCP 1 +#define CONFIG_NET_SCH_RED_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNBYTES_MODULE 1 +#define CONFIG_PAGE_OFFSET 0xC0000000 +#define CONFIG_USB_PRINTER_MODULE 1 +#define CONFIG_FONT_8x8 1 +#define CONFIG_USB_GSPCA_PAC207_MODULE 1 +#define CONFIG_USB_SERIAL_IR_MODULE 1 +#define CONFIG_SND_SOC_AK4104_MODULE 1 +#define CONFIG_XOR_BLOCKS_MODULE 1 +#define CONFIG_HID_TWINHAN_MODULE 1 +#define CONFIG_ZBOOT_ROM_BSS 0x0 +#define CONFIG_INPUT_JOYSTICK 1 +#define CONFIG_QNX4FS_FS_MODULE 1 +#define CONFIG_RT2X00_LIB_MODULE 1 +#define CONFIG_USB_STORAGE_SDDR55_MODULE 1 +#define CONFIG_IP_NF_TARGET_TTL_MODULE 1 +#define CONFIG_CFG80211_DEFAULT_PS 1 +#define CONFIG_USB_LED_MODULE 1 +#define CONFIG_SND_SOC_WM8974_MODULE 1 +#define CONFIG_TOUCHSCREEN_WACOM_W8001_MODULE 1 +#define CONFIG_PREEMPT_NONE 1 +#define CONFIG_RT2X00_LIB_FIRMWARE 1 +#define CONFIG_DVB_ZL10353_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_TIME_MODULE 1 +#define CONFIG_IP_VS_MODULE 1 +#define CONFIG_HAVE_KERNEL_GZIP 1 +#define CONFIG_USB_XUSBATM_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MAC_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_NFLOG_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_JASTEC 1 +#define CONFIG_DVB_B2C2_FLEXCOP_USB_MODULE 1 +#define CONFIG_TCP_CONG_WESTWOOD_MODULE 1 +#define CONFIG_USB_GSPCA_SPCA561_MODULE 1 +#define CONFIG_LIBCRC32C_MODULE 1 +#define CONFIG_KEYBOARD_MATRIX_MODULE 1 +#define CONFIG_CRYPTO_SHA256_MODULE 1 +#define CONFIG_JOYSTICK_GUILLEMOT_MODULE 1 +#define CONFIG_VIDEO_AU0828_MODULE 1 +#define CONFIG_INET_TCP_DIAG 1 +#define CONFIG_HID_SONY_MODULE 1 +#define CONFIG_VIDEO_PVRUSB2_DVB 1 +#define CONFIG_RTC_INTF_DEV_UIE_EMUL 1 +#define CONFIG_HW_CONSOLE 1 +#define CONFIG_SOC_CAMERA_TW9910_MODULE 1 +#define CONFIG_SOC_CAMERA_MT9V022_MODULE 1 +#define CONFIG_IPX_MODULE 1 +#define CONFIG_RT2X00_LIB_HT 1 +#define CONFIG_OMFS_FS_MODULE 1 +#define CONFIG_USB_GSPCA_ZC3XX_MODULE 1 +#define CONFIG_SND_SPI 1 +#define CONFIG_TOUCHSCREEN_MTOUCH_MODULE 1 +#define CONFIG_HID_MONTEREY_MODULE 1 +#define CONFIG_USB_SERIAL_CYPRESS_M8_MODULE 1 +#define CONFIG_HID_EZKEY_MODULE 1 +#define CONFIG_IOSCHED_NOOP 1 +#define CONFIG_DVB_S5H1409_MODULE 1 +#define CONFIG_LEDS_CPU 1 +#define CONFIG_SCSI_OSD_ULD_MODULE 1 +#define CONFIG_BT_MRVL_MODULE 1 +#define CONFIG_QUOTACTL 1 +#define CONFIG_CRYPTO_CRYPTD_MODULE 1 +#define CONFIG_SND_SOC_AK4535_MODULE 1 +#define CONFIG_COMPAT_BRK 1 +#define CONFIG_VIDEO_CX2341X_MODULE 1 +#define CONFIG_LOCALVERSION "" +#define CONFIG_CPU_PABRT_LEGACY 1 +#define CONFIG_RADIO_ADAPTERS 1 +#define CONFIG_KEYBOARD_XTKBD_MODULE 1 +#define CONFIG_USB_GSPCA_MARS_MODULE 1 +#define CONFIG_CAN_RAW_MODULE 1 +#define CONFIG_CRYPTO 1 +#define CONFIG_USB_TRANCEVIBRATOR_MODULE 1 +#define CONFIG_USB_STKWEBCAM_MODULE 1 +#define CONFIG_LEDS_GPIO_PLATFORM 1 +#define CONFIG_DEFAULT_MMAP_MIN_ADDR 4096 +#define CONFIG_IP_NF_IPTABLES_MODULE 1 +#define CONFIG_CMDLINE "mem=64M console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rw rootwait init=/sbin/init" +#define CONFIG_SPI_GPIO_MODULE 1 +#define CONFIG_DEFAULT_CUBIC 1 +#define CONFIG_HID_SAMSUNG_MODULE 1 +#define CONFIG_SND_SOC_WM8955_MODULE 1 +#define CONFIG_USB_ISIGHTFW_MODULE 1 +#define CONFIG_SND_SEQ_HRTIMER_DEFAULT 1 +#define CONFIG_USB_ARCH_HAS_HCD 1 +#define CONFIG_DVB_DIB3000MC_MODULE 1 +#define CONFIG_CACHEFILES_MODULE 1 +#define CONFIG_LCD_ILI9320_MODULE 1 +#define CONFIG_JOYSTICK_A3D_MODULE 1 +#define CONFIG_SND_SOC_CS4270_MODULE 1 +#define CONFIG_ALIGNMENT_TRAP 1 +#define CONFIG_TCP_CONG_HSTCP_MODULE 1 +#define CONFIG_SCSI_MOD 1 +#define CONFIG_SND_SOC_SSM2602_MODULE 1 +#define CONFIG_JOYSTICK_ZHENHUA_MODULE 1 +#define CONFIG_USB_SERIAL_SPCP8X5_MODULE 1 +#define CONFIG_SND_SOC_TLV320AIC26_MODULE 1 +#define CONFIG_P54_USB_MODULE 1 +#define CONFIG_TOUCHSCREEN_MK712_MODULE 1 +#define CONFIG_CRYPTO_CRC32C_MODULE 1 +#define CONFIG_SERIAL_CORE 1 +#define CONFIG_FUSE_FS_MODULE 1 +#define CONFIG_UID16 1 +#define CONFIG_MTD_NAND_ATMEL_ECC_SOFT 1 +#define CONFIG_EMBEDDED 1 +#define CONFIG_HID_MICROSOFT_MODULE 1 +#define CONFIG_HAVE_KRETPROBES 1 +#define CONFIG_USB_GSPCA_CONEX_MODULE 1 +#define CONFIG_VIDEO_DEV_MODULE 1 +#define CONFIG_KS0108_MODULE 1 +#define CONFIG_IRCOMM_MODULE 1 +#define CONFIG_INLINE_READ_UNLOCK 1 +#define CONFIG_SOUND_PRIME_MODULE 1 +#define CONFIG_USB_ET61X251_MODULE 1 +#define CONFIG_HAS_DMA 1 +#define CONFIG_NF_CT_PROTO_SCTP_MODULE 1 +#define CONFIG_USB_SERIAL_VISOR_MODULE 1 +#define CONFIG_BT_L2CAP_MODULE 1 +#define CONFIG_SCSI 1 +#define CONFIG_AT76C50X_USB_MODULE 1 +#define CONFIG_NF_NAT_PPTP_MODULE 1 +#define CONFIG_HID_CHICONY_MODULE 1 +#define CONFIG_HID 1 +#define CONFIG_LIBERTAS_THINFIRM_USB_MODULE 1 +#define CONFIG_SND_SERIAL_U16550_MODULE 1 +#define CONFIG_USB_ARMLINUX 1 +#define CONFIG_JOYSTICK_GF2K_MODULE 1 +#define CONFIG_FONT_8x16 1 +#define CONFIG_MAC80211_HWSIM_MODULE 1 +#define CONFIG_DVB_LGDT330X_MODULE 1 +#define CONFIG_LIBFC_MODULE 1 +#define CONFIG_RTC_DRV_CMOS 1 +#define CONFIG_IEEE802154_DRIVERS_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_IRTOUCH 1 +#define CONFIG_USB_PWC_MODULE 1 +#define CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE 3 +#define CONFIG_MEDIA_TUNER_TDA8290_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_PANJIT 1 +#define CONFIG_JBD2 1 +#define CONFIG_ATM_BR2684_MODULE 1 +#define CONFIG_SPI_TLE62X0_MODULE 1 +#define CONFIG_INET6_IPCOMP_MODULE 1 +#define CONFIG_IRDA_FAST_RR 1 +#define CONFIG_PHYLIB 1 +#define CONFIG_IPV6_TUNNEL_MODULE 1 +#define CONFIG_INPUT_APMPOWER_MODULE 1 +#define CONFIG_MEDIA_TUNER_MT20XX_MODULE 1 +#define CONFIG_JFFS2_RTIME 1 +#define CONFIG_MISC_FILESYSTEMS 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNLIMIT_MODULE 1 +#define CONFIG_IP_NF_RAW_MODULE 1 +#define CONFIG_IP_NF_ARPFILTER_MODULE 1 +#define CONFIG_W1_CON 1 +#define CONFIG_KEYBOARD_ADP5588_MODULE 1 +#define CONFIG_HID_TOPSEED_MODULE 1 +#define CONFIG_XENO_OPT_STATS 1 +#define CONFIG_NF_NAT_H323_MODULE 1 +#define CONFIG_JOYSTICK_TURBOGRAFX_MODULE 1 +#define CONFIG_JFFS2_SUMMARY 1 +#define CONFIG_INLINE_READ_UNLOCK_IRQ 1 +#define CONFIG_HID_A4TECH_MODULE 1 +#define CONFIG_MEDIA_TUNER_MC44S803_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_ESP_MODULE 1 +#define CONFIG_PRINT_QUOTA_WARNING 1 +#define CONFIG_IP_NF_TARGET_NETMAP_MODULE 1 +#define CONFIG_USB_GSPCA_SPCA505_MODULE 1 +#define CONFIG_USB_GSPCA_SQ905C_MODULE 1 +#define CONFIG_USB_ZR364XX_MODULE 1 +#define CONFIG_SND_VERBOSE_PROCFS 1 +#define CONFIG_DVB_LNBP21_MODULE 1 +#define CONFIG_DVB_TDA10048_MODULE 1 +#define CONFIG_INPUT_FF_MEMLESS_MODULE 1 +#define CONFIG_CHR_DEV_SG_MODULE 1 +#define CONFIG_NET_SCH_DSMARK_MODULE 1 +#define CONFIG_SMS_SDIO_DRV_MODULE 1 +#define CONFIG_XENO_FASTSYNCH_DEP 1 +#define CONFIG_SND_MPU401_MODULE 1 +#define CONFIG_DVB_CX24116_MODULE 1 +#define CONFIG_CRYPTO_XCBC_MODULE 1 +#define CONFIG_NF_NAT_AMANDA_MODULE 1 +#define CONFIG_IP6_NF_MATCH_IPV6HEADER_MODULE 1 +#define CONFIG_JOYSTICK_IFORCE_MODULE 1 +#define CONFIG_SND_SOC_WM8731_MODULE 1 +#define CONFIG_INET6_XFRM_MODE_TRANSPORT_MODULE 1 +#define CONFIG_CRYPTO_ARC4_MODULE 1 +#define CONFIG_DVB_STV0900_MODULE 1 +#define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_MODULE 1 +#define CONFIG_USB_GL860_MODULE 1 +#define CONFIG_SCSI_TGT 1 +#define CONFIG_CRYPTO_MANAGER_MODULE 1 +#define CONFIG_NET_SCH_HTB_MODULE 1 +#define CONFIG_HOSTAP_FIRMWARE_NVRAM 1 +#define CONFIG_DVB_USB_TTUSB2_MODULE 1 +#define CONFIG_MTD_NAND 1 +#define CONFIG_RT_MUTEXES 1 +#define CONFIG_VECTORS_BASE 0xffff0000 +#define CONFIG_NETFILTER_XT_TARGET_MARK_MODULE 1 +#define CONFIG_XENO_OPT_PIPELINE_HEAD 1 +#define CONFIG_MEDIA_TUNER_MXL5007T_MODULE 1 +#define CONFIG_MD_LINEAR_MODULE 1 +#define CONFIG_VIDEO_CX231XX_DVB_MODULE 1 +#define CONFIG_IPIPE_DOMAINS 4 +#define CONFIG_I2C_ALGOBIT_MODULE 1 +#define CONFIG_MMC_BLOCK 1 +#define CONFIG_NET_CLS_FW_MODULE 1 +#define CONFIG_SND_SOC_WM8727_MODULE 1 +#define CONFIG_LCD_LTV350QV_MODULE 1 +#define CONFIG_VIDEO_MT9V011_MODULE 1 +#define CONFIG_TOUCHSCREEN_W90X900_MODULE 1 +#define CONFIG_WIRELESS 1 +#define CONFIG_WEXT_PROC 1 +#define CONFIG_SND_SOC_ALL_CODECS_MODULE 1 +#define CONFIG_SQUASHFS 1 +#define CONFIG_NET_SCH_TBF_MODULE 1 +#define CONFIG_BT_HCIBTUSB_MODULE 1 +#define CONFIG_PERF_USE_VMALLOC 1 +#define CONFIG_DVB_CX22702_MODULE 1 +#define CONFIG_FAT_DEFAULT_IOCHARSET "iso8859-1" +#define CONFIG_ASYNC_XOR_MODULE 1 +#define CONFIG_NET_CLS_RSVP_MODULE 1 +#define CONFIG_DVB_STB6100_MODULE 1 +#define CONFIG_MD_RAID0_MODULE 1 +#define CONFIG_FRAME_WARN 1024 +#define CONFIG_ACT200L_DONGLE_MODULE 1 +#define CONFIG_ASYNC_RAID6_TEST_MODULE 1 +#define CONFIG_USB_ETH_MODULE 1 +#define CONFIG_GENERIC_HWEIGHT 1 +#define CONFIG_INITRAMFS_SOURCE "" +#define CONFIG_XENO_OPT_NUCLEUS 1 +#define CONFIG_ATM_CLIP_MODULE 1 +#define CONFIG_LZO_COMPRESS_MODULE 1 +#define CONFIG_MMC 1 +#define CONFIG_TOUCHSCREEN_USB_GUNZE 1 +#define CONFIG_CRYPTO_SEQIV_MODULE 1 +#define CONFIG_TOUCHSCREEN_AD7877_MODULE 1 +#define CONFIG_HID_LOGITECH_MODULE 1 +#define CONFIG_DM_LOG_USERSPACE_MODULE 1 +#define CONFIG_JOYSTICK_GAMECON_MODULE 1 +#define CONFIG_IPIPE_AT91_TC 0 +#define CONFIG_XENO_OPT_PIPE 1 +#define CONFIG_SCSI_SAS_LIBSAS_MODULE 1 +#define CONFIG_INLINE_SPIN_UNLOCK 1 +#define CONFIG_USB_NET_RNDIS_WLAN_MODULE 1 +#define CONFIG_VIDEO_TUNER_MODULE 1 +#define CONFIG_HAS_IOPORT 1 +#define CONFIG_LEDS_LP3944_MODULE 1 +#define CONFIG_USB_SEVSEG_MODULE 1 +#define CONFIG_VIDEOBUF_DMA_CONTIG_MODULE 1 +#define CONFIG_MTD_NAND_ATMEL 1 +#define CONFIG_SND_MPU401_UART_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_MPS 1 +#define CONFIG_USB_CDC_COMPOSITE_MODULE 1 +#define CONFIG_USB_DSBR_MODULE 1 +#define CONFIG_USB_SERIAL_OTI6858_MODULE 1 +#define CONFIG_ACTISYS_DONGLE_MODULE 1 +#define CONFIG_CAN_BCM_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_HEAP 1 +#define CONFIG_RTC_DRV_AT91SAM9_GPBR 0 +#define CONFIG_USB_ATM_MODULE 1 +#define CONFIG_HZ 100 +#define CONFIG_SND_AT73C213_MODULE 1 +#define CONFIG_USB_AT91 1 +#define CONFIG_I2C_HELPER_AUTO 1 +#define CONFIG_NETFILTER_XT_MATCH_U32_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA49WLC 1 +#define CONFIG_INLINE_SPIN_UNLOCK_IRQ 1 +#define CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE 1 +#define CONFIG_SND_MTS64_MODULE 1 +#define CONFIG_XENO_HW_UNLOCKED_SWITCH 1 +#define CONFIG_CRYPTO_RMD160_MODULE 1 +#define CONFIG_INET_AH_MODULE 1 +#define CONFIG_DEFAULT_IOSCHED "noop" +#define CONFIG_TABLET_USB_KBTAB_MODULE 1 +#define CONFIG_UDF_FS_MODULE 1 +#define CONFIG_IPV6_MIP6_MODULE 1 +#define CONFIG_VXFS_FS_MODULE 1 +#define CONFIG_NLATTR 1 +#define CONFIG_ZD1211RW_MODULE 1 +#define CONFIG_TCP_CONG_CUBIC 1 +#define CONFIG_SCSI_NETLINK 1 +#define CONFIG_SUSPEND_FREEZER 1 +#define CONFIG_SND_SUPPORT_OLD_API 1 +#define CONFIG_DVB_DIB7000M_MODULE 1 +#define CONFIG_NETFILTER_XT_CONNMARK_MODULE 1 +#define CONFIG_HID_KYE_MODULE 1 +#define CONFIG_MOUSE_PS2_TRACKPOINT 1 +#define CONFIG_MOUSE_VSXXXAA_MODULE 1 +#define CONFIG_FIRMWARE_IN_KERNEL 1 +#define CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ 1024 +#define CONFIG_SYSFS 1 +#define CONFIG_LIB80211_CRYPT_WEP_MODULE 1 +#define CONFIG_INPUT_TOUCHSCREEN 1 +#define CONFIG_RADIO_SI4713_MODULE 1 +#define CONFIG_ARM_THUMB 1 +#define CONFIG_IP_NF_MATCH_AH_MODULE 1 +#define CONFIG_VIDEO_OVCAMCHIP_MODULE 1 +#define CONFIG_TCP_CONG_VENO_MODULE 1 +#define CONFIG_DVB_S5H1420_MODULE 1 +#define CONFIG_AFS_FS_MODULE 1 +#define CONFIG_SOC_CAMERA_MT9M001_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_LIMIT_MODULE 1 +#define CONFIG_IP6_NF_QUEUE_MODULE 1 +#define CONFIG_IRLAN_MODULE 1 +#define CONFIG_MOUSE_SERIAL_MODULE 1 +#define CONFIG_JOYSTICK_ANALOG_MODULE 1 +#define CONFIG_WIMAX_MODULE 1 +#define CONFIG_DVB_LGDT3305_MODULE 1 +#define CONFIG_FB_MODULE 1 +#define CONFIG_I2C_COMPAT 1 +#define CONFIG_KEYBOARD_OPENCORES_MODULE 1 +#define CONFIG_USB_GSPCA_SPCA500_MODULE 1 +#define CONFIG_OCFS2_FS_STATS 1 +#define CONFIG_MSDOS_PARTITION 1 +#define CONFIG_PATA_PLATFORM_MODULE 1 +#define CONFIG_BT_HCIUART_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_NEXIO 1 +#define CONFIG_SND_SOC_WM8903_MODULE 1 +#define CONFIG_HAVE_OPROFILE 1 +#define CONFIG_HAVE_GENERIC_DMA_COHERENT 1 +#define CONFIG_CPU_IDLE_GOV_LADDER 1 +#define CONFIG_TOUCHSCREEN_TOUCHRIGHT_MODULE 1 +#define CONFIG_INPUT_POWERMATE_MODULE 1 +#define CONFIG_SND_SOC_WM_HUBS_MODULE 1 +#define CONFIG_DVB_MT312_MODULE 1 +#define CONFIG_HID_PETALYNX_MODULE 1 +#define CONFIG_ATM_LANE_MODULE 1 +#define CONFIG_HAVE_ARCH_KGDB 1 +#define CONFIG_IP_FIB_HASH 1 +#define CONFIG_USB_ARCH_HAS_OHCI 1 +#define CONFIG_NF_CONNTRACK_IPV4_MODULE 1 +#define CONFIG_ZONE_DMA_FLAG 0 +#define CONFIG_B43LEGACY_HWRNG 1 +#define CONFIG_HAVE_AT91_USART4 1 +#define CONFIG_SND_DUMMY_MODULE 1 +#define CONFIG_USB_WUSB_CBAF_MODULE 1 +#define CONFIG_USB_NET_ZAURUS_MODULE 1 +#define CONFIG_INET6_XFRM_TUNNEL_MODULE 1 +#define CONFIG_DM_MULTIPATH_ST_MODULE 1 +#define CONFIG_LEGACY_PTY_COUNT 16 +#define CONFIG_TOUCHSCREEN_USB_DMC_TSC10 1 +#define CONFIG_DVB_ZL10039_MODULE 1 +#define CONFIG_MTD_MAP_BANK_WIDTH_2 1 +#define CONFIG_USB_SERIAL_DEBUG_MODULE 1 +#define CONFIG_TABLET_USB_ACECAD_MODULE 1 +#define CONFIG_VIDEO_MEDIA_MODULE 1 +#define CONFIG_CUSE_MODULE 1 +#define CONFIG_SND_SOC_WM8728_MODULE 1 +#define CONFIG_USB_ZERO_MODULE 1 +#define CONFIG_CRYPTO_RMD256_MODULE 1 +#define CONFIG_DVB_MT352_MODULE 1 +#define CONFIG_SPI_ATMEL 1 +#define CONFIG_MOUSE_APPLETOUCH_MODULE 1 +#define CONFIG_DEFAULT_SECURITY "" +#define CONFIG_TICK_ONESHOT 1 +#define CONFIG_NF_NAT_PROTO_UDPLITE_MODULE 1 +#define CONFIG_USB_SERIAL_SIERRAWIRELESS_MODULE 1 +#define CONFIG_CRYPTO_CTR_MODULE 1 +#define CONFIG_VIDEO_SAA5246A_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE 1 +#define CONFIG_WIRELESS_EXT 1 +#define CONFIG_MEDIA_TUNER_MT2060_MODULE 1 +#define CONFIG_HW_RANDOM 1 +#define CONFIG_DVB_USB_AU6610_MODULE 1 +#define CONFIG_RWSEM_GENERIC_SPINLOCK 1 +#define CONFIG_DEFAULT_NOOP 1 +#define CONFIG_IRTTY_SIR_MODULE 1 +#define CONFIG_NTFS_FS_MODULE 1 +#define CONFIG_RT2X00_LIB_CRYPTO 1 +#define CONFIG_SCSI_DH_HP_SW_MODULE 1 +#define CONFIG_IP_SCTP_MODULE 1 +#define CONFIG_BASE_SMALL 0 +#define CONFIG_CRYPTO_BLKCIPHER2_MODULE 1 +#define CONFIG_SCSI_SAS_ATTRS_MODULE 1 +#define CONFIG_RTL8187_MODULE 1 +#define CONFIG_SND_SEQ_DUMMY_MODULE 1 +#define CONFIG_USB_SERIAL_SIEMENS_MPI_MODULE 1 +#define CONFIG_MD_RAID6_PQ_MODULE 1 +#define CONFIG_USB_GSPCA_SONIXJ_MODULE 1 +#define CONFIG_CRYPTO_KHAZAD_MODULE 1 +#define CONFIG_PROC_FS 1 +#define CONFIG_MTD_BLOCK 1 +#define CONFIG_SND_SOC_WM8523_MODULE 1 +#define CONFIG_RC_MAP_MODULE 1 +#define CONFIG_WEXT_PRIV 1 +#define CONFIG_SCSI_LOWLEVEL 1 +#define CONFIG_ROSE_MODULE 1 +#define CONFIG_INPUT_GPIO_ROTARY_ENCODER_MODULE 1 +#define CONFIG_IP_VS_PROTO_AH_ESP 1 +#define CONFIG_NILFS2_FS_MODULE 1 +#define CONFIG_HID_PANTHERLORD_MODULE 1 +#define CONFIG_SND_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_EVENT 1 +#define CONFIG_FLATMEM 1 +#define CONFIG_NET_SCH_TEQL_MODULE 1 +#define CONFIG_IR_RC6_DECODER_MODULE 1 +#define CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR 0xFF108018 +#define CONFIG_IP_VS_SH_MODULE 1 +#define CONFIG_VIDEO_MSP3400_MODULE 1 +#define CONFIG_USB_TMC_MODULE 1 +#define CONFIG_SND_SOC_L3_MODULE 1 +#define CONFIG_PAGEFLAGS_EXTENDED 1 +#define CONFIG_IKCONFIG_MODULE 1 +#define CONFIG_DVB_STB6000_MODULE 1 +#define CONFIG_LEDS 1 +#define CONFIG_SUSPEND_NVS 1 +#define CONFIG_SYSCTL 1 +#define CONFIG_BRIDGE_IGMP_SNOOPING 1 +#define CONFIG_IP_NF_TARGET_CLUSTERIP_MODULE 1 +#define CONFIG_W1_SLAVE_THERM 1 +#define CONFIG_JOYSTICK_TWIDJOY_MODULE 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA19QI 1 +#define CONFIG_CIFS_MODULE 1 +#define CONFIG_XFRM_USER_MODULE 1 +#define CONFIG_TCP_CONG_BIC_MODULE 1 +#define CONFIG_SCSI_DH_EMC_MODULE 1 +#define CONFIG_USB_SE401_MODULE 1 +#define CONFIG_SND_SOC_WM8988_MODULE 1 +#define CONFIG_HAVE_PERF_EVENTS 1 +#define CONFIG_ATA_SFF 1 +#define CONFIG_JOYSTICK_WALKERA0701_MODULE 1 +#define CONFIG_CRYPTO_LRW_MODULE 1 +#define CONFIG_USB_GSPCA_T613_MODULE 1 +#define CONFIG_SND_SOC_WM8580_MODULE 1 +#define CONFIG_SND_MTPAV_MODULE 1 +#define CONFIG_MD_RAID10_MODULE 1 +#define CONFIG_ATMEL_TCLIB 1 +#define CONFIG_SSB_SDIOHOST_POSSIBLE 1 +#define CONFIG_CRAMFS 1 +#define CONFIG_SLAB 1 +#define CONFIG_KEYBOARD_LM8323_MODULE 1 +#define CONFIG_CHR_DEV_ST_MODULE 1 +#define CONFIG_DM_MULTIPATH_MODULE 1 +#define CONFIG_SYS_SUPPORTS_APM_EMULATION 1 +#define CONFIG_B43LEGACY_MODULE 1 +#define CONFIG_SND_SOC_WM8904_MODULE 1 +#define CONFIG_XENO_OPT_NATIVE_PIPE 1 +#define CONFIG_DVB_USB_A800_MODULE 1 +#define CONFIG_SND_SOC_WM2000_MODULE 1 +#define CONFIG_SND_TIMER_MODULE 1 +#define CONFIG_FAT_DEFAULT_CODEPAGE 437 +#define CONFIG_BLK_DEV 1 +#define CONFIG_USB_SERIAL_MOTOROLA_MODULE 1 +#define CONFIG_MAC80211_RC_DEFAULT "minstrel" +#define CONFIG_XENO_DRIVERS_TIMERBENCH 1 +#define CONFIG_USB_SERIAL_OMNINET_MODULE 1 +#define CONFIG_BRIDGE_NETFILTER 1 +#define CONFIG_TCP_CONG_SCALABLE_MODULE 1 +#define CONFIG_JOYSTICK_TMDC_MODULE 1 +#define CONFIG_TRACING_SUPPORT 1 +#define CONFIG_UNIX98_PTYS 1 +#define CONFIG_NETFILTER_XT_TARGET_CONNMARK_MODULE 1 +#define CONFIG_CRYPTO_MICHAEL_MIC_MODULE 1 +#define CONFIG_CRYPTO_ANSI_CPRNG_MODULE 1 +#define CONFIG_NET_SCHED 1 +#define CONFIG_XENO_OPT_SEM_HEAPSZ 12 +#define CONFIG_JBD 1 +#define CONFIG_DVB_PLL_MODULE 1 +#define CONFIG_VIDEO_SH_MOBILE_CEU_MODULE 1 +#define CONFIG_INPUT_MOUSEDEV_SCREEN_Y 240 +#define CONFIG_NETFILTER_XT_MATCH_QUOTA_MODULE 1 +#define CONFIG_HAVE_KERNEL_LZO 1 +#define CONFIG_ASYNC_CORE_MODULE 1 +#define CONFIG_NET_SCH_MULTIQ_MODULE 1 +#define CONFIG_INET_DIAG 1 +#define CONFIG_CRYPTO_GHASH_MODULE 1 +#define CONFIG_OCFS2_DEBUG_MASKLOG 1 +#define CONFIG_NF_NAT_FTP_MODULE 1 +#define CONFIG_MAC80211_RC_MINSTREL 1 +#define CONFIG_CRYPTO_RMD320_MODULE 1 +#define CONFIG_NF_CT_PROTO_UDPLITE_MODULE 1 +#define CONFIG_IKCONFIG_PROC 1 +#define CONFIG_JOYSTICK_WARRIOR_MODULE 1 +#define CONFIG_ELF_CORE 1 +#define CONFIG_TEXTSEARCH 1 +#define CONFIG_INOTIFY 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA19QW 1 +#define CONFIG_USB_SUPPORT 1 +#define CONFIG_INPUT_POLLDEV_MODULE 1 +#define CONFIG_USB_GSPCA_PAC7311_MODULE 1 +#define CONFIG_RTC_DEBUG 1 +#define CONFIG_MTD_CHAR 1 +#define CONFIG_FLAT_NODE_MEM_MAP 1 +#define CONFIG_ATM_MODULE 1 +#define CONFIG_SCSI_FC_ATTRS_MODULE 1 +#define CONFIG_VT_CONSOLE 1 +#define CONFIG_LEDS_GPIO 1 +#define CONFIG_USB_GSPCA_STK014_MODULE 1 +#define CONFIG_IP_VS_FTP_MODULE 1 +#define CONFIG_CFG80211_WEXT 1 +#define CONFIG_NOP_USB_XCEIV_MODULE 1 +#define CONFIG_FPE_NWFPE 1 +#define CONFIG_XENOMAI 1 +#define CONFIG_DVB_USB_DIBUSB_MB_MODULE 1 +#define CONFIG_BLK_DEV_RAM 1 +#define CONFIG_TOUCHSCREEN_AD7879_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_STATE_MODULE 1 +#define CONFIG_INPUT_EVBUG_MODULE 1 +#define CONFIG_USB_STORAGE_FREECOM_MODULE 1 +#define CONFIG_LCD_VGG2432A4_MODULE 1 +#define CONFIG_TOUCHSCREEN_ADS7846_MODULE 1 +#define CONFIG_IR_RC5_DECODER_MODULE 1 +#define CONFIG_NET_SCH_GRED_MODULE 1 +#define CONFIG_INET6_XFRM_MODE_BEET_MODULE 1 +#define CONFIG_USB_USS720_MODULE 1 +#define CONFIG_LEDS_DAC124S085_MODULE 1 +#define CONFIG_MOUSE_GPIO_MODULE 1 +#define CONFIG_RT73USB_MODULE 1 +#define CONFIG_USB_CYTHERM_MODULE 1 +#define CONFIG_IP6_NF_MATCH_EUI64_MODULE 1 +#define CONFIG_USB_STORAGE_JUMPSHOT_MODULE 1 +#define CONFIG_GENERIC_CLOCKEVENTS_BUILD 1 +#define CONFIG_VIDEOBUF_GEN_MODULE 1 +#define CONFIG_VIDEO_V4L2_MODULE 1 +#define CONFIG_DVB_STV6110_MODULE 1 +#define CONFIG_SYSVIPC_SYSCTL 1 +#define CONFIG_USB_SERIAL_KEYSPAN_USA19 1 +#define CONFIG_HID_NTRIG_MODULE 1 +#define CONFIG_DVB_USB_NOVA_T_USB2_MODULE 1 +#define CONFIG_SND_PORTMAN2X4_MODULE 1 +#define CONFIG_DECOMPRESS_GZIP 1 +#define CONFIG_USB_SERIAL_ARK3116_MODULE 1 +#define CONFIG_QUOTA 1 +#define CONFIG_I2C_CHARDEV 1 +#define CONFIG_LLC_MODULE 1 +#define CONFIG_CROSS_COMPILE "" +#define CONFIG_MEDIA_TUNER_TEA5761_MODULE 1 +#define CONFIG_USB_GADGET_SELECTED 1 +#define CONFIG_IPDDP_MODULE 1 +#define CONFIG_LIB80211_CRYPT_CCMP_MODULE 1 +#define CONFIG_MOUSE_PS2_SYNAPTICS 1 +#define CONFIG_AT91_TIMER_HZ 100 +#define CONFIG_ATA_BMDMA 1 +#define CONFIG_ATALK_MODULE 1 +#define CONFIG_AT91_PMC_UNIT 1 +#define CONFIG_CPU_ABRT_EV5TJ 1 +#define CONFIG_NLS_UTF8 1 +#define CONFIG_JOYSTICK_XPAD_MODULE 1 +#define CONFIG_INPUT_YEALINK_MODULE 1 +#define CONFIG_DVB_DIB3000MB_MODULE 1 +#define CONFIG_XENO_OPT_TIMING_VIRTICK 1000 +#define CONFIG_IWMC3200TOP_MODULE 1 +#define CONFIG_USB_USBNET_MODULE 1 +#define CONFIG_SCSI_MULTI_LUN 1 +#define CONFIG_USB_SERIAL_PL2303_MODULE 1 +#define CONFIG_HAMRADIO 1 +#define CONFIG_DVB_USB_CINERGY_T2_MODULE 1 +#define CONFIG_USB_MICROTEK_MODULE 1 +#define CONFIG_IPIPE_DELAYED_ATOMICSW 1 +#define CONFIG_HID_SMARTJOYPLUS_MODULE 1 +#define CONFIG_NEW_LEDS 1 +#define CONFIG_SWAP 1 +#define CONFIG_NET_SCH_HFSC_MODULE 1 +#define CONFIG_MAC80211_MODULE 1 +#define CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 1 +#define CONFIG_AT91_EARLY_USART0 1 +#define CONFIG_CRC_CCITT_MODULE 1 +#define CONFIG_BLK_DEV_SD 1 +#define CONFIG_NETFILTER_NETLINK_MODULE 1 +#define CONFIG_MODULE_UNLOAD 1 +#define CONFIG_NF_CT_ACCT 1 +#define CONFIG_DVB_USB_CXUSB_MODULE 1 +#define CONFIG_RCU_FANOUT 32 +#define CONFIG_BITREVERSE 1 +#define CONFIG_BLK_DEV_RAM_SIZE 8192 +#define CONFIG_USB_SERIAL_WWAN_MODULE 1 +#define CONFIG_CRYPTO_PCOMP_MODULE 1 +#define CONFIG_VIDEO_V4L2_COMMON_MODULE 1 +#define CONFIG_CRYPTO_BLKCIPHER_MODULE 1 +#define CONFIG_USB_STORAGE_ONETOUCH_MODULE 1 +#define CONFIG_NF_CONNTRACK_MODULE 1 +#define CONFIG_LCD_CLASS_DEVICE_MODULE 1 +#define CONFIG_FILE_LOCKING 1 +#define CONFIG_USB_GSPCA_SN9C20X_MODULE 1 +#define CONFIG_SND_SOC_I2C_AND_SPI_MODULE 1 +#define CONFIG_AIO 1 +#define CONFIG_VIDEO_USBVIDEO_MODULE 1 +#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1 +#define CONFIG_LEDS_CLASS 1 +#define CONFIG_GENERIC_HARDIRQS 1 +#define CONFIG_DVB_USB_DIGITV_MODULE 1 +#define CONFIG_IP6_NF_MATCH_HL_MODULE 1 +#define CONFIG_IP_VS_TAB_BITS 12 +#define CONFIG_IP6_NF_MATCH_OPTS_MODULE 1 +#define CONFIG_SCSI_SAS_HOST_SMP 1 +#define CONFIG_RTC_INTF_DEV 1 +#define CONFIG_MTD_MAP_BANK_WIDTH_4 1 +#define CONFIG_HID_SUPPORT 1 +#define CONFIG_DVB_USB_CE6230_MODULE 1 +#define CONFIG_USB_SERIAL_SYMBOL_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_OSF_MODULE 1 +#define CONFIG_EXT4_FS_XATTR 1 +#define CONFIG_SND_VIRMIDI_MODULE 1 +#define CONFIG_LIB80211_CRYPT_TKIP_MODULE 1 +#define CONFIG_IP_VS_PROTO_UDP 1 +#define CONFIG_NLS_DEFAULT "iso8859-1" +#define CONFIG_NF_CT_PROTO_GRE_MODULE 1 +#define CONFIG_BT_HCIUART_BCSP 1 +#define CONFIG_NF_CT_NETLINK_MODULE 1 +#define CONFIG_AUXDISPLAY 1 +#define CONFIG_P54_SPI_MODULE 1 +#define CONFIG_CRYPTO_AEAD2_MODULE 1 +#define CONFIG_CRYPTO_FCRYPT_MODULE 1 +#define CONFIG_MOUSE_PS2 1 +#define CONFIG_NET_IPIP_MODULE 1 +#define CONFIG_USB_SERIAL_IPAQ_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_HL_MODULE 1 +#define CONFIG_CRYPTO_ALGAPI2_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_LED_MODULE 1 +#define CONFIG_WEXT_SPY 1 +#define CONFIG_ZBOOT_ROM_TEXT 0x0 +#define CONFIG_INPUT 1 +#define CONFIG_IP_NF_MATCH_ADDRTYPE_MODULE 1 +#define CONFIG_PROC_SYSCTL 1 +#define CONFIG_MMU 1 +#define CONFIG_DVB_CX24123_MODULE 1 +#define CONFIG_OCFS2_FS_MODULE 1 +#define CONFIG_TABLET_USB_AIPTEK_MODULE 1 +#define CONFIG_INPUT_ATI_REMOTE_MODULE 1 +#define CONFIG_INLINE_WRITE_UNLOCK 1 diff -urN orig/linux-2.6.35.9//include/generated/compile.h relase/linux-2.6.35.9//include/generated/compile.h --- orig/linux-2.6.35.9//include/generated/compile.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/generated/compile.h 2011-03-15 17:48:55.802032002 +0100 @@ -0,0 +1,8 @@ +/* This file is auto generated, version 2 */ +#define UTS_MACHINE "arm" +#define UTS_VERSION "#2 Tue Mar 15 17:48:55 CET 2011" +#define LINUX_COMPILE_TIME "17:48:55" +#define LINUX_COMPILE_BY "fede" +#define LINUX_COMPILE_HOST "fede-Compaq-Presario-CQ61-Notebook-PC" +#define LINUX_COMPILE_DOMAIN "(none)" +#define LINUX_COMPILER "gcc version 4.3.2 (Debian 4.3.2-1.1) " diff -urN orig/linux-2.6.35.9//include/generated/mach-types.h relase/linux-2.6.35.9//include/generated/mach-types.h --- orig/linux-2.6.35.9//include/generated/mach-types.h 1970-01-01 01:00:00.000000000 +0100 +++ relase/linux-2.6.35.9//include/generated/mach-types.h 2011-03-15 11:08:31.409702442 +0100 @@ -0,0 +1,38166 @@ +/* + * This was automagically generated from arch/arm/tools/mach-types! + * Do NOT edit + */ + +#ifndef __ASM_ARM_MACH_TYPE_H +#define __ASM_ARM_MACH_TYPE_H + +#ifndef __ASSEMBLY__ +/* The type of machine we're running on */ +extern unsigned int __machine_arch_type; +#endif + +/* see arch/arm/kernel/arch.c for a description of these */ +#define MACH_TYPE_EBSA110 0 +#define MACH_TYPE_RISCPC 1 +#define MACH_TYPE_NEXUSPCI 3 +#define MACH_TYPE_EBSA285 4 +#define MACH_TYPE_NETWINDER 5 +#define MACH_TYPE_CATS 6 +#define MACH_TYPE_TBOX 7 +#define MACH_TYPE_CO285 8 +#define MACH_TYPE_CLPS7110 9 +#define MACH_TYPE_ARCHIMEDES 10 +#define MACH_TYPE_A5K 11 +#define MACH_TYPE_ETOILE 12 +#define MACH_TYPE_LACIE_NAS 13 +#define MACH_TYPE_CLPS7500 14 +#define MACH_TYPE_SHARK 15 +#define MACH_TYPE_BRUTUS 16 +#define MACH_TYPE_PERSONAL_SERVER 17 +#define MACH_TYPE_ITSY 18 +#define MACH_TYPE_L7200 19 +#define MACH_TYPE_PLEB 20 +#define MACH_TYPE_INTEGRATOR 21 +#define MACH_TYPE_H3600 22 +#define MACH_TYPE_IXP1200 23 +#define MACH_TYPE_P720T 24 +#define MACH_TYPE_ASSABET 25 +#define MACH_TYPE_VICTOR 26 +#define MACH_TYPE_LART 27 +#define MACH_TYPE_RANGER 28 +#define MACH_TYPE_GRAPHICSCLIENT 29 +#define MACH_TYPE_XP860 30 +#define MACH_TYPE_CERF 31 +#define MACH_TYPE_NANOENGINE 32 +#define MACH_TYPE_FPIC 33 +#define MACH_TYPE_EXTENEX1 34 +#define MACH_TYPE_SHERMAN 35 +#define MACH_TYPE_ACCELENT_SA 36 +#define MACH_TYPE_ACCELENT_L7200 37 +#define MACH_TYPE_NETPORT 38 +#define MACH_TYPE_PANGOLIN 39 +#define MACH_TYPE_YOPY 40 +#define MACH_TYPE_COOLIDGE 41 +#define MACH_TYPE_HUW_WEBPANEL 42 +#define MACH_TYPE_SPOTME 43 +#define MACH_TYPE_FREEBIRD 44 +#define MACH_TYPE_TI925 45 +#define MACH_TYPE_RISCSTATION 46 +#define MACH_TYPE_CAVY 47 +#define MACH_TYPE_JORNADA720 48 +#define MACH_TYPE_OMNIMETER 49 +#define MACH_TYPE_EDB7211 50 +#define MACH_TYPE_CITYGO 51 +#define MACH_TYPE_PFS168 52 +#define MACH_TYPE_SPOT 53 +#define MACH_TYPE_FLEXANET 54 +#define MACH_TYPE_WEBPAL 55 +#define MACH_TYPE_LINPDA 56 +#define MACH_TYPE_ANAKIN 57 +#define MACH_TYPE_MVI 58 +#define MACH_TYPE_JUPITER 59 +#define MACH_TYPE_PSIONW 60 +#define MACH_TYPE_ALN 61 +#define MACH_TYPE_CAMELOT 62 +#define MACH_TYPE_GDS2200 63 +#define MACH_TYPE_PSION_SERIES7 64 +#define MACH_TYPE_XFILE 65 +#define MACH_TYPE_ACCELENT_EP9312 66 +#define MACH_TYPE_IC200 67 +#define MACH_TYPE_CREDITLART 68 +#define MACH_TYPE_HTM 69 +#define MACH_TYPE_IQ80310 70 +#define MACH_TYPE_FREEBOT 71 +#define MACH_TYPE_ENTEL 72 +#define MACH_TYPE_ENP3510 73 +#define MACH_TYPE_TRIZEPS 74 +#define MACH_TYPE_NESA 75 +#define MACH_TYPE_VENUS 76 +#define MACH_TYPE_TARDIS 77 +#define MACH_TYPE_MERCURY 78 +#define MACH_TYPE_EMPEG 79 +#define MACH_TYPE_I80200FCC 80 +#define MACH_TYPE_ITT_CPB 81 +#define MACH_TYPE_SVC 82 +#define MACH_TYPE_ALPHA2 84 +#define MACH_TYPE_ALPHA1 85 +#define MACH_TYPE_NETARM 86 +#define MACH_TYPE_SIMPAD 87 +#define MACH_TYPE_PDA1 88 +#define MACH_TYPE_LUBBOCK 89 +#define MACH_TYPE_ANIKO 90 +#define MACH_TYPE_CLEP7212 91 +#define MACH_TYPE_CS89712 92 +#define MACH_TYPE_WEARARM 93 +#define MACH_TYPE_POSSIO_PX 94 +#define MACH_TYPE_SIDEARM 95 +#define MACH_TYPE_STORK 96 +#define MACH_TYPE_SHANNON 97 +#define MACH_TYPE_ACE 98 +#define MACH_TYPE_BALLYARM 99 +#define MACH_TYPE_SIMPUTER 100 +#define MACH_TYPE_NEXTERM 101 +#define MACH_TYPE_SA1100_ELF 102 +#define MACH_TYPE_GATOR 103 +#define MACH_TYPE_GRANITE 104 +#define MACH_TYPE_CONSUS 105 +#define MACH_TYPE_AAED2000 106 +#define MACH_TYPE_CDB89712 107 +#define MACH_TYPE_GRAPHICSMASTER 108 +#define MACH_TYPE_ADSBITSY 109 +#define MACH_TYPE_PXA_IDP 110 +#define MACH_TYPE_PLCE 111 +#define MACH_TYPE_PT_SYSTEM3 112 +#define MACH_TYPE_MEDALB 113 +#define MACH_TYPE_EAGLE 114 +#define MACH_TYPE_DSC21 115 +#define MACH_TYPE_DSC24 116 +#define MACH_TYPE_TI5472 117 +#define MACH_TYPE_AUTCPU12 118 +#define MACH_TYPE_UENGINE 119 +#define MACH_TYPE_BLUESTEM 120 +#define MACH_TYPE_XINGU8 121 +#define MACH_TYPE_BUSHSTB 122 +#define MACH_TYPE_EPSILON1 123 +#define MACH_TYPE_BALLOON 124 +#define MACH_TYPE_PUPPY 125 +#define MACH_TYPE_ELROY 126 +#define MACH_TYPE_GMS720 127 +#define MACH_TYPE_S24X 128 +#define MACH_TYPE_JTEL_CLEP7312 129 +#define MACH_TYPE_CX821XX 130 +#define MACH_TYPE_EDB7312 131 +#define MACH_TYPE_BSA1110 132 +#define MACH_TYPE_POWERPIN 133 +#define MACH_TYPE_OPENARM 134 +#define MACH_TYPE_WHITECHAPEL 135 +#define MACH_TYPE_H3100 136 +#define MACH_TYPE_H3800 137 +#define MACH_TYPE_BLUE_V1 138 +#define MACH_TYPE_PXA_CERF 139 +#define MACH_TYPE_ARM7TEVB 140 +#define MACH_TYPE_D7400 141 +#define MACH_TYPE_PIRANHA 142 +#define MACH_TYPE_SBCAMELOT 143 +#define MACH_TYPE_KINGS 144 +#define MACH_TYPE_SMDK2400 145 +#define MACH_TYPE_COLLIE 146 +#define MACH_TYPE_IDR 147 +#define MACH_TYPE_BADGE4 148 +#define MACH_TYPE_WEBNET 149 +#define MACH_TYPE_D7300 150 +#define MACH_TYPE_CEP 151 +#define MACH_TYPE_FORTUNET 152 +#define MACH_TYPE_VC547X 153 +#define MACH_TYPE_FILEWALKER 154 +#define MACH_TYPE_NETGATEWAY 155 +#define MACH_TYPE_SYMBOL2800 156 +#define MACH_TYPE_SUNS 157 +#define MACH_TYPE_FRODO 158 +#define MACH_TYPE_MACH_TYTE_MS301 159 +#define MACH_TYPE_MX1ADS 160 +#define MACH_TYPE_H7201 161 +#define MACH_TYPE_H7202 162 +#define MACH_TYPE_AMICO 163 +#define MACH_TYPE_IAM 164 +#define MACH_TYPE_TT530 165 +#define MACH_TYPE_SAM2400 166 +#define MACH_TYPE_JORNADA56X 167 +#define MACH_TYPE_ACTIVE 168 +#define MACH_TYPE_IQ80321 169 +#define MACH_TYPE_WID 170 +#define MACH_TYPE_SABINAL 171 +#define MACH_TYPE_IXP425_MATACUMBE 172 +#define MACH_TYPE_MINIPRINT 173 +#define MACH_TYPE_ADM510X 174 +#define MACH_TYPE_SVS200 175 +#define MACH_TYPE_ATG_TCU 176 +#define MACH_TYPE_JORNADA820 177 +#define MACH_TYPE_S3C44B0 178 +#define MACH_TYPE_MARGIS2 179 +#define MACH_TYPE_KS8695 180 +#define MACH_TYPE_BRH 181 +#define MACH_TYPE_S3C2410 182 +#define MACH_TYPE_POSSIO_PX30 183 +#define MACH_TYPE_S3C2800 184 +#define MACH_TYPE_FLEETWOOD 185 +#define MACH_TYPE_OMAHA 186 +#define MACH_TYPE_TA7 187 +#define MACH_TYPE_NOVA 188 +#define MACH_TYPE_HMK 189 +#define MACH_TYPE_KARO 190 +#define MACH_TYPE_FESTER 191 +#define MACH_TYPE_GPI 192 +#define MACH_TYPE_SMDK2410 193 +#define MACH_TYPE_I519 194 +#define MACH_TYPE_NEXIO 195 +#define MACH_TYPE_BITBOX 196 +#define MACH_TYPE_G200 197 +#define MACH_TYPE_GILL 198 +#define MACH_TYPE_PXA_MERCURY 199 +#define MACH_TYPE_CEIVA 200 +#define MACH_TYPE_FRET 201 +#define MACH_TYPE_EMAILPHONE 202 +#define MACH_TYPE_H3900 203 +#define MACH_TYPE_PXA1 204 +#define MACH_TYPE_KOAN369 205 +#define MACH_TYPE_COGENT 206 +#define MACH_TYPE_ESL_SIMPUTER 207 +#define MACH_TYPE_ESL_SIMPUTER_CLR 208 +#define MACH_TYPE_ESL_SIMPUTER_BW 209 +#define MACH_TYPE_HHP_CRADLE 210 +#define MACH_TYPE_HE500 211 +#define MACH_TYPE_INHANDELF2 212 +#define MACH_TYPE_INHANDFTIP 213 +#define MACH_TYPE_DNP1110 214 +#define MACH_TYPE_PNP1110 215 +#define MACH_TYPE_CSB226 216 +#define MACH_TYPE_ARNOLD 217 +#define MACH_TYPE_VOICEBLUE 218 +#define MACH_TYPE_JZ8028 219 +#define MACH_TYPE_H5400 220 +#define MACH_TYPE_FORTE 221 +#define MACH_TYPE_ACAM 222 +#define MACH_TYPE_ABOX 223 +#define MACH_TYPE_ATMEL 224 +#define MACH_TYPE_SITSANG 225 +#define MACH_TYPE_CPU1110LCDNET 226 +#define MACH_TYPE_MPL_VCMA9 227 +#define MACH_TYPE_OPUS_A1 228 +#define MACH_TYPE_DAYTONA 229 +#define MACH_TYPE_KILLBEAR 230 +#define MACH_TYPE_YOHO 231 +#define MACH_TYPE_JASPER 232 +#define MACH_TYPE_DSC25 233 +#define MACH_TYPE_OMAP_INNOVATOR 234 +#define MACH_TYPE_RAMSES 235 +#define MACH_TYPE_S28X 236 +#define MACH_TYPE_MPORT3 237 +#define MACH_TYPE_PXA_EAGLE250 238 +#define MACH_TYPE_PDB 239 +#define MACH_TYPE_BLUE_2G 240 +#define MACH_TYPE_BLUEARCH 241 +#define MACH_TYPE_IXDP2400 242 +#define MACH_TYPE_IXDP2800 243 +#define MACH_TYPE_EXPLORER 244 +#define MACH_TYPE_IXDP425 245 +#define MACH_TYPE_CHIMP 246 +#define MACH_TYPE_STORK_NEST 247 +#define MACH_TYPE_STORK_EGG 248 +#define MACH_TYPE_WISMO 249 +#define MACH_TYPE_EZLINX 250 +#define MACH_TYPE_AT91RM9200 251 +#define MACH_TYPE_ADTECH_ORION 252 +#define MACH_TYPE_NEPTUNE 253 +#define MACH_TYPE_HACKKIT 254 +#define MACH_TYPE_PXA_WINS30 255 +#define MACH_TYPE_LAVINNA 256 +#define MACH_TYPE_PXA_UENGINE 257 +#define MACH_TYPE_INNOKOM 258 +#define MACH_TYPE_BMS 259 +#define MACH_TYPE_IXCDP1100 260 +#define MACH_TYPE_PRPMC1100 261 +#define MACH_TYPE_AT91RM9200DK 262 +#define MACH_TYPE_ARMSTICK 263 +#define MACH_TYPE_ARMONIE 264 +#define MACH_TYPE_MPORT1 265 +#define MACH_TYPE_S3C5410 266 +#define MACH_TYPE_ZCP320A 267 +#define MACH_TYPE_I_BOX 268 +#define MACH_TYPE_STLC1502 269 +#define MACH_TYPE_SIREN 270 +#define MACH_TYPE_GREENLAKE 271 +#define MACH_TYPE_ARGUS 272 +#define MACH_TYPE_COMBADGE 273 +#define MACH_TYPE_ROKEPXA 274 +#define MACH_TYPE_CINTEGRATOR 275 +#define MACH_TYPE_GUIDEA07 276 +#define MACH_TYPE_TAT257 277 +#define MACH_TYPE_IGP2425 278 +#define MACH_TYPE_BLUEGRAMMA 279 +#define MACH_TYPE_IPOD 280 +#define MACH_TYPE_ADSBITSYX 281 +#define MACH_TYPE_TRIZEPS2 282 +#define MACH_TYPE_VIPER 283 +#define MACH_TYPE_ADSBITSYPLUS 284 +#define MACH_TYPE_ADSAGC 285 +#define MACH_TYPE_STP7312 286 +#define MACH_TYPE_NX_PHNX 287 +#define MACH_TYPE_WEP_EP250 288 +#define MACH_TYPE_INHANDELF3 289 +#define MACH_TYPE_ADI_COYOTE 290 +#define MACH_TYPE_IYONIX 291 +#define MACH_TYPE_DAMICAM_SA1110 292 +#define MACH_TYPE_MEG03 293 +#define MACH_TYPE_PXA_WHITECHAPEL 294 +#define MACH_TYPE_NWSC 295 +#define MACH_TYPE_NWLARM 296 +#define MACH_TYPE_IXP425_MGUARD 297 +#define MACH_TYPE_PXA_NETDCU4 298 +#define MACH_TYPE_IXDP2401 299 +#define MACH_TYPE_IXDP2801 300 +#define MACH_TYPE_ZODIAC 301 +#define MACH_TYPE_ARMMODUL 302 +#define MACH_TYPE_KETOP 303 +#define MACH_TYPE_AV7200 304 +#define MACH_TYPE_ARCH_TI925 305 +#define MACH_TYPE_ACQ200 306 +#define MACH_TYPE_PT_DAFIT 307 +#define MACH_TYPE_IHBA 308 +#define MACH_TYPE_QUINQUE 309 +#define MACH_TYPE_NIMBRAONE 310 +#define MACH_TYPE_NIMBRA29X 311 +#define MACH_TYPE_NIMBRA210 312 +#define MACH_TYPE_HHP_D95XX 313 +#define MACH_TYPE_LABARM 314 +#define MACH_TYPE_M825XX 315 +#define MACH_TYPE_M7100 316 +#define MACH_TYPE_NIPC2 317 +#define MACH_TYPE_FU7202 318 +#define MACH_TYPE_ADSAGX 319 +#define MACH_TYPE_PXA_POOH 320 +#define MACH_TYPE_BANDON 321 +#define MACH_TYPE_PCM7210 322 +#define MACH_TYPE_NMS9200 323 +#define MACH_TYPE_LOGODL 324 +#define MACH_TYPE_M7140 325 +#define MACH_TYPE_KOREBOT 326 +#define MACH_TYPE_IQ31244 327 +#define MACH_TYPE_KOAN393 328 +#define MACH_TYPE_INHANDFTIP3 329 +#define MACH_TYPE_GONZO 330 +#define MACH_TYPE_BAST 331 +#define MACH_TYPE_SCANPASS 332 +#define MACH_TYPE_EP7312_POOH 333 +#define MACH_TYPE_TA7S 334 +#define MACH_TYPE_TA7V 335 +#define MACH_TYPE_ICARUS 336 +#define MACH_TYPE_H1900 337 +#define MACH_TYPE_GEMINI 338 +#define MACH_TYPE_AXIM 339 +#define MACH_TYPE_AUDIOTRON 340 +#define MACH_TYPE_H2200 341 +#define MACH_TYPE_LOOX600 342 +#define MACH_TYPE_NIOP 343 +#define MACH_TYPE_DM310 344 +#define MACH_TYPE_SEEDPXA_C2 345 +#define MACH_TYPE_IXP4XX_MGUARD_PCI 346 +#define MACH_TYPE_H1940 347 +#define MACH_TYPE_SCORPIO 348 +#define MACH_TYPE_VIVA 349 +#define MACH_TYPE_PXA_XCARD 350 +#define MACH_TYPE_CSB335 351 +#define MACH_TYPE_IXRD425 352 +#define MACH_TYPE_IQ80315 353 +#define MACH_TYPE_NMP7312 354 +#define MACH_TYPE_CX861XX 355 +#define MACH_TYPE_ENP2611 356 +#define MACH_TYPE_XDA 357 +#define MACH_TYPE_CSIR_IMS 358 +#define MACH_TYPE_IXP421_DNAEETH 359 +#define MACH_TYPE_POCKETSERV9200 360 +#define MACH_TYPE_TOTO 361 +#define MACH_TYPE_S3C2440 362 +#define MACH_TYPE_KS8695P 363 +#define MACH_TYPE_SE4000 364 +#define MACH_TYPE_QUADRICEPS 365 +#define MACH_TYPE_BRONCO 366 +#define MACH_TYPE_ESL_WIRELESS_TAB 367 +#define MACH_TYPE_ESL_SOFCOMP 368 +#define MACH_TYPE_S5C7375 369 +#define MACH_TYPE_SPEARHEAD 370 +#define MACH_TYPE_PANTERA 371 +#define MACH_TYPE_PRAYOGLITE 372 +#define MACH_TYPE_GUMSTIX 373 +#define MACH_TYPE_RCUBE 374 +#define MACH_TYPE_REA_OLV 375 +#define MACH_TYPE_PXA_IPHONE 376 +#define MACH_TYPE_S3C3410 377 +#define MACH_TYPE_ESPD_4510B 378 +#define MACH_TYPE_MP1X 379 +#define MACH_TYPE_AT91RM9200TB 380 +#define MACH_TYPE_ADSVGX 381 +#define MACH_TYPE_OMAP_H2 382 +#define MACH_TYPE_PELEE 383 +#define MACH_TYPE_E740 384 +#define MACH_TYPE_IQ80331 385 +#define MACH_TYPE_VERSATILE_PB 387 +#define MACH_TYPE_KEV7A400 388 +#define MACH_TYPE_LPD7A400 389 +#define MACH_TYPE_LPD7A404 390 +#define MACH_TYPE_FUJITSU_CAMELOT 391 +#define MACH_TYPE_JANUS2M 392 +#define MACH_TYPE_EMBTF 393 +#define MACH_TYPE_HPM 394 +#define MACH_TYPE_SMDK2410TK 395 +#define MACH_TYPE_SMDK2410AJ 396 +#define MACH_TYPE_STREETRACER 397 +#define MACH_TYPE_EFRAME 398 +#define MACH_TYPE_CSB337 399 +#define MACH_TYPE_PXA_LARK 400 +#define MACH_TYPE_PNP2110 401 +#define MACH_TYPE_TCC72X 402 +#define MACH_TYPE_ALTAIR 403 +#define MACH_TYPE_KC3 404 +#define MACH_TYPE_SINTEFTD 405 +#define MACH_TYPE_MAINSTONE 406 +#define MACH_TYPE_ADAY4X 407 +#define MACH_TYPE_LITE300 408 +#define MACH_TYPE_S5C7376 409 +#define MACH_TYPE_MT02 410 +#define MACH_TYPE_MPORT3S 411 +#define MACH_TYPE_RA_ALPHA 412 +#define MACH_TYPE_XCEP 413 +#define MACH_TYPE_ARCOM_VULCAN 414 +#define MACH_TYPE_STARGATE 415 +#define MACH_TYPE_ARMADILLOJ 416 +#define MACH_TYPE_ELROY_JACK 417 +#define MACH_TYPE_BACKEND 418 +#define MACH_TYPE_S5LINBOX 419 +#define MACH_TYPE_NOMADIK 420 +#define MACH_TYPE_IA_CPU_9200 421 +#define MACH_TYPE_AT91_BJA1 422 +#define MACH_TYPE_CORGI 423 +#define MACH_TYPE_POODLE 424 +#define MACH_TYPE_TEN 425 +#define MACH_TYPE_ROVERP5P 426 +#define MACH_TYPE_SC2700 427 +#define MACH_TYPE_EX_EAGLE 428 +#define MACH_TYPE_NX_PXA12 429 +#define MACH_TYPE_NX_PXA5 430 +#define MACH_TYPE_BLACKBOARD2 431 +#define MACH_TYPE_I819 432 +#define MACH_TYPE_IXMB995E 433 +#define MACH_TYPE_SKYRIDER 434 +#define MACH_TYPE_SKYHAWK 435 +#define MACH_TYPE_ENTERPRISE 436 +#define MACH_TYPE_DEP2410 437 +#define MACH_TYPE_ARMCORE 438 +#define MACH_TYPE_HOBBIT 439 +#define MACH_TYPE_H7210 440 +#define MACH_TYPE_PXA_NETDCU5 441 +#define MACH_TYPE_ACC 442 +#define MACH_TYPE_ESL_SARVA 443 +#define MACH_TYPE_XM250 444 +#define MACH_TYPE_T6TC1XB 445 +#define MACH_TYPE_ESS710 446 +#define MACH_TYPE_MX31ADS 447 +#define MACH_TYPE_HIMALAYA 448 +#define MACH_TYPE_BOLFENK 449 +#define MACH_TYPE_AT91RM9200KR 450 +#define MACH_TYPE_EDB9312 451 +#define MACH_TYPE_OMAP_GENERIC 452 +#define MACH_TYPE_AXIMX3 453 +#define MACH_TYPE_EB67XDIP 454 +#define MACH_TYPE_WEBTXS 455 +#define MACH_TYPE_HAWK 456 +#define MACH_TYPE_CCAT91SBC001 457 +#define MACH_TYPE_EXPRESSO 458 +#define MACH_TYPE_H4000 459 +#define MACH_TYPE_DINO 460 +#define MACH_TYPE_ML675K 461 +#define MACH_TYPE_EDB9301 462 +#define MACH_TYPE_EDB9315 463 +#define MACH_TYPE_RECIVA_TT 464 +#define MACH_TYPE_CSTCB01 465 +#define MACH_TYPE_CSTCB1 466 +#define MACH_TYPE_SHADWELL 467 +#define MACH_TYPE_GOEPEL263 468 +#define MACH_TYPE_ACQ100 469 +#define MACH_TYPE_MX1FS2 470 +#define MACH_TYPE_HIPTOP_G1 471 +#define MACH_TYPE_SPARKY 472 +#define MACH_TYPE_NS9750 473 +#define MACH_TYPE_PHOENIX 474 +#define MACH_TYPE_VR1000 475 +#define MACH_TYPE_DEISTERPXA 476 +#define MACH_TYPE_BCM1160 477 +#define MACH_TYPE_PCM022 478 +#define MACH_TYPE_ADSGCX 479 +#define MACH_TYPE_DREADNAUGHT 480 +#define MACH_TYPE_DM320 481 +#define MACH_TYPE_MARKOV 482 +#define MACH_TYPE_COS7A400 483 +#define MACH_TYPE_MILANO 484 +#define MACH_TYPE_UE9328 485 +#define MACH_TYPE_UEX255 486 +#define MACH_TYPE_UE2410 487 +#define MACH_TYPE_A620 488 +#define MACH_TYPE_OCELOT 489 +#define MACH_TYPE_CHEETAH 490 +#define MACH_TYPE_OMAP_PERSEUS2 491 +#define MACH_TYPE_ZVUE 492 +#define MACH_TYPE_ROVERP1 493 +#define MACH_TYPE_ASIDIAL2 494 +#define MACH_TYPE_S3C24A0 495 +#define MACH_TYPE_E800 496 +#define MACH_TYPE_E750 497 +#define MACH_TYPE_S3C5500 498 +#define MACH_TYPE_SMDK5500 499 +#define MACH_TYPE_SIGNALSYNC 500 +#define MACH_TYPE_NBC 501 +#define MACH_TYPE_KODIAK 502 +#define MACH_TYPE_NETBOOKPRO 503 +#define MACH_TYPE_HW90200 504 +#define MACH_TYPE_CONDOR 505 +#define MACH_TYPE_CUP 506 +#define MACH_TYPE_KITE 507 +#define MACH_TYPE_SCB9328 508 +#define MACH_TYPE_OMAP_H3 509 +#define MACH_TYPE_OMAP_H4 510 +#define MACH_TYPE_N10 511 +#define MACH_TYPE_MONTAJADE 512 +#define MACH_TYPE_SG560 513 +#define MACH_TYPE_DP1000 514 +#define MACH_TYPE_OMAP_OSK 515 +#define MACH_TYPE_RG100V3 516 +#define MACH_TYPE_MX2ADS 517 +#define MACH_TYPE_PXA_KILO 518 +#define MACH_TYPE_IXP4XX_EAGLE 519 +#define MACH_TYPE_TOSA 520 +#define MACH_TYPE_MB2520F 521 +#define MACH_TYPE_EMC1000 522 +#define MACH_TYPE_TIDSC25 523 +#define MACH_TYPE_AKCPMXL 524 +#define MACH_TYPE_AV3XX 525 +#define MACH_TYPE_AVILA 526 +#define MACH_TYPE_PXA_MPM10 527 +#define MACH_TYPE_PXA_KYANITE 528 +#define MACH_TYPE_SGOLD 529 +#define MACH_TYPE_OSCAR 530 +#define MACH_TYPE_EPXA4USB2 531 +#define MACH_TYPE_XSENGINE 532 +#define MACH_TYPE_IP600 533 +#define MACH_TYPE_MCAN2 534 +#define MACH_TYPE_DDI_BLUERIDGE 535 +#define MACH_TYPE_SKYMINDER 536 +#define MACH_TYPE_LPD79520 537 +#define MACH_TYPE_EDB9302 538 +#define MACH_TYPE_HW90340 539 +#define MACH_TYPE_CIP_BOX 540 +#define MACH_TYPE_IVPN 541 +#define MACH_TYPE_RSOC2 542 +#define MACH_TYPE_HUSKY 543 +#define MACH_TYPE_BOXER 544 +#define MACH_TYPE_SHEPHERD 545 +#define MACH_TYPE_AML42800AA 546 +#define MACH_TYPE_LPC2294 548 +#define MACH_TYPE_SWITCHGRASS 549 +#define MACH_TYPE_ENS_CMU 550 +#define MACH_TYPE_MM6_SDB 551 +#define MACH_TYPE_SATURN 552 +#define MACH_TYPE_I30030EVB 553 +#define MACH_TYPE_MXC27530EVB 554 +#define MACH_TYPE_SMDK2800 555 +#define MACH_TYPE_MTWILSON 556 +#define MACH_TYPE_ZITI 557 +#define MACH_TYPE_GRANDFATHER 558 +#define MACH_TYPE_TENGINE 559 +#define MACH_TYPE_S3C2460 560 +#define MACH_TYPE_PDM 561 +#define MACH_TYPE_H4700 562 +#define MACH_TYPE_H6300 563 +#define MACH_TYPE_RZ1700 564 +#define MACH_TYPE_A716 565 +#define MACH_TYPE_ESTK2440A 566 +#define MACH_TYPE_ATWIXP425 567 +#define MACH_TYPE_CSB336 568 +#define MACH_TYPE_RIRM2 569 +#define MACH_TYPE_CX23518 570 +#define MACH_TYPE_CX2351X 571 +#define MACH_TYPE_COMPUTIME 572 +#define MACH_TYPE_IZARUS 573 +#define MACH_TYPE_RTS 574 +#define MACH_TYPE_SE5100 575 +#define MACH_TYPE_S3C2510 576 +#define MACH_TYPE_CSB437TL 577 +#define MACH_TYPE_SLAUSON 578 +#define MACH_TYPE_PEARLRIVER 579 +#define MACH_TYPE_TDC_P210 580 +#define MACH_TYPE_SG580 581 +#define MACH_TYPE_WRSBCARM7 582 +#define MACH_TYPE_IPD 583 +#define MACH_TYPE_PXA_DNP2110 584 +#define MACH_TYPE_XAENIAX 585 +#define MACH_TYPE_SOMN4250 586 +#define MACH_TYPE_PLEB2 587 +#define MACH_TYPE_CORNWALLIS 588 +#define MACH_TYPE_GURNEY_DRV 589 +#define MACH_TYPE_CHAFFEE 590 +#define MACH_TYPE_RMS101 591 +#define MACH_TYPE_RX3715 592 +#define MACH_TYPE_SWIFT 593 +#define MACH_TYPE_ROVERP7 594 +#define MACH_TYPE_PR818S 595 +#define MACH_TYPE_TRXPRO 596 +#define MACH_TYPE_NSLU2 597 +#define MACH_TYPE_E400 598 +#define MACH_TYPE_TRAB 599 +#define MACH_TYPE_CMC_PU2 600 +#define MACH_TYPE_FULCRUM 601 +#define MACH_TYPE_NETGATE42X 602 +#define MACH_TYPE_STR710 603 +#define MACH_TYPE_IXDPG425 604 +#define MACH_TYPE_TOMTOMGO 605 +#define MACH_TYPE_VERSATILE_AB 606 +#define MACH_TYPE_EDB9307 607 +#define MACH_TYPE_SG565 608 +#define MACH_TYPE_LPD79524 609 +#define MACH_TYPE_LPD79525 610 +#define MACH_TYPE_RMS100 611 +#define MACH_TYPE_KB9200 612 +#define MACH_TYPE_SX1 613 +#define MACH_TYPE_HMS39C7092 614 +#define MACH_TYPE_ARMADILLO 615 +#define MACH_TYPE_IPCU 616 +#define MACH_TYPE_LOOX720 617 +#define MACH_TYPE_IXDP465 618 +#define MACH_TYPE_IXDP2351 619 +#define MACH_TYPE_ADSVIX 620 +#define MACH_TYPE_DM270 621 +#define MACH_TYPE_SOCLTPLUS 622 +#define MACH_TYPE_ECIA 623 +#define MACH_TYPE_CM4008 624 +#define MACH_TYPE_P2001 625 +#define MACH_TYPE_TWISTER 626 +#define MACH_TYPE_MUDSHARK 627 +#define MACH_TYPE_HB2 628 +#define MACH_TYPE_IQ80332 629 +#define MACH_TYPE_SENDT 630 +#define MACH_TYPE_MX2JAZZ 631 +#define MACH_TYPE_MULTIIO 632 +#define MACH_TYPE_HRDISPLAY 633 +#define MACH_TYPE_MXC27530ADS 634 +#define MACH_TYPE_TRIZEPS3 635 +#define MACH_TYPE_ZEFEERDZA 636 +#define MACH_TYPE_ZEFEERDZB 637 +#define MACH_TYPE_ZEFEERDZG 638 +#define MACH_TYPE_ZEFEERDZN 639 +#define MACH_TYPE_ZEFEERDZQ 640 +#define MACH_TYPE_GTWX5715 641 +#define MACH_TYPE_ASTRO_JACK 643 +#define MACH_TYPE_TIP03 644 +#define MACH_TYPE_A9200EC 645 +#define MACH_TYPE_PNX0105 646 +#define MACH_TYPE_ADCPOECPU 647 +#define MACH_TYPE_CSB637 648 +#define MACH_TYPE_MB9200 650 +#define MACH_TYPE_KULUN 651 +#define MACH_TYPE_SNAPPER 652 +#define MACH_TYPE_OPTIMA 653 +#define MACH_TYPE_DLHSBC 654 +#define MACH_TYPE_X30 655 +#define MACH_TYPE_N30 656 +#define MACH_TYPE_MANGA_KS8695 657 +#define MACH_TYPE_AJAX 658 +#define MACH_TYPE_NEC_MP900 659 +#define MACH_TYPE_VVTK1000 661 +#define MACH_TYPE_KAFA 662 +#define MACH_TYPE_VVTK3000 663 +#define MACH_TYPE_PIMX1 664 +#define MACH_TYPE_OLLIE 665 +#define MACH_TYPE_SKYMAX 666 +#define MACH_TYPE_JAZZ 667 +#define MACH_TYPE_TEL_T3 668 +#define MACH_TYPE_AISINO_FCR255 669 +#define MACH_TYPE_BTWEB 670 +#define MACH_TYPE_DBG_LH79520 671 +#define MACH_TYPE_CM41XX 672 +#define MACH_TYPE_TS72XX 673 +#define MACH_TYPE_NGGPXA 674 +#define MACH_TYPE_CSB535 675 +#define MACH_TYPE_CSB536 676 +#define MACH_TYPE_PXA_TRAKPOD 677 +#define MACH_TYPE_PRAXIS 678 +#define MACH_TYPE_LH75411 679 +#define MACH_TYPE_OTOM 680 +#define MACH_TYPE_NEXCODER_2440 681 +#define MACH_TYPE_LOOX410 682 +#define MACH_TYPE_WESTLAKE 683 +#define MACH_TYPE_NSB 684 +#define MACH_TYPE_ESL_SARVA_STN 685 +#define MACH_TYPE_ESL_SARVA_TFT 686 +#define MACH_TYPE_ESL_SARVA_IAD 687 +#define MACH_TYPE_ESL_SARVA_ACC 688 +#define MACH_TYPE_TYPHOON 689 +#define MACH_TYPE_CNAV 690 +#define MACH_TYPE_A730 691 +#define MACH_TYPE_NETSTAR 692 +#define MACH_TYPE_PHASEFALE_SUPERCON 693 +#define MACH_TYPE_SHIVA1100 694 +#define MACH_TYPE_ETEXSC 695 +#define MACH_TYPE_IXDPG465 696 +#define MACH_TYPE_A9M2410 697 +#define MACH_TYPE_A9M2440 698 +#define MACH_TYPE_A9M9750 699 +#define MACH_TYPE_A9M9360 700 +#define MACH_TYPE_UNC90 701 +#define MACH_TYPE_ECO920 702 +#define MACH_TYPE_SATVIEW 703 +#define MACH_TYPE_ROADRUNNER 704 +#define MACH_TYPE_AT91RM9200EK 705 +#define MACH_TYPE_GP32 706 +#define MACH_TYPE_GEM 707 +#define MACH_TYPE_I858 708 +#define MACH_TYPE_HX2750 709 +#define MACH_TYPE_MXC91131EVB 710 +#define MACH_TYPE_P700 711 +#define MACH_TYPE_CPE 712 +#define MACH_TYPE_SPITZ 713 +#define MACH_TYPE_NIMBRA340 714 +#define MACH_TYPE_LPC22XX 715 +#define MACH_TYPE_COMET3 716 +#define MACH_TYPE_COMET4 717 +#define MACH_TYPE_CSB625 718 +#define MACH_TYPE_FORTUNET2 719 +#define MACH_TYPE_S5H2200 720 +#define MACH_TYPE_OPTORM920 721 +#define MACH_TYPE_ADSBITSYXB 722 +#define MACH_TYPE_ADSSPHERE 723 +#define MACH_TYPE_ADSPORTAL 724 +#define MACH_TYPE_LN2410SBC 725 +#define MACH_TYPE_CB3RUFC 726 +#define MACH_TYPE_MP2USB 727 +#define MACH_TYPE_NTNP425C 728 +#define MACH_TYPE_COLIBRI 729 +#define MACH_TYPE_PCM7220 730 +#define MACH_TYPE_GATEWAY7001 731 +#define MACH_TYPE_PCM027 732 +#define MACH_TYPE_CMPXA 733 +#define MACH_TYPE_ANUBIS 734 +#define MACH_TYPE_ITE8152 735 +#define MACH_TYPE_LPC3XXX 736 +#define MACH_TYPE_PUPPETEER 737 +#define MACH_TYPE_E570 739 +#define MACH_TYPE_X50 740 +#define MACH_TYPE_RECON 741 +#define MACH_TYPE_XBOARDGP8 742 +#define MACH_TYPE_FPIC2 743 +#define MACH_TYPE_AKITA 744 +#define MACH_TYPE_A81 745 +#define MACH_TYPE_SVM_SC25X 746 +#define MACH_TYPE_VADATECH020 747 +#define MACH_TYPE_TLI 748 +#define MACH_TYPE_EDB9315LC 749 +#define MACH_TYPE_PASSEC 750 +#define MACH_TYPE_DS_TIGER 751 +#define MACH_TYPE_E310 752 +#define MACH_TYPE_E330 753 +#define MACH_TYPE_RT3000 754 +#define MACH_TYPE_NOKIA770 755 +#define MACH_TYPE_PNX0106 756 +#define MACH_TYPE_HX21XX 757 +#define MACH_TYPE_FARADAY 758 +#define MACH_TYPE_SBC9312 759 +#define MACH_TYPE_BATMAN 760 +#define MACH_TYPE_JPD201 761 +#define MACH_TYPE_MIPSA 762 +#define MACH_TYPE_KACOM 763 +#define MACH_TYPE_SWARCOCPU 764 +#define MACH_TYPE_SWARCODSL 765 +#define MACH_TYPE_BLUEANGEL 766 +#define MACH_TYPE_HAIRYGRAMA 767 +#define MACH_TYPE_BANFF 768 +#define MACH_TYPE_CARMEVA 769 +#define MACH_TYPE_SAM255 770 +#define MACH_TYPE_PPM10 771 +#define MACH_TYPE_EDB9315A 772 +#define MACH_TYPE_SUNSET 773 +#define MACH_TYPE_STARGATE2 774 +#define MACH_TYPE_INTELMOTE2 775 +#define MACH_TYPE_TRIZEPS4 776 +#define MACH_TYPE_MAINSTONE2 777 +#define MACH_TYPE_EZ_IXP42X 778 +#define MACH_TYPE_TAPWAVE_ZODIAC 779 +#define MACH_TYPE_UNIVERSALMETER 780 +#define MACH_TYPE_HICOARM9 781 +#define MACH_TYPE_PNX4008 782 +#define MACH_TYPE_KWS6000 783 +#define MACH_TYPE_PORTUX920T 784 +#define MACH_TYPE_EZ_X5 785 +#define MACH_TYPE_OMAP_RUDOLPH 786 +#define MACH_TYPE_CPUAT91 787 +#define MACH_TYPE_REA9200 788 +#define MACH_TYPE_ACTS_PUNE_SA1110 789 +#define MACH_TYPE_IXP425 790 +#define MACH_TYPE_I30030ADS 791 +#define MACH_TYPE_PERCH 792 +#define MACH_TYPE_EIS05R1 793 +#define MACH_TYPE_PEPPERPAD 794 +#define MACH_TYPE_SB3010 795 +#define MACH_TYPE_RM9200 796 +#define MACH_TYPE_DMA03 797 +#define MACH_TYPE_ROAD_S101 798 +#define MACH_TYPE_IQ81340SC 799 +#define MACH_TYPE_IQ_NEXTGEN_B 800 +#define MACH_TYPE_IQ81340MC 801 +#define MACH_TYPE_IQ_NEXTGEN_D 802 +#define MACH_TYPE_IQ_NEXTGEN_E 803 +#define MACH_TYPE_MALLOW_AT91 804 +#define MACH_TYPE_CYBERTRACKER_I 805 +#define MACH_TYPE_GESBC931X 806 +#define MACH_TYPE_CENTIPAD 807 +#define MACH_TYPE_ARMSOC 808 +#define MACH_TYPE_SE4200 809 +#define MACH_TYPE_EMS197A 810 +#define MACH_TYPE_MICRO9 811 +#define MACH_TYPE_MICRO9L 812 +#define MACH_TYPE_UC5471DSP 813 +#define MACH_TYPE_SJ5471ENG 814 +#define MACH_TYPE_CMPXA26X 815 +#define MACH_TYPE_NC 816 +#define MACH_TYPE_OMAP_PALMTE 817 +#define MACH_TYPE_AJAX52X 818 +#define MACH_TYPE_SIRIUSTAR 819 +#define MACH_TYPE_IODATA_HDLG 820 +#define MACH_TYPE_AT91RM9200UTL 821 +#define MACH_TYPE_BIOSAFE 822 +#define MACH_TYPE_MP1000 823 +#define MACH_TYPE_PARSY 824 +#define MACH_TYPE_CCXP 825 +#define MACH_TYPE_OMAP_GSAMPLE 826 +#define MACH_TYPE_REALVIEW_EB 827 +#define MACH_TYPE_SAMOA 828 +#define MACH_TYPE_PALMT3 829 +#define MACH_TYPE_I878 830 +#define MACH_TYPE_BORZOI 831 +#define MACH_TYPE_GECKO 832 +#define MACH_TYPE_DS101 833 +#define MACH_TYPE_OMAP_PALMTT2 834 +#define MACH_TYPE_PALMLD 835 +#define MACH_TYPE_CC9C 836 +#define MACH_TYPE_SBC1670 837 +#define MACH_TYPE_IXDP28X5 838 +#define MACH_TYPE_OMAP_PALMTT 839 +#define MACH_TYPE_ML696K 840 +#define MACH_TYPE_ARCOM_ZEUS 841 +#define MACH_TYPE_OSIRIS 842 +#define MACH_TYPE_MAESTRO 843 +#define MACH_TYPE_PALMTE2 844 +#define MACH_TYPE_IXBBM 845 +#define MACH_TYPE_MX27ADS 846 +#define MACH_TYPE_AX8004 847 +#define MACH_TYPE_AT91SAM9261EK 848 +#define MACH_TYPE_LOFT 849 +#define MACH_TYPE_MAGPIE 850 +#define MACH_TYPE_MX21ADS 851 +#define MACH_TYPE_MB87M3400 852 +#define MACH_TYPE_MGUARD_DELTA 853 +#define MACH_TYPE_DAVINCI_DVDP 854 +#define MACH_TYPE_HTCUNIVERSAL 855 +#define MACH_TYPE_TPAD 856 +#define MACH_TYPE_ROVERP3 857 +#define MACH_TYPE_JORNADA928 858 +#define MACH_TYPE_MV88FXX81 859 +#define MACH_TYPE_STMP36XX 860 +#define MACH_TYPE_SXNI79524 861 +#define MACH_TYPE_AMS_DELTA 862 +#define MACH_TYPE_URANIUM 863 +#define MACH_TYPE_UCON 864 +#define MACH_TYPE_NAS100D 865 +#define MACH_TYPE_L083_1000 866 +#define MACH_TYPE_EZX 867 +#define MACH_TYPE_PNX5220 868 +#define MACH_TYPE_BUTTE 869 +#define MACH_TYPE_SRM2 870 +#define MACH_TYPE_DSBR 871 +#define MACH_TYPE_CRYSTALBALL 872 +#define MACH_TYPE_TINYPXA27X 873 +#define MACH_TYPE_HERBIE 874 +#define MACH_TYPE_MAGICIAN 875 +#define MACH_TYPE_CM4002 876 +#define MACH_TYPE_B4 877 +#define MACH_TYPE_MAUI 878 +#define MACH_TYPE_CYBERTRACKER_G 879 +#define MACH_TYPE_NXDKN 880 +#define MACH_TYPE_MIO8390 881 +#define MACH_TYPE_OMI_BOARD 882 +#define MACH_TYPE_MX21CIV 883 +#define MACH_TYPE_MAHI_CDAC 884 +#define MACH_TYPE_PALMTX 885 +#define MACH_TYPE_S3C2413 887 +#define MACH_TYPE_SAMSYS_EP0 888 +#define MACH_TYPE_WG302V1 889 +#define MACH_TYPE_WG302V2 890 +#define MACH_TYPE_EB42X 891 +#define MACH_TYPE_IQ331ES 892 +#define MACH_TYPE_COSYDSP 893 +#define MACH_TYPE_UPLAT7D 894 +#define MACH_TYPE_PTDAVINCI 895 +#define MACH_TYPE_MBUS 896 +#define MACH_TYPE_NADIA2VB 897 +#define MACH_TYPE_R1000 898 +#define MACH_TYPE_HW90250 899 +#define MACH_TYPE_OMAP_2430SDP 900 +#define MACH_TYPE_DAVINCI_EVM 901 +#define MACH_TYPE_OMAP_TORNADO 902 +#define MACH_TYPE_OLOCREEK 903 +#define MACH_TYPE_PALMZ72 904 +#define MACH_TYPE_NXDB500 905 +#define MACH_TYPE_APF9328 906 +#define MACH_TYPE_OMAP_WIPOQ 907 +#define MACH_TYPE_OMAP_TWIP 908 +#define MACH_TYPE_TREO650 909 +#define MACH_TYPE_ACUMEN 910 +#define MACH_TYPE_XP100 911 +#define MACH_TYPE_FS2410 912 +#define MACH_TYPE_PXA270_CERF 913 +#define MACH_TYPE_SQ2FTLPALM 914 +#define MACH_TYPE_BSEMSERVER 915 +#define MACH_TYPE_NETCLIENT 916 +#define MACH_TYPE_PALMT5 917 +#define MACH_TYPE_PALMTC 918 +#define MACH_TYPE_OMAP_APOLLON 919 +#define MACH_TYPE_MXC30030EVB 920 +#define MACH_TYPE_REA_2D 921 +#define MACH_TYPE_TI3E524 922 +#define MACH_TYPE_ATEB9200 923 +#define MACH_TYPE_AUCKLAND 924 +#define MACH_TYPE_AK3320M 925 +#define MACH_TYPE_DURAMAX 926 +#define MACH_TYPE_N35 927 +#define MACH_TYPE_PRONGHORN 928 +#define MACH_TYPE_FUNDY 929 +#define MACH_TYPE_LOGICPD_PXA270 930 +#define MACH_TYPE_CPU777 931 +#define MACH_TYPE_SIMICON9201 932 +#define MACH_TYPE_LEAP2_HPM 933 +#define MACH_TYPE_CM922TXA10 934 +#define MACH_TYPE_PXA 935 +#define MACH_TYPE_SANDGATE2 936 +#define MACH_TYPE_SANDGATE2G 937 +#define MACH_TYPE_SANDGATE2P 938 +#define MACH_TYPE_FRED_JACK 939 +#define MACH_TYPE_TTG_COLOR1 940 +#define MACH_TYPE_NXEB500HMI 941 +#define MACH_TYPE_NETDCU8 942 +#define MACH_TYPE_NG_FVX538 944 +#define MACH_TYPE_NG_FVS338 945 +#define MACH_TYPE_PNX4103 946 +#define MACH_TYPE_HESDB 947 +#define MACH_TYPE_XSILO 948 +#define MACH_TYPE_ESPRESSO 949 +#define MACH_TYPE_EMLC 950 +#define MACH_TYPE_SISTERON 951 +#define MACH_TYPE_RX1950 952 +#define MACH_TYPE_TSC_VENUS 953 +#define MACH_TYPE_DS101J 954 +#define MACH_TYPE_MXC30030ADS 955 +#define MACH_TYPE_FUJITSU_WIMAXSOC 956 +#define MACH_TYPE_DUALPCMODEM 957 +#define MACH_TYPE_GESBC9312 958 +#define MACH_TYPE_HTCAPACHE 959 +#define MACH_TYPE_IXDP435 960 +#define MACH_TYPE_CATPROVT100 961 +#define MACH_TYPE_PICOTUX1XX 962 +#define MACH_TYPE_PICOTUX2XX 963 +#define MACH_TYPE_DSMG600 964 +#define MACH_TYPE_EMPC2 965 +#define MACH_TYPE_VENTURA 966 +#define MACH_TYPE_PHIDGET_SBC 967 +#define MACH_TYPE_IJ3K 968 +#define MACH_TYPE_PISGAH 969 +#define MACH_TYPE_OMAP_FSAMPLE 970 +#define MACH_TYPE_SG720 971 +#define MACH_TYPE_REDFOX 972 +#define MACH_TYPE_MYSH_EP9315_1 973 +#define MACH_TYPE_TPF106 974 +#define MACH_TYPE_AT91RM9200KG 975 +#define MACH_TYPE_SLEDB 976 +#define MACH_TYPE_ONTRACK 977 +#define MACH_TYPE_PM1200 978 +#define MACH_TYPE_ESS24XXX 979 +#define MACH_TYPE_COREMP7 980 +#define MACH_TYPE_NEXCODER_6446 981 +#define MACH_TYPE_STVC8380 982 +#define MACH_TYPE_TEKLYNX 983 +#define MACH_TYPE_CARBONADO 984 +#define MACH_TYPE_SYSMOS_MP730 985 +#define MACH_TYPE_SNAPPER_CL15 986 +#define MACH_TYPE_PGIGIM 987 +#define MACH_TYPE_PTX9160P2 988 +#define MACH_TYPE_DCORE1 989 +#define MACH_TYPE_VICTORPXA 990 +#define MACH_TYPE_MX2DTB 991 +#define MACH_TYPE_PXA_IREX_ER0100 992 +#define MACH_TYPE_OMAP_PALMZ71 993 +#define MACH_TYPE_BARTEC_DEG 994 +#define MACH_TYPE_HW50251 995 +#define MACH_TYPE_IBOX 996 +#define MACH_TYPE_ATLASLH7A404 997 +#define MACH_TYPE_PT2026 998 +#define MACH_TYPE_HTCALPINE 999 +#define MACH_TYPE_BARTEC_VTU 1000 +#define MACH_TYPE_VCOREII 1001 +#define MACH_TYPE_PDNB3 1002 +#define MACH_TYPE_HTCBEETLES 1003 +#define MACH_TYPE_S3C6400 1004 +#define MACH_TYPE_S3C2443 1005 +#define MACH_TYPE_OMAP_LDK 1006 +#define MACH_TYPE_SMDK2460 1007 +#define MACH_TYPE_SMDK2440 1008 +#define MACH_TYPE_SMDK2412 1009 +#define MACH_TYPE_WEBBOX 1010 +#define MACH_TYPE_CWWNDP 1011 +#define MACH_TYPE_DRAGON 1012 +#define MACH_TYPE_OPENDO_CPU_BOARD 1013 +#define MACH_TYPE_CCM2200 1014 +#define MACH_TYPE_ETWARM 1015 +#define MACH_TYPE_M93030 1016 +#define MACH_TYPE_CC7U 1017 +#define MACH_TYPE_MTT_RANGER 1018 +#define MACH_TYPE_NEXUS 1019 +#define MACH_TYPE_DESMAN 1020 +#define MACH_TYPE_BKDE303 1021 +#define MACH_TYPE_SMDK2413 1022 +#define MACH_TYPE_AML_M7200 1023 +#define MACH_TYPE_AML_M5900 1024 +#define MACH_TYPE_SG640 1025 +#define MACH_TYPE_EDG79524 1026 +#define MACH_TYPE_AI2410 1027 +#define MACH_TYPE_IXP465 1028 +#define MACH_TYPE_BALLOON3 1029 +#define MACH_TYPE_HEINS 1030 +#define MACH_TYPE_MPLUSEVA 1031 +#define MACH_TYPE_RT042 1032 +#define MACH_TYPE_CWIEM 1033 +#define MACH_TYPE_CM_X270 1034 +#define MACH_TYPE_CM_X255 1035 +#define MACH_TYPE_ESH_AT91 1036 +#define MACH_TYPE_SANDGATE3 1037 +#define MACH_TYPE_PRIMO 1038 +#define MACH_TYPE_GEMSTONE 1039 +#define MACH_TYPE_PRONGHORNMETRO 1040 +#define MACH_TYPE_SIDEWINDER 1041 +#define MACH_TYPE_PICOMOD1 1042 +#define MACH_TYPE_SG590 1043 +#define MACH_TYPE_AKAI9307 1044 +#define MACH_TYPE_FONTAINE 1045 +#define MACH_TYPE_WOMBAT 1046 +#define MACH_TYPE_ACQ300 1047 +#define MACH_TYPE_MOD_270 1048 +#define MACH_TYPE_VC0820 1049 +#define MACH_TYPE_ANI_AIM 1050 +#define MACH_TYPE_JELLYFISH 1051 +#define MACH_TYPE_AMANITA 1052 +#define MACH_TYPE_VLINK 1053 +#define MACH_TYPE_DEXFLEX 1054 +#define MACH_TYPE_EIGEN_TTQ 1055 +#define MACH_TYPE_ARCOM_TITAN 1056 +#define MACH_TYPE_TABLA 1057 +#define MACH_TYPE_MDIRAC3 1058 +#define MACH_TYPE_MRHFBP2 1059 +#define MACH_TYPE_AT91RM9200RB 1060 +#define MACH_TYPE_ANI_APM 1061 +#define MACH_TYPE_ELLA1 1062 +#define MACH_TYPE_INHAND_PXA27X 1063 +#define MACH_TYPE_INHAND_PXA25X 1064 +#define MACH_TYPE_EMPOS_XM 1065 +#define MACH_TYPE_EMPOS 1066 +#define MACH_TYPE_EMPOS_TINY 1067 +#define MACH_TYPE_EMPOS_SM 1068 +#define MACH_TYPE_EGRET 1069 +#define MACH_TYPE_OSTRICH 1070 +#define MACH_TYPE_N50 1071 +#define MACH_TYPE_ECBAT91 1072 +#define MACH_TYPE_STAREAST 1073 +#define MACH_TYPE_DSPG_DW 1074 +#define MACH_TYPE_ONEARM 1075 +#define MACH_TYPE_MRG110_6 1076 +#define MACH_TYPE_WRT300NV2 1077 +#define MACH_TYPE_XM_BULVERDE 1078 +#define MACH_TYPE_MSM6100 1079 +#define MACH_TYPE_ETI_B1 1080 +#define MACH_TYPE_ZILOG_ZA9L 1081 +#define MACH_TYPE_BIT2440 1082 +#define MACH_TYPE_NBI 1083 +#define MACH_TYPE_SMDK2443 1084 +#define MACH_TYPE_VDAVINCI 1085 +#define MACH_TYPE_ATC6 1086 +#define MACH_TYPE_MULTMDW 1087 +#define MACH_TYPE_MBA2440 1088 +#define MACH_TYPE_ECSD 1089 +#define MACH_TYPE_PALMZ31 1090 +#define MACH_TYPE_FSG 1091 +#define MACH_TYPE_RAZOR101 1092 +#define MACH_TYPE_OPERA_TDM 1093 +#define MACH_TYPE_COMCERTO 1094 +#define MACH_TYPE_TB0319 1095 +#define MACH_TYPE_KWS8000 1096 +#define MACH_TYPE_B2 1097 +#define MACH_TYPE_LCL54 1098 +#define MACH_TYPE_AT91SAM9260EK 1099 +#define MACH_TYPE_GLANTANK 1100 +#define MACH_TYPE_N2100 1101 +#define MACH_TYPE_N4100 1102 +#define MACH_TYPE_VERTICAL_RSC4 1103 +#define MACH_TYPE_SG8100 1104 +#define MACH_TYPE_IM42XX 1105 +#define MACH_TYPE_FTXX 1106 +#define MACH_TYPE_LWFUSION 1107 +#define MACH_TYPE_QT2410 1108 +#define MACH_TYPE_KIXRP435 1109 +#define MACH_TYPE_CCW9C 1110 +#define MACH_TYPE_DABHS 1111 +#define MACH_TYPE_GZMX 1112 +#define MACH_TYPE_IPNW100AP 1113 +#define MACH_TYPE_CC9P9360DEV 1114 +#define MACH_TYPE_CC9P9750DEV 1115 +#define MACH_TYPE_CC9P9360VAL 1116 +#define MACH_TYPE_CC9P9750VAL 1117 +#define MACH_TYPE_NX70V 1118 +#define MACH_TYPE_AT91RM9200DF 1119 +#define MACH_TYPE_SE_PILOT2 1120 +#define MACH_TYPE_MTCN_T800 1121 +#define MACH_TYPE_VCMX212 1122 +#define MACH_TYPE_LYNX 1123 +#define MACH_TYPE_AT91SAM9260ID 1124 +#define MACH_TYPE_HW86052 1125 +#define MACH_TYPE_PILZ_PMI3 1126 +#define MACH_TYPE_EDB9302A 1127 +#define MACH_TYPE_EDB9307A 1128 +#define MACH_TYPE_CT_DFS 1129 +#define MACH_TYPE_PILZ_PMI4 1130 +#define MACH_TYPE_XCEEDNP_IXP 1131 +#define MACH_TYPE_SMDK2442B 1132 +#define MACH_TYPE_XNODE 1133 +#define MACH_TYPE_AIDX270 1134 +#define MACH_TYPE_REMA 1135 +#define MACH_TYPE_BPS1000 1136 +#define MACH_TYPE_HW90350 1137 +#define MACH_TYPE_OMAP_3430SDP 1138 +#define MACH_TYPE_BLUETOUCH 1139 +#define MACH_TYPE_VSTMS 1140 +#define MACH_TYPE_XSBASE270 1141 +#define MACH_TYPE_AT91SAM9260EK_CN 1142 +#define MACH_TYPE_ADSTURBOXB 1143 +#define MACH_TYPE_OTI4110 1144 +#define MACH_TYPE_HME_PXA 1145 +#define MACH_TYPE_DEISTERDCA 1146 +#define MACH_TYPE_CES_SSEM2 1147 +#define MACH_TYPE_CES_MTR 1148 +#define MACH_TYPE_TDS_AVNG_SBC 1149 +#define MACH_TYPE_EVEREST 1150 +#define MACH_TYPE_PNX4010 1151 +#define MACH_TYPE_OXNAS 1152 +#define MACH_TYPE_FIORI 1153 +#define MACH_TYPE_ML1200 1154 +#define MACH_TYPE_PECOS 1155 +#define MACH_TYPE_NB2XXX 1156 +#define MACH_TYPE_HW6900 1157 +#define MACH_TYPE_CDCS_QUOLL 1158 +#define MACH_TYPE_QUICKSILVER 1159 +#define MACH_TYPE_UPLAT926 1160 +#define MACH_TYPE_DEP2410_THOMAS 1161 +#define MACH_TYPE_DTK2410 1162 +#define MACH_TYPE_CHILI 1163 +#define MACH_TYPE_DEMETER 1164 +#define MACH_TYPE_DIONYSUS 1165 +#define MACH_TYPE_AS352X 1166 +#define MACH_TYPE_SERVICE 1167 +#define MACH_TYPE_CS_E9301 1168 +#define MACH_TYPE_MICRO9M 1169 +#define MACH_TYPE_IA_MOSPCK 1170 +#define MACH_TYPE_QL201B 1171 +#define MACH_TYPE_BBM 1174 +#define MACH_TYPE_EXXX 1175 +#define MACH_TYPE_WMA11B 1176 +#define MACH_TYPE_PELCO_ATLAS 1177 +#define MACH_TYPE_G500 1178 +#define MACH_TYPE_BUG 1179 +#define MACH_TYPE_MX33ADS 1180 +#define MACH_TYPE_CHUB 1181 +#define MACH_TYPE_NEO1973_GTA01 1182 +#define MACH_TYPE_W90N740 1183 +#define MACH_TYPE_MEDALLION_SA2410 1184 +#define MACH_TYPE_IA_CPU_9200_2 1185 +#define MACH_TYPE_DIMMRM9200 1186 +#define MACH_TYPE_PM9261 1187 +#define MACH_TYPE_ML7304 1189 +#define MACH_TYPE_UCP250 1190 +#define MACH_TYPE_INTBOARD 1191 +#define MACH_TYPE_GULFSTREAM 1192 +#define MACH_TYPE_LABQUEST 1193 +#define MACH_TYPE_VCMX313 1194 +#define MACH_TYPE_URG200 1195 +#define MACH_TYPE_CPUX255LCDNET 1196 +#define MACH_TYPE_NETDCU9 1197 +#define MACH_TYPE_NETDCU10 1198 +#define MACH_TYPE_DSPG_DGA 1199 +#define MACH_TYPE_DSPG_DVW 1200 +#define MACH_TYPE_SOLOS 1201 +#define MACH_TYPE_AT91SAM9263EK 1202 +#define MACH_TYPE_OSSTBOX 1203 +#define MACH_TYPE_KBAT9261 1204 +#define MACH_TYPE_CT1100 1205 +#define MACH_TYPE_AKCPPXA 1206 +#define MACH_TYPE_OCHAYA1020 1207 +#define MACH_TYPE_HITRACK 1208 +#define MACH_TYPE_SYME1 1209 +#define MACH_TYPE_SYHL1 1210 +#define MACH_TYPE_EMPCA400 1211 +#define MACH_TYPE_EM7210 1212 +#define MACH_TYPE_HTCHERMES 1213 +#define MACH_TYPE_ETI_C1 1214 +#define MACH_TYPE_AC100 1216 +#define MACH_TYPE_SNEETCH 1217 +#define MACH_TYPE_STUDENTMATE 1218 +#define MACH_TYPE_ZIR2410 1219 +#define MACH_TYPE_ZIR2413 1220 +#define MACH_TYPE_DLONIP3 1221 +#define MACH_TYPE_INSTREAM 1222 +#define MACH_TYPE_AMBARELLA 1223 +#define MACH_TYPE_NEVIS 1224 +#define MACH_TYPE_HTC_TRINITY 1225 +#define MACH_TYPE_QL202B 1226 +#define MACH_TYPE_VPAC270 1227 +#define MACH_TYPE_RD129 1228 +#define MACH_TYPE_HTCWIZARD 1229 +#define MACH_TYPE_TREO680 1230 +#define MACH_TYPE_TECON_TMEZON 1231 +#define MACH_TYPE_ZYLONITE 1233 +#define MACH_TYPE_GENE1270 1234 +#define MACH_TYPE_ZIR2412 1235 +#define MACH_TYPE_MX31LITE 1236 +#define MACH_TYPE_T700WX 1237 +#define MACH_TYPE_VF100 1238 +#define MACH_TYPE_NSB2 1239 +#define MACH_TYPE_NXHMI_BB 1240 +#define MACH_TYPE_NXHMI_RE 1241 +#define MACH_TYPE_N4100PRO 1242 +#define MACH_TYPE_SAM9260 1243 +#define MACH_TYPE_OMAP_TREO600 1244 +#define MACH_TYPE_INDY2410 1245 +#define MACH_TYPE_NELT_A 1246 +#define MACH_TYPE_N311 1248 +#define MACH_TYPE_AT91SAM9260VGK 1249 +#define MACH_TYPE_AT91LEPPE 1250 +#define MACH_TYPE_AT91LEPCCN 1251 +#define MACH_TYPE_APC7100 1252 +#define MACH_TYPE_STARGAZER 1253 +#define MACH_TYPE_SONATA 1254 +#define MACH_TYPE_SCHMOOGIE 1255 +#define MACH_TYPE_AZTOOL 1256 +#define MACH_TYPE_MIOA701 1257 +#define MACH_TYPE_SXNI9260 1258 +#define MACH_TYPE_MXC27520EVB 1259 +#define MACH_TYPE_ARMADILLO5X0 1260 +#define MACH_TYPE_MB9260 1261 +#define MACH_TYPE_MB9263 1262 +#define MACH_TYPE_IPAC9302 1263 +#define MACH_TYPE_CC9P9360JS 1264 +#define MACH_TYPE_GALLIUM 1265 +#define MACH_TYPE_MSC2410 1266 +#define MACH_TYPE_GHI270 1267 +#define MACH_TYPE_DAVINCI_LEONARDO 1268 +#define MACH_TYPE_OIAB 1269 +#define MACH_TYPE_SMDK6400 1270 +#define MACH_TYPE_NOKIA_N800 1271 +#define MACH_TYPE_GREENPHONE 1272 +#define MACH_TYPE_COMPEXWP18 1273 +#define MACH_TYPE_XMATE 1274 +#define MACH_TYPE_ENERGIZER 1275 +#define MACH_TYPE_IME1 1276 +#define MACH_TYPE_SWEDATMS 1277 +#define MACH_TYPE_NTNP435C 1278 +#define MACH_TYPE_SPECTRO2 1279 +#define MACH_TYPE_H6039 1280 +#define MACH_TYPE_EP80219 1281 +#define MACH_TYPE_SAMOA_II 1282 +#define MACH_TYPE_CWMXL 1283 +#define MACH_TYPE_AS9200 1284 +#define MACH_TYPE_SFX1149 1285 +#define MACH_TYPE_NAVI010 1286 +#define MACH_TYPE_MULTMDP 1287 +#define MACH_TYPE_SCB9520 1288 +#define MACH_TYPE_HTCATHENA 1289 +#define MACH_TYPE_XP179 1290 +#define MACH_TYPE_H4300 1291 +#define MACH_TYPE_GORAMO_MLR 1292 +#define MACH_TYPE_MXC30020EVB 1293 +#define MACH_TYPE_ADSBITSYG5 1294 +#define MACH_TYPE_ADSPORTALPLUS 1295 +#define MACH_TYPE_MMSP2PLUS 1296 +#define MACH_TYPE_EM_X270 1297 +#define MACH_TYPE_TPP302 1298 +#define MACH_TYPE_TPM104 1299 +#define MACH_TYPE_TPM102 1300 +#define MACH_TYPE_TPM109 1301 +#define MACH_TYPE_FBXO1 1302 +#define MACH_TYPE_HXD8 1303 +#define MACH_TYPE_NEO1973_GTA02 1304 +#define MACH_TYPE_EMTEST 1305 +#define MACH_TYPE_AD6900 1306 +#define MACH_TYPE_EUROPA 1307 +#define MACH_TYPE_METROCONNECT 1308 +#define MACH_TYPE_EZ_S2410 1309 +#define MACH_TYPE_EZ_S2440 1310 +#define MACH_TYPE_EZ_EP9312 1311 +#define MACH_TYPE_EZ_EP9315 1312 +#define MACH_TYPE_EZ_X7 1313 +#define MACH_TYPE_GODOTDB 1314 +#define MACH_TYPE_MISTRAL 1315 +#define MACH_TYPE_MSM 1316 +#define MACH_TYPE_CT5910 1317 +#define MACH_TYPE_CT5912 1318 +#define MACH_TYPE_HYNET_INE 1319 +#define MACH_TYPE_HYNET_APP 1320 +#define MACH_TYPE_MSM7200 1321 +#define MACH_TYPE_MSM7600 1322 +#define MACH_TYPE_CEB255 1323 +#define MACH_TYPE_CIEL 1324 +#define MACH_TYPE_SLM5650 1325 +#define MACH_TYPE_AT91SAM9RLEK 1326 +#define MACH_TYPE_COMTECH_ROUTER 1327 +#define MACH_TYPE_SBC2410X 1328 +#define MACH_TYPE_AT4X0BD 1329 +#define MACH_TYPE_CBIFR 1330 +#define MACH_TYPE_ARCOM_QUANTUM 1331 +#define MACH_TYPE_MATRIX520 1332 +#define MACH_TYPE_MATRIX510 1333 +#define MACH_TYPE_MATRIX500 1334 +#define MACH_TYPE_M501 1335 +#define MACH_TYPE_AAEON1270 1336 +#define MACH_TYPE_MATRIX500EV 1337 +#define MACH_TYPE_PAC500 1338 +#define MACH_TYPE_PNX8181 1339 +#define MACH_TYPE_COLIBRI320 1340 +#define MACH_TYPE_AZTOOLBB 1341 +#define MACH_TYPE_AZTOOLG2 1342 +#define MACH_TYPE_DVLHOST 1343 +#define MACH_TYPE_ZIR9200 1344 +#define MACH_TYPE_ZIR9260 1345 +#define MACH_TYPE_COCOPAH 1346 +#define MACH_TYPE_NDS 1347 +#define MACH_TYPE_ROSENCRANTZ 1348 +#define MACH_TYPE_FTTX_ODSC 1349 +#define MACH_TYPE_CLASSE_R6904 1350 +#define MACH_TYPE_CAM60 1351 +#define MACH_TYPE_MXC30031ADS 1352 +#define MACH_TYPE_DATACALL 1353 +#define MACH_TYPE_AT91EB01 1354 +#define MACH_TYPE_RTY 1355 +#define MACH_TYPE_DWL2100 1356 +#define MACH_TYPE_VINSI 1357 +#define MACH_TYPE_DB88F5281 1358 +#define MACH_TYPE_CSB726 1359 +#define MACH_TYPE_TIK27 1360 +#define MACH_TYPE_MX_UC7420 1361 +#define MACH_TYPE_RIRM3 1362 +#define MACH_TYPE_PELCO_ODYSSEY 1363 +#define MACH_TYPE_ADX_ABOX 1365 +#define MACH_TYPE_ADX_TPID 1366 +#define MACH_TYPE_MINICHECK 1367 +#define MACH_TYPE_IDAM 1368 +#define MACH_TYPE_MARIO_MX 1369 +#define MACH_TYPE_VI1888 1370 +#define MACH_TYPE_ZR4230 1371 +#define MACH_TYPE_T1_IX_BLUE 1372 +#define MACH_TYPE_SYHQ2 1373 +#define MACH_TYPE_COMPUTIME_R3 1374 +#define MACH_TYPE_ORATIS 1375 +#define MACH_TYPE_MIKKO 1376 +#define MACH_TYPE_HOLON 1377 +#define MACH_TYPE_OLIP8 1378 +#define MACH_TYPE_GHI270HG 1379 +#define MACH_TYPE_DAVINCI_DM6467_EVM 1380 +#define MACH_TYPE_DAVINCI_DM355_EVM 1381 +#define MACH_TYPE_BLACKRIVER 1383 +#define MACH_TYPE_SANDGATEWP 1384 +#define MACH_TYPE_CDOTBWSG 1385 +#define MACH_TYPE_QUARK963 1386 +#define MACH_TYPE_CSB735 1387 +#define MACH_TYPE_LITTLETON 1388 +#define MACH_TYPE_MIO_P550 1389 +#define MACH_TYPE_MOTION2440 1390 +#define MACH_TYPE_IMM500 1391 +#define MACH_TYPE_HOMEMATIC 1392 +#define MACH_TYPE_ERMINE 1393 +#define MACH_TYPE_KB9202B 1394 +#define MACH_TYPE_HS1XX 1395 +#define MACH_TYPE_STUDENTMATE2440 1396 +#define MACH_TYPE_ARVOO_L1_Z1 1397 +#define MACH_TYPE_DEP2410K 1398 +#define MACH_TYPE_XXSVIDEO 1399 +#define MACH_TYPE_IM4004 1400 +#define MACH_TYPE_OCHAYA1050 1401 +#define MACH_TYPE_LEP9261 1402 +#define MACH_TYPE_SVENMEB 1403 +#define MACH_TYPE_FORTUNET2NE 1404 +#define MACH_TYPE_NXHX 1406 +#define MACH_TYPE_REALVIEW_PB11MP 1407 +#define MACH_TYPE_IDS500 1408 +#define MACH_TYPE_ORS_N725 1409 +#define MACH_TYPE_HSDARM 1410 +#define MACH_TYPE_SHA_PON003 1411 +#define MACH_TYPE_SHA_PON004 1412 +#define MACH_TYPE_SHA_PON007 1413 +#define MACH_TYPE_SHA_PON011 1414 +#define MACH_TYPE_H6042 1415 +#define MACH_TYPE_H6043 1416 +#define MACH_TYPE_LOOXC550 1417 +#define MACH_TYPE_CNTY_TITAN 1418 +#define MACH_TYPE_APP3XX 1419 +#define MACH_TYPE_SIDEOATSGRAMA 1420 +#define MACH_TYPE_TREO700P 1421 +#define MACH_TYPE_TREO700W 1422 +#define MACH_TYPE_TREO750 1423 +#define MACH_TYPE_TREO755P 1424 +#define MACH_TYPE_EZREGANUT9200 1425 +#define MACH_TYPE_SARGE 1426 +#define MACH_TYPE_A696 1427 +#define MACH_TYPE_TURTLE 1428 +#define MACH_TYPE_MX27_3DS 1430 +#define MACH_TYPE_BISHOP 1431 +#define MACH_TYPE_PXX 1432 +#define MACH_TYPE_REDWOOD 1433 +#define MACH_TYPE_OMAP_2430DLP 1436 +#define MACH_TYPE_OMAP_2430OSK 1437 +#define MACH_TYPE_SARDINE 1438 +#define MACH_TYPE_HALIBUT 1439 +#define MACH_TYPE_TROUT 1440 +#define MACH_TYPE_GOLDFISH 1441 +#define MACH_TYPE_GESBC2440 1442 +#define MACH_TYPE_NOMAD 1443 +#define MACH_TYPE_ROSALIND 1444 +#define MACH_TYPE_CC9P9215 1445 +#define MACH_TYPE_CC9P9210 1446 +#define MACH_TYPE_CC9P9215JS 1447 +#define MACH_TYPE_CC9P9210JS 1448 +#define MACH_TYPE_NASFFE 1449 +#define MACH_TYPE_TN2X0BD 1450 +#define MACH_TYPE_GWMPXA 1451 +#define MACH_TYPE_EXYPLUS 1452 +#define MACH_TYPE_JADOO21 1453 +#define MACH_TYPE_LOOXN560 1454 +#define MACH_TYPE_BONSAI 1455 +#define MACH_TYPE_ADSMILGATO 1456 +#define MACH_TYPE_GBA 1457 +#define MACH_TYPE_H6044 1458 +#define MACH_TYPE_APP 1459 +#define MACH_TYPE_TCT_HAMMER 1460 +#define MACH_TYPE_HERALD 1461 +#define MACH_TYPE_ARTEMIS 1462 +#define MACH_TYPE_HTCTITAN 1463 +#define MACH_TYPE_QRANIUM 1464 +#define MACH_TYPE_ADX_WSC2 1465 +#define MACH_TYPE_ADX_MEDCOM 1466 +#define MACH_TYPE_BBOARD 1467 +#define MACH_TYPE_CAMBRIA 1468 +#define MACH_TYPE_MT7XXX 1469 +#define MACH_TYPE_MATRIX512 1470 +#define MACH_TYPE_MATRIX522 1471 +#define MACH_TYPE_IPAC5010 1472 +#define MACH_TYPE_SAKURA 1473 +#define MACH_TYPE_GROCX 1474 +#define MACH_TYPE_PM9263 1475 +#define MACH_TYPE_SIM_ONE 1476 +#define MACH_TYPE_ACQ132 1477 +#define MACH_TYPE_DATR 1478 +#define MACH_TYPE_ACTUX1 1479 +#define MACH_TYPE_ACTUX2 1480 +#define MACH_TYPE_ACTUX3 1481 +#define MACH_TYPE_FLEXIT 1482 +#define MACH_TYPE_BH2X0BD 1483 +#define MACH_TYPE_ATB2002 1484 +#define MACH_TYPE_XENON 1485 +#define MACH_TYPE_FM607 1486 +#define MACH_TYPE_MATRIX514 1487 +#define MACH_TYPE_MATRIX524 1488 +#define MACH_TYPE_INPOD 1489 +#define MACH_TYPE_JIVE 1490 +#define MACH_TYPE_TLL_MX21 1491 +#define MACH_TYPE_SBC2800 1492 +#define MACH_TYPE_CC7UCAMRY 1493 +#define MACH_TYPE_UBISYS_P9_SC15 1494 +#define MACH_TYPE_UBISYS_P9_SSC2D10 1495 +#define MACH_TYPE_UBISYS_P9_RCU3 1496 +#define MACH_TYPE_AML_M8000 1497 +#define MACH_TYPE_SNAPPER_270 1498 +#define MACH_TYPE_OMAP_BBX 1499 +#define MACH_TYPE_UCN2410 1500 +#define MACH_TYPE_SAM9_L9260 1501 +#define MACH_TYPE_ETI_C2 1502 +#define MACH_TYPE_AVALANCHE 1503 +#define MACH_TYPE_REALVIEW_PB1176 1504 +#define MACH_TYPE_DP1500 1505 +#define MACH_TYPE_APPLE_IPHONE 1506 +#define MACH_TYPE_YL9200 1507 +#define MACH_TYPE_RD88F5182 1508 +#define MACH_TYPE_KUROBOX_PRO 1509 +#define MACH_TYPE_SE_POET 1510 +#define MACH_TYPE_MX31_3DS 1511 +#define MACH_TYPE_R270 1512 +#define MACH_TYPE_ARMOUR21 1513 +#define MACH_TYPE_DT2 1514 +#define MACH_TYPE_VT4 1515 +#define MACH_TYPE_TYCO320 1516 +#define MACH_TYPE_ADMA 1517 +#define MACH_TYPE_WP188 1518 +#define MACH_TYPE_CORSICA 1519 +#define MACH_TYPE_BIGEYE 1520 +#define MACH_TYPE_TLL5000 1522 +#define MACH_TYPE_BEBOT 1523 +#define MACH_TYPE_QONG 1524 +#define MACH_TYPE_TCOMPACT 1525 +#define MACH_TYPE_PUMA5 1526 +#define MACH_TYPE_ELARA 1527 +#define MACH_TYPE_ELLINGTON 1528 +#define MACH_TYPE_XDA_ATOM 1529 +#define MACH_TYPE_ENERGIZER2 1530 +#define MACH_TYPE_ODIN 1531 +#define MACH_TYPE_ACTUX4 1532 +#define MACH_TYPE_ESL_OMAP 1533 +#define MACH_TYPE_OMAP2EVM 1534 +#define MACH_TYPE_OMAP3EVM 1535 +#define MACH_TYPE_ADX_PCU57 1536 +#define MACH_TYPE_MONACO 1537 +#define MACH_TYPE_LEVANTE 1538 +#define MACH_TYPE_TMXIPX425 1539 +#define MACH_TYPE_LEEP 1540 +#define MACH_TYPE_RAAD 1541 +#define MACH_TYPE_DNS323 1542 +#define MACH_TYPE_AP1000 1543 +#define MACH_TYPE_A9SAM6432 1544 +#define MACH_TYPE_SHINY 1545 +#define MACH_TYPE_OMAP3_BEAGLE 1546 +#define MACH_TYPE_CSR_BDB2 1547 +#define MACH_TYPE_NOKIA_N810 1548 +#define MACH_TYPE_C270 1549 +#define MACH_TYPE_SENTRY 1550 +#define MACH_TYPE_PCM038 1551 +#define MACH_TYPE_ANC300 1552 +#define MACH_TYPE_HTCKAISER 1553 +#define MACH_TYPE_SBAT100 1554 +#define MACH_TYPE_MODUNORM 1555 +#define MACH_TYPE_PELOS_TWARM 1556 +#define MACH_TYPE_FLANK 1557 +#define MACH_TYPE_SIRLOIN 1558 +#define MACH_TYPE_BRISKET 1559 +#define MACH_TYPE_CHUCK 1560 +#define MACH_TYPE_OTTER 1561 +#define MACH_TYPE_DAVINCI_LDK 1562 +#define MACH_TYPE_PHREEDOM 1563 +#define MACH_TYPE_SG310 1564 +#define MACH_TYPE_TS209 1565 +#define MACH_TYPE_AT91CAP9ADK 1566 +#define MACH_TYPE_TION9315 1567 +#define MACH_TYPE_MAST 1568 +#define MACH_TYPE_PFW 1569 +#define MACH_TYPE_YL_P2440 1570 +#define MACH_TYPE_ZSBC32 1571 +#define MACH_TYPE_OMAP_PACE2 1572 +#define MACH_TYPE_IMX_PACE2 1573 +#define MACH_TYPE_MX31MOBOARD 1574 +#define MACH_TYPE_MX37_3DS 1575 +#define MACH_TYPE_RCC 1576 +#define MACH_TYPE_ARM9 1577 +#define MACH_TYPE_VISION_EP9307 1578 +#define MACH_TYPE_SCLY1000 1579 +#define MACH_TYPE_FONTEL_EP 1580 +#define MACH_TYPE_VOICEBLUE3G 1581 +#define MACH_TYPE_TT9200 1582 +#define MACH_TYPE_DIGI2410 1583 +#define MACH_TYPE_TERASTATION_PRO2 1584 +#define MACH_TYPE_LINKSTATION_PRO 1585 +#define MACH_TYPE_MOTOROLA_A780 1587 +#define MACH_TYPE_MOTOROLA_E6 1588 +#define MACH_TYPE_MOTOROLA_E2 1589 +#define MACH_TYPE_MOTOROLA_E680 1590 +#define MACH_TYPE_UR2410 1591 +#define MACH_TYPE_TAS9261 1592 +#define MACH_TYPE_HERMES_HD 1593 +#define MACH_TYPE_PERSEO_HD 1594 +#define MACH_TYPE_STARGAZER2 1595 +#define MACH_TYPE_E350 1596 +#define MACH_TYPE_WPCM450 1597 +#define MACH_TYPE_CARTESIO 1598 +#define MACH_TYPE_TOYBOX 1599 +#define MACH_TYPE_TX27 1600 +#define MACH_TYPE_TS409 1601 +#define MACH_TYPE_P300 1602 +#define MACH_TYPE_XDACOMET 1603 +#define MACH_TYPE_DEXFLEX2 1604 +#define MACH_TYPE_OW 1605 +#define MACH_TYPE_ARMEBS3 1606 +#define MACH_TYPE_U3 1607 +#define MACH_TYPE_SMDK2450 1608 +#define MACH_TYPE_RSI_EWS 1609 +#define MACH_TYPE_TNB 1610 +#define MACH_TYPE_TOEPATH 1611 +#define MACH_TYPE_KB9263 1612 +#define MACH_TYPE_MT7108 1613 +#define MACH_TYPE_SMTR2440 1614 +#define MACH_TYPE_MANAO 1615 +#define MACH_TYPE_CM_X300 1616 +#define MACH_TYPE_GULFSTREAM_KP 1617 +#define MACH_TYPE_LANREADYFN522 1618 +#define MACH_TYPE_ARMA37 1619 +#define MACH_TYPE_MENDEL 1620 +#define MACH_TYPE_PELCO_ILIAD 1621 +#define MACH_TYPE_UNIT2P 1622 +#define MACH_TYPE_INC20OTTER 1623 +#define MACH_TYPE_AT91SAM9G20EK 1624 +#define MACH_TYPE_STORCENTER 1625 +#define MACH_TYPE_SMDK6410 1626 +#define MACH_TYPE_U300 1627 +#define MACH_TYPE_U500 1628 +#define MACH_TYPE_DS9260 1629 +#define MACH_TYPE_RIVERROCK 1630 +#define MACH_TYPE_SCIBATH 1631 +#define MACH_TYPE_AT91SAM7SE512EK 1632 +#define MACH_TYPE_WRT350N_V2 1633 +#define MACH_TYPE_MULTIMEDIA 1634 +#define MACH_TYPE_MARVIN 1635 +#define MACH_TYPE_X500 1636 +#define MACH_TYPE_AWLUG4LCU 1637 +#define MACH_TYPE_PALERMOC 1638 +#define MACH_TYPE_OMAP_LDP 1639 +#define MACH_TYPE_IP500 1640 +#define MACH_TYPE_ASE2 1642 +#define MACH_TYPE_MX35EVB 1643 +#define MACH_TYPE_AML_M8050 1644 +#define MACH_TYPE_MX35_3DS 1645 +#define MACH_TYPE_MARS 1646 +#define MACH_TYPE_NEUROS_OSD2 1647 +#define MACH_TYPE_BADGER 1648 +#define MACH_TYPE_TRIZEPS4WL 1649 +#define MACH_TYPE_TRIZEPS5 1650 +#define MACH_TYPE_MARLIN 1651 +#define MACH_TYPE_TS78XX 1652 +#define MACH_TYPE_HPIPAQ214 1653 +#define MACH_TYPE_AT572D940DCM 1654 +#define MACH_TYPE_NE1BOARD 1655 +#define MACH_TYPE_ZANTE 1656 +#define MACH_TYPE_SFFSDR 1657 +#define MACH_TYPE_TW2662 1658 +#define MACH_TYPE_VF10XX 1659 +#define MACH_TYPE_ZORAN43XX 1660 +#define MACH_TYPE_SONIX926 1661 +#define MACH_TYPE_CELESTIALSEMI 1662 +#define MACH_TYPE_CC9M2443JS 1663 +#define MACH_TYPE_TW5334 1664 +#define MACH_TYPE_HTCARTEMIS 1665 +#define MACH_TYPE_NAL_HLITE 1666 +#define MACH_TYPE_HTCVOGUE 1667 +#define MACH_TYPE_SMARTWEB 1668 +#define MACH_TYPE_MV86XX 1669 +#define MACH_TYPE_MV87XX 1670 +#define MACH_TYPE_SONGYOUNGHO 1671 +#define MACH_TYPE_YOUNGHOTEMA 1672 +#define MACH_TYPE_PCM037 1673 +#define MACH_TYPE_MMVP 1674 +#define MACH_TYPE_MMAP 1675 +#define MACH_TYPE_PTID2410 1676 +#define MACH_TYPE_JAMES_926 1677 +#define MACH_TYPE_FM6000 1678 +#define MACH_TYPE_DB88F6281_BP 1680 +#define MACH_TYPE_RD88F6192_NAS 1681 +#define MACH_TYPE_RD88F6281 1682 +#define MACH_TYPE_DB78X00_BP 1683 +#define MACH_TYPE_SMDK2416 1685 +#define MACH_TYPE_OCE_SPIDER_SI 1686 +#define MACH_TYPE_OCE_SPIDER_SK 1687 +#define MACH_TYPE_ROVERN6 1688 +#define MACH_TYPE_PELCO_EVOLUTION 1689 +#define MACH_TYPE_WBD111 1690 +#define MACH_TYPE_ELARACPE 1691 +#define MACH_TYPE_MABV3 1692 +#define MACH_TYPE_MV2120 1693 +#define MACH_TYPE_CSB737 1695 +#define MACH_TYPE_MX51_3DS 1696 +#define MACH_TYPE_G900 1697 +#define MACH_TYPE_APF27 1698 +#define MACH_TYPE_GGUS2000 1699 +#define MACH_TYPE_OMAP_2430_MIMIC 1700 +#define MACH_TYPE_IMX27LITE 1701 +#define MACH_TYPE_ALMEX 1702 +#define MACH_TYPE_CONTROL 1703 +#define MACH_TYPE_MBA2410 1704 +#define MACH_TYPE_VOLCANO 1705 +#define MACH_TYPE_ZENITH 1706 +#define MACH_TYPE_MUCHIP 1707 +#define MACH_TYPE_MAGELLAN 1708 +#define MACH_TYPE_USB_A9260 1709 +#define MACH_TYPE_USB_A9263 1710 +#define MACH_TYPE_QIL_A9260 1711 +#define MACH_TYPE_CME9210 1712 +#define MACH_TYPE_HCZH4 1713 +#define MACH_TYPE_SPEARBASIC 1714 +#define MACH_TYPE_DEP2440 1715 +#define MACH_TYPE_HDL_GXR 1716 +#define MACH_TYPE_HDL_GT 1717 +#define MACH_TYPE_HDL_4G 1718 +#define MACH_TYPE_S3C6000 1719 +#define MACH_TYPE_MMSP2_MDK 1720 +#define MACH_TYPE_MPX220 1721 +#define MACH_TYPE_KZM_ARM11_01 1722 +#define MACH_TYPE_HTC_POLARIS 1723 +#define MACH_TYPE_HTC_KAISER 1724 +#define MACH_TYPE_LG_KS20 1725 +#define MACH_TYPE_HHGPS 1726 +#define MACH_TYPE_NOKIA_N810_WIMAX 1727 +#define MACH_TYPE_INSIGHT 1728 +#define MACH_TYPE_SAPPHIRE 1729 +#define MACH_TYPE_CSB637XO 1730 +#define MACH_TYPE_EVISIONG 1731 +#define MACH_TYPE_STMP37XX 1732 +#define MACH_TYPE_STMP378X 1733 +#define MACH_TYPE_TNT 1734 +#define MACH_TYPE_TBXT 1735 +#define MACH_TYPE_PLAYMATE 1736 +#define MACH_TYPE_PNS10 1737 +#define MACH_TYPE_EZNAVI 1738 +#define MACH_TYPE_PS4000 1739 +#define MACH_TYPE_EZX_A780 1740 +#define MACH_TYPE_EZX_E680 1741 +#define MACH_TYPE_EZX_A1200 1742 +#define MACH_TYPE_EZX_E6 1743 +#define MACH_TYPE_EZX_E2 1744 +#define MACH_TYPE_EZX_A910 1745 +#define MACH_TYPE_CWMX31 1746 +#define MACH_TYPE_SL2312 1747 +#define MACH_TYPE_BLENNY 1748 +#define MACH_TYPE_DS107 1749 +#define MACH_TYPE_DSX07 1750 +#define MACH_TYPE_PICOCOM1 1751 +#define MACH_TYPE_LYNX_WOLVERINE 1752 +#define MACH_TYPE_UBISYS_P9_SC19 1753 +#define MACH_TYPE_KRATOS_LOW 1754 +#define MACH_TYPE_M700 1755 +#define MACH_TYPE_EDMINI_V2 1756 +#define MACH_TYPE_ZIPIT2 1757 +#define MACH_TYPE_HSLFEMTOCELL 1758 +#define MACH_TYPE_DAINTREE_AT91 1759 +#define MACH_TYPE_SG560USB 1760 +#define MACH_TYPE_OMAP3_PANDORA 1761 +#define MACH_TYPE_USR8200 1762 +#define MACH_TYPE_S1S65K 1763 +#define MACH_TYPE_S2S65A 1764 +#define MACH_TYPE_ICORE 1765 +#define MACH_TYPE_MSS2 1766 +#define MACH_TYPE_BELMONT 1767 +#define MACH_TYPE_ASUSP525 1768 +#define MACH_TYPE_LB88RC8480 1769 +#define MACH_TYPE_HIPXA 1770 +#define MACH_TYPE_MX25_3DS 1771 +#define MACH_TYPE_M800 1772 +#define MACH_TYPE_OMAP3530_LV_SOM 1773 +#define MACH_TYPE_PRIMA_EVB 1774 +#define MACH_TYPE_MX31BT1 1775 +#define MACH_TYPE_ATLAS4_EVB 1776 +#define MACH_TYPE_MX31CICADA 1777 +#define MACH_TYPE_MI424WR 1778 +#define MACH_TYPE_AXS_ULTRAX 1779 +#define MACH_TYPE_AT572D940DEB 1780 +#define MACH_TYPE_DAVINCI_DA830_EVM 1781 +#define MACH_TYPE_EP9302 1782 +#define MACH_TYPE_AT572D940HFEB 1783 +#define MACH_TYPE_CYBOOK3 1784 +#define MACH_TYPE_WDG002 1785 +#define MACH_TYPE_SG560ADSL 1786 +#define MACH_TYPE_NEXTIO_N2800_ICA 1787 +#define MACH_TYPE_DOVE_DB 1788 +#define MACH_TYPE_MARVELL_NEWDB 1789 +#define MACH_TYPE_VANDIHUD 1790 +#define MACH_TYPE_MAGX_E8 1791 +#define MACH_TYPE_MAGX_Z6 1792 +#define MACH_TYPE_MAGX_V8 1793 +#define MACH_TYPE_MAGX_U9 1794 +#define MACH_TYPE_TOUGHCF08 1795 +#define MACH_TYPE_ZW4400 1796 +#define MACH_TYPE_MARAT91 1797 +#define MACH_TYPE_OVERO 1798 +#define MACH_TYPE_AT2440EVB 1799 +#define MACH_TYPE_NEOCORE926 1800 +#define MACH_TYPE_WNR854T 1801 +#define MACH_TYPE_IMX27 1802 +#define MACH_TYPE_MOOSE_DB 1803 +#define MACH_TYPE_FAB4 1804 +#define MACH_TYPE_HTCDIAMOND 1805 +#define MACH_TYPE_FIONA 1806 +#define MACH_TYPE_MXC30030_X 1807 +#define MACH_TYPE_BMP1000 1808 +#define MACH_TYPE_LOGI9200 1809 +#define MACH_TYPE_TQMA31 1810 +#define MACH_TYPE_CCW9P9215JS 1811 +#define MACH_TYPE_RD88F5181L_GE 1812 +#define MACH_TYPE_SIFMAIN 1813 +#define MACH_TYPE_SAM9_L9261 1814 +#define MACH_TYPE_CC9M2443 1815 +#define MACH_TYPE_XARIA300 1816 +#define MACH_TYPE_IT9200 1817 +#define MACH_TYPE_RD88F5181L_FXO 1818 +#define MACH_TYPE_KRISS_SENSOR 1819 +#define MACH_TYPE_PILZ_PMI5 1820 +#define MACH_TYPE_JADE 1821 +#define MACH_TYPE_KS8695_SOFTPLC 1822 +#define MACH_TYPE_GPRISC3 1823 +#define MACH_TYPE_STAMP9G20 1824 +#define MACH_TYPE_SMDK6430 1825 +#define MACH_TYPE_SMDKC100 1826 +#define MACH_TYPE_TAVOREVB 1827 +#define MACH_TYPE_SAAR 1828 +#define MACH_TYPE_DEISTER_EYECAM 1829 +#define MACH_TYPE_AT91SAM9M10G45EK 1830 +#define MACH_TYPE_LINKSTATION_PRODUO 1831 +#define MACH_TYPE_HIT_B0 1832 +#define MACH_TYPE_ADX_RMU 1833 +#define MACH_TYPE_XG_CPE_MAIN 1834 +#define MACH_TYPE_EDB9407A 1835 +#define MACH_TYPE_DTB9608 1836 +#define MACH_TYPE_EM104V1 1837 +#define MACH_TYPE_DEMO 1838 +#define MACH_TYPE_LOGI9260 1839 +#define MACH_TYPE_MX31_EXM32 1840 +#define MACH_TYPE_USB_A9G20 1841 +#define MACH_TYPE_PICPROJE2008 1842 +#define MACH_TYPE_CS_E9315 1843 +#define MACH_TYPE_QIL_A9G20 1844 +#define MACH_TYPE_SHA_PON020 1845 +#define MACH_TYPE_NAD 1846 +#define MACH_TYPE_SBC35_A9260 1847 +#define MACH_TYPE_SBC35_A9G20 1848 +#define MACH_TYPE_DAVINCI_BEGINNING 1849 +#define MACH_TYPE_UWC 1850 +#define MACH_TYPE_MXLADS 1851 +#define MACH_TYPE_HTCNIKE 1852 +#define MACH_TYPE_DEISTER_PXA270 1853 +#define MACH_TYPE_CME9210JS 1854 +#define MACH_TYPE_CC9P9360 1855 +#define MACH_TYPE_MOCHA 1856 +#define MACH_TYPE_WAPD170AG 1857 +#define MACH_TYPE_LINKSTATION_MINI 1858 +#define MACH_TYPE_AFEB9260 1859 +#define MACH_TYPE_W90X900 1860 +#define MACH_TYPE_W90X700 1861 +#define MACH_TYPE_KT300IP 1862 +#define MACH_TYPE_KT300IP_G20 1863 +#define MACH_TYPE_SRCM 1864 +#define MACH_TYPE_WLNX_9260 1865 +#define MACH_TYPE_OPENMOKO_GTA03 1866 +#define MACH_TYPE_OSPREY2 1867 +#define MACH_TYPE_KBIO9260 1868 +#define MACH_TYPE_GINZA 1869 +#define MACH_TYPE_A636N 1870 +#define MACH_TYPE_IMX27IPCAM 1871 +#define MACH_TYPE_NEMOC 1872 +#define MACH_TYPE_GENEVA 1873 +#define MACH_TYPE_HTCPHAROS 1874 +#define MACH_TYPE_NEONC 1875 +#define MACH_TYPE_NAS7100 1876 +#define MACH_TYPE_TEUPHONE 1877 +#define MACH_TYPE_ANNAX_ETH2 1878 +#define MACH_TYPE_CSB733 1879 +#define MACH_TYPE_BK3 1880 +#define MACH_TYPE_OMAP_EM32 1881 +#define MACH_TYPE_ET9261CP 1882 +#define MACH_TYPE_JASPERC 1883 +#define MACH_TYPE_ISSI_ARM9 1884 +#define MACH_TYPE_UED 1885 +#define MACH_TYPE_ESIBLADE 1886 +#define MACH_TYPE_EYE02 1887 +#define MACH_TYPE_IMX27KBD 1888 +#define MACH_TYPE_SST61VC010_FPGA 1889 +#define MACH_TYPE_KIXVP435 1890 +#define MACH_TYPE_KIXNP435 1891 +#define MACH_TYPE_AFRICA 1892 +#define MACH_TYPE_NH233 1893 +#define MACH_TYPE_RD88F6183AP_GE 1894 +#define MACH_TYPE_BCM4760 1895 +#define MACH_TYPE_EDDY_V2 1896 +#define MACH_TYPE_REALVIEW_PBA8 1897 +#define MACH_TYPE_HID_A7 1898 +#define MACH_TYPE_HERO 1899 +#define MACH_TYPE_OMAP_POSEIDON 1900 +#define MACH_TYPE_REALVIEW_PBX 1901 +#define MACH_TYPE_MICRO9S 1902 +#define MACH_TYPE_MAKO 1903 +#define MACH_TYPE_XDAFLAME 1904 +#define MACH_TYPE_PHIDGET_SBC2 1905 +#define MACH_TYPE_LIMESTONE 1906 +#define MACH_TYPE_IPROBE_C32 1907 +#define MACH_TYPE_RUT100 1908 +#define MACH_TYPE_ASUSP535 1909 +#define MACH_TYPE_HTCRAPHAEL 1910 +#define MACH_TYPE_SYGDG1 1911 +#define MACH_TYPE_SYGDG2 1912 +#define MACH_TYPE_SEOUL 1913 +#define MACH_TYPE_SALERNO 1914 +#define MACH_TYPE_UCN_S3C64XX 1915 +#define MACH_TYPE_MSM7201A 1916 +#define MACH_TYPE_LPR1 1917 +#define MACH_TYPE_ARMADILLO500FX 1918 +#define MACH_TYPE_G3EVM 1919 +#define MACH_TYPE_Z3_DM355 1920 +#define MACH_TYPE_W90P910EVB 1921 +#define MACH_TYPE_W90P920EVB 1922 +#define MACH_TYPE_W90P950EVB 1923 +#define MACH_TYPE_W90N960EVB 1924 +#define MACH_TYPE_CAMHD 1925 +#define MACH_TYPE_MVC100 1926 +#define MACH_TYPE_ELECTRUM_200 1927 +#define MACH_TYPE_HTCJADE 1928 +#define MACH_TYPE_MEMPHIS 1929 +#define MACH_TYPE_IMX27SBC 1930 +#define MACH_TYPE_LEXTAR 1931 +#define MACH_TYPE_MV88F6281GTW_GE 1932 +#define MACH_TYPE_NCP 1933 +#define MACH_TYPE_Z32AN 1934 +#define MACH_TYPE_TMQ_CAPD 1935 +#define MACH_TYPE_OMAP3_WL 1936 +#define MACH_TYPE_CHUMBY 1937 +#define MACH_TYPE_ATSARM9 1938 +#define MACH_TYPE_DAVINCI_DM365_EVM 1939 +#define MACH_TYPE_BAHAMAS 1940 +#define MACH_TYPE_DAS 1941 +#define MACH_TYPE_MINIDAS 1942 +#define MACH_TYPE_VK1000 1943 +#define MACH_TYPE_CENTRO 1944 +#define MACH_TYPE_CTERA_2BAY 1945 +#define MACH_TYPE_EDGECONNECT 1946 +#define MACH_TYPE_ND27000 1947 +#define MACH_TYPE_GEMALTO_COBRA 1948 +#define MACH_TYPE_INGELABS_COMET 1949 +#define MACH_TYPE_POLLUX_WIZ 1950 +#define MACH_TYPE_BLACKSTONE 1951 +#define MACH_TYPE_TOPAZ 1952 +#define MACH_TYPE_AIXLE 1953 +#define MACH_TYPE_MW998 1954 +#define MACH_TYPE_NOKIA_RX51 1955 +#define MACH_TYPE_VSC5605EV 1956 +#define MACH_TYPE_NT98700DK 1957 +#define MACH_TYPE_ICONTACT 1958 +#define MACH_TYPE_SWARCO_FRCPU 1959 +#define MACH_TYPE_SWARCO_SCPU 1960 +#define MACH_TYPE_BBOX_P16 1961 +#define MACH_TYPE_BSTD 1962 +#define MACH_TYPE_SBC2440II 1963 +#define MACH_TYPE_PCM034 1964 +#define MACH_TYPE_NESO 1965 +#define MACH_TYPE_WLNX_9G20 1966 +#define MACH_TYPE_OMAP_ZOOM2 1967 +#define MACH_TYPE_TOTEMNOVA 1968 +#define MACH_TYPE_C5000 1969 +#define MACH_TYPE_UNIPO_AT91SAM9263 1970 +#define MACH_TYPE_ETHERNUT5 1971 +#define MACH_TYPE_ARM11 1972 +#define MACH_TYPE_CPUAT9260 1973 +#define MACH_TYPE_CPUPXA255 1974 +#define MACH_TYPE_CPUIMX27 1975 +#define MACH_TYPE_CHEFLUX 1976 +#define MACH_TYPE_EB_CPUX9K2 1977 +#define MACH_TYPE_OPCOTEC 1978 +#define MACH_TYPE_YT 1979 +#define MACH_TYPE_MOTOQ 1980 +#define MACH_TYPE_BSB1 1981 +#define MACH_TYPE_ACS5K 1982 +#define MACH_TYPE_MILAN 1983 +#define MACH_TYPE_QUARTZV2 1984 +#define MACH_TYPE_RSVP 1985 +#define MACH_TYPE_RMP200 1986 +#define MACH_TYPE_SNAPPER_9260 1987 +#define MACH_TYPE_DSM320 1988 +#define MACH_TYPE_ADSGCM 1989 +#define MACH_TYPE_ASE2_400 1990 +#define MACH_TYPE_PIZZA 1991 +#define MACH_TYPE_SPOT_NGPL 1992 +#define MACH_TYPE_ARMATA 1993 +#define MACH_TYPE_EXEDA 1994 +#define MACH_TYPE_MX31SF005 1995 +#define MACH_TYPE_F5D8231_4_V2 1996 +#define MACH_TYPE_Q2440 1997 +#define MACH_TYPE_QQ2440 1998 +#define MACH_TYPE_MINI2440 1999 +#define MACH_TYPE_COLIBRI300 2000 +#define MACH_TYPE_JADES 2001 +#define MACH_TYPE_SPARK 2002 +#define MACH_TYPE_BENZINA 2003 +#define MACH_TYPE_BLAZE 2004 +#define MACH_TYPE_LINKSTATION_LS_HGL 2005 +#define MACH_TYPE_HTCKOVSKY 2006 +#define MACH_TYPE_SONY_PRS505 2007 +#define MACH_TYPE_HANLIN_V3 2008 +#define MACH_TYPE_SAPPHIRA 2009 +#define MACH_TYPE_DACK_SDA_01 2010 +#define MACH_TYPE_ARMBOX 2011 +#define MACH_TYPE_HARRIS_RVP 2012 +#define MACH_TYPE_RIBALDO 2013 +#define MACH_TYPE_AGORA 2014 +#define MACH_TYPE_OMAP3_MINI 2015 +#define MACH_TYPE_A9SAM6432_B 2016 +#define MACH_TYPE_USG2410 2017 +#define MACH_TYPE_PC72052_I10_REVB 2018 +#define MACH_TYPE_MX35_EXM32 2019 +#define MACH_TYPE_TOPAS910 2020 +#define MACH_TYPE_HYENA 2021 +#define MACH_TYPE_POSPAX 2022 +#define MACH_TYPE_HDL_GX 2023 +#define MACH_TYPE_CTERA_4BAY 2024 +#define MACH_TYPE_CTERA_PLUG_C 2025 +#define MACH_TYPE_CRWEA_PLUG_I 2026 +#define MACH_TYPE_EGAUGE2 2027 +#define MACH_TYPE_DIDJ 2028 +#define MACH_TYPE_MEISTER 2029 +#define MACH_TYPE_HTCBLACKSTONE 2030 +#define MACH_TYPE_CPUAT9G20 2031 +#define MACH_TYPE_SMDK6440 2032 +#define MACH_TYPE_OMAP_35XX_MVP 2033 +#define MACH_TYPE_CTERA_PLUG_I 2034 +#define MACH_TYPE_PVG610 2035 +#define MACH_TYPE_HPRW6815 2036 +#define MACH_TYPE_OMAP3_OSWALD 2037 +#define MACH_TYPE_NAS4220B 2038 +#define MACH_TYPE_HTCRAPHAEL_CDMA 2039 +#define MACH_TYPE_HTCDIAMOND_CDMA 2040 +#define MACH_TYPE_SCALER 2041 +#define MACH_TYPE_ZYLONITE2 2042 +#define MACH_TYPE_ASPENITE 2043 +#define MACH_TYPE_TETON 2044 +#define MACH_TYPE_TTC_DKB 2045 +#define MACH_TYPE_BISHOP2 2046 +#define MACH_TYPE_IPPV5 2047 +#define MACH_TYPE_FARM926 2048 +#define MACH_TYPE_MMCCPU 2049 +#define MACH_TYPE_SGMSFL 2050 +#define MACH_TYPE_TT8000 2051 +#define MACH_TYPE_ZRN4300LP 2052 +#define MACH_TYPE_MPTC 2053 +#define MACH_TYPE_H6051 2054 +#define MACH_TYPE_PVG610_101 2055 +#define MACH_TYPE_STAMP9261_PC_EVB 2056 +#define MACH_TYPE_PELCO_ODYSSEUS 2057 +#define MACH_TYPE_TNY_A9260 2058 +#define MACH_TYPE_TNY_A9G20 2059 +#define MACH_TYPE_AESOP_MP2530F 2060 +#define MACH_TYPE_DX900 2061 +#define MACH_TYPE_CPODC2 2062 +#define MACH_TYPE_TILT_8925 2063 +#define MACH_TYPE_DAVINCI_DM357_EVM 2064 +#define MACH_TYPE_SWORDFISH 2065 +#define MACH_TYPE_CORVUS 2066 +#define MACH_TYPE_TAURUS 2067 +#define MACH_TYPE_AXM 2068 +#define MACH_TYPE_AXC 2069 +#define MACH_TYPE_BABY 2070 +#define MACH_TYPE_MP200 2071 +#define MACH_TYPE_PCM043 2072 +#define MACH_TYPE_HANLIN_V3C 2073 +#define MACH_TYPE_KBK9G20 2074 +#define MACH_TYPE_ADSTURBOG5 2075 +#define MACH_TYPE_AVENGER_LITE1 2076 +#define MACH_TYPE_SUC 2077 +#define MACH_TYPE_AT91SAM7S256 2078 +#define MACH_TYPE_MENDOZA 2079 +#define MACH_TYPE_KIRA 2080 +#define MACH_TYPE_MX1HBM 2081 +#define MACH_TYPE_QUATRO43XX 2082 +#define MACH_TYPE_QUATRO4230 2083 +#define MACH_TYPE_NSB400 2084 +#define MACH_TYPE_DRP255 2085 +#define MACH_TYPE_THOTH 2086 +#define MACH_TYPE_FIRESTONE 2087 +#define MACH_TYPE_ASUSP750 2088 +#define MACH_TYPE_CTERA_DL 2089 +#define MACH_TYPE_SOCR 2090 +#define MACH_TYPE_HTCOXYGEN 2091 +#define MACH_TYPE_HEROC 2092 +#define MACH_TYPE_ZENO6800 2093 +#define MACH_TYPE_SC2MCS 2094 +#define MACH_TYPE_GENE100 2095 +#define MACH_TYPE_AS353X 2096 +#define MACH_TYPE_SHEEVAPLUG 2097 +#define MACH_TYPE_AT91SAM9G20 2098 +#define MACH_TYPE_MV88F6192GTW_FE 2099 +#define MACH_TYPE_CC9200 2100 +#define MACH_TYPE_SM9200 2101 +#define MACH_TYPE_TP9200 2102 +#define MACH_TYPE_SNAPPERDV 2103 +#define MACH_TYPE_AVENGERS_LITE 2104 +#define MACH_TYPE_AVENGERS_LITE1 2105 +#define MACH_TYPE_OMAP3AXON 2106 +#define MACH_TYPE_MA8XX 2107 +#define MACH_TYPE_MP201EK 2108 +#define MACH_TYPE_DAVINCI_TUX 2109 +#define MACH_TYPE_MPA1600 2110 +#define MACH_TYPE_PELCO_TROY 2111 +#define MACH_TYPE_NSB667 2112 +#define MACH_TYPE_ROVERS5_4MPIX 2113 +#define MACH_TYPE_TWOCOM 2114 +#define MACH_TYPE_UBISYS_P9_RCU3R2 2115 +#define MACH_TYPE_HERO_ESPRESSO 2116 +#define MACH_TYPE_AFEUSB 2117 +#define MACH_TYPE_T830 2118 +#define MACH_TYPE_SPD8020_CC 2119 +#define MACH_TYPE_OM_3D7K 2120 +#define MACH_TYPE_PICOCOM2 2121 +#define MACH_TYPE_UWG4MX27 2122 +#define MACH_TYPE_UWG4MX31 2123 +#define MACH_TYPE_CHERRY 2124 +#define MACH_TYPE_MX51_BABBAGE 2125 +#define MACH_TYPE_S3C2440TURKIYE 2126 +#define MACH_TYPE_TX37 2127 +#define MACH_TYPE_SBC2800_9G20 2128 +#define MACH_TYPE_BENZGLB 2129 +#define MACH_TYPE_BENZTD 2130 +#define MACH_TYPE_CARTESIO_PLUS 2131 +#define MACH_TYPE_SOLRAD_G20 2132 +#define MACH_TYPE_MX27WALLACE 2133 +#define MACH_TYPE_FMZWEBMODUL 2134 +#define MACH_TYPE_RD78X00_MASA 2135 +#define MACH_TYPE_SMALLOGGER 2136 +#define MACH_TYPE_CCW9P9215 2137 +#define MACH_TYPE_DM355_LEOPARD 2138 +#define MACH_TYPE_TS219 2139 +#define MACH_TYPE_TNY_A9263 2140 +#define MACH_TYPE_APOLLO 2141 +#define MACH_TYPE_AT91CAP9STK 2142 +#define MACH_TYPE_SPC300 2143 +#define MACH_TYPE_EKO 2144 +#define MACH_TYPE_CCW9M2443 2145 +#define MACH_TYPE_CCW9M2443JS 2146 +#define MACH_TYPE_M2M_ROUTER_DEVICE 2147 +#define MACH_TYPE_STAR9104NAS 2148 +#define MACH_TYPE_PCA100 2149 +#define MACH_TYPE_Z3_DM365_MOD_01 2150 +#define MACH_TYPE_HIPOX 2151 +#define MACH_TYPE_OMAP3_PITEDS 2152 +#define MACH_TYPE_BM150R 2153 +#define MACH_TYPE_TBONE 2154 +#define MACH_TYPE_MERLIN 2155 +#define MACH_TYPE_FALCON 2156 +#define MACH_TYPE_DAVINCI_DA850_EVM 2157 +#define MACH_TYPE_S5P6440 2158 +#define MACH_TYPE_AT91SAM9G10EK 2159 +#define MACH_TYPE_OMAP_4430SDP 2160 +#define MACH_TYPE_LPC313X 2161 +#define MACH_TYPE_MAGX_ZN5 2162 +#define MACH_TYPE_MAGX_EM30 2163 +#define MACH_TYPE_MAGX_VE66 2164 +#define MACH_TYPE_MEESC 2165 +#define MACH_TYPE_OTC570 2166 +#define MACH_TYPE_BCU2412 2167 +#define MACH_TYPE_BEACON 2168 +#define MACH_TYPE_ACTIA_TGW 2169 +#define MACH_TYPE_E4430 2170 +#define MACH_TYPE_QL300 2171 +#define MACH_TYPE_BTMAVB101 2172 +#define MACH_TYPE_BTMAWB101 2173 +#define MACH_TYPE_SQ201 2174 +#define MACH_TYPE_QUATRO45XX 2175 +#define MACH_TYPE_OPENPAD 2176 +#define MACH_TYPE_TX25 2177 +#define MACH_TYPE_OMAP3_TORPEDO 2178 +#define MACH_TYPE_HTCRAPHAEL_K 2179 +#define MACH_TYPE_LAL43 2181 +#define MACH_TYPE_HTCRAPHAEL_CDMA500 2182 +#define MACH_TYPE_ANW6410 2183 +#define MACH_TYPE_HTCPROPHET 2185 +#define MACH_TYPE_CFA_10022 2186 +#define MACH_TYPE_IMX27_VISSTRIM_M10 2187 +#define MACH_TYPE_PX2IMX27 2188 +#define MACH_TYPE_STM3210E_EVAL 2189 +#define MACH_TYPE_DVS10 2190 +#define MACH_TYPE_PORTUXG20 2191 +#define MACH_TYPE_ARM_SPV 2192 +#define MACH_TYPE_SMDKC110 2193 +#define MACH_TYPE_CABESPRESSO 2194 +#define MACH_TYPE_HMC800 2195 +#define MACH_TYPE_SHOLES 2196 +#define MACH_TYPE_BTMXC31 2197 +#define MACH_TYPE_DT501 2198 +#define MACH_TYPE_KTX 2199 +#define MACH_TYPE_OMAP3517EVM 2200 +#define MACH_TYPE_NETSPACE_V2 2201 +#define MACH_TYPE_NETSPACE_MAX_V2 2202 +#define MACH_TYPE_D2NET_V2 2203 +#define MACH_TYPE_NET2BIG_V2 2204 +#define MACH_TYPE_NET4BIG_V2 2205 +#define MACH_TYPE_NET5BIG_V2 2206 +#define MACH_TYPE_ENDB2443 2207 +#define MACH_TYPE_INETSPACE_V2 2208 +#define MACH_TYPE_TROS 2209 +#define MACH_TYPE_PELCO_HOMER 2210 +#define MACH_TYPE_OFSP8 2211 +#define MACH_TYPE_AT91SAM9G45EKES 2212 +#define MACH_TYPE_GUF_CUPID 2213 +#define MACH_TYPE_EAB1R 2214 +#define MACH_TYPE_DESIREC 2215 +#define MACH_TYPE_CORDOBA 2216 +#define MACH_TYPE_IRVINE 2217 +#define MACH_TYPE_SFF772 2218 +#define MACH_TYPE_PELCO_MILANO 2219 +#define MACH_TYPE_PC7302 2220 +#define MACH_TYPE_BIP6000 2221 +#define MACH_TYPE_SILVERMOON 2222 +#define MACH_TYPE_VC0830 2223 +#define MACH_TYPE_DT430 2224 +#define MACH_TYPE_JI42PF 2225 +#define MACH_TYPE_GNET_KSM 2226 +#define MACH_TYPE_GNET_SGM 2227 +#define MACH_TYPE_GNET_SGR 2228 +#define MACH_TYPE_OMAP3_ICETEKEVM 2229 +#define MACH_TYPE_PNP 2230 +#define MACH_TYPE_CTERA_2BAY_K 2231 +#define MACH_TYPE_CTERA_2BAY_U 2232 +#define MACH_TYPE_SAS_C 2233 +#define MACH_TYPE_VMA2315 2234 +#define MACH_TYPE_VCS 2235 +#define MACH_TYPE_SPEAR600 2236 +#define MACH_TYPE_SPEAR300 2237 +#define MACH_TYPE_SPEAR1300 2238 +#define MACH_TYPE_LILLY1131 2239 +#define MACH_TYPE_ARVOO_AX301 2240 +#define MACH_TYPE_MAPPHONE 2241 +#define MACH_TYPE_LEGEND 2242 +#define MACH_TYPE_SALSA 2243 +#define MACH_TYPE_LOUNGE 2244 +#define MACH_TYPE_VISION 2245 +#define MACH_TYPE_VMB20 2246 +#define MACH_TYPE_HY2410 2247 +#define MACH_TYPE_HY9315 2248 +#define MACH_TYPE_BULLWINKLE 2249 +#define MACH_TYPE_ARM_ULTIMATOR2 2250 +#define MACH_TYPE_VS_V210 2252 +#define MACH_TYPE_VS_V212 2253 +#define MACH_TYPE_HMT 2254 +#define MACH_TYPE_SUEN3 2255 +#define MACH_TYPE_VESPER 2256 +#define MACH_TYPE_STR9 2257 +#define MACH_TYPE_OMAP3_WL_FF 2258 +#define MACH_TYPE_SIMCOM 2259 +#define MACH_TYPE_MCWEBIO 2260 +#define MACH_TYPE_OMAP3_PHRAZER 2261 +#define MACH_TYPE_DARWIN 2262 +#define MACH_TYPE_ORATISCOMU 2263 +#define MACH_TYPE_RTSBC20 2264 +#define MACH_TYPE_I780 2265 +#define MACH_TYPE_GEMINI324 2266 +#define MACH_TYPE_ORATISLAN 2267 +#define MACH_TYPE_ORATISALOG 2268 +#define MACH_TYPE_ORATISMADI 2269 +#define MACH_TYPE_ORATISOT16 2270 +#define MACH_TYPE_ORATISDESK 2271 +#define MACH_TYPE_VEXPRESS 2272 +#define MACH_TYPE_SINTEXO 2273 +#define MACH_TYPE_CM3389 2274 +#define MACH_TYPE_OMAP3_CIO 2275 +#define MACH_TYPE_SGH_I900 2276 +#define MACH_TYPE_BST100 2277 +#define MACH_TYPE_PASSION 2278 +#define MACH_TYPE_INDESIGN_AT91SAM 2279 +#define MACH_TYPE_C4_BADGER 2280 +#define MACH_TYPE_C4_VIPER 2281 +#define MACH_TYPE_D2NET 2282 +#define MACH_TYPE_BIGDISK 2283 +#define MACH_TYPE_NOTALVISION 2284 +#define MACH_TYPE_OMAP3_KBOC 2285 +#define MACH_TYPE_CYCLONE 2286 +#define MACH_TYPE_NINJA 2287 +#define MACH_TYPE_AT91SAM9G20EK_2MMC 2288 +#define MACH_TYPE_BCMRING 2289 +#define MACH_TYPE_RESOL_DL2 2290 +#define MACH_TYPE_IFOSW 2291 +#define MACH_TYPE_HTCRHODIUM 2292 +#define MACH_TYPE_HTCTOPAZ 2293 +#define MACH_TYPE_MATRIX504 2294 +#define MACH_TYPE_MRFSA 2295 +#define MACH_TYPE_SC_P270 2296 +#define MACH_TYPE_ATLAS5_EVB 2297 +#define MACH_TYPE_PELCO_LOBOX 2298 +#define MACH_TYPE_DILAX_PCU200 2299 +#define MACH_TYPE_LEONARDO 2300 +#define MACH_TYPE_ZORAN_APPROACH7 2301 +#define MACH_TYPE_DP6XX 2302 +#define MACH_TYPE_BCM2153_VESPER 2303 +#define MACH_TYPE_MAHIMAHI 2304 +#define MACH_TYPE_CLICKC 2305 +#define MACH_TYPE_ZB_GATEWAY 2306 +#define MACH_TYPE_TAZCARD 2307 +#define MACH_TYPE_TAZDEV 2308 +#define MACH_TYPE_ANNAX_CB_ARM 2309 +#define MACH_TYPE_ANNAX_DM3 2310 +#define MACH_TYPE_CEREBRIC 2311 +#define MACH_TYPE_ORCA 2312 +#define MACH_TYPE_PC9260 2313 +#define MACH_TYPE_EMS285A 2314 +#define MACH_TYPE_GEC2410 2315 +#define MACH_TYPE_GEC2440 2316 +#define MACH_TYPE_ARCH_MW903 2317 +#define MACH_TYPE_MW2440 2318 +#define MACH_TYPE_ECAC2378 2319 +#define MACH_TYPE_TAZKIOSK 2320 +#define MACH_TYPE_WHITERABBIT_MCH 2321 +#define MACH_TYPE_SBOX9263 2322 +#define MACH_TYPE_OREO 2323 +#define MACH_TYPE_SMDK6442 2324 +#define MACH_TYPE_OPENRD_BASE 2325 +#define MACH_TYPE_INCREDIBLE 2326 +#define MACH_TYPE_INCREDIBLEC 2327 +#define MACH_TYPE_HEROCT 2328 +#define MACH_TYPE_MMNET1000 2329 +#define MACH_TYPE_DEVKIT8000 2330 +#define MACH_TYPE_DEVKIT9000 2331 +#define MACH_TYPE_MX31TXTR 2332 +#define MACH_TYPE_U380 2333 +#define MACH_TYPE_HUALU_BOARD 2334 +#define MACH_TYPE_NPCMX50 2335 +#define MACH_TYPE_MX51_LANGE51 2336 +#define MACH_TYPE_MX51_LANGE52 2337 +#define MACH_TYPE_RIOM 2338 +#define MACH_TYPE_COMCAS 2339 +#define MACH_TYPE_WSI_MX27 2340 +#define MACH_TYPE_CM_T35 2341 +#define MACH_TYPE_NET2BIG 2342 +#define MACH_TYPE_MOTOROLA_A1600 2343 +#define MACH_TYPE_IGEP0020 2344 +#define MACH_TYPE_IGEP0010 2345 +#define MACH_TYPE_MV6281GTWGE2 2346 +#define MACH_TYPE_SCAT100 2347 +#define MACH_TYPE_SANMINA 2348 +#define MACH_TYPE_MOMENTO 2349 +#define MACH_TYPE_NUC9XX 2350 +#define MACH_TYPE_NUC910EVB 2351 +#define MACH_TYPE_NUC920EVB 2352 +#define MACH_TYPE_NUC950EVB 2353 +#define MACH_TYPE_NUC945EVB 2354 +#define MACH_TYPE_NUC960EVB 2355 +#define MACH_TYPE_NUC932EVB 2356 +#define MACH_TYPE_NUC900 2357 +#define MACH_TYPE_SD1SOC 2358 +#define MACH_TYPE_LN2440BC 2359 +#define MACH_TYPE_RSBC 2360 +#define MACH_TYPE_OPENRD_CLIENT 2361 +#define MACH_TYPE_HPIPAQ11X 2362 +#define MACH_TYPE_WAYLAND 2363 +#define MACH_TYPE_ACNBSX102 2364 +#define MACH_TYPE_HWAT91 2365 +#define MACH_TYPE_AT91SAM9263CS 2366 +#define MACH_TYPE_CSB732 2367 +#define MACH_TYPE_U8500 2368 +#define MACH_TYPE_HUQIU 2369 +#define MACH_TYPE_MX51_KUNLUN 2370 +#define MACH_TYPE_PMT1G 2371 +#define MACH_TYPE_HTCELF 2372 +#define MACH_TYPE_ARMADILLO420 2373 +#define MACH_TYPE_ARMADILLO440 2374 +#define MACH_TYPE_U_CHIP_DUAL_ARM 2375 +#define MACH_TYPE_CSR_BDB3 2376 +#define MACH_TYPE_DOLBY_CAT1018 2377 +#define MACH_TYPE_HY9307 2378 +#define MACH_TYPE_A_ES 2379 +#define MACH_TYPE_DAVINCI_IRIF 2380 +#define MACH_TYPE_AGAMA9263 2381 +#define MACH_TYPE_MARVELL_JASPER 2382 +#define MACH_TYPE_FLINT 2383 +#define MACH_TYPE_TAVOREVB3 2384 +#define MACH_TYPE_SCH_M490 2386 +#define MACH_TYPE_RBL01 2387 +#define MACH_TYPE_OMNIFI 2388 +#define MACH_TYPE_OTAVALO 2389 +#define MACH_TYPE_SIENNA 2390 +#define MACH_TYPE_HTC_EXCALIBUR_S620 2391 +#define MACH_TYPE_HTC_OPAL 2392 +#define MACH_TYPE_TOUCHBOOK 2393 +#define MACH_TYPE_LATTE 2394 +#define MACH_TYPE_XA200 2395 +#define MACH_TYPE_NIMROD 2396 +#define MACH_TYPE_CC9P9215_3G 2397 +#define MACH_TYPE_CC9P9215_3GJS 2398 +#define MACH_TYPE_TK71 2399 +#define MACH_TYPE_COMHAM3525 2400 +#define MACH_TYPE_MX31EREBUS 2401 +#define MACH_TYPE_MCARDMX27 2402 +#define MACH_TYPE_PARADISE 2403 +#define MACH_TYPE_TIDE 2404 +#define MACH_TYPE_WZL2440 2405 +#define MACH_TYPE_SDRDEMO 2406 +#define MACH_TYPE_ETHERCAN2 2407 +#define MACH_TYPE_ECMIMG20 2408 +#define MACH_TYPE_OMAP_DRAGON 2409 +#define MACH_TYPE_HALO 2410 +#define MACH_TYPE_HUANGSHAN 2411 +#define MACH_TYPE_VL_MA2SC 2412 +#define MACH_TYPE_RAUMFELD_RC 2413 +#define MACH_TYPE_RAUMFELD_CONNECTOR 2414 +#define MACH_TYPE_RAUMFELD_SPEAKER 2415 +#define MACH_TYPE_MULTIBUS_MASTER 2416 +#define MACH_TYPE_MULTIBUS_PBK 2417 +#define MACH_TYPE_TNETV107X 2418 +#define MACH_TYPE_SNAKE 2419 +#define MACH_TYPE_CWMX27 2420 +#define MACH_TYPE_SCH_M480 2421 +#define MACH_TYPE_PLATYPUS 2422 +#define MACH_TYPE_PSS2 2423 +#define MACH_TYPE_DAVINCI_APM150 2424 +#define MACH_TYPE_STR9100 2425 +#define MACH_TYPE_NET5BIG 2426 +#define MACH_TYPE_SEABED9263 2427 +#define MACH_TYPE_MX51_M2ID 2428 +#define MACH_TYPE_OCTVOCPLUS_EB 2429 +#define MACH_TYPE_KLK_FIREFOX 2430 +#define MACH_TYPE_KLK_WIRMA_MODULE 2431 +#define MACH_TYPE_KLK_WIRMA_MMI 2432 +#define MACH_TYPE_SUPERSONIC 2433 +#define MACH_TYPE_LIBERTY 2434 +#define MACH_TYPE_MH355 2435 +#define MACH_TYPE_PC7802 2436 +#define MACH_TYPE_GNET_SGC 2437 +#define MACH_TYPE_EINSTEIN15 2438 +#define MACH_TYPE_CMPD 2439 +#define MACH_TYPE_DAVINCI_HASE1 2440 +#define MACH_TYPE_LGEINCITEPHONE 2441 +#define MACH_TYPE_EA313X 2442 +#define MACH_TYPE_FWBD_39064 2443 +#define MACH_TYPE_FWBD_390128 2444 +#define MACH_TYPE_PELCO_MOE 2445 +#define MACH_TYPE_MINIMIX27 2446 +#define MACH_TYPE_OMAP3_THUNDER 2447 +#define MACH_TYPE_PASSIONC 2448 +#define MACH_TYPE_MX27AMATA 2449 +#define MACH_TYPE_BGAT1 2450 +#define MACH_TYPE_BUZZ 2451 +#define MACH_TYPE_MB9G20 2452 +#define MACH_TYPE_YUSHAN 2453 +#define MACH_TYPE_LIZARD 2454 +#define MACH_TYPE_OMAP3POLYCOM 2455 +#define MACH_TYPE_SMDKV210 2456 +#define MACH_TYPE_BRAVO 2457 +#define MACH_TYPE_SIOGENTOO1 2458 +#define MACH_TYPE_SIOGENTOO2 2459 +#define MACH_TYPE_SM3K 2460 +#define MACH_TYPE_ACER_TEMPO_F900 2461 +#define MACH_TYPE_SST61VC010_DEV 2462 +#define MACH_TYPE_GLITTERTIND 2463 +#define MACH_TYPE_OMAP_ZOOM3 2464 +#define MACH_TYPE_OMAP_3630SDP 2465 +#define MACH_TYPE_CYBOOK2440 2466 +#define MACH_TYPE_TORINO_S 2467 +#define MACH_TYPE_HAVANA 2468 +#define MACH_TYPE_BEAUMONT_11 2469 +#define MACH_TYPE_VANGUARD 2470 +#define MACH_TYPE_S5PC110_DRACO 2471 +#define MACH_TYPE_CARTESIO_TWO 2472 +#define MACH_TYPE_ASTER 2473 +#define MACH_TYPE_VOGUESV210 2474 +#define MACH_TYPE_ACM500X 2475 +#define MACH_TYPE_KM9260 2476 +#define MACH_TYPE_NIDEFLEXG1 2477 +#define MACH_TYPE_CTERA_PLUG_IO 2478 +#define MACH_TYPE_SMARTQ7 2479 +#define MACH_TYPE_AT91SAM9G10EK2 2480 +#define MACH_TYPE_ASUSP527 2481 +#define MACH_TYPE_AT91SAM9G20MPM2 2482 +#define MACH_TYPE_TOPASA900 2483 +#define MACH_TYPE_ELECTRUM_100 2484 +#define MACH_TYPE_MX51GRB 2485 +#define MACH_TYPE_XEA300 2486 +#define MACH_TYPE_HTCSTARTREK 2487 +#define MACH_TYPE_LIMA 2488 +#define MACH_TYPE_CSB740 2489 +#define MACH_TYPE_USB_S8815 2490 +#define MACH_TYPE_WATSON_EFM_PLUGIN 2491 +#define MACH_TYPE_MILKYWAY 2492 +#define MACH_TYPE_G4EVM 2493 +#define MACH_TYPE_PICOMOD6 2494 +#define MACH_TYPE_OMAPL138_HAWKBOARD 2495 +#define MACH_TYPE_IP6000 2496 +#define MACH_TYPE_IP6010 2497 +#define MACH_TYPE_UTM400 2498 +#define MACH_TYPE_OMAP3_ZYBEX 2499 +#define MACH_TYPE_WIRELESS_SPACE 2500 +#define MACH_TYPE_SX560 2501 +#define MACH_TYPE_TS41X 2502 +#define MACH_TYPE_ELPHEL10373 2503 +#define MACH_TYPE_RHOBOT 2504 +#define MACH_TYPE_MX51_REFRESH 2505 +#define MACH_TYPE_LS9260 2506 +#define MACH_TYPE_SHANK 2507 +#define MACH_TYPE_QSD8X50_ST1 2508 +#define MACH_TYPE_AT91SAM9M10EKES 2509 +#define MACH_TYPE_HIRAM 2510 +#define MACH_TYPE_PHY3250 2511 +#define MACH_TYPE_EA3250 2512 +#define MACH_TYPE_FDI3250 2513 +#define MACH_TYPE_WHITESTONE 2514 +#define MACH_TYPE_AT91SAM9263NIT 2515 +#define MACH_TYPE_CCMX51 2516 +#define MACH_TYPE_CCMX51JS 2517 +#define MACH_TYPE_CCWMX51 2518 +#define MACH_TYPE_CCWMX51JS 2519 +#define MACH_TYPE_MINI6410 2520 +#define MACH_TYPE_TINY6410 2521 +#define MACH_TYPE_NANO6410 2522 +#define MACH_TYPE_AT572D940HFNLDB 2523 +#define MACH_TYPE_HTCLEO 2524 +#define MACH_TYPE_AVP13 2525 +#define MACH_TYPE_XXSVIDEOD 2526 +#define MACH_TYPE_VPNEXT 2527 +#define MACH_TYPE_SWARCO_ITC3 2528 +#define MACH_TYPE_TX51 2529 +#define MACH_TYPE_DOLBY_CAT1021 2530 +#define MACH_TYPE_MX28EVK 2531 +#define MACH_TYPE_PHOENIX260 2532 +#define MACH_TYPE_UVACA_STORK 2533 +#define MACH_TYPE_SMARTQ5 2534 +#define MACH_TYPE_ALL3078 2535 +#define MACH_TYPE_CTERA_2BAY_DS 2536 +#define MACH_TYPE_SIOGENTOO3 2537 +#define MACH_TYPE_EPB5000 2538 +#define MACH_TYPE_HY9263 2539 +#define MACH_TYPE_ACER_TEMPO_M900 2540 +#define MACH_TYPE_ACER_TEMPO_DX900 2541 +#define MACH_TYPE_ACER_TEMPO_X960 2542 +#define MACH_TYPE_ACER_ETEN_V900 2543 +#define MACH_TYPE_ACER_ETEN_X900 2544 +#define MACH_TYPE_BONNELL 2545 +#define MACH_TYPE_OHT_MX27 2546 +#define MACH_TYPE_HTCQUARTZ 2547 +#define MACH_TYPE_DAVINCI_DM6467TEVM 2548 +#define MACH_TYPE_C3AX03 2549 +#define MACH_TYPE_MXT_TD60 2550 +#define MACH_TYPE_ESYX 2551 +#define MACH_TYPE_DOVE_DB2 2552 +#define MACH_TYPE_BULLDOG 2553 +#define MACH_TYPE_DERELL_ME2000 2554 +#define MACH_TYPE_BCMRING_BASE 2555 +#define MACH_TYPE_BCMRING_EVM 2556 +#define MACH_TYPE_BCMRING_EVM_JAZZ 2557 +#define MACH_TYPE_BCMRING_SP 2558 +#define MACH_TYPE_BCMRING_SV 2559 +#define MACH_TYPE_BCMRING_SV_JAZZ 2560 +#define MACH_TYPE_BCMRING_TABLET 2561 +#define MACH_TYPE_BCMRING_VP 2562 +#define MACH_TYPE_BCMRING_EVM_SEIKOR 2563 +#define MACH_TYPE_BCMRING_SP_WQVGA 2564 +#define MACH_TYPE_BCMRING_CUSTOM 2565 +#define MACH_TYPE_ACER_S200 2566 +#define MACH_TYPE_BT270 2567 +#define MACH_TYPE_ISEO 2568 +#define MACH_TYPE_CEZANNE 2569 +#define MACH_TYPE_LUCCA 2570 +#define MACH_TYPE_SUPERSMART 2571 +#define MACH_TYPE_CS_MISANO 2572 +#define MACH_TYPE_MAGNOLIA2 2573 +#define MACH_TYPE_EMXX 2574 +#define MACH_TYPE_OUTLAW 2575 +#define MACH_TYPE_RIOT_BEI2 2576 +#define MACH_TYPE_RIOT_VOX 2577 +#define MACH_TYPE_RIOT_X37 2578 +#define MACH_TYPE_MEGA25MX 2579 +#define MACH_TYPE_BENZINA2 2580 +#define MACH_TYPE_IGNITE 2581 +#define MACH_TYPE_FOGGIA 2582 +#define MACH_TYPE_AREZZO 2583 +#define MACH_TYPE_LEICA_SKYWALKER 2584 +#define MACH_TYPE_JACINTO2_JAMR 2585 +#define MACH_TYPE_GTS_NOVA 2586 +#define MACH_TYPE_P3600 2587 +#define MACH_TYPE_DLT2 2588 +#define MACH_TYPE_DF3120 2589 +#define MACH_TYPE_ECUCORE_9G20 2590 +#define MACH_TYPE_NAUTEL_LPC3240 2591 +#define MACH_TYPE_GLACIER 2592 +#define MACH_TYPE_PHRAZER_BULLDOG 2593 +#define MACH_TYPE_OMAP3_BULLDOG 2594 +#define MACH_TYPE_PCA101 2595 +#define MACH_TYPE_BUZZC 2596 +#define MACH_TYPE_SASIE2 2597 +#define MACH_TYPE_DAVINCI_CIO 2598 +#define MACH_TYPE_SMARTMETER_DL 2599 +#define MACH_TYPE_WZL6410 2600 +#define MACH_TYPE_WZL6410M 2601 +#define MACH_TYPE_WZL6410F 2602 +#define MACH_TYPE_WZL6410I 2603 +#define MACH_TYPE_SPACECOM1 2604 +#define MACH_TYPE_PINGU920 2605 +#define MACH_TYPE_BRAVOC 2606 +#define MACH_TYPE_CYBO2440 2607 +#define MACH_TYPE_VDSSW 2608 +#define MACH_TYPE_ROMULUS 2609 +#define MACH_TYPE_OMAP_MAGIC 2610 +#define MACH_TYPE_ELTD100 2611 +#define MACH_TYPE_CAPC7117 2612 +#define MACH_TYPE_SWAN 2613 +#define MACH_TYPE_VEU 2614 +#define MACH_TYPE_RM2 2615 +#define MACH_TYPE_TT2100 2616 +#define MACH_TYPE_VENICE 2617 +#define MACH_TYPE_PC7323 2618 +#define MACH_TYPE_MASP 2619 +#define MACH_TYPE_FUJITSU_TVSTBSOC 2620 +#define MACH_TYPE_FUJITSU_TVSTBSOC1 2621 +#define MACH_TYPE_LEXIKON 2622 +#define MACH_TYPE_MINI2440V2 2623 +#define MACH_TYPE_ICONTROL 2624 +#define MACH_TYPE_SHEEVAD 2625 +#define MACH_TYPE_QSD8X50A_ST1_1 2626 +#define MACH_TYPE_QSD8X50A_ST1_5 2627 +#define MACH_TYPE_BEE 2628 +#define MACH_TYPE_MX23EVK 2629 +#define MACH_TYPE_AP4EVB 2630 +#define MACH_TYPE_STOCKHOLM 2631 +#define MACH_TYPE_LPC_H3131 2632 +#define MACH_TYPE_STINGRAY 2633 +#define MACH_TYPE_KRAKEN 2634 +#define MACH_TYPE_GW2388 2635 +#define MACH_TYPE_JADECPU 2636 +#define MACH_TYPE_CARLISLE 2637 +#define MACH_TYPE_LUX_SFT9 2638 +#define MACH_TYPE_NEMID_TB 2639 +#define MACH_TYPE_TERRIER 2640 +#define MACH_TYPE_TURBOT 2641 +#define MACH_TYPE_SANDDAB 2642 +#define MACH_TYPE_MX35_CICADA 2643 +#define MACH_TYPE_GHI2703D 2644 +#define MACH_TYPE_LUX_SFX9 2645 +#define MACH_TYPE_LUX_SF9G 2646 +#define MACH_TYPE_LUX_EDK9 2647 +#define MACH_TYPE_HW90240 2648 +#define MACH_TYPE_DM365_LEOPARD 2649 +#define MACH_TYPE_MITYOMAPL138 2650 +#define MACH_TYPE_SCAT110 2651 +#define MACH_TYPE_ACER_A1 2652 +#define MACH_TYPE_CMCONTROL 2653 +#define MACH_TYPE_PELCO_LAMAR 2654 +#define MACH_TYPE_RFP43 2655 +#define MACH_TYPE_SK86R0301 2656 +#define MACH_TYPE_CTPXA 2657 +#define MACH_TYPE_EPB_ARM9_A 2658 +#define MACH_TYPE_GURUPLUG 2659 +#define MACH_TYPE_SPEAR310 2660 +#define MACH_TYPE_SPEAR320 2661 +#define MACH_TYPE_ROBOTX 2662 +#define MACH_TYPE_LSXHL 2663 +#define MACH_TYPE_SMARTLITE 2664 +#define MACH_TYPE_CWS2 2665 +#define MACH_TYPE_M619 2666 +#define MACH_TYPE_SMARTVIEW 2667 +#define MACH_TYPE_LSA_SALSA 2668 +#define MACH_TYPE_KIZBOX 2669 +#define MACH_TYPE_HTCCHARMER 2670 +#define MACH_TYPE_GUF_NESO_LT 2671 +#define MACH_TYPE_PM9G45 2672 +#define MACH_TYPE_HTCPANTHER 2673 +#define MACH_TYPE_HTCPANTHER_CDMA 2674 +#define MACH_TYPE_REB01 2675 +#define MACH_TYPE_AQUILA 2676 +#define MACH_TYPE_SPARK_SLS_HW2 2677 +#define MACH_TYPE_ESATA_SHEEVAPLUG 2678 +#define MACH_TYPE_MSM7X30_SURF 2679 +#define MACH_TYPE_MICRO2440 2680 +#define MACH_TYPE_AM2440 2681 +#define MACH_TYPE_TQ2440 2682 +#define MACH_TYPE_LPC2478OEM 2683 +#define MACH_TYPE_AK880X 2684 +#define MACH_TYPE_COBRA3530 2685 +#define MACH_TYPE_PMPPB 2686 +#define MACH_TYPE_U6715 2687 +#define MACH_TYPE_AXAR1500_SENDER 2688 +#define MACH_TYPE_G30_DVB 2689 +#define MACH_TYPE_VC088X 2690 +#define MACH_TYPE_MIOA702 2691 +#define MACH_TYPE_HPMIN 2692 +#define MACH_TYPE_AK880XAK 2693 +#define MACH_TYPE_ARM926TOMAP850 2694 +#define MACH_TYPE_LKEVM 2695 +#define MACH_TYPE_MW6410 2696 +#define MACH_TYPE_TERASTATION_WXL 2697 +#define MACH_TYPE_CPU8000E 2698 +#define MACH_TYPE_CATANIA 2699 +#define MACH_TYPE_TOKYO 2700 +#define MACH_TYPE_MSM7201A_SURF 2701 +#define MACH_TYPE_MSM7201A_FFA 2702 +#define MACH_TYPE_MSM7X25_SURF 2703 +#define MACH_TYPE_MSM7X25_FFA 2704 +#define MACH_TYPE_MSM7X27_SURF 2705 +#define MACH_TYPE_MSM7X27_FFA 2706 +#define MACH_TYPE_MSM7X30_FFA 2707 +#define MACH_TYPE_QSD8X50_SURF 2708 +#define MACH_TYPE_QSD8X50_COMET 2709 +#define MACH_TYPE_QSD8X50_FFA 2710 +#define MACH_TYPE_QSD8X50A_SURF 2711 +#define MACH_TYPE_QSD8X50A_FFA 2712 +#define MACH_TYPE_ADX_XGCP10 2713 +#define MACH_TYPE_MCGWUMTS2A 2714 +#define MACH_TYPE_MOBIKT 2715 +#define MACH_TYPE_MX53_EVK 2716 +#define MACH_TYPE_IGEP0030 2717 +#define MACH_TYPE_AXELL_H40_H50_CTRL 2718 +#define MACH_TYPE_DTCOMMOD 2719 +#define MACH_TYPE_GOULD 2720 +#define MACH_TYPE_SIBERIA 2721 +#define MACH_TYPE_SBC3530 2722 +#define MACH_TYPE_QARM 2723 +#define MACH_TYPE_MIPS 2724 +#define MACH_TYPE_MX27GRB 2725 +#define MACH_TYPE_SBC8100 2726 +#define MACH_TYPE_SAARB 2727 +#define MACH_TYPE_OMAP3MINI 2728 +#define MACH_TYPE_CNMBOOK7SE 2729 +#define MACH_TYPE_CATAN 2730 +#define MACH_TYPE_HARMONY 2731 +#define MACH_TYPE_TONGA 2732 +#define MACH_TYPE_CYBOOK_ORIZON 2733 +#define MACH_TYPE_HTCRHODIUMCDMA 2734 +#define MACH_TYPE_EPC_G45 2735 +#define MACH_TYPE_EPC_LPC3250 2736 +#define MACH_TYPE_MXC91341EVB 2737 +#define MACH_TYPE_RTW1000 2738 +#define MACH_TYPE_BOBCAT 2739 +#define MACH_TYPE_TRIZEPS6 2740 +#define MACH_TYPE_MSM7X30_FLUID 2741 +#define MACH_TYPE_NEDAP9263 2742 +#define MACH_TYPE_NETGEAR_MS2110 2743 +#define MACH_TYPE_BMX 2744 +#define MACH_TYPE_NETSTREAM 2745 +#define MACH_TYPE_VPNEXT_RCU 2746 +#define MACH_TYPE_VPNEXT_MPU 2747 +#define MACH_TYPE_BCMRING_TABLET_V1 2748 +#define MACH_TYPE_SGARM10 2749 +#define MACH_TYPE_CM_T3517 2750 +#define MACH_TYPE_OMAP3_CPS 2751 +#define MACH_TYPE_AXAR1500_RECEIVER 2752 +#define MACH_TYPE_WBD222 2753 +#define MACH_TYPE_MT65XX 2754 +#define MACH_TYPE_MSM8X60_SURF 2755 +#define MACH_TYPE_MSM8X60_SIM 2756 +#define MACH_TYPE_VMC300 2757 +#define MACH_TYPE_TCC8000_SDK 2758 +#define MACH_TYPE_NANOS 2759 +#define MACH_TYPE_STAMP9G10 2760 +#define MACH_TYPE_STAMP9G45 2761 +#define MACH_TYPE_H6053 2762 +#define MACH_TYPE_SMINT01 2763 +#define MACH_TYPE_PRTLVT2 2764 +#define MACH_TYPE_AP420 2765 +#define MACH_TYPE_HTCSHIFT 2766 +#define